Resource provisioning uses a REST POST request sent to the APS controller, which in turn will interact with the application service responsible for the requested resource type.
APS implements two different ways of synchronizing the resource provisioning:
synchronous and asynchronous.
The APS controller explicitly specifies it in the APS-Request-Phase
header of a REST request.
The APS controller can provision a single resource as explained in the Synchronous Provisioning and Asynchronous Provisioning sections or a bunch of resources as explained in Batch Provisioning.
Warning
The size of a payload sent in a POST request must comply with the Limitations.
In this document:
To require a sync
provisioning, the APS controller must use the POST request with
the APS-Request-Phase:sync
header. In the following example,
a user requests creation of a VPS. The controller forwards the POST request
to the application service endpoint (/vpscloud/vpses/) defined in the APS connector. It also specifies
that the request must be processed in the sync
mode.
The APS application instance (or simply application) must call the provision()
method
that returns the completion
code notifying about success or failure. In the example above, the application notifies
the APS controller about successful completion of the operation. The APS controller
forwards the return code to the initiator of the operation. The resource status will be
aps:ready
.
Asynchronous provisioning is started the same way as the synchronous operation considered earlier. The application service must decide whether to complete the operation as synchronous or transfer it to asynchronous. The whole transaction actually contains two request phases.
The transaction is started with the synchronous phase, as described earlier.
The APS controller requires the synchronous provisioning by sending a POST request
with the APS-Request-Phase:sync
header.
Once a sync
request is received, the application will call the method for synchronous provisioning.
If APS PHP runtime is used, it must be the provision()
method.
The difference starts here. The method contains a decision code that completes
the provisioning either synchronously (as described earlier) or informs the APS controller
that the provisioning can be started in the async
mode.
Here, we will consider the second case, when the application service requires transferring to
the asynchronous phase. Therefore, it returns the 202 Accepted code to the APS controller. In the same
response packet, it sends two headers that helps the APS controller to arrange the async
phase.
The APS-Info
header contains task description, and the APS-Retry-Timeout
header
defines the period the controller must use for sending subsequent requests.
Once the 202 Accepted code is received, the APS controller completes the synchronous phase by forwarding
the response to the initiator of the operation. The resource status will be aps:provisioning
.
The asynchronous phase is processed as follows.
The APS controller calls the task manager of the hosting platform to schedule a workflow
and set its timeout equal to APS-Retry-Timeout
. In accordance with this workflow,
the task manager must wake up the APS controller to initiate the asynchronous request.
First time, the task manager will activate the scheduled workflow immediately. The APS
controller sends its first async
request to the endpoint to confirm its readiness to proceed in the
asynchronous mode. This time, inside the endpoint, the method for async
provisioning must be called.
APS PHP runtime calls the provisionAsync()
class method, when a provisioning operation with
APS-Request-Phase:async
is required.
If the endpoint returns the expected 202 Accepted code, the APS controller reschedules the workflow task.
Next time, the task manager runs the scheduled task not earlier than the specified APS-Retry-Timeout
value.
This is repeated until the endpoint returns a code different from 202 Accepted.
Once a code different from 202 Accepted is received, the APS controller calls the task manager
to finish the scheduled workflow. If the requested resource was created successfully, its
status will be aps:ready
.
The following example illustrates how the APS PHP runtime on the application endpoint helps to develop operations for synchronous and asynchronous provisioning. The sample code defines two operations in the custom vps class.
The provision()
method is called when the request for the sync
provisioning is received.
It checks the hardware->VM property to identify the kind of VPS required.
If VM
is false, a container must be created. Since this does not take long, the synchronous
operation is completed successfully. Actually, the provision()
function does nothing in this case,
and the PHP runtime returns 200 OK to the APS controller.
If VM
is true, the virtual machine (VM) is required. Since this usually takes long,
the method throws the exception that the PHP runtime processes and returns 202 Accepted
to the APS controller.
In the code here, we simulate 5 retries with 30 sec timeout.
public function provision() {
// VM requires more time, thus the *async* operation is required
if ($this->hardware->VM) {
$this->state = "creating"; // VPS state is intermediate
$this->retry = 5; // Assuming VM provisioning requires 5 retries
// Throw exception to return code *202 Accepted* to APS controller
throw new \Rest\Accepted($this, "Creating VPS", 30);
}; // Else do nothing to return code *200 OK*
}
public function provisionAsync() {
$this->retry -=1; // Decrement the retry counter
if ($this->retry <= 0) {
$this->state = "ready"; // Finish the Async operation - return *200 OK* to APSC
}
else { // Return code *202 Accepted*
throw new \Rest\Accepted($this, "Creating VPS", 30);
}
}
When the endpoint receives a request for async
provisioning, it calls the provisionAsync()
method.
If the provisioning is not completed (simulated by a number of retries), the function throws
the same exception as the provision()
function does. The 202 Accepted code is returned.
The state
property is an internal resource property managed by the provisioning code as needed. It can
be used by the custom UI script to display the VPS state to users.
If the provisioning is completed, the function will not throw an exception, and the PHP runtime returns the 200 OK code to the APS controller.
If it is often necessary to provision many resources at a time, the application developer can use the batch provisioning operation. The REST request looks as follows:
POST /aps/2/resources
[
{
"aps": {
"type": "APS type ID",
"id": "APS ID - optional property"
},
"<property-1>": "<value-1",
...
"<link1>": { "aps": { "id": "APS ID of the resource to link with" }},
...
},
{
"aps": {
"type": "APS type ID",
"id": "APS ID - optional property"
},
"<other properties>": "<other properties"
...
"<link1>": { "aps": { "id": "APS ID of the resource to link with" }},
...
},
...
]
Note the specifics:
The body of a batch request is an array of JSON representations of APS resources.
To link a resource to another resource, the APS ID of the latter resource must be contained explicitly in the JSON representation of the former resource as demonstrated in the Create APS Resources example.
Once the APS controller receives a request for batch provisioning, it schedules provisioning of each resource in the list one by one ordering them in a queue in accordance with these rules:
If there are resources to be linked to each other, the APS controller provisions firstly those resources that have dependents.
If resources are not related to each other in the resource model, the order of their provisioning is unpredictable.
The provisioning rules are not affected by the provisioning type - whether some of the resources are provisioned synchronously and the others asynchronously.
When testing and debugging your APS application provisioning, be aware that if a subscription has more than one resource to be auto-provisioned, those resources are provisioned through a batch request and all of the above rules are in action.
When provisioning a resource by a request from the APS controller, the application can request the APS controller to provision some resources and link them with the resource being processed. Also, the application may require the APS controller to link existing resources with the resource being processed. Normally, the APS controller rejects such requests until the resource is provisioned and gets the aps:ready status. However, if the application adds the sub-requests to the started transaction, the APS controller overcomes that limitation.
If processing of the initial request or a sub-request fails, the APS controller rolls back the whole transaction.