Decide how requests are handled

Resource management determines whether a supported HTTP operation proceeds immediately or waits for the agent’s decision. Choose that boundary from your resource contract, rather than from whether the agent performs proactive work.

Start with passive management

The greeting collection from chapter 2 processes supported writes directly and notifies the agent afterward. This fits a contract where creating or replacing data is permitted without deliberation. The agent may still reason proactively after the change.

A passive resource handles a write and separately notifies the agent.

If a later agent plan cannot achieve a business goal, that does not undo the earlier HTTP write. Model that outcome explicitly, as the delivery tutorial does with status: "failed".

Intercept a supported request

An active resource queues a supported request and emits httpEvent(Index, Method). The index identifies that request on that artifact. The agent can inspect it and call !acceptRequest or !refuseRequest.

An active resource waits for acceptance or refusal before invoking the resource handler.

Extending mams.javatypes.Active alone does not install a restrictive policy: its inherited handler accepts requests. Override the general event handler so methods you did not intend to permit do not fall through to that default.

Download the active read-only item. Its policy is:

agent Main extends mams.javatypes.Active {
    module Strings strings;

    plan +!main(list args) {
        mams.MAMSAgent::!setup();
        mams.MAMSAgent::!created("base");
        mams.javatypes.Active::!itemResource("hello", "Hello");
    }

    plan $cartago.signal(string ArtifactName, httpEvent(int Index, string Method))
        : artifact(string Name, ArtifactName, cartago.ArtifactId Id) {
        if (Method == "GET" | Method == "OPTIONS") {
            mams.javatypes.Active::!acceptRequest(Index, ArtifactName);
        } else {
            mams.javatypes.Active::!refuseRequest(Index, ArtifactName);
        }
    }
}

Stop the passive service and start this project with mvn clean compile astra:run. GET /main/hello succeeds. Try the same PUT as chapter 1: it now returns 403 Forbidden, and a following GET shows the unchanged state.

An unsupported method returns 405 before the decision plan. 403 means the resource supports the operation but the agent refused it. These two outcomes tell clients different things.

Complete the decision on every path

Inspect pending headers or a JSON body before accepting or refusing; either decision consumes the queued request. A late or duplicate decision fails with unknown_http_event. The default decision window is 30 seconds; expiry returns 504.

Keep interception short. Long-running business work belongs after submission, with a result resource clients can read. Ensure inspection failures also lead to a refusal or another explicit outcome: a failed plan does not automatically become an HTTP refusal. The detailed request handling section covers operations for inspecting the queue.

A read-only policy is not authentication. Checking an Authorization header requires a real application policy for validating it; simply finding the header does not identify a caller.

Apply the contract to delivery requests

For deliveries, permit POST to the collection and GET to read results. Refuse client PUT and DELETE because they could overwrite agent-owned progress or remove a live request. On creation, reset service-owned fields rather than trusting them in the client’s JSON.

There are two validation moments:

Moment

Outcome a client can observe

Before creation

An HTTP error and no newly created request

After creation, in the agent

A request resource recording a failed business outcome

The existing delivery example uses the second approach for missing business fields. Its 201 response therefore does not guarantee that a valid delivery was accepted or completed. Choose and document the semantics deliberately.

Try it

Test GET, PUT and an unsupported method against the read-only item. Then inspect the delivery policy and identify which part prevents a client from claiming a parcel has been delivered.

Next: Connect services.

Further Details