Enactor Core

The role of the Enactor is to shield the technical details of how to communicate with each specific testbed from the higher level Resource Manager. Once the Resource Manager has decided to perform an action on a testbed, the Enactor is in charge of transforming that request onto suitable format for the appropriate testbeds through a collection of adaptors. In this way the Resource Manager always talks an uniform OCCI language without worry whatever languague the testbed talks.

The adaptors can be classified into four different categories: OCCI adaptors (that are subdivided into four different types: Open Nebula Enactor Adaptor, HP Enactor Adaptor, Virtual Wall Enactor Adaptor, and Wellness Enactor Adaptor), Amazon Enactor Adaptor, AutoBAHN Adaptor, and Federica Enactor Adaptor. In any case, it is possible to add other kind of adaptors outside those categories, making BonFIRE easily extendable in the future.

The Enactor is not responsible for the security of the incoming call – but in counterpart it must enforce secure communication with the testbeds. The Enactor is in charge of authenticating itself against testbed APIs (for example, by presenting a valid certificate, while user attributes are passed as HTTP headers – the testbed APIs can log/use them as they wish for auditing/accounting purposes).

The Enactor supports multiple, concurrent, possibly time-consuming requests. It is a non-blocking service, capable of serving other requests while asynchronously waiting for a response from one of the testbed APIs.

Implementation Details

The following image details the Block Diagram for the Enactor

../_images/enactor-block-diagram.png

As it can be seen in the previous figure, the Enactor exposes an BonFIRE OCCI interface. Through this interface the Resource Manager will send its requests (only the Resource Manager is going to interact with the Enactor). Those requests are then processed by the respective adaptor, depending on which testbed the Resource Manager requires are targeted at. The following figure details the sequence diagram of the previously described process

../_images/enactor-sequence-diagram.png

The BonFIRE DB stores a list of locations with the respective url. For each location, the DB also stores the specific adaptor information that the Enactor needs to know to be able to select the right endpoint or adaptor. The following sequence diagram details this process.

The Enactor supports one entry point for each resource/URI that can be accessed. The possible operations are listed in the following subsection.

APIs provided

As previously commented the Enactor offers an REST API that the Resource Manager uses to be able to access in an homogeneous way to the different tesbeds federated to `BonFIRE <http://www.bonfire-project.eu`_. All the REST queries comming to the Enactor will be passed to one of the Enactor Endpoints with the exception of two of them:

GET /locations

It returnds information of the type: application/vnd.bonfire+xml

<collection xmlns="http://api.bonfire-project.eu/doc/schemas/occi">
 <items offset="0" total="5">
       <location>
         <name>uk-epcc</name>
         <description />
         <longitude>-3.1875</longitude>
         <latitude>55.9502</latitude>
         <link rel="self" href="/locations/uk-epcc" type="application/vnd.bonfire+xml" />
         <link rel="parent" href="/locations" type="application/vnd.bonfire+xml" />
       </location>
       <location>
         <name>federica</name>
         <description />
         <longitude />
         <latitude />
         <link rel="self" href="/locations/federica" type="application/vnd.bonfire+xml" />
         <link rel="parent" href="/locations" type="application/vnd.bonfire+xml" />
       </location>
  </items>
  <link rel="self" href="/locations" type="application/vnd.bonfire+xml" />
  <link rel="parent" href="/" type="application/vnd.bonfire+xml" />
</collection>

GET /locations/<location_id>

It returnds information of the type: application/vnd.bonfire+xml

<collections xmlns="http://api.bonfire-project.eu/doc/schemas/occi">
 <compute_collection href="/locations/uk-epcc/computes" />
 <instance_type_collection href="/locations/uk-epcc/instance_type" />
 <network_collection href="/locations/uk-epcc/networks" />
 <storage_collection href="/locations/uk-epcc/storages" />
</collections>

The response of the rest of the possible queries are dependent on the typo of testbed and are detailed in the following section. There you will find examples of input messages, sent messages to the testbeds, response messages for the testbeds and their translation to the BonFIRE OCCI XML format.

Adding a new Adaptor

The Enactor architecture is extensible making possible to add new adaptors if necessary. To do so, the developers need to create a new adaptor that implements the following interface in Java:

package eu.bonfire.broker.enactor.endpoints;

/**
 * Interface that defines the EndPoint/Adaptor that the Enactor uses to connect to
 * the Broker API or the different testbeds
 */
public interface EndPoint {

  /**
   * Sends a HTTP request to the Testbed or to the Broker API
   *
   * @param UrlEnd URL to connect to the testbed or to the API
   * @param verb HTTP verb to use in the connection
   * @param headers Headers needed to send in the connection
   * @param payload Payload to be sended to the testbed or to the Broker PAI
   * @return The response of the testbed or the Broker API
   * @throws Exception
   */
  public EndPointResponse sendRequest(String UrlEnd,
                    String verb,
                    String[] headers,
                    String payload) throws Exception;

  public String getURL();
  public String getLocation();
}

Also, it is necessary to extend the method “create” of the class “EndPointFactory” so the Enactor is aware of the new adaptor.

Development details

The Enactor has been developed using Java, using the following libraries and tools: Spring, Jersey, Tomcat, Hibernate, or Maven.

To be able to develop and locally run the Enactor, please read the following requirements and steps:

Requirements

To be able to execute the Enactor you need to have installed on your machine the following tools:

  • Oracle JDK 1.6.x - You can download the correctly one for your platform at: JDK 1.6.x. After installed, you have to make sure JAVA_HOME variable is set pointing to the folder Java was just installed. (Note: The Enactor has never been tested with Java 7, so it is not sure that it is going to work with this new version. The Enactor has been tested and it is know that works without problem with OpenJDK 1.6.x).
  • Maven - You can download from this address: Maven download .
  • BonFIRE DB - A BonFIRE DB configured with the locations and occi_schema tables.

Configuring Maven

Lets asume that the enactor code is located in the following folder:

/broker/Enactor/trunk

Execute the following lines to add the following external dependencies not available in standard repositories: .. code-block:: console

$ mvn install:install-file -DgroupId=com.hp.bonfire -DartifactId=HPOCCIBonFIRE -Dversion=0.10 -Dfile=lib/hp-occi-bonfire-0.10.jar -Dpackaging=jar -DgeneratePom=true
$ mvn install:install-file -Dfile=./lib/user-access-point-client-0.0.1-SNAPSHOT.jar -DpomFile=./lib/user-access-point-client-0.0.1-SNAPSHOT.pom
$ mvn install:install-file -Dfile=lib/jta-1.0.1B.jar -DpomFile=./lib/jta-1.0.1B.pom

Try to create a Enactor.war file. To do so, please, execute the following command:

$ mvn package

Importing the code to Eclipse

The core of the Enactor has been developed using the Eclipse Java IDE, although others Java editors could be used, here we only provide the instructions about how to import the code into Eclipse.

The first step is to tell Maven to create the necessary Eclipse project files executing this:

$ mvn eclipse:eclipse

The previous command is going to generate the eclipse project files: .settings, .classpath, and .project. Again, please never upload those files to the svn, it is going to deconfigure the eclipse of other developers (it is easy to fix, just an annoying waste of time).

After it, you can from your eclipse import the project. Go to “import project from file” go to the trunk folder, and you should see the Enactor project ready to be imported in your Eclipse. Probably eclipse is going to complain about missing libraries, you need to create the following variable inside Eclipse: M2_REPO pointing to the .m2/repository in your computer (Linux or Mac OS X: ~/.m2/repository Windows 7: /Users/[username]/.m2/repository)

Running localy the Enactor

To execute the Enactor on Tomcat, just execute the following maven command on the trunk folder:

$ mvn tomcat:run

In that step Maven creates a War file ready to be deployed on Tomcat (if the unit test pass successfully). After it, it starts a Tomcat server and deploys the Enactor on it (it is not necessary to install Tomcat on your machine, Maven takes care of that).

In the console that you started the process, you will see the tomcat log. If you want to stop the server just push the following combination of keys: “Ctrl+C”, that will stop nicely Tomcat. Remember, this is a testing environment, not a production one.

Testing everything with cURL

The easiest way to play with the Enactor is to use cURL. For example, if you want to know the available locations in your local enviroment, you can execute the following curl command (in the header x_bonfire_asserted_id:jenkins put a valid username for the site your are connecting, in this case I’m using “jenkins” test user):

$ curl -v --header x_bonfire_asserted_id:jenkins http://localhost:8080/Enactor/webresources/locations
* About to connect() to localhost port 8080
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 8080
> GET /Enactor/webresources/locations HTTP/1.1
> User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: localhost:8080
> Accept: */*
> x_bonfire_asserted_id:jenkins
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/vnd.bonfire+xml
< Transfer-Encoding: chunked
< Date: Wed, 25 Jul 2012 13:07:23 GMT
<collection xmlns="http://api.bonfire-project.eu/doc/schemas/occi">
 <items offset="0" total="5">
   <location>
     <name>fr-inria</name>
     <description />
     <longitude>9.1808</longitude>
     <latitude>48.7771</latitude>
     <link rel="self" href="/locations/fr-inria" type="application/vnd.bonfire+xml" />
     <link rel="parent" href="/locations" type="application/vnd.bonfire+xml" />
   </location>
   <location>
     <name>uk-epcc</name>
     <description />
     <longitude>-3.1875</longitude>
     <latitude>55.9502</latitude>
     <link rel="self" href="/locations/uk-epcc" type="application/vnd.bonfire+xml" />
     <link rel="parent" href="/locations" type="application/vnd.bonfire+xml" />
   </location>
   <location>
     <name>uk-hplabs</name>
     <description />
     <longitude>9.1808</longitude>
     <latitude>48.7771</latitude>
     <link rel="self" href="/locations/uk-hplabs" type="application/vnd.bonfire+xml" />
     <link rel="parent" href="/locations" type="application/vnd.bonfire+xml" />
   </location>
   <location>
     <name>be-ibbt</name>
     <description />
     <longitude>-3.1875</longitude>
     <latitude>55.9502</latitude>
     <link rel="self" href="/locations/be-ibbt" type="application/vnd.bonfire+xml" />
     <link rel="parent" href="/locations" type="application/vnd.bonfire+xml" />
   </location>
   <location>
     <name>useast-aws</name>
     <description />
     <longitude />
     <latitude />
     <link rel="self" href="/locations/useast-aws" type="application/vnd.bonfire+xml" />
     <link rel="parent" href="/locations" type="application/vnd.bonfire+xml" />
   </location>
 </items>
 <link rel="self" href="/locations" type="application/vnd.bonfire+xml" />
 <link rel="parent" href="/" type="application/vnd.bonfire+xml" />
</collection>

* Connection #0 to host localhost left intact
* Closing connection #0

You can query a site using GET command in cURL (the default one). For example the list of storages at Inria:

$ curl -v --header x_bonfire_asserted_id:jenkins http://localhost:8080/Enactor/webresources/locations/fr-inria/storages
* About to connect() to localhost port 8080
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 8080
> GET /Enactor/webresources/locations/fr-inria/storages HTTP/1.1
> User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: localhost:8080
> Accept: */*
> x_bonfire_asserted_id:jenkins
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Via:  1.1 enactor:8080 (bonfire-enactor/0.5)
< Content-Type: application/vnd.bonfire+xml
< Transfer-Encoding: chunked
< Date: Wed, 25 Jul 2012 13:09:22 GMT
<collection xmlns="http://api.bonfire-project.eu/doc/schemas/occi">
 <items>
   <storage href="/locations/fr-inria/storages/386" name="BonFIRE Load Balancer 2G" state="READY" />
   <storage href="/locations/fr-inria/storages/394" name="BonFIRE Zabbix Aggregator v6" state="READY" />
   <storage href="/locations/fr-inria/storages/416" name="test754_saveas" state="READY" />
   <storage href="/locations/fr-inria/storages/435" name="maxenced_test-public" state="READY" />
   <storage href="/locations/fr-inria/storages/462" name="BonFIRE EaaS 2G v1" state="READY" />
   <storage href="/locations/fr-inria/storages/570" name="BonFIRE Debian Squeeze v4" state="READY" />
   <storage href="/locations/fr-inria/storages/571" name="BonFIRE Debian Squeeze 2G v4" state="READY" />
   <storage href="/locations/fr-inria/storages/652" name="BonFIRE Load Balancer 1500M" state="USED" />
   <storage href="/locations/fr-inria/storages/657" name="BonFIRE Zabbix Aggregator v5" state="USED" />
 </items>
</collection>

* Connection #0 to host localhost left intact
* Closing connection #0

If you want to create a resource, for example an storage at Inria:

$ curl -v --header x_bonfire_asserted_id:jenkins http://localhost:8080/Enactor/webresources/locations/fr-inria/storages -X POST -d'<storage xmlns="http://api.bonfire-project.eu/doc/schemas/occi"><name>storage</name><description>a nice storage</description><type>DATABLOCK</type><size>200</size><fstype>ext3</fstype></storage>'
* About to connect() to localhost port 8080
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 8080
> POST /Enactor/webresources/locations/fr-inria/storages HTTP/1.1
> User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: localhost:8080
> Accept: */*
> x_bonfire_asserted_id:jenkins
> Content-Length: 194
> Content-Type: application/x-www-form-urlencoded
>
> <storage xmlns="http://api.bonfire-project.eu/doc/schemas/occi"><name>storage</name><description>a nice storage</description><type>DATABLOCK</type><size>200</size><fstype>ext3</fstype></storage>HTTP/1.1 201 Created
< Server: Apache-Coyote/1.1
< Via:  1.1 enactor:8080 (bonfire-enactor/0.5)
< Content-Type: application/vnd.bonfire+xml
< Transfer-Encoding: chunked
< Date: Wed, 25 Jul 2012 13:13:35 GMT
<storage xmlns="http://api.bonfire-project.eu/doc/schemas/occi" href="/locations/fr-inria/storages/659">
 <id>659</id>
 <name>jenkins_storage</name>
 <user_id href="/locations/fr-inria/users/6">jenkins</user_id>
 <groups>users</groups>
 <state>LOCKED</state>
 <type>DATABLOCK</type>
 <description>a nice storage</description>
 <size>200</size>
 <fstype>ext3</fstype>
 <public>NO</public>
 <persistent>NO</persistent>
</storage>

* Connection #0 to host localhost left intact
* Closing connection #0

Modifications are doing in the same way, but using -X PUT instead of -X POST

If we want to delete the storage:

$ curl -v --header x_bonfire_asserted_id:jenkins http://localhost:8080/Enactor/webresources/locations/fr-inria/storages/659 -X DELETE
* About to connect() to localhost port 8080
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 8080
> DELETE /Enactor/webresources/locations/fr-inria/storages/659 HTTP/1.1
> User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: localhost:8080
> Accept: */*
> x_bonfire_asserted_id:jenkins
>
< HTTP/1.1 204 No Content
< Server: Apache-Coyote/1.1
< Via:  1.1 enactor:8080 (bonfire-enactor/0.5)
< Date: Wed, 25 Jul 2012 13:15:18 GMT
* Connection #0 to host localhost left intact
* Closing connection #0