Extending vCloud API with vCloud Extensibility Framework : Extension Example : 3.1 Register an Extension
   
3.1 Register an Extension
To create a custom extension, you must POST a service element. A service element describes the name, namespace, routing key, exchange to use, and URL patterns (APIFilters) and ServiceLink elements to be used as API filters.
The parameters used to create the extension are as follows:
Name – Name of the entity.
o For example: gcp-ticketing.
Namespace – Service namespace, which must be unique among all registered extension services. Service namespace names must follow the naming convention used for Java packages.
o This example uses the namespace local.gcp.ticketing.
RoutingKey – AMQP routing key that vCloud Director must use when routing messages to the service.
o This example uses the routing key gcp-ticketing.
Exchange – AMQP exchange name that vCloud Director must use when routing messages to the service. The service must create the specified exchange on the AMQP service that vCloud Director uses.
o This example uses the AMQP exchange name vcdext, which is different than the one that was configured with vCloud Director. The exchange used for extensions must be of the type Direct.
APIFilters – One or more URL patterns that the vCloud Director REST service must treat as extension requests. URL patterns can include regular expressions recognizable by java.util.regex.Pattern.
o For example: (/api/org/.*/ticketing/*[0-9]*)
This allows you to match on:
/api/org/org-uuid/ticketing
/api/org/org-uuid/ticketing/
/api/org/org-uuid/ticketing/12345
In this case, the addition to org is limited. If you wanted to also allow this creation on individual VMs, you could specify:
(/api/org/.*/ticketing*[0-9]*)|(/api/vApp/vm-.*/ticketing*[0-9]*)
The XML for the API extension is created in a file called ext-reg.xml (https://github.com/johnnycuse/vcd-api-examples/blob/master/ticketing/ext-reg.xml), and this will be passed to vCloud to register the extension:
<?xml version="1.0" encoding="UTF-8"?>
<vmext:Service xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:vmext="http://www.vmware.com/vcloud/extension/v1.5" name="gcp-ticketing">
<vmext:Namespace>local.gcp.ticketing</vmext:Namespace>
<vmext:Enabled>true</vmext:Enabled>
<vmext:RoutingKey>gcp-ticketing</vmext:RoutingKey>
<vmext:Exchange>vcdext</vmext:Exchange>
<vmext:ApiFilters>
<vmext:ApiFilter>
<vmext:UrlPattern>(/api/org/.*/ticketing/*[0-9]*)</vmext:UrlPattern>
</vmext:ApiFilter>
</vmext:ApiFilters>
</vmext:Service>
To register, POST to /api/admin/extension/service
with:
Content Type: application/vnd.vmware.admin.service+xml
'Accept:application/*+xml;version=5.6
To do this with HTTPie, execute the following command:
# http --verify no --session=vcloud-gcp-admin POST https://vcd.gcp.local/api/admin/extension/service 'Content-type: application/vnd.vmware.admin.service+xml' 'Accept:application/*+xml;version=5.6' < ext-reg.xml
You will receive the following output:
<?xml version="1.0" encoding="UTF-8"?>
<vmext:Service xmlns:vmext="http://www.vmware.com/vcloud/extension/v1.5" xmlns:vcloud="http://www.vmware.com/vcloud/v1.5" name="gcp-test" id="urn:vcloud:externalService:f79f562a-8d7a-44d6-9bab-82ddf40589f7" href="https://vcd.gcp.local/api/admin/extension/service/f79f562a-8d7a-44d6-9bab-82ddf40589f7" type="application/vnd.vmware.admin.service+xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/extension/v1.5 http://vcd.gcp.local/api/v1.5/schema/vmwextensions.xsd http://www.vmware.com/vcloud/v1.5 http://vcd.gcp.local/api/v1.5/schema/master.xsd">
<vcloud:Link rel="remove" href="https://vcd.gcp.local/api/admin/extension/service/f79f562a-8d7a-44d6-9bab-82ddf40589f7"/>
<vcloud:Link rel="edit" href="https://vcd.gcp.local/api/admin/extension/service/f79f562a-8d7a-44d6-9bab-82ddf40589f7" type="application/vnd.vmware.admin.service+xml"/>
<vcloud:Link rel="rights" href="https://vcd.gcp.local/api/admin/extension/service/f79f562a-8d7a-44d6-9bab-82ddf40589f7/rights" type="application/vnd.vmware.admin.rights+xml"/>
<vcloud:Link rel="down:serviceLinks" href="https://vcd.gcp.local/api/admin/extension/service/f79f562a-8d7a-44d6-9bab-82ddf40589f7/links" type="application/vnd.vmware.vcloud.query.records+xml"/>
<vcloud:Link rel="bundle:upload" href="https://vcd.gcp.local/api/admin/extension/service/localizationbundles" type="application/vnd.vmware.admin.bundleUploadParams+xml"/>
<vcloud:Link rel="add" href="https://vcd.gcp.local/api/admin/extension/service/f79f562a-8d7a-44d6-9bab-82ddf40589f7/links" type="application/vnd.vmware.admin.serviceLink+xml"/>
<vcloud:Link rel="down:apiFilters" href="https://vcd.gcp.local/api/admin/extension/service/f79f562a-8d7a-44d6-9bab-82ddf40589f7/apifilters" type="application/vnd.vmware.vcloud.query.records+xml"/>
<vcloud:Link rel="add" href="https://vcd.gcp.local/api/admin/extension/service/f79f562a-8d7a-44d6-9bab-82ddf40589f7/apifilters" type="application/vnd.vmware.admin.apiFilter+xml"/>
<vcloud:Link rel="add" href="https://vcd.gcp.local/api/admin/extension/service/f79f562a-8d7a-44d6-9bab-82ddf40589f7/apidefinitions" type="application/vnd.vmware.admin.apiDefinition+xml"/>
<vcloud:Link rel="down:apiDefinitions" href="https://vcd.gcp.local/api/admin/extension/service/f79f562a-8d7a-44d6-9bab-82ddf40589f7/apidefinitions" type="application/vnd.vmware.vcloud.query.records+xml"/>
<vcloud:Link rel="add" href="https://vcd.gcp.local/api/admin/extension/service/f79f562a-8d7a-44d6-9bab-82ddf40589f7/resourceclasses" type="application/vnd.vmware.admin.resourceClass+xml"/>
<vcloud:Link rel="down:resourceClasses" href="https://vcd.gcp.local/api/admin/extension/service/f79f562a-8d7a-44d6-9bab-82ddf40589f7/resourceclasses" type="application/vnd.vmware.vcloud.query.records+xml"/>
<vcloud:Link rel="authorization:check" href="https://vcd.gcp.local/api/admin/extension/service/f79f562a-8d7a-44d6-9bab-82ddf40589f7/authorizationcheck" type="application/vnd.vmware.admin.authorizationCheckParams+xml"/>
<vmext:Namespace>local.gcp.ticketing</vmext:Namespace>
<vmext:Enabled>true</vmext:Enabled>
<vmext:AuthorizationEnabled>false</vmext:AuthorizationEnabled>
<vmext:RoutingKey>gcp-ticketing</vmext:RoutingKey>
<vmext:Priority>0</vmext:Priority>
<vmext:Exchange>vcdext</vmext:Exchange>
</vmext:Service>
 
To retrieve a list of all extensions you can execute:
# http --verify no --session=vcloud-gcp-admin --pretty colors GET https://vcd.gcp.local/api/admin/extension/service/query
To test that the extension allows calling the ticketing method for an organization, execute the following command:
# http --verify no --session=vcloud-gcp-admin --pretty colors GET https://vcd.gcp.local/api/org/<ORG_UUID>/ticketing
When this test command is executed, the call will hang for 10 seconds, and eventually return a 504 error message, “External service ‘gcp-ticketing’ failed to respond in the specified timeout (10 SECONDS).” This verifies that the new extension was registered successfully, however, nothing was configured yet to handle the message that was added to the message queue.