Management

Last updated: 18 Jun 18 20:39 CEST

Management Overview

Many of the operations on the adlantics platform make use of core data defined specifically for a realm. Core data (or settings) of this kind is often persistent, that is, it is defined once, stored by the adlantics platform, and referenced on all subsequent invocations. Examples of such data are schema definitions, hierarchies, notifications, etc. This is in contrast to transient, short-lived data such as tokens or one-off queries that are submitted in a header or request body where they only affect the current operation. The adlantics Management (mg) service provides the interface for managing persistent data, as well as other, platform-generated data of a supplemental, realm-wide nature such as activity statistics, billing information, etc.

We refer the reader to the platform overview for a high-level introduction to the adlantics platform, and we recommend completing the quick start tutorial, which covers basic considerations such as connecting and authenticating. For the purpose of this article, we will assume basic familiarity with web services and with accessing the same from the command line. We will also assume that you have successfully authenticated to the platform as described in the quick start tutorial.

Preliminaries

Before delving into the management features of the mg service, we discuss a number of data structures and conventions that recur throughout the mg service and the adlantics platform more generally.

Response Status

The response status codes of mg's create, read, update, and delete (CRUD) operations follow the general conventions for RESTful services:

  • status 200 is returned in response to a successful operation
  • status 403 is returned if the caller is not authorized to perform the requested operation
  • status 404 is returned if the referenced data item is unknown

Note that the identifiers for data items within adlantics mg are user-selected. Consequently, the PUT and POST verbs have identical "create or update" semantics. In particular, the PUT verb does not return a 201 status code with a URI for the item in the response body as the URI is known ahead of time.

Artifact Descriptors

Core data on the adlantics platform must be identifiable and in some cases versioned. Consider, for example, the organizational structure of a learning organization and its evolution over time. If we wish to refer to this "org chart" from within our xAPI statements we need a way of referencing it as a distinct data item, and we may additionally need the ability to refer to its state at a given moment in time (in case the structure changes over time). The adlantics platform uses so-called (versioned) artifact descriptor to achieve these goals.

An artifact descriptor is an object consisting of one or two attributes that follow certain syntactic conventions. As an example of a valid artifact descriptor consider the following object in JSON notation:

{
    "artifact": "com.adlantics.lo",
    "version": "1.0.0"
}

This example illustrates certain key characteristics of artifact descriptors. Artifact descriptors:

  • have a mandatory artifact name in reverse domain name notation as used in many popular programming languages. Artifact names consist of 1 - 128 lowercase latin characters, digits, underscores, or periods and must uniquely identify a data item. The uniqueness requirement refers only to a given realm and a specific data type within the realm (e.g., the set of all hierarchies).
  • have an optional version of the commonly used dot-separated numeric type. Versions must consist of 1 - 16 digits and periods.

When printing artifact descriptors, the system sometimes uses the alternative artifact descriptor string notation:

com.adlantics.lo-1.0.0

While the interpretation of data items identified by artifact descriptors is beyond the scope of this section we note that the usual version semantics apply. In particular, users should be careful when changing data associated with a particular version number and follow strict versioning practices instead.

Language Maps

Many data items on the adlantics platform are labeled with a human-readable label. Because analytics consumers often speak different languages, the adlantics platform is built with multi-language support from the ground up. Language maps are simple constructs used to express multi-lingual labels. The following example illustrates the concept:

{
    "en": "Air Law",
    "de": "Luftrecht",
    "nl": "Luchtwet"
}

Language maps must contain at least one language / label pair where the locale is denoted using the IETF BCP 47 notation for language identification and the label is any single-line unicode string. The interpretation of language maps, in particular the selection of a language, is specific to each operation, but as a general rule of thumb the adlantics platform will select the language a user requested if available, and fall back to English if the requested language is unavailable or if the request did not contain a language preference.

Managing Hierarchies

Hierarchies are one of the key building blocks underlying adlantics' analytical capabilities. Whereas the xAPI specification has no built-in notion of hierarchies, many real-world applications rely heavily on hierarchical structures, some of which evolve over time. Two prominent examples of hierarchical structures in learning environments are learning outcome statements (i.e., hierarchies of learning outcomes that learners have to achieve) and organizational structures (i.e., the hierarchies of departments, units, and classes used to organize the totality of learners). By making the hierarchical structure in our data explicit to the system, powerful analytical capabilities become available, such as breakdowns of key performance metrics across the organization, or statistical comparisons between cohorts over time.

Within the adlantics platform, hierarchies are a general construct that is used across many different application areas. The following example illustrates the concept using a learning outcome statement:

{
    "artifact": {
        "artifact": "com.adlantics.lo",
        "version": "1.0.0"
    },
    "items": [
        {
            "id": "010 00 00 00 00",
            "title": {
                "en": "Air Law",
                "de": "Luftrecht"
            },
            "children": [
                {
                    "id": "010 01 00 00 00",
                    "title": {
                        "en": "International Law",
                        "de": "Internationales Recht"
                    },
                    ...

The example shows several key characteristics of hierarchies:

  • Hierarchies are general forests, that is, they consist of zero or more items at the highest level, each of which may have zero or more children in turn. Hierarchies do not have to be balanced, i.e., they can be deeper in some branches than in others.
  • Each item has a mandatory identifier (id) that must be unique across the entire hierarchy. There are no constraints on identifiers other than their uniqueness. While all identifiers in the example are numeric and reflect the structure of the items themselves, "ID/Q/z(7)" is a legitimate identifier and "Q62543" is a legitimate identifier for one of its children.
  • Items can be optionally labeled using the language map construct used above.

A realm may contain an arbitrary number of hierarchies and in the following sections we will show how these are managed using the mg interface. To access or change hierarchies callers must be authenticated and hold the read or write permission on the target realm, respectively. Note that the adlantics mg is only concerned with the storage and retrieval of hierarchies. The specifics of how these hierarchies are used are explained in the context of other adlantics services, such as the Experience Store.

Reading

All hierarchies within a given realm are identified by their (versioned) artifact descriptors. The hierarchy behind an artifact descriptor can be retrieved from the /hierarchy/<id> endpoint, where id refers to the artifact descriptor string:

curl -XGET -H"Realm: [your realm]" \
           -H"Authorization: Bearer [your access token]" \
            https://mg.adlantics.com/hierarchy/com.adlantics.lo-1.0.0
[
    {
        "artifact": {
            "artifact": "com.adlantics.lo",
            "version": "1.0.0"
        },
        "items": [ ... ]
    }
]

Because hierarchies can become quite large, mg provides an additional HEAD operation on the /hierarchy/<id> endpoint that returns only the response headers (in particular, the status code) without the response body.

curl -XHEAD -H"Realm: [your realm]" \
            -H"Authorization: Bearer [your access token]" \
             https://mg.adlantics.com/hierarchy/com.adlantics.lo-1.0.0

Creating and Updating

Callers can create new or update existing hierarchies through a PUT or POST on the /hierarchy/<id> endpoint where the body contains the new hierarchy in JSON format:

curl -XPUT -H"Realm: [your realm]" \
           -H"Authorization: Bearer [your access token]" \
           -d '{
                 "artifact": {
                   "artifact": "com.adlantics.lo",
                   "version": "1.0.0"
                 },
                  "items": [ ... ]
               }' \
            https://mg.adlantics.com/hierarchy/com.adlantics.lo-1.0.0

The POST verb has the same "create or update" semantics as PUT.

Deleting

Callers can delete existing hierarchies through a DELETE on the /hierarchy/<id> endpoint:

curl -XDELETE -H"Realm: [your realm]" \
              -H"Authorization: Bearer [your access token]" \
               https://mg.adlantics.com/hierarchy/com.adlantics.lo-1.0.0

Delete operations are exceptional as hierarchies should be immutable and changes to existing hierarchies should usually be indicated through a new version.

Managing Notifications

Notifications are a feature of the adlantics Experience Store (xs) through which callers can request callbacks from xs whenever a realm's data changes in such a way that the result of a query can be expected to change. Notifications follow a publish-subscribe pattern where callers first create a named subscription, called notification definition, to a given series of events identified by an xs query. Callers are then notified under the chosen name whenever the notification is triggered.

Notification definitions must be named uniquely within a realm and their names must consist of 1 - 16 lower- or uppercase latin characters, underscores, or digits.

A realm may contain an arbitrary number of notification definitions and in the following sections we will show how these are managed using the mg interface. To access or change notification definitions callers must be authenticated and hold the read or write permission on the target realm, respectively.

Reading

All notification definitions within a realm can be retrieved from the /notifications (plural) endpoint:

curl -XGET -H"Realm: [your realm]" \
           -H"Authorization: Bearer [your access token]" \
            https://mg.adlantics.com/notifications
{
    "startedstmts": {
        "facts": [],
        "filter": {
            "field": "verb_id",
            "value": "http://adxx.io/started"
        },
        "axes": []
    }
}

The response to this request is a map where the keys ("startedstmts" in the example) are the identifiers and the values are the notification definitions. See the xs documentation for more details on the query and notification definition syntax.

If the identifier or identifiers of the desired notification definition are known, the /notification/<ids> (singular) endpoint can be used instead, where ids may contain a comma-separated list of identifiers:

curl -XGET -H"Realm: [your realm]" \
           -H"Authorization: Bearer [your access token]" \
            https://mg.adlantics.com/notification/n1,n2
[
    { n1 },
    { n2 },
    ...
]

Creating and Updating

Callers can create new or update existing notification definitions through a PUT or POST on the /notification/<id> (singular) endpoint where the body contains the new notification definition in JSON format:

curl -XPUT -H"Realm: [your realm]" \
           -H"Authorization: Bearer [your access token]" \
           -d '{
                   "facts": [],
                   "filter": {
                       "field": "verb_id",
                       "value": "http://adxx.io/started"
                   },
                   "axes": []
               }' \
            https://mg.adlantics.com/notification/startedstmts

The POST verb has the same "create or update" semantics as PUT.

Deleting

Callers can delete existing notification definitions through a DELETE on the /hierarchy/<id> endpoint:

curl -XDELETE -H"Realm: [your realm]" \
              -H"Authorization: Bearer [your access token]" \
               https://mg.adlantics.com/notification/startedstmts