Note
The examples in this section are applicable to endpoint hosts using the APS PHP runtime.
In this document:
By default, you can find the application backend scripts and application instance configuration in
a subfolder of the Apache document root. In the following example, the application endpoint subfolder
is basic1p
:
# ls -al /var/www/html/basic1p/
total 32
drwxr-xr-x 4 apache apache 4096 Mar 16 17:15 .
drwxr-xr-x 8 root root 4096 Mar 17 17:53 ..
-rwxr-xr-x 1 apache apache 1131 Feb 12 18:53 clouds.php
drwxr-xr-x 2 apache apache 4096 Mar 16 17:15 config
-rwxr-xr-x 1 apache apache 1612 Feb 12 18:53 contexts.php
-rwxr-xr-x 1 apache apache 372 Mar 16 17:15 .htaccess
drwxr-xr-x 3 apache apache 4096 Mar 16 17:17 typeCache
-rwxr-xr-x 1 apache apache 2152 Feb 12 18:53 vpses.php
The config/
folder in the above list contains SSL certificates and keys for the APS application
instances, as outlined here:
# ls -al /var/www/html/basic1p/config/
total 28
drwxr-xr-x 2 apache apache 4096 Mar 16 17:15 .
drwxr-xr-x 4 apache apache 4096 Mar 16 17:15 ..
-rw------- 1 apache apache 4223 Mar 16 17:15 3641e96b-4ab4-4c00-8a45-b6f9d2a61fd0
-rw------- 1 apache apache 1196 Mar 16 17:15 3641e96b-4ab4-4c00-8a45-b6f9d2a61fd0.apsc.pem
-rw------- 1 apache apache 2818 Mar 16 17:15 3641e96b-4ab4-4c00-8a45-b6f9d2a61fd0.pem
-rw-r--r-- 1 apache apache 31 Mar 16 17:15 .htaccess
While testing and debugging a PHP script, define the APS_DEVELOPMENT_MODE global constant in it:
if (!defined('APS_DEVELOPMENT_MODE')) define ('APS_DEVELOPMENT_MODE', 'on');
require_once("aps/2/runtime.php");
Defining this global constant in your PHP script enables:
The APS PHP framework to record traced calls of this script in the Apache error_log
file.
The use of debug
and trace
log levels.
In the following example with the global constant defined, a user saves an edited resource (VPS)
and the error_log
file records the following trace:
Note
For brevity, the example omits most strings and suffixes with date and time, and adds some inline comments using the “//” suffix:
DEBUG Incoming Application API request: PUT user/vpses/1645e72d-6d90-488e-8e94-089bf7c00ddf
DEBUG Request:
{
"aps":
{
"type": "http://aps-standard.org/samples/suwizard1p/vps/1.1",
"id": "1645e72d-6d90-488e-8e94-089bf7c00ddf",
// ...
},
// ... Full JSON representation of the resource with the updated property
"hardware":
{
"CPU":
{
"number": 4 // Request to set the new value
},
// ...
}
}
DEBUG TypeLibrary: Found class "http://aps-standard.org/samples/suwizard1p/vps/1.1" in local type cache.
TRACE #Request to APS controller [apsc-request-56e7b60a4f40f]:
GET https://10.28.110.145:6308/aps/2.2/resources/1645e72d-6d90-488e-8e94-089bf7c00ddf
APS-Controller-URI: https://10.28.110.145:6308/
APS-Request-ID: a5d3c74f-2b4b-4516-a2bb-6ff76238f548
Content-type: application/json
..............................
TRACE #Response from APS controller [apsc-request-56e7b60a4f40f]:
HTTP/1.1 200 OK
..............................
Content-Type: application/json
{
"aps":
{
"type": "http://aps-standard.org/samples/suwizard1p/vps/1.1",
"id": "1645e72d-6d90-488e-8e94-089bf7c00ddf",
// ...
},
// ... Full JSON representation of the current resource properties
"hardware":
{
"CPU":
{
"number": 2 // This is the current value
},
// ...
}
}
...
DEBUG TypeLibrary: Found registered class "http://aps-standard.org/samples/suwizard1p/vps/1.1".
DEBUG Result:
{
"aps": {
"type": "http://aps-standard.org/samples/suwizard1p/vps/1.1",
"id": "1645e72d-6d90-488e-8e94-089bf7c00ddf",
...// Full JSON representation of the updated resource
},
// ...
"hardware":
{
"CPU":
{
"number": 4 // The property updated to the required value
},
// ...
}
}
The log shows the following traced steps:
The vpses
service of the application receives a PUT request from the APSC to update the specified VPS.
The service calls the APSC for the current VPS properties using the GET request. The application needs to know all the other properties so that it does not change them in its response.
The service returns the updated VPS representation to the APSC to confirm the update.
You can use the following Apache (HTTPD) logs to identify and analyze error and information records.
ssl_access_log
- provides data about REST requests sent to the APS application endpoints.
[root@endpoint ~]# tail -f /var/log/httpd/ssl_access_log
10.28.99.128 - - [30/Jan/2015:11:34:10 +0300] "POST /async/vpses HTTP/1.1" 202 466
10.28.99.128 - - [30/Jan/2015:11:34:11 +0300] "POST /async/vpses HTTP/1.1" 202 466
error_log
- stores the log messages that application scripts send using the log methods.
[root@endpoint ~]# tail -fn0 /var/log/httpd/error_log
[2013/12/02 09:25:35] DEBUG TypeLibrary: Can't found class 'http://aps-standard.org/types/core/resource/1.0',
loading from /usr/share/aps/php/aps/2/types/org/standard/aps/types/core/resource/Resource.php
[2013/12/02 09:25:35] DEBUG Incoming Application API request: POST package/users
[Mon Dec 02 13:25:35 2013] [error] [client 10.10.2.224] PHP Fatal error: Class 'Logger' not found
in /var/www/html/package/users.php on line 88
In development mode, the error log contains traced calls in the most detailed format.
The APS PHP runtime provides the APSLoggerRegistry class
that you can use to record data in the error_log
file.
To mark those records with specific log levels, use their respective functions:
fatal
, error
, info
, debug
, and trace
, for example:
public function provision() {
$logger = \APS\LoggerRegistry::get();
...
$logger->error("This is a log message of the error level");
$logger->debug("This is a log message of the debug level");
...
}
The debug
and trace
levels are only available in APS development mode.
If you need to send an array or object to the log, first convert it to a string:
$msg = print_r(<object or array>, true);
$logger->info("This is an object: ".$msg);
The command line interface (CLI) allows you to send REST requests directly from any host that can communicate with the management node or endpoint host.
To send a REST request to the APSC on behalf of an account, you need to add the account token to the request. The steps to do so are as follows:
Note
For brevity, an ellipsis (…) shows abbreviated example code.
Get the account token from the management node by executing the following command from the platform XML API (account ID in the system is 4 in this example):
curl -d @get-accnt-token.xml http://<management-node>:8440
The get-accnt-token.xml
file used in the above command contains the XML request:
<?xml version='1.0'?>
<methodCall>
<methodName>pem.APS.getAccountToken</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>account_id</name>
<value>
<i4>4</i4>
</value>
</member>
<member>
<name>subscription_id</name>
<value>
<i4>0</i4>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>
Using the account token, run the desired REST request. For example, to get a list of the resources owned by the customer, send:
# curl -k -X GET -H 'APS-Token:JEFFUy0xMjgtR0NNJ...` \
https://<management-node>:6308/aps/2/resources/
To create a resource, send a POST request similar to:
# curl -k -X POST -d @v-102.json -H 'APS-Token:JEFFU...` \
-H 'APS-Subscription-ID:f7fbf93f-...' \
https://<management-node>:6308/aps/2/resources/
The v-102.json
file contains the JSON representation of the required resource.
To update the created resource (for example, to change the state
property), send a PUT request similar to:
# curl -k -X PUT -d'{"aps":{"id":"38146701-..."},"state":"Running"}' \
-H 'APS-Token:JEFFU...` \
https://<management-node>:6308/aps/2/resources/38146701-...
To send a REST request on behalf of your application instance to the APSC, you need to send
the application SSL certificate that the APS controller trusts. The certificate is contained in
the <endpoint>/config/<instance-id>.pem
file, where:
<endpoint> is the root folder of the APS application endpoint
<instance-id> is the APS ID assigned to the APS application instance
If you are on the endpoint host, use the following syntax to send a GET request:
# cd <endpoint>/config
# curl -k -X GET -E ./`ls | grep '^[a-z0-9-]\{36\}\.pem$'` https://<management-node>:6308/aps/2/resources/
As explained in the From an Account to the APS Controller section, you can also send PUT and POST requests.
You can verify a PHP script by sending a test REST request directly to it.
For example, to trace provisioning of a VPS by the vpses.php
script, use the following command:
# php vpses.php < request.txt
The input data in the request.txt
file may look as follows (many lines are omitted for brevity):
PUT /user/vpses/545838c3-d2e3-46f6-ac65-4e7ed54f5ba4 HTTP/1.1
APS-Instance-Id:57e6af16-1e81-4bd9-91dc-d8b6b452e61c
{
"aps":
{
"type": "http://aps-standard.org/samples/suwizard1p/vps/1.1",
"id": "1645e72d-6d90-488e-8e94-089bf7c00ddf",
...
},
... // Full JSON representation of the resource
"hardware": { "CPU": { "number": 3 } },
...
}
Because an APS application endpoint can serve many application instances, the request must contain
the APS-Instance-Id
header. You can find the needed value in the config/
subfolder
in the APS application endpoint folder. For example:
# ls -l config/
total 16
-rw------- 1 apache apache 4225 Mar 4 12:06 57e6af16-1e81-4bd9-91dc-d8b6b452e61c
-rw------- 1 apache apache 1196 Mar 4 12:06 57e6af16-1e81-4bd9-91dc-d8b6b452e61c.apsc.pem
-rw------- 1 apache apache 2818 Mar 4 12:06 57e6af16-1e81-4bd9-91dc-d8b6b452e61c.pem
An application instance cannot function if its SSL certificate is lost or damaged.
The gen_appcert.py
script enables you to generate a new SSL certificate and keys
for an application instance. The script requires the instance ID as the input argument that
you can find using the following steps:
In the provider control panel, go to Services > Applications > APS Instances.
Identify the instance of the application and note the ID displayed in the first column.
Establish an SSH connection to the management node and access the database. In the following example, the application instance ID is 15:
# su postgres -c psql
postgres=# \l
postgres=# \connect oss;
oss=> select uuid from aps_application_instances where app_instance_id=15;
uuid
--------------------------------------
83fb36d2-1adb-453a-a0b4-db998ea1946c
(1 row)
To restore the application instance with the same UUID, use the gen_appcert.py
script.
The following example uses the UUID found in the previous step:
# python gen_appcert.py 83fb36d2-1adb-453a-a0b4-db998ea1946c