MAMS resource API reference

This reference covers the interfaces used by the Java-Types examples with MAMS 2.4.1 and ASTRA 2.6.1. It describes the source at MAMS commit 280367e and distinguishes ASTRA goals, beliefs, events and CArtAgO operations. For a runnable introduction, see Your first MAMS service.

Application and resource goals

The first five goals below are provided by mams.MAMSAgent; the resource creation goals are supplied by mams.javatypes.Passive or mams.javatypes.Active.

Goal

Purpose and prerequisites

!setup()

Start local CArtAgO infrastructure, web server and REST client on port 9000. Call once per application.

!setup(int Port)

Perform setup on the chosen port.

!init()

Join the local environment and find the existing web server and REST client. Other agents call this after setup has completed.

!created("base")

Create this agent’s resource base and route it through the web server. Requires initialisation.

!agentUri(string Uri)

Obtain the URI of this agent’s resource base. Requires the base to exist.

!itemResource(string Name, string ClassName)

Create an individual item beneath the base, link it, focus on it and record its artifact. Use a fully qualified Java data class name when it has a package.

!listResource(string Name, string ClassName)

Create a collection beneath the base. Each child uses the specified Java data class.

!createResource(string Name, string Parent, string ArtifactClass, list Params, cartago.ArtifactId Id)

Since 2.4.0, in mams.MAMSAgent. Create a resource from any ResourceArtifact class, linked beneath the resource Parent (for example "base"), routed and focused. Adds artifact(Name, ResName, Id) and uri(ResName, Uri) and gives the resource a self link.

!setResourceHeader(string Name, string Key, string Value)

Since 2.4.0. Send a custom header in the resource’s responses. A header the response sets itself takes precedence.

!addResourceLink(string Name, string Rel, string Href)

Since 2.4.0. Add a link, sent in the resource’s Link header (<href>; rel="rel") and shown in its HAL _links.

For example:

mams.MAMSAgent::!setup();
mams.MAMSAgent::!created("base");
mams.javatypes.Passive::!itemResource("hello", "Hello");
mams.MAMSAgent::!agentUri(string Uri);

These calls belong inside a plan in an agent extending the relevant MAMS class. Do not repeat setup for every agent sharing the same application.

Beliefs and inferences

Formula

Meaning

artifact(string Name, string QualifiedName, cartago.ArtifactId Id)

Maps a logical resource name to its CArtAgO name and identifier. Also records shared infrastructure artifacts.

have(string Name)

Inference indicating that an artifact mapping exists for the logical name.

created(string QualifiedName)

Inference over qualified artifact names; the base creation plan also records created("base"). This is distinct from invoking !created("base").

itemResource(string Name, string ClassName)

Records an item and its Java data class. The current Java-Types classes record items by qualified artifact name, including directly created items and discovered collection children.

listResource(string Name, string ClassName)

Records a collection by its logical name and Java data class.

uri(string QualifiedName, string Uri)

Stores a resource URI where the implementation records one; passive collection creation does so. An inference can resolve a logical name through the artifact mapping.

agentUri(string Uri)

Cached base URI after it has been obtained. Prefer !agentUri(string Uri) when retrieving it.

baseArtifact(string ClassName)

Selects the artifact implementation for the base. The current Java-Types classes initialise it to mams.javatypes.artifacts.BaseJavaTypesArtifact.

Logical and qualified names are not interchangeable. For the main agent’s hello item, a mapping typically has logical name hello and qualified name main-base-hello. Dynamically discovered collection children use their qualified name in both name positions.

Find an item by logical name and then use its identifier:

query(artifact("hello", string QualifiedName, cartago.ArtifactId Id));
cartago.operation(Id, get(Hello Value));

Resource field values are observable artifact properties, rather than ordinary ASTRA beliefs. See CArtAgO observations.

Read and change resource state

Artifact operations below are invoked through cartago.operation(Id, ...). Id must identify the relevant resource artifact, and output arguments are typed unbound variables.

Operation

Meaning

get(Object Value)

Reconstruct the Java object from the resource’s observable properties. A compatible concrete type such as Hello can be used for the output variable.

replace(Object Value)

Apply the supplied object’s field values and emit replaced(Value). Supply the complete state required by your contract.

update(Object Value)

Apply an update and emit patchedResource(Value) in the common typed artifact implementation. It does not invoke the passive !itemUpdated callback automatically.

getStringProperty(string Key, string Value)

Read a string-valued property.

setStringProperty(string Key, string Value)

Update one string-valued observable property. This is not the object replacement operation and does not itself emit replaced.

getUri(string Uri)

Obtain the artifact’s URI.

size(int Count)

Read the number of children of a collection.

Java-Types implementations use public data fields and reflection. In the common typed implementation, replacement skips null field values, so it should not be treated as a general-purpose way of clearing nullable fields. Primitive field defaults and omitted JSON fields also need to be considered when defining partial-update contracts.

The passive agent class additionally provides these wrappers:

Goal

Meaning

!getObject(string ArtifactName, Object Value)

Execute get(Value) on an item whose mapping has ArtifactName in both name positions, as is the case for discovered collection children.

!updateObject(string ArtifactName, Object Value)

Execute update(Value) on an item with that same mapping shape.

!itemUpdated(string ArtifactName, Object Value)

Callback goal invoked by the passive library when it receives replaced(Value). Override its plan to react to replacement.

For a directly created item whose names differ, resolve its artifact(...) mapping and use the operations rather than assuming these wrappers will find it.

Signals and event plans

The first argument of $cartago.signal is the qualified artifact name. The Index in httpEvent identifies a queued request on that artifact.

Event pattern

Meaning and handling

$cartago.signal(string Name, replaced(Object Value))

Resource state was replaced. The passive class translates this into !itemUpdated(Name, Value). Active agents can handle this signal directly.

$cartago.signal(string Name, patchedResource(Object Value))

The common typed artifact’s update operation ran. Handle it explicitly if this notification is part of your contract.

$cartago.signal(string Source, listItemArtifactCreated(string Child, string ClassName))

A child was attached to a collection. The inherited passive and active classes discover and focus on it, then record its artifact and item beliefs.

$cartago.signal(string Name, httpEvent(int Index, string Method))

An active artifact has queued a supported HTTP request and awaits a decision.

+itemResource(string Name, string ClassName)

A resource information belief was added. Commonly used to react to newly discovered collection children. It is a belief event, not a creation goal.

Signal names can vary across resource implementations. These entries describe the Java-Types interfaces used here; they are not a universal event contract for HAL, JSON Schema or RDF artifacts. A field property change can also be observed through CArtAgO property events.

Active request decisions

These goals are supplied by mams.javatypes.Active:

Goal

Effect

!acceptRequest(int Index, string ArtifactName)

Consume the queued request, invoke its resource handler and send the resulting HTTP response. An accepted PUT still updates state and emits its replacement notification.

!refuseRequest(int Index, string ArtifactName)

Consume the queued request and return 403 Forbidden without invoking the requested handler.

Before deciding, inspect the queued request through its artifact:

Operation

Meaning

header(int Index, string HeaderName, string Value)

Read a header; a missing header is returned as an empty string.

jsonBody(int Index, JsonNode Body)

Parse a JSON request body. Requires import com.fasterxml.jackson.databind.JsonNode;. Use only for a suitable body.

Read headers or data before accepting or refusing: either decision removes the queued request. Complete one decision per request, including failure paths. In the current implementation, pending requests expire after 30 seconds with 504 Gateway Timeout. A client disconnect also removes the pending request. Late or duplicate decisions fail the artifact operation with unknown_http_event; handle that failure rather than attempting another response. An artifact subclass can change the decision window by overriding requestTimeout() with a positive Duration. Unsupported HTTP methods return 405 Method Not Allowed before this interception path.

The inherited Java-Types active handler accepts requests by default. Install a complete override to apply a policy; a GET-only override leaves other requests to the inherited handler. See Active resource examples.

Outgoing HTTP goals

These goals are supplied by mams.MAMSAgent. Import mams.web.HttpResponse for the response type and mams.web.HttpRequest for a custom request. Initialisation must have made the shared REST client available.

Goal

Meaning

!get(string Uri, HttpResponse Response)

Read a representation.

!get(string Uri, list Headers, HttpResponse Response)

GET with explicit headers.

!post(string Uri, string JsonBody, HttpResponse Response)

POST a JSON body.

!post(string Uri, string Body, string MediaType, HttpResponse Response)

Since 2.4.0. POST a body with the given media type.

!post(string Uri, list Headers, string Body, HttpResponse Response)

Since 2.4.0. POST with explicit headers.

!put(string Uri, string JsonBody, HttpResponse Response)

PUT a JSON body.

!patch(string Uri, string JsonBody, HttpResponse Response)

PATCH a JSON body, where supported by the target.

!delete(string Uri, HttpResponse Response)

Delete a resource.

!head(string Uri, HttpResponse Response)

Request headers without a response body.

!options(string Uri, HttpResponse Response)

Query supported methods.

!httpRequest(HttpRequest Request, HttpResponse Response)

Execute a request constructed using httpUtils, including custom headers.

Use httpUtils.hasCode(Response, Code) to check the status, httpUtils.bodyAsString(Response) to read content, and httpUtils.header(Response, "Location") to retrieve a created resource’s URI. An HTTP error response is a result to inspect; it is not evidence that the remote business task completed successfully. See the complete HTTP client agent.

See HTTP formats and errors for negotiation, structured error bodies and timeout statuses in the audited implementation.

MAMS 2.4.0 adds WebSub for following changes to resources. MAMS 2.0.0 added optional Hydra/JSON-LD representations through a runtime dependency. It introduces no new ASTRA resource goals; the HTTP goals above can request the new media type and inspect its response.