Application Packaging Standard

Last updated 18-Mar-2019

Resource Configuration

To update resource properties, an initiator must send a REST PUT request to the APS controller. The request contains the resource ID in the URL and the updated properties in the message body. APS controller must forward the request to the application service responsible for the resource. The request contains the updated resource representation in JSON format.

Classification

APS implements two different ways of synchronizing the resource update: synchronous and asynchronous. The APS controller explicitly specifies it in the APS-Request-Phase header of a REST request.

Synchronous Configuration

To require a synchronous update, the APS controller must send a PUT request with the APS-Request-Phase: sync header. In the following diagram, a user requests resource update. The controller forwards the PUT request with the full JSON representation of the updated resource to the application service endpoint (/{svc}/{resource-ID}). It also specifies that the request must be processed by the sync operation.

If PHP runtime is used in the endpoint host, it must call the configure($newConfiguration) method defined in the respective custom service class. The latter 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.

Asynchronous Configuration

Asynchronous configuration starts the same way as the considered earlier synchronous operation does. The application service must decide whether to complete the operation as synchronous or transfer it to the asynchronous phase. The whole transaction actually contains two request phases. In the following diagram, the request body is omitted for brevity.

The transaction is started with the synchronous phase, as described earlier.

  1. The APS controller requires the synchronous update by sending a PUT request with the APS-Request-Phase:sync header.
  2. Once a sync request is received, the endpoint environment will call the method for synchronous update. If APS PHP runtime is used, it must be the configure($newConfiguration) method.
  3. The difference starts here. The method contains a decision code that completes the configuration either synchronously (as described earlier) or informs the APS controller that it can proceed the configuration in the asynchronous 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 help the APS controller to arrange the asynchronous 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.
  4. Once the APS controller receives the 202 Accepted code it completes the synchronous phase by changing the resource status to aps:configuring and forwarding the response to the initiator of the operation.

The asynchronous phase is processed as follows.

  1. 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.
  2. First time, the task manager will activate the scheduled workflow immediately. The APS controller sends its first asynchronous request to the endpoint to confirm its readiness to proceed in the asynchronous mode. If APS PHP runtime is used, it calls the configureAsync($new) method.
  3. If the application returns the expected 202 Accepted code, the APS controller reschedules the workflow task.
  4. Next time, the task manager runs the scheduled task not earlier than the specified APS-Retry-Timeout value. Steps 3 and 4 are repeated until the endpoint returns a code different from 202 Accepted.
  5. Once the APS controller receives a code different from 202 Accepted it requests the task manager to finish the scheduled workflow. If the requested resource was updated successfully and the application did not require to change the resource status in its response, the controller returns the resource status to the value it has when the configuration started, for example, aps:ready.

Note

When responding to a PUT request, the application sends back those properties that it has changed since the previous PUT request. If this list is not empty, the APS controller triggers a respective Changed event.

PHP Runtime Implementation

PHP runtime defines a pair of methods to configure a resource:

  • configure($new=null) - synchronous configuration
  • configureAsync($new=null) - asynchronous configuration

The following example illustrates how the APS PHP runtime on the application endpoint helps develop operations for synchronous and asynchronous configuration. The sample code defines two operations in the custom vps class.

  • The configure() method is called when a request for synchronous configuration is received.

    The method throws the exception that the PHP runtime processes and returns 202 Accepted to the APS controller.

    The following code simulates 5 retries with 30 sec timeout.

    public function configure($new = null) {
        // Save the new object and pass it to APS controller on method completion
        $this->_copy($new);
        if($new != null) {
           $this->state = "Updating"; // VPS state is intermediate
           $this->retry = 5; // Set the number of async cycles
           throw new \Rest\Accepted($this, "Updating VPS", 30); // Return "202 Accepted"
        }
    }
    
  • When the endpoint receives a request for asynchronous configuration, it calls the configureAsync($new) method.

    public function configureAsync($new = null) {
        $this->retry -=1;             // Decrement the retry counter
        if($this->retry == 0) {
           $this->state = "Stopped"; // Finish the Async operation - return "200 OK" to APSC
        }
        else {
           throw new \Rest\Accepted($this, "Updating VPS", 30); // Return "202 Accepted"
        }
    }
    
    • If the configuration is not completed (simulated by a number of retries), the function throws the same exception as the configure($new) function does. The 202 Accepted code is returned. The state property in the above example is an internal resource property managed by the configuration code as needed. The custom UI script can use it to display the VPS state to users.
    • If the configuration is completed, the function will not throw an exception, and the PHP runtime returns the 200 OK code to the APS controller.

Configuration Rules

Status Processing

There are some resource status processing rules that the APS controller follows when configuring a resource:

  • The controller can start a resource configuration if the status of the resource is in the ready range, that is the status is either aps:ready, aps:activating, or a custom status.
  • When the controller switches to the async configuration, it sets the resource status to aps:configuring. This protects the resource from starting other configurations until the current operation is completed.
  • If the resource status is aps:configuring, the controller returns the 409 Conflict code to any subsequent REST requests for the resource configuration.
  • Once resource async configuration is completed, the APS controller sets the resource status to its initial value (it had before the configuration started) unless the application sets another status as explained in the Managing Statuses section.

Note

When the system requests to change the limit of a counter or limit structure in a resource that is under configuration, the APS controller schedules this system request and activates it once the current resource configuration is completed. Refer to Resource Counters for more details regarding usage, limit, and counter processing.

Synchronization of Properties

When the APS controller starts changing some properties of a resource, it will synchronize these properties with the application in accordance with the following rules:

  1. APS controller can accept the full set of resource properties or part of it (partial configuration). If some properties are missed in the request, the APS controller will leave them intact in its database.

    Note

    Partial update is supported by the APS Controller for all properties that are not elements of an array. In JSON, arrays are not indexed, thus it is hard to distinguish their elements from each other.

  2. To update resource properties in the application, the APS controller sends to the application service all resource properties, except for the following:

    • Properties, whose current value is null and they are not requested for change
    • Properties that are requested to be null
  3. On receiving the PUT request, the application must interpret it as follows:

    • APS controller wishes to set explicitly all sent properties as specified in the request.
    • APS controller wishes to set implicitly all missed out properties to null.
  4. When generating its response, the application must take into account the following synchronization rules of the APS controller:

    • In its database, the APS controller will finally set the properties to the values received from the application.
    • If the application misses out some properties in its response, the APS controller will consider it as if the application agreed with the request and these properties are already in sync.

    Note

    By default, the APS PHP runtime code, used in application endpoint, sends all resource properties in the response, including the properties set to null. This makes the resource synchronization the most robust.

Example

In the following example, let us assume that the VPS resource has only five properties, whose initial values were: name = ‘VPS-103’, description = ‘Test’, memory = 512, diskspace = 32, state = ‘stopped’.

The subscriber needs to change only three of them: memory = 1024, description = null, state = ‘running’. The update process consists of the following steps as described below.

  1. The custom UI code sends to the APS controller a request for partial update, containing only three properties with new assigned values. One of these values, namely description, must be set to null.
  2. In accordance with the outlined rules, APS controller sends to the application endpoint all VPS properties, except for description, since its value must be set to null.
  3. The application is able to satisfy the request. In respect with the above rules, the application sends back the full set of the VPS properties with their actual values.
  4. APS controller sets the VPS properties in its database to the actual values received from the application response.
  5. APS controller responds to the subscriber’s request by sending the actual values of the VPS properties. It does not include description in the response, since its value is null.

The following excerpts illustrate the contents of the initial request and final response.

Request:

PUT /aps/2/resources/7ab1be46-a02c-414c-a44a-88b199ba9047
Content-Type: application/json; charset=UTF-8

{
   "aps":{"type":"http://basic.demo.apsdemo.org/vpsclouds/vpses/1.0"},
   "description": null,
   "hardware":{
      "memory":"1024"
   },
   "state":"running"
}

Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8

{
   "aps":
   {
      "type": "http://basic.demo.apsdemo.org/vpsclouds/vpses/1.0",
      "id": "7ab1be46-a02c-414c-a44a-88b199ba9047",
      "status": "aps:ready",
      "revision": 3,
      "modified": "2014-02-18T10:08:26Z",
      "package":
      {
         "id": "ed0f664a-8b45-4040-aca8-4256d09855a9",
         "href": "/aps/2/packages/ed0f664a-8b45-4040-aca8-4256d09855a9"
      }
   },
   "hardware":
   {
      "CPU":
      {
         "number": 4
      },
      "diskspace": 32,
      "memory": 1024
   },
   "name": "VPS-103",
   "platform":
   {
      "OS":
      {
         "name": "centos6"
      }
   },
   "state": "running",
   "context":
   {
      "aps":
      {
         "link": "strong",
         "href": "/aps/2/resources/92d931b1-674e-4e09-86f1-62945d63eb9f",
         "id": "92d931b1-674e-4e09-86f1-62945d63eb9f"
      }
   }
}