Push Configuration Workflow
With push configuration, an external process uses ARI to perform a configuration operation. The configuration operation could be any one of the four classic operations for persistent storage - Create, Retrieve, Update, or Delete. For the purposes of this workflow, we'll assume that the operation is to create a configuration change in Asterisk.
The ARI client makes a
PUT request, where the body contains the configuration object to create, encoded in JSON. This is first handled by ARI, which performs basic validation on the inbound request and its contents. Once the request is validated, ARI asks the Sorcery framework to create the actual object.
Sorcery requires three pieces of information, at a minimum, to create an object:
- The overall class of configuration types. This is usually a module or namespace that provides multiple types of objects to be created, e.g., 'res_pjsip'.
- The type of configuration object to create, e.g., 'endpoint'.
- A unique identifier (amongst objects of the same type) for the object, e.g., 'alice'.
Once Sorcery has determined that it knows how to create the type of object, it creates it using the provided data in the JSON body. If some piece of data in the body can't be converted to an attribute on the object, the inbound request is rejected.
If the object is created successfully, Sorcery then has to determine what to do with it. While we've just had a piece of configuration pushed to Asterisk, Sorcery is responsible for storing it in some permanent - or semi-permanent - storage. For this, it looks to its configuration in
sorcery.conf. We'll assume that our object should be created in the AstDB, a SQLite database. In that case, Asterisk pushes the newly created object to
res_sorcery_astdb, which is the Sorcery driver for the AstDB. This module then writes the information to the SQLite database.
When the PJSIP stack next needs the object - such as when an
INVITE request is received that maps to Alice's endpoint - it queries Sorcery for the object. At this point, from Sorcery's perspective, the retrieval of the configuration information is exactly the same as if a static configuration file or a relational database was providing the information, and it returns the pushed configuration information.
To make use of push configuration, you must configure Sorcery to persist the pushed configuration somewhere. If you don't want the information to persist beyond reloads, you can use the in-memory Sorcery driver,
res_sorcery_memory. The example below assumes that we will push configuration to the PJSIP stack, and that we want information to persist even if Asterisk is restarted. For that reason, we'll use the AstDB.
Pushing PJSIP Configuration
This walk-through will show how we can use the
asterisk resource in ARI to push a PJSIP endpoint into the AstDB, and then later remove the endpoint.
Original PJSIP Configuration
Assume we have the following static PJSIP configuration file that defines an endpoint for Alice:
If we then ask Asterisk what endpoints we have, it will show us something like the following:
Our goal is to recreate alice, using ARI.
Remove Alice from
Tell the Sorcery data abstraction framework to pull endpoint, aor, and auth objects from the Asterisk Database:
Now, if we ask Asterisk for the PJSIP endpoints, it will tell us none are defined:
First, let's push in Alice's authentication:
We can note a few things from this:
- We supply the non-default values that make up Alice's authentication in the JSON body of the request. The body specifies the "fields" to update, which is a list of attributes to modify on the object we're creating.
- We don't have to provide default values for the object. This includes the "type" attribute - ARI is smart enough to figure out what that is from the request URI, where we specify that we are creating an "auth" object.
- When we've created the object successfully, ARI returns back all the attributes that make up that object as a list of attribute/value pairs - even the attributes we didn't specify.
Next, we can push in Alice's AoRs:
Finally, we can push in Alice's endpoint:
We can now verify that Alice's endpoint exists:
We can also verify that Alice exists in the AstDB:
If we no longer want Alice to have an endpoint, we can remove it and its related objects using the
And we can confirm that Alice no longer exists: