--- /dev/null
+build.xml
+/nbproject
+nb-configuration.xml
+/target/
+nbactions.xml
--- /dev/null
+language: java
+
+jdk:
+ - openjdk7
+ - oraclejdk7
+ - oraclejdk8
+
+bracnhes:
+ only:
+ - master
--- /dev/null
+The work represented by this source file is partially or entirely funded
+by the EGI-InSPIRE project through the European Commission's 7th Framework
+Programme (contract # INFSO-RI-261323)
+
+Copyright (c) 2014-2015 CESNET
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
--- /dev/null
+jOCCI-api - A Java OCCI Framework
+==================================
+
+[](http://travis-ci.org/EGI-FCTF/jOCCI-api)
+
+Requirements
+------------
+* JDK 7+
+* Maven
+
+Instalation
+-----------
+Using Maven:
+```xml
+<dependency>
+ <groupId>cz.cesnet.cloud</groupId>
+ <artifactId>jocci-api</artifactId>
+ <version>0.2.6</version>
+</dependency>
+```
+
+Usage
+-----
+Detailed documentation is available in project's [Wiki](https://github.com/EGI-FCTF/jOCCI-api/wiki).
+
+### Continuous integration
+
+[Continuous integration for jOCCI by Travis-CI](http://travis-ci.org/EGI-FCTF/jOCCI-api/)
+
+### Contribute
+
+1. Fork it.
+2. Create a branch (git checkout -b my_markup)
+3. Commit your changes (git commit -am "My changes")
+4. Push to the branch (git push origin my_markup)
+5. Create an Issue with a link to your branch
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>cz.cesnet.cloud</groupId>
+ <artifactId>jocci-api</artifactId>
+ <version>0.2.6</version>
+ <packaging>jar</packaging>
+ <name>${project.groupId}:${project.artifactId}</name>
+ <description>A Java OCCI framework - transport api library.</description>
+ <url>https://github.com/EGI-FCTF/jOCCI-api</url>
+ <licenses>
+ <license>
+ <name>The Apache License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ </license>
+ </licenses>
+ <developers>
+ <developer>
+ <name>Michal Kimle</name>
+ <email>kimle.michal@gmail.com</email>
+ <organization>CESNET</organization>
+ <organizationUrl>http://www.cesnet.cz/</organizationUrl>
+ </developer>
+ </developers>
+ <scm>
+ <connection>scm:git:git@github.com:EGI-FCTF/jOCCI-api.git</connection>
+ <developerConnection>scm:git:git@github.com:EGI-FCTF/jOCCI-api.git</developerConnection>
+ <url>https://github.com/EGI-FCTF/jOCCI-api</url>
+ <tag>jocci-api-0.2.6</tag>
+ </scm>
+ <dependencies>
+ <dependency>
+ <groupId>cz.cesnet.cloud</groupId>
+ <artifactId>jocci-core</artifactId>
+ <version>0.2.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.7.7</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.7.7</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.10</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.github.tomakehurst</groupId>
+ <artifactId>wiremock</artifactId>
+ <version>1.53</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.3.6</version>
+ </dependency>
+ <dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk16</artifactId>
+ <version>1.46</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>2.5</version>
+ </dependency>
+ </dependencies>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <maven.compiler.source>1.7</maven.compiler.source>
+ <maven.compiler.target>1.7</maven.compiler.target>
+ </properties>
+ <distributionManagement>
+ <snapshotRepository>
+ <id>ossrh</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ </snapshotRepository>
+ <repository>
+ <id>ossrh</id>
+ <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
+ </repository>
+ </distributionManagement>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.9</version>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>javadoc</report>
+ </reports>
+ </reportSet>
+ <reportSet>
+ <id>aggregate</id>
+ <inherited>false</inherited>
+ <reports>
+ <report>aggregate</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ </plugins>
+ </reporting>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.sonatype.plugins</groupId>
+ <artifactId>nexus-staging-maven-plugin</artifactId>
+ <version>1.6.3</version>
+ <extensions>true</extensions>
+ <configuration>
+ <serverId>ossrh</serverId>
+ <nexusUrl>https://oss.sonatype.org/</nexusUrl>
+ <autoReleaseAfterClose>true</autoReleaseAfterClose>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <version>2.5</version>
+ <configuration>
+ <autoVersionSubmodules>true</autoVersionSubmodules>
+ <useReleaseProfile>false</useReleaseProfile>
+ <releaseProfiles>release</releaseProfiles>
+ <goals>deploy</goals>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>3.4</version>
+ </plugin>
+ <plugin>
+ <groupId>com.github.github</groupId>
+ <artifactId>site-maven-plugin</artifactId>
+ <version>0.11</version>
+ <configuration>
+ <message>Creating site for ${project.version}</message>
+ <server>github</server>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>site</goal>
+ </goals>
+ <phase>site</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.2.1</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.9.1</version>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-gpg-plugin</artifactId>
+ <version>1.5</version>
+ <executions>
+ <execution>
+ <id>sign-artifacts</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>sign</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
\ No newline at end of file
--- /dev/null
+package cz.cesnet.cloud.occi.api;
+
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+
+/**
+ * Authentication method interface
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public interface Authentication {
+
+ /**
+ * Returns unique identifier for this authentication method.
+ *
+ * @return unique authentication identifier
+ */
+ String getIdentifier();
+
+ /**
+ * Returns authentication's fallback authentication method.
+ *
+ * @return fallback authentication method
+ */
+ Authentication getFallback();
+
+ /**
+ * Runs the authentication.
+ *
+ * @throws CommunicationException when error occures during the
+ * communication
+ */
+ void authenticate() throws CommunicationException;
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api;
+
+import cz.cesnet.cloud.occi.Model;
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+import cz.cesnet.cloud.occi.core.ActionInstance;
+import cz.cesnet.cloud.occi.core.Entity;
+import java.net.URI;
+import java.util.List;
+
+/**
+ * Abstract class representing an OCCI client.
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public abstract class Client {
+
+ public static final String MODEL_URI = "/-/";
+ private URI endpoint;
+ private Model model;
+ private boolean connected;
+ private Authentication authentication;
+
+ /**
+ * Returns client's endpoint.
+ *
+ * @return client's endpoint
+ */
+ public URI getEndpoint() {
+ return endpoint;
+ }
+
+ /**
+ * Sets client's endpoint.
+ *
+ * @param endpoint client's endpoint
+ */
+ public void setEndpoint(URI endpoint) {
+ this.endpoint = endpoint.normalize();
+ }
+
+ /**
+ * Returns model.
+ *
+ * @return model
+ */
+ public Model getModel() {
+ return model;
+ }
+
+ /**
+ * Sets model.
+ *
+ * @param model model
+ */
+ public void setModel(Model model) {
+ this.model = model;
+ }
+
+ /**
+ * Checks whether client is connected.
+ *
+ * @return true if client is connected false otherwise
+ */
+ public boolean isConnected() {
+ return connected;
+ }
+
+ /**
+ * Sets whether client is connected or not.
+ *
+ * @param connected client's connection status
+ */
+ public void setConnected(boolean connected) {
+ this.connected = connected;
+ }
+
+ /**
+ * Returns client's authentication method.
+ *
+ * @return client's authentication method
+ */
+ public Authentication getAuthentication() {
+ return authentication;
+ }
+
+ /**
+ * Sets client's authentication method.
+ *
+ * @param authentication client's authentication method
+ */
+ public void setAuthentication(Authentication authentication) {
+ this.authentication = authentication;
+ }
+
+ /**
+ * <p>
+ * Retrieves all available resources represented by resource locations
+ * (URIs).</p>
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * List<URI> list = client.list();}</pre>
+ *
+ * @return resources represented by resource locations (URIs)
+ * @throws CommunicationException when error occured during the
+ * communication with server
+ */
+ public abstract List<URI> list() throws CommunicationException;
+
+ /**
+ * Retrieves available resources of a certain type represented by resource
+ * locations (URIs).
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * List<URI> list = client.list("compute");}</pre>
+ *
+ * @param resourceType resource type in shortened format (e.g. "compute",
+ * "storage", "network")
+ * @return resources represented by resource locations (URIs)
+ * @throws CommunicationException when error occured during the
+ * communication with server
+ */
+ public abstract List<URI> list(String resourceType) throws CommunicationException;
+
+ /**
+ * Retrieves available resources of a certain type represented by resource
+ * locations (URIs).
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * List<URI> list = client.list(URI.create("http://schemas.ogf.org/occi/infrastructure#network"));}</pre>
+ *
+ * @param resourceIdentifier full resource type identifier
+ * @return resources represented by resource locations (URIs)
+ * @throws CommunicationException when error occured during the
+ * communication with server
+ */
+ public abstract List<URI> list(URI resourceIdentifier) throws CommunicationException;
+
+ /**
+ * Retrieves descriptions for all available resources.
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * List<Entity> list = client.describe();}</pre>
+ *
+ * @return list of resource or link descriptions
+ * @throws CommunicationException when error occured during the
+ * communication with server
+ */
+ public abstract List<Entity> describe() throws CommunicationException;
+
+ /**
+ * Retrieves descriptions for available resources of a certain type.
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * List<Entity> list = client.describe("compute");}</pre>
+ *
+ * @param resourceType resource type in shortened format (e.g. "compute",
+ * "storage", "network")
+ * @return list of resource or link descriptions
+ * @throws CommunicationException when error occured during the
+ * communication with server
+ */
+ public abstract List<Entity> describe(String resourceType) throws CommunicationException;
+
+ /**
+ * Retrieves descriptions for available resources specified by a type
+ * identifier or resource identifier.
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * List<Entity> list = client.describe(URI.create("http://schemas.ogf.org/occi/infrastructure#network"));
+ *...
+ *list = client.describe(URI.create("https://remote.server.net/storage/123"));}</pre>
+ *
+ * @param resourceIdentifier either full resource type identifier or full
+ * resource identifier
+ * @return list of resource or link descriptions
+ * @throws CommunicationException when error occured during the
+ * communication with server
+ */
+ public abstract List<Entity> describe(URI resourceIdentifier) throws CommunicationException;
+
+ /**
+ * Creates a new resource on the server.
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * Model model = client.getModel();
+ *EntityBuilder entityBuilder = new EntityBuilder(model);
+ *Compute compute = entityBuilder.getCompute();
+ *compute.addMixin(model.findMixin("debian7", "os_tpl"));
+ *compute.addMixin(model.findMixin("small", "resource_tpl"));
+ *compute.setMemory(1024);
+ *compute.setCores(4);
+ *URI location = client.create(compute);}</pre>
+ *
+ * @param entity Creates a new resource on the server.
+ * @return URI of the new resource
+ * @throws CommunicationException when error occured during the
+ * communication with server
+ */
+ public abstract URI create(Entity entity) throws CommunicationException;
+
+ public abstract URI update(Entity entity) throws CommunicationException;
+
+ /**
+ * Deletes all resource of a certain resource type from the server.
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * boolean wasSuccessful = client.delete("compute");}</pre>
+ *
+ * @param resourceType resource type in shortened format (e.g. "compute",
+ * "storage", "network")
+ * @return true if the deletion was successful, false otherwise
+ * @throws CommunicationException when error occured during the
+ * communication with server
+ */
+ public abstract boolean delete(String resourceType) throws CommunicationException;
+
+ /**
+ * Deletes all resource of a certain resource type or specific resource from
+ * the server.
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * boolean wasSuccessful = client.delete(URI.create("http://schemas.ogf.org/occi/infrastructure#network"));
+ *...
+ *wasSuccessful = client.delete(URI.create("https://remote.server.net/storage/123"));}</pre>
+ *
+ * @param resourceIdentifier either full resource type identifier or full
+ * resource identifier
+ * @return true if the deletion was successful, false otherwise
+ * @throws CommunicationException when error occured during the
+ * communication with server
+ */
+ public abstract boolean delete(URI resourceIdentifier) throws CommunicationException;
+
+ /**
+ * Triggers given action on a specified set of resources.
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * Model model = client.getModel();
+ *EntityBuilder entityBuilder = new EntityBuilder(model);
+ *ActionInstance actionInstance = entityBuilder.getActionInstance("start");
+ *boolean wasSuccessful = client.trigger("compute", actionInstance);}</pre>
+ *
+ * @param resourceType resource type in shortened format (e.g. "compute",
+ * "storage", "network")
+ * @param action type of action
+ * @return true if the action was successful, false otherwise
+ * @throws CommunicationException when error occured during the
+ * communication with server
+ */
+ public abstract boolean trigger(String resourceType, ActionInstance action) throws CommunicationException;
+
+ /**
+ * Triggers given action on a set of resources or on a specified resource.
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * Model model = client.getModel();
+ *EntityBuilder entityBuilder = new EntityBuilder(model);
+ *ActionInstance actionInstance = entityBuilder.getActionInstance("start");
+ *boolean wasSuccessful = client.trigger(URI.create("http://schemas.ogf.org/occi/infrastructure#network"), actionInstance);
+ *...
+ *wasSuccessful = client.trigger(URI.create("https://remote.server.net/compute/456"), actionInstance);}</pre>
+ *
+ * @param resourceIdentifier either full resource type identifier or full
+ * resource identifier
+ * @param action type of action
+ * @return true if the action was successful, false otherwise
+ * @throws CommunicationException when error occured during the
+ * communication with server
+ */
+ public abstract boolean trigger(URI resourceIdentifier, ActionInstance action) throws CommunicationException;
+
+ /**
+ * Refreshes the Model used inside the client. Useful for updating the model
+ * without creating a new instance or reconnecting. Saves a lot of time in
+ * an interactive mode.
+ *
+ * @throws CommunicationException when error occured during the
+ * communication with server
+ */
+ public abstract void refresh() throws CommunicationException;
+
+ /**
+ * Establishes a connection.
+ *
+ * @throws CommunicationException when error occured during the
+ * communication with server
+ */
+ public abstract void connect() throws CommunicationException;
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api;
+
+import cz.cesnet.cloud.occi.Model;
+import cz.cesnet.cloud.occi.api.exception.EntityBuildingException;
+import cz.cesnet.cloud.occi.core.Action;
+import cz.cesnet.cloud.occi.core.ActionInstance;
+import cz.cesnet.cloud.occi.core.Kind;
+import cz.cesnet.cloud.occi.core.Link;
+import cz.cesnet.cloud.occi.core.Mixin;
+import cz.cesnet.cloud.occi.core.Resource;
+import cz.cesnet.cloud.occi.exception.AmbiguousIdentifierException;
+import cz.cesnet.cloud.occi.exception.InvalidAttributeValueException;
+import cz.cesnet.cloud.occi.infrastructure.Compute;
+import cz.cesnet.cloud.occi.infrastructure.IPNetwork;
+import cz.cesnet.cloud.occi.infrastructure.IPNetworkInterface;
+import cz.cesnet.cloud.occi.infrastructure.Network;
+import cz.cesnet.cloud.occi.infrastructure.NetworkInterface;
+import cz.cesnet.cloud.occi.infrastructure.Storage;
+import cz.cesnet.cloud.occi.infrastructure.StorageLink;
+import java.net.URI;
+import java.util.UUID;
+
+/**
+ * Builder class that helps with creation of OCCI entities.
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class EntityBuilder {
+
+ private Model model;
+
+ /**
+ * Default constructor.
+ *
+ * @param model cannot be null
+ */
+ public EntityBuilder(Model model) {
+ if (model == null) {
+ throw new NullPointerException("model cannot be null");
+ }
+
+ this.model = model;
+ }
+
+ private Kind getKind(String type) throws EntityBuildingException, AmbiguousIdentifierException {
+ Kind kind = model.findKind(type);
+ if (kind == null) {
+ throw new EntityBuildingException("unknown type '" + type + "'");
+ }
+
+ return kind;
+ }
+
+ private Kind getKind(URI identifier) throws EntityBuildingException {
+ Kind kind = model.findKind(identifier);
+ if (kind == null) {
+ throw new EntityBuildingException("unknown identifier '" + identifier + "'");
+ }
+
+ return kind;
+ }
+
+ private Kind getKind(Class resourceClass) throws EntityBuildingException {
+ URI uri = null;
+ Kind defaultKind = null;
+
+ if (resourceClass.equals(Compute.class)) {
+ uri = URI.create(Compute.KIND_IDENTIFIER_DEFAULT);
+ defaultKind = Compute.getDefaultKind();
+ } else if (resourceClass.equals(Network.class)) {
+ uri = URI.create(Network.KIND_IDENTIFIER_DEFAULT);
+ defaultKind = Network.getDefaultKind();
+ } else if (resourceClass.equals(Storage.class)) {
+ uri = URI.create(Storage.KIND_IDENTIFIER_DEFAULT);
+ defaultKind = Storage.getDefaultKind();
+ } else if (resourceClass.equals(StorageLink.class)) {
+ uri = URI.create(StorageLink.KIND_IDENTIFIER_DEFAULT);
+ defaultKind = StorageLink.getDefaultKind();
+ } else if (resourceClass.equals(NetworkInterface.class)) {
+ uri = URI.create(NetworkInterface.KIND_IDENTIFIER_DEFAULT);
+ defaultKind = NetworkInterface.getDefaultKind();
+ } else {
+ throw new EntityBuildingException("unknown class '" + resourceClass.getName() + "'");
+ }
+
+ Kind kind;
+ try {
+ kind = getKind(uri);
+ } catch (EntityBuildingException ex) {
+ kind = defaultKind;
+ }
+
+ return kind;
+ }
+
+ private Mixin getMixin(URI identifier) throws EntityBuildingException {
+ Mixin mixin = model.findMixin(identifier);
+ if (mixin == null) {
+ throw new EntityBuildingException("unknown identifier '" + identifier + "'");
+ }
+
+ return mixin;
+ }
+
+ private Action getAction(String type) throws EntityBuildingException, AmbiguousIdentifierException {
+ Action action = model.findAction(type);
+ if (action == null) {
+ throw new EntityBuildingException("unknown type '" + type + "'");
+ }
+
+ return action;
+ }
+
+ private Action getAction(URI identifier) throws EntityBuildingException {
+ Action action = model.findAction(identifier);
+ if (action == null) {
+ throw new EntityBuildingException("unknown identifier '" + identifier + "'");
+ }
+
+ return action;
+ }
+
+ /**
+ * Creates a link of given linkType (kind's term).
+ *
+ * @param linkType
+ * @return new Link instance of given linkType
+ * @throws EntityBuildingException if link type is ambiguous
+ */
+ public Link getLink(String linkType) throws EntityBuildingException {
+ try {
+ Kind kind = getKind(linkType);
+ return createLink(kind);
+ } catch (AmbiguousIdentifierException ex) {
+ throw new EntityBuildingException(ex);
+ }
+ }
+
+ /**
+ * Creates a link identified by linkIdentifier (kind's scheme+term).
+ *
+ * @param linkIdentifier
+ * @return new Link instance identified by linkIdentifier
+ * @throws EntityBuildingException if kind with specified identifier is not
+ * found in the model
+ */
+ public Link getLink(URI linkIdentifier) throws EntityBuildingException {
+ return createLink(getKind(linkIdentifier));
+ }
+
+ /**
+ * Creates a resource of given resourceType (kind's term).
+ *
+ * @param resourceType
+ * @return new Resource instance of given resourceType
+ * @throws EntityBuildingException if resource type is ambiguous
+ */
+ public Resource getResource(String resourceType) throws EntityBuildingException {
+ try {
+ Kind kind = getKind(resourceType);
+ return createResource(kind);
+ } catch (AmbiguousIdentifierException ex) {
+ throw new EntityBuildingException(ex);
+ }
+ }
+
+ /**
+ * Creates a resource identified by resourceIdentifier (kind's scheme+term).
+ *
+ * @param resourceIdentifier
+ * @return new Resource instance identified by resourceIdentifier
+ * @throws EntityBuildingException if kind with specified identifier is not
+ * found in the model
+ */
+ public Resource getResource(URI resourceIdentifier) throws EntityBuildingException {
+ return createResource(getKind(resourceIdentifier));
+ }
+
+ /**
+ * Creates an action instance of given actionType (action's term).
+ *
+ * @param actionType
+ * @return new ActionInstance instance of given actionType
+ * @throws EntityBuildingException if action type is ambiguous
+ */
+ public ActionInstance getActionInstance(String actionType) throws EntityBuildingException {
+ try {
+ Action action = getAction(actionType);
+ return createActionInstance(action);
+ } catch (AmbiguousIdentifierException ex) {
+ throw new EntityBuildingException(ex);
+ }
+ }
+
+ /**
+ * Creates an action instance identified by actionIdentifier (action's
+ * scheme+term).
+ *
+ * @param actionIdentifier
+ * @return new ActionInstance instance identified by actionIdentifier
+ * @throws EntityBuildingException if action with specified identifier is
+ * not found in the model
+ */
+ public ActionInstance getActionInstance(URI actionIdentifier) throws EntityBuildingException {
+ return createActionInstance(getAction(actionIdentifier));
+ }
+
+ /**
+ * Creates an compute instance identified by resourceIdentifier (compute's
+ * scheme+term).
+ *
+ * @param resourceIdentifier
+ * @return new Compute instance identified by resourceIdentifier
+ * @throws EntityBuildingException if compute with specified identifier is
+ * not found in the model
+ */
+ public Compute getCompute(URI resourceIdentifier) throws EntityBuildingException {
+ return createCompute(getKind(resourceIdentifier));
+ }
+
+ /**
+ * Creates a default compute instance.
+ *
+ * @return new default Compute instance
+ * @throws EntityBuildingException
+ */
+ public Compute getCompute() throws EntityBuildingException {
+ return createCompute(getKind(Compute.class));
+ }
+
+ /**
+ * Creates an network instance identified by resourceIdentifier (network's
+ * scheme+term).
+ *
+ * @param resourceIdentifier
+ * @return new Network instance identified by resourceIdentifier
+ * @throws EntityBuildingException
+ */
+ public Network getNetwork(URI resourceIdentifier) throws EntityBuildingException {
+ return createNetwork(getKind(resourceIdentifier));
+ }
+
+ /**
+ * Creates a default network instance.
+ *
+ * @return new default Network instance
+ * @throws EntityBuildingException
+ */
+ public Network getNetwork() throws EntityBuildingException {
+ return createNetwork(getKind(Network.class));
+ }
+
+ /**
+ * Creates an storage instance identified by resourceIdentifier (storage's
+ * scheme+term).
+ *
+ * @param resourceIdentifier
+ * @return new Storage instance identified by resourceIdentifier
+ * @throws EntityBuildingException
+ */
+ public Storage getStorage(URI resourceIdentifier) throws EntityBuildingException {
+ return createStorage(getKind(resourceIdentifier));
+ }
+
+ /**
+ * Creates a default storage instance.
+ *
+ * @return new default Storage instance
+ * @throws EntityBuildingException
+ */
+ public Storage getStorage() throws EntityBuildingException {
+ return createStorage(getKind(Storage.class));
+ }
+
+ /**
+ * Creates an storage link instance identified by resourceIdentifier (link's
+ * scheme+term).
+ *
+ * @param resourceIdentifier
+ * @return new StorageLink instance identified by resourceIdentifier
+ * @throws EntityBuildingException
+ */
+ public StorageLink getStorageLink(URI resourceIdentifier) throws EntityBuildingException {
+ return createStorageLink(getKind(resourceIdentifier));
+ }
+
+ /**
+ * Creates a default storage link instance.
+ *
+ * @return new default StorageLink instance
+ * @throws EntityBuildingException
+ */
+ public StorageLink getStorageLink() throws EntityBuildingException {
+ return createStorageLink(getKind(StorageLink.class));
+ }
+
+ /**
+ * Creates an network interface instance identified by resourceIdentifier
+ * (interface's scheme+term).
+ *
+ * @param resourceIdentifier
+ * @return new NetworkInterface instance identified by resourceIdentifier
+ * @throws EntityBuildingException
+ */
+ public NetworkInterface getNetworkInterface(URI resourceIdentifier) throws EntityBuildingException {
+ return createNetworkInterface(getKind(resourceIdentifier));
+ }
+
+ /**
+ * Creates a default network interface instance.
+ *
+ * @return new default NetworkInterface instance
+ * @throws EntityBuildingException
+ */
+ public NetworkInterface getNetworkInterface() throws EntityBuildingException {
+ return createNetworkInterface(getKind(NetworkInterface.class));
+ }
+
+ /**
+ * Creates an ip network instance identified by kind and mixin identifier
+ * (scheme+term).
+ *
+ * @param kindIdentifier
+ * @param mixinIdentifier
+ * @return new IPNetwork instance identified by its kind and mixin
+ * identifiers
+ * @throws EntityBuildingException
+ */
+ public IPNetwork getIPNetwork(URI kindIdentifier, URI mixinIdentifier) throws EntityBuildingException {
+ return createIPNetwork(getKind(kindIdentifier), getMixin(mixinIdentifier));
+ }
+
+ /**
+ * Creates a default ip network instance.
+ *
+ * @return new default IPNetwork instance
+ * @throws EntityBuildingException
+ */
+ public IPNetwork getIPNetwork() throws EntityBuildingException {
+ Kind kind = getKind(Network.class);
+
+ Mixin mixin;
+ try {
+ mixin = getMixin(URI.create(IPNetwork.MIXIN_IDENTIFIER_DEFAULT));
+ } catch (EntityBuildingException ex) {
+ mixin = IPNetwork.getDefaultMixin();
+ }
+
+ return createIPNetwork(kind, mixin);
+ }
+
+ /**
+ * Creates an ip network interface instance identified by kind and mixin
+ * identifier (scheme+term).
+ *
+ * @param kindIdentifier
+ * @param mixinIdentifier
+ * @return new IPNetworkInterface instance identified by its kind and mixin
+ * identifiers
+ * @throws EntityBuildingException
+ */
+ public IPNetworkInterface getIPNetworkInterface(URI kindIdentifier, URI mixinIdentifier) throws EntityBuildingException {
+ return createIPNetworkInterface(getKind(kindIdentifier), getMixin(mixinIdentifier));
+ }
+
+ /**
+ * Creates a default ip network interface instance.
+ *
+ * @return new default IPNetworkInterface instance
+ * @throws EntityBuildingException
+ */
+ public IPNetworkInterface getIPNetworkInterface() throws EntityBuildingException {
+ Kind kind = getKind(NetworkInterface.class);
+
+ Mixin mixin;
+ try {
+ mixin = getMixin(URI.create(IPNetworkInterface.MIXIN_IDENTIFIER_DEFAULT));
+ } catch (EntityBuildingException ex) {
+ mixin = IPNetworkInterface.getDefaultMixin();
+ }
+
+ return createIPNetworkInterface(kind, mixin);
+ }
+
+ private Resource createResource(Kind kind) {
+ try {
+ Resource resource = new Resource(UUID.randomUUID().toString(), kind);
+ resource.setModel(model);
+ return resource;
+ } catch (InvalidAttributeValueException ex) {
+ throw new RuntimeException("Invalid ID attribute value. This should not happen!", ex);
+ }
+ }
+
+ private Link createLink(Kind kind) {
+ try {
+ Link link = new Link(UUID.randomUUID().toString(), kind);
+ link.setModel(model);
+ return link;
+ } catch (InvalidAttributeValueException ex) {
+ throw new RuntimeException("Invalid ID attribute value. This should not happen!", ex);
+ }
+ }
+
+ private ActionInstance createActionInstance(Action action) {
+ ActionInstance ai = new ActionInstance(action);
+ ai.setModel(model);
+ return ai;
+ }
+
+ private Compute createCompute(Kind kind) {
+ try {
+ Compute compute = new Compute(UUID.randomUUID().toString(), kind);
+ compute.setModel(model);
+ return compute;
+ } catch (InvalidAttributeValueException ex) {
+ throw new RuntimeException("Invalid ID attribute value. This should not happen!", ex);
+ }
+ }
+
+ private Network createNetwork(Kind kind) {
+ try {
+ Network network = new Network(UUID.randomUUID().toString(), kind);
+ network.setModel(model);
+ return network;
+ } catch (InvalidAttributeValueException ex) {
+ throw new RuntimeException("Invalid ID attribute value. This should not happen!", ex);
+ }
+ }
+
+ private Storage createStorage(Kind kind) {
+ try {
+ Storage storage = new Storage(UUID.randomUUID().toString(), kind);
+ storage.setModel(model);
+ return storage;
+ } catch (InvalidAttributeValueException ex) {
+ throw new RuntimeException("Invalid ID attribute value. This should not happen!", ex);
+ }
+ }
+
+ private StorageLink createStorageLink(Kind kind) {
+ try {
+ StorageLink storageLink = new StorageLink(UUID.randomUUID().toString(), kind);
+ storageLink.setModel(model);
+ return storageLink;
+ } catch (InvalidAttributeValueException ex) {
+ throw new RuntimeException("Invalid ID attribute value. This should not happen!", ex);
+ }
+ }
+
+ private NetworkInterface createNetworkInterface(Kind kind) {
+ try {
+ NetworkInterface networkInterface = new NetworkInterface(UUID.randomUUID().toString(), kind);
+ networkInterface.setModel(model);
+ return networkInterface;
+ } catch (InvalidAttributeValueException ex) {
+ throw new RuntimeException("Invalid ID attribute value. This should not happen!", ex);
+ }
+ }
+
+ private IPNetwork createIPNetwork(Kind kind, Mixin mixin) {
+ try {
+ IPNetwork ipnetwork = new IPNetwork(UUID.randomUUID().toString(), kind);
+ ipnetwork.setModel(model);
+ ipnetwork.addMixin(mixin);
+ return ipnetwork;
+ } catch (InvalidAttributeValueException ex) {
+ throw new RuntimeException("Invalid ID attribute value. This should not happen!", ex);
+ }
+ }
+
+ private IPNetworkInterface createIPNetworkInterface(Kind kind, Mixin mixin) {
+ try {
+ IPNetworkInterface ipnetworkInterface = new IPNetworkInterface(UUID.randomUUID().toString(), kind);
+ ipnetworkInterface.setModel(model);
+ ipnetworkInterface.addMixin(mixin);
+ return ipnetworkInterface;
+ } catch (InvalidAttributeValueException ex) {
+ throw new RuntimeException("Invalid ID attribute value. This should not happen!", ex);
+ }
+ }
+
+ /**
+ * Returns model.
+ *
+ * @return model
+ */
+ public Model getModel() {
+ return model;
+ }
+
+ /**
+ * Sets model.
+ *
+ * @param model model
+ */
+ public void setModel(Model model) {
+ this.model = model;
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.example;
+
+import cz.cesnet.cloud.occi.Model;
+import cz.cesnet.cloud.occi.api.Client;
+import cz.cesnet.cloud.occi.api.EntityBuilder;
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+import cz.cesnet.cloud.occi.api.exception.EntityBuildingException;
+import cz.cesnet.cloud.occi.api.http.HTTPClient;
+import cz.cesnet.cloud.occi.api.http.auth.HTTPAuthentication;
+import cz.cesnet.cloud.occi.api.http.auth.X509Authentication;
+import cz.cesnet.cloud.occi.core.ActionInstance;
+import cz.cesnet.cloud.occi.core.Entity;
+import cz.cesnet.cloud.occi.core.Mixin;
+import cz.cesnet.cloud.occi.core.Resource;
+import cz.cesnet.cloud.occi.exception.AmbiguousIdentifierException;
+import cz.cesnet.cloud.occi.exception.InvalidAttributeValueException;
+import cz.cesnet.cloud.occi.exception.RenderingException;
+import cz.cesnet.cloud.occi.infrastructure.Compute;
+import cz.cesnet.cloud.occi.parser.MediaType;
+import java.net.URI;
+import java.util.List;
+
+/**
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class AdvancedUsageExample {
+
+ public static void main(String[] args) {
+ try {
+ HTTPAuthentication authentication = new X509Authentication("/path/to/certificate.pem", "password");
+ //set custom certificates if needed
+ authentication.setCAPath("/path/to/certificate/directory");
+ Client client = new HTTPClient(URI.create("https://localhost:1234"), authentication, MediaType.TEXT_PLAIN, false);
+
+ //connect client
+ client.connect();
+
+ //list all resources
+ System.out.println("Listing resources...");
+ List<URI> list = client.list();
+ System.out.println("Locations:");
+ for (URI uri : list) {
+ System.out.println(uri);
+ }
+
+ //creating a compute resource
+ System.out.println("Creating compute resource...");
+
+ Model model = client.getModel();
+ EntityBuilder eb = new EntityBuilder(model);
+
+ System.out.println("Listing available os template mixins...");
+ List<Mixin> mixins = model.findRelatedMixins("os_tpl");
+
+ if (mixins.isEmpty()) {
+ System.err.println("No os template mixins available. Quiting.");
+ return;
+ }
+
+ Resource compute = eb.getResource("compute");
+ Mixin mixin = mixins.get(0);
+ System.out.println("Mixin:");
+ System.out.println(mixin.toText());
+ compute.addMixin(mixins.get(0));
+ compute.addAttribute(Compute.ARCHITECTURE_ATTRIBUTE_NAME, "x86");
+ compute.addAttribute(Compute.CORES_ATTRIBUTE_NAME, "2");
+ compute.addAttribute(Compute.HOSTNAME_ATTRIBUTE_NAME, "jocci-test");
+ compute.addAttribute(Compute.MEMORY_ATTRIBUTE_NAME, "2");
+
+ URI location = client.create(compute);
+ System.out.println("Created compute instance at location: '" + location + "'.");
+
+ //describing resource
+ List<Entity> entities = client.describe(location);
+ System.out.println("Description:");
+ System.out.println(entities.get(0).toText());
+
+ System.out.println("Waiting for compute to become active...");
+ for (int i = 0; i < 5; i++) {
+ entities = client.describe(location);
+ if (entities.get(0).getValue(Compute.STATE_ATTRIBUTE_NAME).equals("active")) {
+ System.out.println("Compute active.");
+ break;
+ }
+ System.out.println(".");
+ Thread.sleep(5000);
+ }
+
+ //triggering actions
+ //stopping compute
+ System.out.println("Stopping previously created compute...");
+ ActionInstance actionInstance = eb.getActionInstance(URI.create("http://schemas.ogf.org/occi/infrastructure/compute/action#stop"));
+ boolean status = client.trigger(location, actionInstance);
+ if (status) {
+ System.out.println("Triggered: OK");
+ } else {
+ System.out.println("Triggered: FAIL");
+ }
+
+ //starting compute
+ System.out.println("Starting previously created compute...");
+ actionInstance = eb.getActionInstance(URI.create("http://schemas.ogf.org/occi/infrastructure/compute/action#start"));
+ status = client.trigger(location, actionInstance);
+ if (status) {
+ System.out.println("Triggered: OK");
+ } else {
+ System.out.println("Triggered: FAIL");
+ }
+
+ //deleting resource
+ System.out.println("Deleting previously created compute...");
+ status = client.delete(location);
+ if (status) {
+ System.out.println("Deleted: OK");
+ } else {
+ System.out.println("Deleted: FAIL");
+ }
+ } catch (CommunicationException | AmbiguousIdentifierException | EntityBuildingException |
+ InvalidAttributeValueException | RenderingException | InterruptedException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.example;
+
+import cz.cesnet.cloud.occi.api.Authentication;
+import cz.cesnet.cloud.occi.api.Client;
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+import cz.cesnet.cloud.occi.api.http.HTTPClient;
+import cz.cesnet.cloud.occi.api.http.auth.BasicAuthentication;
+import java.net.URI;
+import java.util.List;
+
+/**
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class BasicAuthenticationExample {
+
+ public static void main(String[] args) {
+ try {
+ Authentication authentication = new BasicAuthentication("username", "password");
+ Client client = new HTTPClient(URI.create("http://localhost:1234"), authentication);
+
+ List<URI> list = client.list();
+ System.out.println("Locations:");
+ for (URI uri : list) {
+ System.out.println(uri);
+ }
+ } catch (CommunicationException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.example;
+
+import cz.cesnet.cloud.occi.api.Authentication;
+import cz.cesnet.cloud.occi.api.Client;
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+import cz.cesnet.cloud.occi.api.http.HTTPClient;
+import cz.cesnet.cloud.occi.api.http.auth.DigestAuthentication;
+import java.net.URI;
+import java.util.List;
+
+/**
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class DigestAuthenticationExample {
+
+ public static void main(String[] args) {
+ try {
+ Authentication authentication = new DigestAuthentication("username", "password");
+ Client client = new HTTPClient(URI.create("http://localhost:1234"), authentication);
+
+ List<URI> list = client.list();
+ System.out.println("Locations:");
+ for (URI uri : list) {
+ System.out.println(uri);
+ }
+ } catch (CommunicationException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.example;
+
+import cz.cesnet.cloud.occi.api.Client;
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+import cz.cesnet.cloud.occi.api.http.HTTPClient;
+import java.net.URI;
+import java.util.List;
+
+/**
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class SimpleUsageExample {
+
+ public static void main(String[] args) {
+
+ try {
+ Client client = new HTTPClient(URI.create("http://localhost:1234"));
+ client.connect();
+
+ List<URI> list = client.list();
+ System.out.println("Locations:");
+ for (URI uri : list) {
+ System.out.println(uri);
+ }
+ } catch (CommunicationException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.example;
+
+import cz.cesnet.cloud.occi.api.Client;
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+import cz.cesnet.cloud.occi.api.http.HTTPClient;
+import cz.cesnet.cloud.occi.api.http.auth.HTTPAuthentication;
+import cz.cesnet.cloud.occi.api.http.auth.VOMSAuthentication;
+import java.net.URI;
+import java.util.List;
+
+/**
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class VOMSAuthenticationExample {
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String[] args) {
+ try {
+ HTTPAuthentication authentication = new VOMSAuthentication("/path/to/certificate.pem");
+ //if custom certificates are needed
+ authentication.setCAPath("/path/to/certificate/directory");
+ Client client = new HTTPClient(URI.create("https://localhost:1234"), authentication);
+
+ List<URI> list = client.list();
+ System.out.println("Locations:");
+ for (URI uri : list) {
+ System.out.println(uri);
+ }
+ } catch (CommunicationException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.example;
+
+import cz.cesnet.cloud.occi.api.Client;
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+import cz.cesnet.cloud.occi.api.http.HTTPClient;
+import cz.cesnet.cloud.occi.api.http.auth.HTTPAuthentication;
+import cz.cesnet.cloud.occi.api.http.auth.X509Authentication;
+import java.net.URI;
+import java.util.List;
+
+/**
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class X509AuthenticationExample {
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String[] args) {
+ try {
+ HTTPAuthentication authentication = new X509Authentication("/path/to/certificate.pem", "password");
+ //if custom certificates are needed
+ authentication.setCAPath("/path/to/certificate/directory");
+ Client client = new HTTPClient(URI.create("https://localhost:1234"), authentication);
+
+ List<URI> list = client.list();
+ System.out.println("Locations:");
+ for (URI uri : list) {
+ System.out.println(uri);
+ }
+ } catch (CommunicationException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.exception;
+
+/**
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class AuthenticationException extends CommunicationException {
+
+ public AuthenticationException(String message) {
+ super(message);
+ }
+
+ public AuthenticationException(String message, Throwable ex) {
+ super(message, ex);
+ }
+
+ public AuthenticationException(Throwable ex) {
+ super(ex);
+ }
+
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.exception;
+
+/**
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class CommunicationException extends Exception {
+
+ public CommunicationException(String message) {
+ super(message);
+ }
+
+ public CommunicationException(String message, Throwable ex) {
+ super(message, ex);
+ }
+
+ public CommunicationException(Throwable ex) {
+ super(ex);
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.exception;
+
+/**
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class EntityBuildingException extends Exception {
+
+ public EntityBuildingException(String message) {
+ super(message);
+ }
+
+ public EntityBuildingException(String message, Throwable ex) {
+ super(message, ex);
+ }
+
+ public EntityBuildingException(Throwable ex) {
+ super(ex);
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.http;
+
+import com.sun.net.httpserver.Headers;
+import cz.cesnet.cloud.occi.Collection;
+import cz.cesnet.cloud.occi.Model;
+import cz.cesnet.cloud.occi.api.Authentication;
+import cz.cesnet.cloud.occi.api.Client;
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+import cz.cesnet.cloud.occi.api.http.auth.HTTPAuthentication;
+import cz.cesnet.cloud.occi.api.http.auth.NoAuthentication;
+import cz.cesnet.cloud.occi.core.ActionInstance;
+import cz.cesnet.cloud.occi.core.Entity;
+import cz.cesnet.cloud.occi.core.Kind;
+import cz.cesnet.cloud.occi.exception.AmbiguousIdentifierException;
+import cz.cesnet.cloud.occi.exception.ParsingException;
+import cz.cesnet.cloud.occi.exception.RenderingException;
+import cz.cesnet.cloud.occi.parser.CollectionType;
+import cz.cesnet.cloud.occi.parser.MediaType;
+import cz.cesnet.cloud.occi.parser.TextParser;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpMessage;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class representing HTTP OCCI client.
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class HTTPClient extends Client {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(HTTPClient.class);
+ private static final String ACTION_URL_PARAMETER = "?action=";
+ private final HTTPConnection connection = new HTTPConnection();
+ private HttpHost target;
+ private String responseMediaType;
+ private String responseBody;
+ private String mediaType;
+ private Headers responseHeaders;
+ private final TextParser parser = new TextParser();
+
+ /**
+ * Constructor.
+ *
+ * <p>
+ * HTTPClient has three constructors via which one can set remote server's
+ * endpoint, authentication method, media type for HTTP messages and whether
+ * client should automatically connect to the server or not.</p>
+ *
+ * <p>
+ * By default text/plain is used as media type and client is initialized
+ * without authentication method. Client automatically connects to the
+ * remote server by default when authentication method is set.</p>
+ *
+ * <p>
+ * Examples:</p>
+ *
+ * <pre>{@code
+ * Client client = new HTTPClient(URI.create("https://remote.server.net")); client.connect();}</pre>
+ *
+ * <pre>{@code
+ * Client client = new HTTPClient(URI.create("https://remote.server.net"), new BasicAuthentication("username", "password"), MediaType.TEXT_OCCI, true);}</pre>
+ *
+ * @param endpoint cannot be null
+ * @param authentication authentication method which will be used to
+ * authenticate client against the server
+ * @param mediaType string representing HTTP media type used in
+ * communication
+ * @param autoconnect
+ * @throws CommunicationException
+ */
+ public HTTPClient(URI endpoint, Authentication authentication, String mediaType, boolean autoconnect) throws CommunicationException {
+ //to avoid SSL handshake unrecognized_name error
+ System.setProperty("jsse.enableSNIExtension", "false");
+
+ if (endpoint == null) {
+ throw new NullPointerException("endpoint cannot be null");
+ }
+ if (authentication == null) {
+ authentication = new NoAuthentication();
+ }
+
+ setEndpoint(endpoint);
+ target = new HttpHost(endpoint.getHost(), endpoint.getPort(), endpoint.getScheme());
+ connection.setPrefix(endpoint.getPath());
+ setAuthentication(authentication);
+
+ setMediaType(mediaType);
+
+ if (autoconnect) {
+ connect();
+ }
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param endpoint cannot be null
+ * @param authentication
+ * @throws CommunicationException
+ */
+ public HTTPClient(URI endpoint, Authentication authentication) throws CommunicationException {
+ this(endpoint, authentication, MediaType.TEXT_PLAIN, true);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param endpoint cannot be null
+ * @throws CommunicationException
+ */
+ public HTTPClient(URI endpoint) throws CommunicationException {
+ this(endpoint, null, MediaType.TEXT_PLAIN, false);
+ }
+
+ /**
+ * Sets media type for the connection.
+ *
+ * @param mediaType media type
+ */
+ public void setMediaType(String mediaType) {
+ this.mediaType = mediaType;
+ connection.setMediaType(mediaType);
+ }
+
+ /**
+ * Returns media type of the connection.
+ *
+ * @return media type
+ */
+ public String getMediaType() {
+ return this.mediaType;
+ }
+
+ /**
+ * @see Client#connect()
+ */
+ @Override
+ public void connect() throws CommunicationException {
+ Authentication auth = getAuthentication();
+ if (!(auth instanceof HTTPAuthentication)) {
+ throw new CommunicationException("authentication method '" + auth + "' is not a valid HTTP authentication method");
+ }
+
+ HTTPAuthentication httpAuth = (HTTPAuthentication) auth;
+ httpAuth.setTarget(target);
+ httpAuth.setConnection(connection);
+ httpAuth.authenticate();
+
+ setConnected(true);
+ obtainModel();
+ }
+
+ private void checkConnection() throws CommunicationException {
+ if (!isConnected()) {
+ connect();
+ }
+ }
+
+ private Headers convertHeaders(Header[] apacheHeaders) {
+ Headers javaHeaders = new Headers();
+ for (Header header : apacheHeaders) {
+ javaHeaders.add(header.getName().toLowerCase(), header.getValue());
+ }
+
+ return javaHeaders;
+ }
+
+ private void runAndParseRequest(HttpRequest request, int[] statuses) throws CommunicationException {
+ try {
+ try (CloseableHttpResponse response = HTTPHelper.runRequest(request, target, connection.getClient(), connection.getContext(), statuses)) {
+ responseMediaType = response.getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue();
+ if (responseMediaType.contains(";")) {
+ responseMediaType = responseMediaType.substring(0, responseMediaType.indexOf(";"));
+ }
+ responseHeaders = convertHeaders(response.getAllHeaders());
+ HttpEntity responseEntity = response.getEntity();
+ if (responseEntity == null) {
+ responseBody = "";
+ } else {
+ responseBody = EntityUtils.toString(responseEntity);
+ }
+ }
+ } catch (IOException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ private void runAndParseRequest(HttpRequest request) throws CommunicationException {
+ runAndParseRequest(request, new int[]{HttpStatus.SC_OK, HttpStatus.SC_NO_CONTENT});
+ }
+
+ private void obtainModel() throws CommunicationException {
+ try {
+ LOGGER.debug("Obtaining model...");
+ checkConnection();
+ HttpGet httpGet = HTTPHelper.prepareGet(Client.MODEL_URI, connection.getHeaders(), connection.getPrefix());
+ runAndParseRequest(httpGet);
+ setModel(parser.parseModel(responseMediaType, responseBody, responseHeaders));
+ LOGGER.debug("Model: {}", getModel());
+ } catch (ParsingException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ /**
+ * @see Client#list()
+ */
+ @Override
+ public List<URI> list() throws CommunicationException {
+ return list("");
+ }
+
+ /**
+ * @see Client#list(java.lang.String)
+ */
+ @Override
+ public List<URI> list(String resourceType) throws CommunicationException {
+ HttpGet httpGet;
+ if (resourceType.isEmpty()) {
+ httpGet = HTTPHelper.prepareGet("/", connection.getHeaders(), connection.getPrefix());
+ } else {
+ Kind kind;
+ try {
+ checkConnection();
+ kind = getModel().findKind(resourceType);
+ } catch (AmbiguousIdentifierException ex) {
+ throw new CommunicationException(ex);
+ }
+ if (kind == null) {
+ throw new CommunicationException("unknown resource type '" + resourceType + "'");
+ }
+ httpGet = HTTPHelper.prepareGet(kind.getLocation(), connection.getHeaders(), connection.getPrefix());
+ }
+
+ return runListGet(httpGet);
+ }
+
+ /**
+ * @see Client#list(java.net.URI)
+ */
+ @Override
+ public List<URI> list(URI resourceIdentifier) throws CommunicationException {
+ checkConnection();
+ Kind kind = getModel().findKind(resourceIdentifier);
+ if (kind == null) {
+ throw new CommunicationException("unknown resource identifier '" + resourceIdentifier + "'");
+ }
+ HttpGet httpGet = HTTPHelper.prepareGet(kind.getLocation(), connection.getHeaders(), connection.getPrefix());
+ return runListGet(httpGet);
+ }
+
+ private List<URI> runListGet(HttpGet httpGet) throws CommunicationException {
+ try {
+ checkConnection();
+ runAndParseRequest(httpGet);
+ List<URI> locations = parser.parseLocations(responseMediaType, responseBody, responseHeaders);
+ LOGGER.debug("Locations: {}", locations);
+ return locations;
+ } catch (ParsingException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ /**
+ * @see Client#describe()
+ */
+ @Override
+ public List<Entity> describe() throws CommunicationException {
+ List<URI> locations = list();
+ Collection collection = new Collection();
+ for (URI location : locations) {
+ collection.merge(describeLocation(location));
+ }
+
+ return generateEntityListFromCollection(collection);
+ }
+
+ /**
+ * @see Client#describe(java.lang.String)
+ */
+ @Override
+ public List<Entity> describe(String resourceType) throws CommunicationException {
+ checkConnection();
+ Model model = getModel();
+ try {
+ Kind kind = model.findKind(resourceType);
+ if (kind == null) {
+ throw new CommunicationException("unknown resource type '" + resourceType + "'");
+ }
+ CollectionType type = model.findKindType(kind);
+ if (type == null) {
+ throw new CommunicationException("unknown resource type '" + resourceType + "'");
+ }
+
+ return describe(list(resourceType), type);
+ } catch (AmbiguousIdentifierException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ /**
+ * @see Client#describe(java.net.URI)
+ */
+ @Override
+ public List<Entity> describe(URI resourceIdentifier) throws CommunicationException {
+ checkConnection();
+ Model model = getModel();
+ Kind kind = model.findKind(resourceIdentifier);
+ if (kind != null) {
+ CollectionType type = model.findKindType(kind);
+ if (type == null) {
+ throw new CommunicationException("unknown resource identifier '" + resourceIdentifier + "'");
+ }
+
+ return describe(list(resourceIdentifier), type);
+ } else {
+ Collection collection = describeLocation(resourceIdentifier);
+
+ return generateEntityListFromCollection(collection);
+ }
+ }
+
+ private Collection describeLocation(URI location) throws CommunicationException {
+ location = getFullUri(location);
+ String path = location.getPath();
+ String[] segments = TextParser.divideUriByLastSegment(path);
+ CollectionType type = getModel().findKindType(segments[1]);
+ if (type == null) {
+ throw new CommunicationException("unknown resource identifier '" + location + "'");
+ }
+
+ HttpGet httpGet = HTTPHelper.prepareGet(location, connection.getHeaders(), connection.getPrefix());
+ return runDescribeGet(httpGet, type);
+ }
+
+ private List<Entity> describe(List<URI> locations, CollectionType type) throws CommunicationException {
+ Collection collection = new Collection();
+ for (URI location : locations) {
+ HttpGet httpGet = HTTPHelper.prepareGet(location, connection.getHeaders(), connection.getPrefix());
+ collection.merge(runDescribeGet(httpGet, type));
+ }
+
+ return generateEntityListFromCollection(collection);
+ }
+
+ private List<Entity> generateEntityListFromCollection(Collection collection) {
+ List<Entity> list = new ArrayList();
+ list.addAll(collection.getLinks());
+ list.addAll(collection.getResources());
+
+ return list;
+ }
+
+ private Collection runDescribeGet(HttpGet httpGet, CollectionType type) throws CommunicationException {
+ try {
+ checkConnection();
+ runAndParseRequest(httpGet);
+ Collection collection = parser.parseCollection(responseMediaType, responseBody, responseHeaders, type);
+ LOGGER.debug("Collection: {}", collection);
+ return collection;
+ } catch (ParsingException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ /**
+ * @see Client#create(cz.cesnet.cloud.occi.core.Entity)
+ */
+ @Override
+ public URI create(Entity entity) throws CommunicationException {
+ Kind kind = entity.getKind();
+ if (kind == null) {
+ throw new CommunicationException("entity with empty kind");
+ }
+
+ HttpPost httpPost = HTTPHelper.preparePost(kind.getLocation(), connection.getHeaders(), connection.getPrefix());
+ try {
+ switch (mediaType) {
+ case MediaType.TEXT_OCCI: {
+ Headers headers = entity.toHeaders();
+ addHeaders(httpPost, headers);
+ }
+ break;
+ case MediaType.TEXT_PLAIN: {
+ HttpEntity httpEntity = new StringEntity(entity.toText());
+ httpPost.setEntity(httpEntity);
+ }
+ break;
+ default:
+ throw new CommunicationException("unsupported media type '" + mediaType + "'");
+ }
+
+ checkConnection();
+ runAndParseRequest(httpPost, new int[]{HttpStatus.SC_CREATED, HttpStatus.SC_OK});
+
+ //HACK
+ //so communication with servers with WRONG OCCI implementation will work
+ if (!responseMediaType.equals(MediaType.TEXT_OCCI) && responseBody.trim().equals("OK") && responseHeaders.containsKey("Location")) {
+ responseMediaType = MediaType.TEXT_OCCI;
+ }
+ //HACK
+
+ List<URI> locations = parser.parseLocations(responseMediaType, responseBody, responseHeaders);
+ if (locations == null || locations.isEmpty()) {
+ throw new CommunicationException("no location returned");
+ }
+
+ return locations.get(0);
+ } catch (RenderingException | ParsingException | UnsupportedEncodingException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ /**
+ * @see Client#update(cz.cesnet.cloud.occi.core.Entity)
+ */
+ @Override
+ public URI update(Entity entity) throws CommunicationException {
+ Kind kind = entity.getKind();
+ if (kind == null) {
+ throw new CommunicationException("entity with empty kind");
+ }
+
+ HttpPut httpPut = HTTPHelper.preparePut(kind.getLocation() + entity.getId(), connection.getHeaders(), connection.getPrefix());
+ try {
+ switch (mediaType) {
+ case MediaType.TEXT_OCCI: {
+ Headers headers = entity.toHeaders();
+ addHeaders(httpPut, headers);
+ }
+ break;
+ case MediaType.TEXT_PLAIN: {
+ HttpEntity httpEntity = new StringEntity(entity.toText());
+ httpPut.setEntity(httpEntity);
+ }
+ break;
+ default:
+ throw new CommunicationException("unsupported media type '" + mediaType + "'");
+ }
+
+ checkConnection();
+ runAndParseRequest(httpPut, new int[]{HttpStatus.SC_CREATED, HttpStatus.SC_OK});
+
+ //HACK
+ //so communication with servers with WRONG OCCI implementation will work
+ if (!responseMediaType.equals(MediaType.TEXT_OCCI) && responseBody.trim().equals("OK") && responseHeaders.containsKey("Location")) {
+ responseMediaType = MediaType.TEXT_OCCI;
+ }
+ //HACK
+
+ List<URI> locations = parser.parseLocations(responseMediaType, responseBody, responseHeaders);
+ if (locations == null || locations.isEmpty()) {
+ throw new CommunicationException("no location returned");
+ }
+
+ return locations.get(0);
+ } catch (RenderingException | ParsingException | UnsupportedEncodingException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ /**
+ * @see Client#delete(java.lang.String)
+ */
+ @Override
+ public boolean delete(String resourceType) throws CommunicationException {
+ Kind kind;
+ try {
+ checkConnection();
+ kind = getModel().findKind(resourceType);
+ } catch (AmbiguousIdentifierException ex) {
+ throw new CommunicationException(ex);
+ }
+ if (kind == null) {
+ throw new CommunicationException("unknown resource type '" + resourceType + "'");
+ }
+ HttpDelete httpDelete = HTTPHelper.prepareDelete(kind.getLocation(), connection.getHeaders(), connection.getPrefix());
+
+ checkConnection();
+ return HTTPHelper.runRequestForStatus(httpDelete, target, connection.getClient(), connection.getContext());
+ }
+
+ /**
+ * @see Client#delete(java.net.URI)
+ */
+ @Override
+ public boolean delete(URI resourceIdentifier) throws CommunicationException {
+ checkConnection();
+ Kind kind = getModel().findKind(resourceIdentifier);
+ HttpDelete httpDelete;
+ if (kind != null) {
+ httpDelete = HTTPHelper.prepareDelete(kind.getLocation(), connection.getHeaders(), connection.getPrefix());
+ } else {
+ resourceIdentifier = getFullUri(resourceIdentifier);
+ httpDelete = HTTPHelper.prepareDelete(resourceIdentifier, connection.getHeaders(), connection.getPrefix());
+ }
+
+ checkConnection();
+ return HTTPHelper.runRequestForStatus(httpDelete, target, connection.getClient(), connection.getContext());
+ }
+
+ /**
+ * @see Client#trigger(java.lang.String,
+ * cz.cesnet.cloud.occi.core.ActionInstance)
+ */
+ @Override
+ public boolean trigger(String resourceType, ActionInstance action) throws CommunicationException {
+ Kind kind;
+ try {
+ checkConnection();
+ kind = getModel().findKind(resourceType);
+ } catch (AmbiguousIdentifierException ex) {
+ throw new CommunicationException(ex);
+ }
+ if (kind == null) {
+ throw new CommunicationException("unknown resource type '" + resourceType + "'");
+ }
+
+ try {
+ String url = kind.getLocation().toString() + ACTION_URL_PARAMETER + action.getAction().getTerm();
+ HttpPost httpPost = HTTPHelper.preparePost(url, connection.getHeaders(), connection.getPrefix());
+ switch (mediaType) {
+ case MediaType.TEXT_OCCI: {
+ Headers headers = action.toHeaders();
+ addHeaders(httpPost, headers);
+ }
+ break;
+ case MediaType.TEXT_PLAIN: {
+ HttpEntity httpEntity = new StringEntity(action.toText());
+ httpPost.setEntity(httpEntity);
+ }
+ break;
+ default:
+ throw new CommunicationException("unsupported media type '" + mediaType + "'");
+ }
+
+ checkConnection();
+ return HTTPHelper.runRequestForStatus(httpPost, target, connection.getClient(), connection.getContext());
+ } catch (UnsupportedEncodingException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ /**
+ * @see Client#trigger(java.net.URI,
+ * cz.cesnet.cloud.occi.core.ActionInstance)
+ */
+ @Override
+ public boolean trigger(URI resourceIdentifier, ActionInstance action) throws CommunicationException {
+ checkConnection();
+ Kind kind = getModel().findKind(resourceIdentifier);
+ String url;
+ if (kind != null) {
+ url = kind.getLocation().toString() + ACTION_URL_PARAMETER + action.getAction().getTerm();
+ } else {
+ resourceIdentifier = getFullUri(resourceIdentifier);
+ url = resourceIdentifier.toString() + ACTION_URL_PARAMETER + action.getAction().getTerm();
+ }
+
+ HttpPost httpPost = HTTPHelper.preparePost(url, connection.getHeaders(), connection.getPrefix());
+ try {
+ switch (mediaType) {
+ case MediaType.TEXT_OCCI: {
+ Headers headers = action.toHeaders();
+ addHeaders(httpPost, headers);
+ }
+ break;
+ case MediaType.TEXT_PLAIN: {
+ HttpEntity httpEntity = new StringEntity(action.toText());
+ httpPost.setEntity(httpEntity);
+ }
+ break;
+ default:
+ throw new CommunicationException("unsupported media type '" + mediaType + "'");
+ }
+
+ checkConnection();
+ return HTTPHelper.runRequestForStatus(httpPost, target, connection.getClient(), connection.getContext());
+ } catch (UnsupportedEncodingException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ private URI getFullUri(URI uri) throws CommunicationException {
+ if (uri.getHost() == null) {
+ try {
+ uri = new URI(getEndpoint().toString() + uri.toString()).normalize();
+ } catch (URISyntaxException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ return uri;
+ }
+
+ private void addHeaders(HttpMessage message, Headers headers) {
+ for (String headerName : headers.keySet()) {
+ for (String value : headers.get(headerName)) {
+ message.addHeader(headerName, value);
+ }
+ }
+ }
+
+ /**
+ * @see Client#refresh()
+ */
+ @Override
+ public void refresh() throws CommunicationException {
+ obtainModel();
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.http;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.http.Header;
+import org.apache.http.HttpHeaders;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.protocol.HttpContext;
+
+/**
+ * Class containing context of HTTP connections.
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class HTTPConnection {
+
+ private CloseableHttpClient client = null;
+ private HttpContext context = HttpClientContext.create();
+ private List<Header> headers = new ArrayList<>();
+ private String prefix = "";
+
+ public CloseableHttpClient getClient() {
+ return client;
+ }
+
+ public void setClient(CloseableHttpClient client) {
+ this.client = client;
+ }
+
+ public HttpContext getContext() {
+ return context;
+ }
+
+ public void setContext(HttpContext context) {
+ this.context = context;
+ }
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ if (prefix == null) {
+ this.prefix = "";
+ }
+ }
+
+ public Header[] getHeaders() {
+ return headers.toArray(new Header[0]);
+ }
+
+ /**
+ * Adds header that will be used in HTTP requests. If connection already
+ * have the header set, its value will be replaced.
+ *
+ * @param header
+ */
+ public void addHeader(Header header) {
+ for (Header h : headers) {
+ if (h.getName().equals(header.getName())) {
+ headers.remove(h);
+ }
+ }
+
+ headers.add(header);
+ }
+
+ /**
+ * Removes all headers from connection.
+ */
+ public void clearHeaders() {
+ headers = new ArrayList<>();
+ }
+
+ /**
+ * Sets headers 'Content-type' and 'Accept' to given media type.
+ *
+ * @param mediaType media type
+ */
+ public void setMediaType(String mediaType) {
+ addHeader(new BasicHeader(HttpHeaders.CONTENT_TYPE, mediaType));
+ addHeader(new BasicHeader(HttpHeaders.ACCEPT, mediaType));
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.http;
+
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+import java.io.IOException;
+import java.net.URI;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class that helps with HTTP requests.
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class HTTPHelper {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(HTTPHelper.class);
+
+ public static HttpGet prepareGet(String uri, Header[] headers, String prefix) {
+ HttpGet httpGet = new HttpGet(addPrefix(uri, prefix));
+ httpGet.setHeaders(headers);
+ return httpGet;
+ }
+
+ public static HttpGet prepareGet(String uri) {
+ return prepareGet(uri, null, "");
+ }
+
+ public static HttpHead prepareHead(String uri, Header[] headers, String prefix) {
+ HttpHead httpHead = new HttpHead(addPrefix(uri, prefix));
+ httpHead.setHeaders(headers);
+ return httpHead;
+ }
+
+ public static HttpHead prepareHead(String uri) {
+ return prepareHead(uri, null, "");
+ }
+
+ public static HttpGet prepareGet(URI uri, Header[] headers, String prefix) {
+ HttpGet httpGet = new HttpGet(addPrefix(uri.toString(), prefix));
+ httpGet.setHeaders(headers);
+ return httpGet;
+ }
+
+ public static HttpGet prepareGet(URI uri) {
+ return prepareGet(uri, null, "");
+ }
+
+ public static HttpHead prepareHead(URI uri, Header[] headers, String prefix) {
+ HttpHead httpHead = new HttpHead(addPrefix(uri.toString(), prefix));
+ httpHead.setHeaders(headers);
+ return httpHead;
+ }
+
+ public static HttpHead prepareHead(URI uri) {
+ return prepareHead(uri, null, "");
+ }
+
+ public static HttpDelete prepareDelete(String uri, Header[] headers, String prefix) {
+ HttpDelete httpDelete = new HttpDelete(addPrefix(uri, prefix));
+ httpDelete.setHeaders(headers);
+ return httpDelete;
+ }
+
+ public static HttpDelete prepareDelete(String uri) {
+ return prepareDelete(uri, null, "");
+ }
+
+ public static HttpDelete prepareDelete(URI uri, Header[] headers, String prefix) {
+ HttpDelete httpDelete = new HttpDelete(addPrefix(uri.toString(), prefix));
+ httpDelete.setHeaders(headers);
+ return httpDelete;
+ }
+
+ public static HttpDelete prepareDelete(URI uri) {
+ return prepareDelete(uri, null, "");
+ }
+
+ public static HttpPost preparePost(String uri, Header[] headers, String prefix) {
+ HttpPost httpPost = new HttpPost(addPrefix(uri, prefix));
+ httpPost.setHeaders(headers);
+ return httpPost;
+ }
+
+ public static HttpPost preparePost(String uri) {
+ return preparePost(uri, null, "");
+ }
+
+ public static HttpPost preparePost(URI uri, Header[] headers, String prefix) {
+ HttpPost httpPost = new HttpPost(addPrefix(uri.toString(), prefix));
+ httpPost.setHeaders(headers);
+ return httpPost;
+ }
+
+ public static HttpPost preparePost(URI uri) {
+ return preparePost(uri, null, "");
+ }
+
+ public static HttpPut preparePut(String uri, Header[] headers, String prefix) {
+ HttpPut httpPut = new HttpPut(addPrefix(uri, prefix));
+ httpPut.setHeaders(headers);
+ return httpPut;
+ }
+
+ public static HttpPut preparePut(String uri) {
+ return preparePut(uri, null, "");
+ }
+
+ public static HttpPut preparePut(URI uri, Header[] headers, String prefix) {
+ HttpPut httpPut = new HttpPut(addPrefix(uri.toString(), prefix));
+ httpPut.setHeaders(headers);
+ return httpPut;
+ }
+
+ public static HttpPut preparePut(URI uri) {
+ return preparePut(uri, null, "");
+ }
+
+ public static CloseableHttpResponse runRequest(HttpRequest httpRequest, HttpHost target, CloseableHttpClient client, HttpContext context, int[] statuses
+ ) throws CommunicationException {
+ try {
+ CloseableHttpResponse response = client.execute(target, httpRequest, context);
+ boolean acceptableStatus = false;
+ for (int status : statuses) {
+ if (response.getStatusLine().getStatusCode() == status) {
+ acceptableStatus = true;
+ }
+ }
+ if (!acceptableStatus) {
+ HttpEntity entity = response.getEntity();
+ String body = "";
+ if (entity != null) {
+ body = EntityUtils.toString(entity);
+ }
+ LOGGER.debug("Response: {}\nHeaders: {}\nBody: {}", response.getStatusLine().toString(), response.getAllHeaders(), body);
+ throw new CommunicationException(response.getStatusLine().toString() + "\n" + body);
+ }
+
+ return response;
+ } catch (IOException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ public static CloseableHttpResponse runRequest(HttpRequest httpRequest, HttpHost target, CloseableHttpClient client, HttpContext context) throws CommunicationException {
+ return runRequest(httpRequest, target, client, context, new int[]{HttpStatus.SC_OK});
+ }
+
+ public static boolean runRequestForStatus(HttpRequest httpRequest, HttpHost target, CloseableHttpClient client, HttpContext context, int[] statuses
+ ) throws CommunicationException {
+ try {
+ try (CloseableHttpResponse response = client.execute(target, httpRequest, context)) {
+ boolean acceptableStatus = false;
+ for (int status : statuses) {
+ if (response.getStatusLine().getStatusCode() == status) {
+ acceptableStatus = true;
+ }
+ }
+ return acceptableStatus;
+ }
+ } catch (IOException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ public static boolean runRequestForStatus(HttpRequest httpRequest, HttpHost target, CloseableHttpClient client, HttpContext context) throws CommunicationException {
+ return runRequestForStatus(httpRequest, target, client, context, new int[]{HttpStatus.SC_OK, HttpStatus.SC_NO_CONTENT});
+ }
+
+ private static String addPrefix(String uri, String prefix) {
+ if (uri.contains(prefix)) {
+ return uri;
+ } else {
+ return prefix + uri;
+ }
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.http.auth;
+
+import cz.cesnet.cloud.occi.api.Authentication;
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.config.AuthSchemes;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class representing BASIC HTTP authentication method.
+ *
+ * <p>
+ * This method has a Keystone authentication method as fallback.</p>
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * HTTPAuthentication auth = new BasicAuthentication("username", "password");
+ *auth.setCAPath("/etc/grid-security/certificates/"); //path to CA directory
+ *Client client = new HTTPClient(URI.create("https://remote.server.net"), auth);}</pre>
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class BasicAuthentication extends HTTPAuthentication {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(BasicAuthentication.class);
+ public static final String IDENTIFIER = "OCCIBasicAuthentication";
+ private String username;
+ private String password;
+ private String authScheme;
+
+ public BasicAuthentication(String username, String password) {
+ this.username = username;
+ this.password = password;
+ this.authScheme = AuthSchemes.BASIC;
+ }
+
+ protected void setAuthScheme(String authScheme) {
+ this.authScheme = authScheme;
+ }
+
+ /**
+ * Returns username.
+ *
+ * @return username
+ */
+ public String getUsername() {
+ return username;
+ }
+
+ /**
+ * Sets username.
+ *
+ * @param username username
+ */
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ /**
+ * Returns password.
+ *
+ * @return password
+ */
+ public String getPassword() {
+ return password;
+ }
+
+ /**
+ * Sets password
+ *
+ * @param password password
+ */
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ @Override
+ public String getIdentifier() {
+ return IDENTIFIER;
+ }
+
+ @Override
+ public Authentication getFallback() {
+ return new KeystoneAuthentication(this);
+ }
+
+ @Override
+ public void authenticate() throws CommunicationException {
+ LOGGER.debug("Creating credentials provider with username: '{}' and password: '{}'", username, password);
+ CredentialsProvider credsProvider = new BasicCredentialsProvider();
+ credsProvider.setCredentials(
+ new AuthScope(getTarget().getHostName(), getTarget().getPort(), null, authScheme),
+ new UsernamePasswordCredentials(username, password));
+ setCredentialsProvider(credsProvider);
+ super.authenticate();
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.http.auth;
+
+import cz.cesnet.cloud.occi.api.Authentication;
+import cz.cesnet.cloud.occi.api.exception.AuthenticationException;
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.KeyManagementException;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.net.ssl.SSLContext;
+import org.apache.http.conn.ssl.SSLContexts;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.openssl.PEMReader;
+import org.bouncycastle.openssl.PasswordFinder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class representing HTTP authentication method via X509 or VOMS certificates.
+ *
+ * <p>
+ * Supports certificates in pk12 or pem format. This method has a Keystone
+ * authentication method as fallback.</p>
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * HTTPAuthentication auth = new CertificateAuthentication("/path/to/certificate.pem", "password");
+ * auth.setCAPath("/etc/grid-security/certificates/"); //path to CA directory
+ * Client client = new HTTPClient(URI.create("https://remote.server.net"), auth);}</pre>
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+abstract public class CertificateAuthentication extends HTTPAuthentication {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CertificateAuthentication.class);
+ private static final String CERT_BEGIN = "-----BEGIN CERTIFICATE-----";
+ private static final String CERT_END = "-----END CERTIFICATE-----";
+ private static final String GROUP_WHOLE = "whole";
+ private static final String GROUP_TYPE = "type";
+ private String certificate;
+ private String password;
+
+ /**
+ * Returns user's certificate.
+ *
+ * @return user's certificate
+ */
+ public String getCertificate() {
+ return certificate;
+ }
+
+ /**
+ * Sets user's certificate.
+ *
+ * @param certificate user's certificate, cannot be null nor empty
+ */
+ public void setCertificate(String certificate) {
+ if (certificate == null) {
+ throw new NullPointerException("certificate cannot be null");
+ }
+ if (certificate.isEmpty()) {
+ throw new IllegalArgumentException("certificate cannot be empty");
+ }
+
+ this.certificate = certificate;
+ }
+
+ /**
+ * Returns user's password.
+ *
+ * @return user's password
+ */
+ public String getPassword() {
+ return password;
+ }
+
+ /**
+ * Sets user's password.
+ *
+ * @param password user's password, cannot be null
+ */
+ public void setPassword(String password) {
+ if (password == null) {
+ throw new NullPointerException("password cannot be null");
+ }
+
+ this.password = password;
+ }
+
+ @Override
+ protected SSLContext createSSLContext() throws AuthenticationException {
+ Security.addProvider(new BouncyCastleProvider());
+ KeyStore trustStore = loadCAs();
+
+ try {
+ KeyStore keyStore;
+ if (certificate.endsWith(".p12")) {
+ keyStore = loadUserCertificateFromPK12();
+ } else {
+ keyStore = loadUserCertificateFromPEM();
+ }
+
+ SSLContext sslContext = SSLContexts.custom()
+ .loadTrustMaterial(trustStore)
+ .loadKeyMaterial(keyStore, password.toCharArray())
+ .build();
+
+ return sslContext;
+ } catch (KeyStoreException | KeyManagementException | NoSuchAlgorithmException | UnrecoverableKeyException ex) {
+ throw new AuthenticationException(ex);
+ }
+
+ }
+
+ private KeyStore loadUserCertificateFromPK12() throws AuthenticationException {
+ try {
+ KeyStore keyStore = KeyStore.getInstance("PKCS12");
+ FileInputStream instream = new FileInputStream(new File(certificate));
+ keyStore.load(instream, password.toCharArray());
+
+ return keyStore;
+ } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException ex) {
+ throw new AuthenticationException(ex);
+ }
+ }
+
+ private KeyStore loadUserCertificateFromPEM() throws AuthenticationException {
+ try {
+ String certFileString = new String(Files.readAllBytes(Paths.get(certificate)));
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ List<X509Certificate> certChain = new ArrayList<>();
+ int startIndex = certFileString.indexOf(CERT_BEGIN, 0);
+ int endIndex;
+
+ PEMReader reader;
+ while (startIndex != -1) {
+ endIndex = certFileString.indexOf(CERT_END, startIndex);
+ String oneCert = certFileString.substring(startIndex, endIndex + CERT_END.length());
+ reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(oneCert.getBytes())), new PasswordFinder() {
+ @Override
+ public char[] getPassword() {
+ return password == null ? null : password.toCharArray();
+ }
+ });
+ X509Certificate cert = (X509Certificate) reader.readObject();
+ if (cert == null) {
+ throw new AuthenticationException("cannot load user certificate");
+ }
+ certChain.add(cert);
+
+ startIndex = certFileString.indexOf(CERT_BEGIN, startIndex + 1);
+ }
+
+ Pattern pattern = Pattern.compile("(?<" + GROUP_WHOLE + ">-----BEGIN (?<" + GROUP_TYPE + ">RSA |DSA |EC |DH )*PRIVATE KEY-----)");
+ Matcher matcher = pattern.matcher(certFileString);
+ if (!matcher.find()) {
+ throw new AuthenticationException("cannot read certificate key");
+ }
+ //cannot use GROUP_WHOLE descriptor because of Java 7 compatibility
+ startIndex = matcher.start(1);
+
+ pattern = Pattern.compile("(?<" + GROUP_WHOLE + ">-----END (?<" + GROUP_TYPE + ">RSA |DSA |EC |DH )*PRIVATE KEY-----)");
+ matcher = pattern.matcher(certFileString);
+ if (!matcher.find(startIndex)) {
+ throw new AuthenticationException("cannot read certificate key");
+ }
+ //cannot use GROUP_WHOLE descriptor because of Java 7 compatibility
+ endIndex = matcher.end(1);
+
+ String key = certFileString.substring(startIndex, endIndex).trim();
+ reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(key.getBytes())), new PasswordFinder() {
+ @Override
+ public char[] getPassword() {
+ return password == null ? null : password.toCharArray();
+ }
+ });
+
+ Object object = reader.readObject();
+ PrivateKey pk = null;
+ if (object instanceof PrivateKey) {
+ pk = (PrivateKey) object;
+ }
+ if (object instanceof KeyPair) {
+ pk = ((KeyPair) object).getPrivate();
+ }
+
+ if (pk == null) {
+ throw new AuthenticationException("cannot load private key");
+ }
+
+ KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+ ks.load(null);
+ for (X509Certificate x509Cert : certChain) {
+ ks.setCertificateEntry(x509Cert.getSubjectX500Principal().getName(), x509Cert);
+ LOGGER.debug("adding certificate: " + x509Cert.getSubjectX500Principal().getName());
+ }
+
+ ks.setKeyEntry("private_key", pk, password.toCharArray(), certChain.toArray(new Certificate[0]));
+ return ks;
+ } catch (IOException | CertificateException | NoSuchAlgorithmException | KeyStoreException ex) {
+ throw new AuthenticationException(ex);
+ }
+ }
+
+ @Override
+ public void authenticate() throws CommunicationException {
+ super.authenticate();
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.http.auth;
+
+import org.apache.http.client.config.AuthSchemes;
+
+/**
+ * Class representing Digest HTTP authentication method.
+ *
+ * <p>
+ * This method has a Keystone authentication method as fallback.</p>
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * HTTPAuthentication auth = new DigestAuthentication("username", "password");
+ *auth.setCAPath("/etc/grid-security/certificates/"); //path to CA directory
+ *Client client = new HTTPClient(URI.create("https://remote.server.net"), auth);}</pre>
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class DigestAuthentication extends BasicAuthentication {
+
+ public static final String IDENTIFIER = "OCCIDigestAuthentication";
+
+ public DigestAuthentication(String username, String password) {
+ super(username, password);
+ setAuthScheme(AuthSchemes.DIGEST);
+ }
+
+ @Override
+ public String getIdentifier() {
+ return IDENTIFIER;
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.http.auth;
+
+import cz.cesnet.cloud.occi.api.Authentication;
+import cz.cesnet.cloud.occi.api.Client;
+import cz.cesnet.cloud.occi.api.exception.AuthenticationException;
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+import cz.cesnet.cloud.occi.api.http.HTTPConnection;
+import cz.cesnet.cloud.occi.api.http.HTTPHelper;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Security;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+import javax.net.ssl.SSLContext;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLContexts;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.util.EntityUtils;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.openssl.PEMReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract class representing HTTP authentication methods. Lets set either
+ * directory path or file containing CAs and uses them during establishing of
+ * connection.
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public abstract class HTTPAuthentication implements Authentication {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(HTTPAuthentication.class);
+ private HttpHost target;
+ private HTTPConnection connection;
+ private CredentialsProvider credentialsProvider;
+ private String CAPath;
+ private String CAFile;
+
+ /**
+ * Returns server that authentication is run against.
+ *
+ * @return
+ */
+ public HttpHost getTarget() {
+ return target;
+ }
+
+ /**
+ * Sets server to run authentication against.
+ *
+ * @param target server
+ */
+ public void setTarget(HttpHost target) {
+ this.target = target;
+ }
+
+ public HTTPConnection getConnection() {
+ return connection;
+ }
+
+ public void setConnection(HTTPConnection connection) {
+ this.connection = connection;
+ }
+
+ public CredentialsProvider getCredentialsProvider() {
+ return credentialsProvider;
+ }
+
+ public void setCredentialsProvider(CredentialsProvider credentialsProvider) {
+ this.credentialsProvider = credentialsProvider;
+ }
+
+ /**
+ * Returns path to the custom CA directory.
+ *
+ * @return path to the custom CA directory
+ */
+ public String getCAPath() {
+ return CAPath;
+ }
+
+ /**
+ * Sets path to custom CA directory.
+ *
+ * @param CAPath path to custom CA directory
+ */
+ public void setCAPath(String CAPath) {
+ this.CAPath = CAPath;
+ }
+
+ /**
+ * Returns path to custom CA file.
+ *
+ * @return path to custom CA file
+ */
+ public String getCAFile() {
+ return CAFile;
+ }
+
+ /**
+ * Sets path to custom CA file
+ *
+ * @param CAFile path to custom CA file
+ */
+ public void setCAFile(String CAFile) {
+ this.CAFile = CAFile;
+ }
+
+ @Override
+ public abstract String getIdentifier();
+
+ @Override
+ public abstract Authentication getFallback();
+
+ /**
+ * Creates a ssl context with custom CAs if set.
+ *
+ * @return ssl context
+ * @throws AuthenticationException
+ */
+ protected SSLContext createSSLContext() throws AuthenticationException {
+ Security.addProvider(new BouncyCastleProvider());
+ KeyStore keyStore = loadCAs();
+
+ try {
+ SSLContext sslContext;
+ if (keyStore == null) {
+ sslContext = SSLContexts.createSystemDefault();
+ } else {
+ sslContext = SSLContexts.custom().loadTrustMaterial(keyStore).build();
+ }
+ return sslContext;
+ } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException ex) {
+ throw new AuthenticationException(ex);
+ }
+ }
+
+ @Override
+ public void authenticate() throws CommunicationException {
+ SSLContext sslContext = createSSLContext();
+ SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
+
+ LOGGER.debug("Running authentication...");
+ try {
+
+ RequestConfig defaultRequestConfig = RequestConfig.custom()
+ .setSocketTimeout(10000)
+ .setConnectTimeout(10000)
+ .setConnectionRequestTimeout(10000)
+ .build();
+
+ HttpClientBuilder builder = HttpClients.custom()
+ .setDefaultCredentialsProvider(credentialsProvider)
+ .setSSLSocketFactory(sslsf)
+ .setDefaultRequestConfig(defaultRequestConfig);
+ if (LOGGER.isDebugEnabled()) {
+ builder.disableContentCompression();
+ }
+
+ CloseableHttpClient client = builder.build();
+ connection.setClient(client);
+ HttpHead httpHead = HTTPHelper.prepareHead(Client.MODEL_URI, connection.getHeaders(), connection.getPrefix());
+ try (CloseableHttpResponse response = connection.getClient().execute(target, httpHead, connection.getContext())) {
+ if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+ Authentication fallback = getFallback();
+ if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED && fallback != null) {
+ if (fallback instanceof KeystoneAuthentication) {
+ LOGGER.debug("Running Keystone fallback...");
+ KeystoneAuthentication ka = (KeystoneAuthentication) fallback;
+ ka.setOriginalResponse(response);
+ ka.authenticate();
+ } else {
+ throw new AuthenticationException("unknown fallback method");
+ }
+ } else {
+ if (response.getEntity() == null) {
+ LOGGER.error("Response: {}\nHeaders: {}\nBody:\n", response.getStatusLine().toString(), response.getAllHeaders());
+ } else {
+ LOGGER.error("Response: {}\nHeaders: {}\nBody: {}", response.getStatusLine().toString(), response.getAllHeaders(), EntityUtils.toString(response.getEntity()));
+ }
+ throw new AuthenticationException(response.getStatusLine().toString());
+ }
+ }
+ }
+ } catch (IOException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ /**
+ * Loads custom CAs either from file or directory. If both set, CA file has
+ * higher priority.
+ *
+ * @return keystore with custom CAs loaded
+ * @throws AuthenticationException
+ */
+ protected KeyStore loadCAs() throws AuthenticationException {
+ KeyStore keyStore = null;
+ if (CAFile != null && !CAFile.isEmpty()) {
+ keyStore = loadCAsFromFile();
+ } else if (CAPath != null && !CAPath.isEmpty()) {
+ keyStore = loadCAsFromPath();
+ }
+
+ return keyStore;
+ }
+
+ private KeyStore loadCAsFromFile() throws AuthenticationException {
+ try {
+ KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ FileInputStream instream = new FileInputStream(new File(CAFile));
+ trustStore.load(instream, null);
+
+ return trustStore;
+ } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException ex) {
+ throw new AuthenticationException(ex);
+ }
+ }
+
+ private KeyStore loadCAsFromPath() throws AuthenticationException {
+ try {
+ File CADir = new File(CAPath);
+ if (!CADir.isDirectory()) {
+ throw new AuthenticationException("'" + CAPath + "' is not a directory.");
+ }
+
+ FilenameFilter fileNameFilter = new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ if (name.lastIndexOf('.') > 0) {
+ int lastIndex = name.lastIndexOf('.');
+ String str = name.substring(lastIndex);
+ if (str.equals(".pem")) {
+ return true;
+ }
+ }
+ return false;
+ }
+ };
+
+ File[] certs = CADir.listFiles(fileNameFilter);
+ KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+ ks.load(null);
+ List<Certificate> rootCertificates = new ArrayList<>();
+ PEMReader reader;
+ for (File cert : certs) {
+ reader = new PEMReader(new InputStreamReader(new FileInputStream(cert)));
+ rootCertificates.add((X509Certificate) reader.readObject());
+ }
+
+ for (Certificate cert : rootCertificates) {
+ X509Certificate x509Cert = (X509Certificate) cert;
+ ks.setCertificateEntry(x509Cert.getSubjectX500Principal().getName(), x509Cert);
+ LOGGER.debug("adding certificate: " + x509Cert.getSubjectX500Principal().getName());
+ }
+
+ return ks;
+ } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException ex) {
+ throw new AuthenticationException(ex);
+ }
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.http.auth;
+
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import cz.cesnet.cloud.occi.api.Authentication;
+import cz.cesnet.cloud.occi.api.exception.AuthenticationException;
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+import cz.cesnet.cloud.occi.api.http.HTTPConnection;
+import cz.cesnet.cloud.occi.api.http.HTTPHelper;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.StringReader;
+import java.net.URI;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.http.Header;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpHost;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class representing OpenStack's Keystone HTTP authentication method.
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class KeystoneAuthentication extends HTTPAuthentication {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(KeystoneAuthentication.class);
+ public static final String IDENTIFIER = "OCCIKeystoneAuthentication";
+ private static final String HEADER_AUTH = "Www-Authenticate";
+ private static final String HEADER_X_AUTH_TOKEN = "X-Auth-Token";
+ private static final String GROUP_URI = "uri";
+ private static final String REGEXP_KEYSTONE_URI = "^(?:Keystone|snf-auth) uri='(?<" + GROUP_URI + ">.+)'$";
+ private static final Pattern PATTERN_KEYSTONE_URI = Pattern.compile(REGEXP_KEYSTONE_URI);
+ private static final String PATH_DEFAULT = "/v2.0";
+ private final HTTPAuthentication originalAuthentication;
+ private CloseableHttpResponse originalResponse = null;
+ private String authToken = null;
+
+ public KeystoneAuthentication(HTTPAuthentication originalAuthentication) {
+ this.originalAuthentication = originalAuthentication;
+ }
+
+ public CloseableHttpResponse getOriginalResponse() {
+ return originalResponse;
+ }
+
+ public void setOriginalResponse(CloseableHttpResponse response) {
+ this.originalResponse = response;
+ }
+
+ @Override
+ public String getIdentifier() {
+ return IDENTIFIER;
+ }
+
+ @Override
+ public Authentication getFallback() {
+ return null;
+ }
+
+ private void checkResponse() throws AuthenticationException {
+ if (originalResponse == null) {
+ throw new AuthenticationException("no response to react to");
+ }
+
+ if (!originalResponse.containsHeader(HEADER_AUTH)) {
+ throw new AuthenticationException("missing '" + HEADER_AUTH + "' header");
+ }
+ }
+
+ @Override
+ public void authenticate() throws CommunicationException {
+ checkResponse();
+
+ Matcher matcher = PATTERN_KEYSTONE_URI.matcher(originalResponse.getFirstHeader(HEADER_AUTH).getValue());
+ if (!matcher.find()) {
+ throw new AuthenticationException("incorrect " + HEADER_AUTH + " content");
+ }
+
+ URI keystoneURI = URI.create(matcher.group(GROUP_URI));
+ HttpHost target = new HttpHost(keystoneURI.getHost(), keystoneURI.getPort(), keystoneURI.getScheme());
+ //TODO
+ //this path normalization should be handled in a better way
+ String path = keystoneURI.getPath();
+ if (path == null) {
+ path = "";
+ }
+
+ if (path.endsWith("/")) {
+ path = path.substring(0, path.length() - 1);
+ }
+
+ if (!path.endsWith(PATH_DEFAULT)) {
+ path = path + PATH_DEFAULT;
+ }
+
+ HTTPConnection connection = originalAuthentication.getConnection();
+ CloseableHttpClient client = connection.getClient();
+ HttpContext context = connection.getContext();
+
+ String response = authenticateAgainstKeystone(target, path, client, context, null);
+ authToken = parseId(response);
+ response = getTenants(target, path, client, context);
+ tryTenants(response, target, path, client, context);
+
+ LOGGER.debug("Scoped token: " + authToken);
+ connection.addHeader(new BasicHeader(HEADER_X_AUTH_TOKEN, authToken));
+ }
+
+ private String authenticateAgainstKeystone(HttpHost target, String path, CloseableHttpClient client, HttpContext context, String tenant) throws CommunicationException {
+ try {
+ HttpPost httpPost = HTTPHelper.preparePost("/tokens", getHeaders(), path);
+ httpPost.setEntity(new StringEntity(getRequestBody(tenant)));
+
+ try (CloseableHttpResponse response = HTTPHelper.runRequest(httpPost, target, client, context)) {
+ return EntityUtils.toString(response.getEntity());
+ }
+ } catch (IOException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ private String getTenants(HttpHost target, String path, CloseableHttpClient client, HttpContext context) throws CommunicationException {
+ try {
+ HttpGet httpGet = HTTPHelper.prepareGet("/tenants", getHeaders(), path);
+ try (CloseableHttpResponse response = HTTPHelper.runRequest(httpGet, target, client, context)) {
+ return EntityUtils.toString(response.getEntity());
+ }
+ } catch (IOException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ private void tryTenants(String json, HttpHost target, String path, CloseableHttpClient client, HttpContext context) throws AuthenticationException, CommunicationException {
+ try (JsonReader reader = new JsonReader(new StringReader(json))) {
+ reader.beginObject();
+ while (reader.hasNext()) {
+ String name = reader.nextName();
+ if (!name.equals("tenants")) {
+ reader.skipValue();
+ continue;
+ }
+
+ reader.beginArray();
+ while (reader.hasNext()) {
+ reader.beginObject();
+ while (reader.hasNext()) {
+ name = reader.nextName();
+ if (!name.equals("name")) {
+ reader.skipValue();
+ continue;
+ }
+
+ String tenant = reader.nextString();
+ try {
+ String response = authenticateAgainstKeystone(target, path, client, context, tenant);
+ authToken = parseId(response);
+ return;
+ } catch (CommunicationException ex) {
+ //ignoring and trying the next tenant
+ }
+ }
+ reader.endObject();
+ }
+ reader.endArray();
+ throw new AuthenticationException("no suitable tenant found");
+ }
+ } catch (IOException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ private String getRequestBody(String tenant) throws AuthenticationException, CommunicationException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try (JsonWriter writer = new JsonWriter(new OutputStreamWriter(out))) {
+ writer.beginObject();
+ writer.name("auth");
+ writer.beginObject();
+
+ String identifier = originalAuthentication.getIdentifier();
+ switch (identifier) {
+ //case X509Authentication.IDENTIFIER: // not sure if should be here or not
+ case VOMSAuthentication.IDENTIFIER: {
+ writer.name("voms").value(true);
+ }
+ break;
+ case BasicAuthentication.IDENTIFIER:
+ case DigestAuthentication.IDENTIFIER: {
+ BasicAuthentication ba = (BasicAuthentication) originalAuthentication;
+ writer.name("passwordCredentials");
+ writer.beginObject();
+ writer.name("username").value(ba.getUsername());
+ writer.name("password").value(ba.getPassword());
+ writer.endObject();
+ }
+ break;
+ default:
+ throw new AuthenticationException("unknown original authentication method");
+ }
+
+ if (tenant != null) {
+ writer.name("tenantName").value(tenant);
+ }
+ writer.endObject();
+ writer.endObject();
+ writer.close();
+
+ return out.toString();
+ } catch (IOException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ private String parseId(String json) throws CommunicationException {
+ try (JsonReader reader = new JsonReader(new StringReader(json))) {
+ String id = null;
+ reader.beginObject();
+ while (reader.hasNext()) {
+ String name = reader.nextName();
+ if (!name.equals("access")) {
+ reader.skipValue();
+ continue;
+ }
+
+ reader.beginObject();
+ while (reader.hasNext()) {
+ name = reader.nextName();
+ if (!name.equals("token")) {
+ reader.skipValue();
+ continue;
+ }
+
+ reader.beginObject();
+ while (reader.hasNext()) {
+ name = reader.nextName();
+ if (!name.equals("id")) {
+ reader.skipValue();
+ continue;
+ }
+
+ id = reader.nextString();
+ break;
+ }
+ break;
+ }
+ break;
+ }
+
+ return id;
+ } catch (IOException ex) {
+ throw new CommunicationException(ex);
+ }
+ }
+
+ private Header[] getHeaders() {
+ Header[] headers;
+ if (authToken != null) {
+ headers = new Header[3];
+ headers[2] = new BasicHeader(HEADER_X_AUTH_TOKEN, authToken);
+ } else {
+ headers = new Header[2];
+ }
+
+ headers[0] = new BasicHeader(HttpHeaders.CONTENT_TYPE, "application/json");
+ headers[1] = new BasicHeader(HttpHeaders.ACCEPT, "application/json");
+
+ return headers;
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.http.auth;
+
+import cz.cesnet.cloud.occi.api.Authentication;
+
+/**
+ * Dummy authentication method representing no authentication.
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class NoAuthentication extends HTTPAuthentication {
+
+ public static final String IDENTIFIER = "OCCINoAuthentication";
+
+ @Override
+ public String getIdentifier() {
+ return IDENTIFIER;
+ }
+
+ @Override
+ public Authentication getFallback() {
+ return null;
+ }
+
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.http.auth;
+
+import cz.cesnet.cloud.occi.api.Authentication;
+
+/**
+ * Class representing HTTP authentication method via VOMS certificates.
+ *
+ * <p>
+ * Supports certificates in pk12 or pem format. This method has a Keystone
+ * authentication method as fallback.</p>
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * HTTPAuthentication auth = new VOMSAuthentication("/path/to/certificate.pem");
+ * auth.setCAPath("/etc/grid-security/certificates/"); //path to CA directory
+ * Client client = new HTTPClient(URI.create("https://remote.server.net"), auth);}</pre>
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class VOMSAuthentication extends CertificateAuthentication {
+
+ public static final String IDENTIFIER = "OCCIVOMSAuthentication";
+
+ /**
+ * Constructor.
+ *
+ * @param certificate cannot be null nor empty
+ */
+ public VOMSAuthentication(String certificate) {
+ setCertificate(certificate);
+ setPassword("");
+ }
+
+ @Override
+ public String getIdentifier() {
+ return IDENTIFIER;
+ }
+
+ @Override
+ public Authentication getFallback() {
+ return new KeystoneAuthentication(this);
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.http.auth;
+
+import cz.cesnet.cloud.occi.api.Authentication;
+
+/**
+ * Class representing HTTP authentication method via X509 certificates.
+ *
+ * <p>
+ * Supports certificates in pk12 or pem format. This method has a Keystone
+ * authentication method as fallback.</p>
+ *
+ * <p>
+ * Example:</p>
+ *
+ * <pre>{@code
+ * HTTPAuthentication auth = new X509Authentication("/path/to/certificate.pem", "password");
+ * auth.setCAPath("/etc/grid-security/certificates/"); //path to CA directory
+ * Client client = new HTTPClient(URI.create("https://remote.server.net"), auth);}</pre>
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class X509Authentication extends CertificateAuthentication {
+
+ public static final String IDENTIFIER = "OCCIX509Authentication";
+
+ /**
+ * Constructor.
+ *
+ * @param certificate cannot be null nor empty
+ * @param password cannot be null nor empty
+ */
+ public X509Authentication(String certificate, String password) {
+ if (password.isEmpty()) {
+ throw new IllegalArgumentException("password cannot be empty");
+ }
+
+ setCertificate(certificate);
+ super.setPassword(password);
+ }
+
+ @Override
+ public String getIdentifier() {
+ return IDENTIFIER;
+ }
+
+ @Override
+ public Authentication getFallback() {
+ return new KeystoneAuthentication(this);
+ }
+
+ /**
+ * Sets user's password.
+ *
+ * @param password user's password, cannot be null nor empty
+ */
+ @Override
+ public void setPassword(String password) {
+ if (password.isEmpty()) {
+ throw new IllegalArgumentException("password cannot be empty");
+ }
+
+ super.setPassword(password);
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi;
+
+import cz.cesnet.cloud.occi.core.Action;
+import cz.cesnet.cloud.occi.core.ActionInstance;
+import cz.cesnet.cloud.occi.core.Attribute;
+import cz.cesnet.cloud.occi.core.Entity;
+import cz.cesnet.cloud.occi.core.Kind;
+import cz.cesnet.cloud.occi.core.Link;
+import cz.cesnet.cloud.occi.core.Mixin;
+import cz.cesnet.cloud.occi.core.Resource;
+import cz.cesnet.cloud.occi.exception.InvalidAttributeValueException;
+import cz.cesnet.cloud.occi.infrastructure.Compute;
+import cz.cesnet.cloud.occi.infrastructure.NetworkInterface;
+import cz.cesnet.cloud.occi.infrastructure.StorageLink;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class DataGenerator {
+
+ public static List<Kind> getMinimalKind() throws URISyntaxException {
+ List<Kind> kinds = new ArrayList<>();
+ Kind kind = new Kind(new URI("http://schemas.ogf.org/occi/core#"), "entity");
+ kind.setLocation(new URI("/entity/"));
+ kinds.add(kind);
+
+ return kinds;
+ }
+
+ public static List<Kind> getFiveKinds() throws URISyntaxException {
+ Set<Attribute> attributes = new HashSet<>();
+ List<Kind> kinds = new ArrayList<>();
+
+ Attribute a = new Attribute("occi.core.id");
+ attributes.add(a);
+ a = new Attribute("occi.core.title");
+ attributes.add(a);
+ Kind entity = new Kind(new URI("http://schemas.ogf.org/occi/core#"), "entity", "Entity", new URI("/entity/"), attributes);
+ kinds.add(entity);
+
+ attributes.clear();
+ a = new Attribute("occi.core.summary");
+ attributes.add(a);
+ Kind resource = new Kind(new URI("http://schemas.ogf.org/occi/core#"), "resource", "Resource", new URI("/resource/"), attributes);
+ resource.addRelation(entity);
+ resource.setParentKind(entity);
+ kinds.add(resource);
+
+ attributes.clear();
+ a = new Attribute("occi.core.target");
+ attributes.add(a);
+ a = new Attribute("occi.core.source");
+ attributes.add(a);
+ Kind link = new Kind(new URI("http://schemas.ogf.org/occi/core#"), "link", "Link", new URI("/link/"), attributes);
+ link.addRelation(entity);
+ link.setParentKind(entity);
+ kinds.add(link);
+
+ attributes.clear();
+ a = new Attribute("occi.compute.architecture", false, true);
+ attributes.add(a);
+ a = new Attribute("occi.compute.cores");
+ attributes.add(a);
+ a = new Attribute("occi.compute.hostname");
+ attributes.add(a);
+ a = new Attribute("occi.compute.speed");
+ attributes.add(a);
+ a = new Attribute("occi.compute.memory");
+ attributes.add(a);
+ a = new Attribute("occi.compute.state");
+ attributes.add(a);
+ Kind k = new Kind(new URI("http://schemas.ogf.org/occi/infrastructure#"), "compute", "Compute Resource", new URI("/compute/"), attributes);
+ Action ac = new Action(new URI("http://schemas.ogf.org/occi/infrastructure/compute/action#"), "start");
+ k.addAction(ac);
+ ac = new Action(new URI("http://schemas.ogf.org/occi/infrastructure/compute/action#"), "stop");
+ k.addAction(ac);
+ ac = new Action(new URI("http://schemas.ogf.org/occi/infrastructure/compute/action#"), "restart");
+ k.addAction(ac);
+ ac = new Action(new URI("http://schemas.ogf.org/occi/infrastructure/compute/action#"), "suspend");
+ k.addAction(ac);
+ k.addRelation(resource);
+ k.setParentKind(resource);
+ kinds.add(k);
+
+ attributes.clear();
+ a = new Attribute("occi.storagelink.deviceid", true, false);
+ attributes.add(a);
+ a = new Attribute("occi.storagelink.mountpoint");
+ attributes.add(a);
+ a = new Attribute("occi.storagelink.state", true, true);
+ attributes.add(a);
+ k = new Kind(new URI("http://schemas.ogf.org/occi/infrastructure#"), "storagelink", "Storage Link", new URI("/storagelink/"), attributes);
+ k.addRelation(link);
+ k.setParentKind(link);
+ kinds.add(k);
+
+ return kinds;
+ }
+
+ public static List<Mixin> getMinimalMixin() throws URISyntaxException {
+ List<Mixin> mixins = new ArrayList<>();
+ Mixin ostpl = new Mixin(new URI("http://schemas.ogf.org/occi/infrastructure#"), "os_tpl");
+ ostpl.setLocation(new URI("/mixins/os_tpl/"));
+ mixins.add(ostpl);
+
+ return mixins;
+ }
+
+ public static List<Mixin> getFiveMixins() throws URISyntaxException {
+ Set<Attribute> attributes = new HashSet<>();
+ List<Mixin> mixins = new ArrayList<>();
+
+ Mixin ostpl = new Mixin(new URI("http://schemas.ogf.org/occi/infrastructure#"), "os_tpl", "Operating System Template", new URI("/mixins/os_tpl/"), attributes);
+ mixins.add(ostpl);
+
+ attributes.clear();
+ Attribute a = new Attribute("occi.network.address", true, false);
+ attributes.add(a);
+ a = new Attribute("occi.network.gateway");
+ attributes.add(a);
+ a = new Attribute("occi.network.allocation");
+ attributes.add(a);
+ a = new Attribute("occi.network.state");
+ attributes.add(a);
+ Mixin m = new Mixin(new URI("http://schemas.ogf.org/occi/infrastructure/network#"), "ipnetwork", "IP Network Mixin", new URI("/mixins/ipnetwork/"), attributes);
+ mixins.add(m);
+
+ attributes.clear();
+ Mixin resourcetpl = new Mixin(new URI("http://schemas.ogf.org/occi/infrastructure#"), "resource_tpl", "Resource Template", new URI("/mixins/resource_tpl/"), attributes);
+ mixins.add(resourcetpl);
+
+ attributes.clear();
+ a = new Attribute("occi.compute.architecture");
+ attributes.add(a);
+ a = new Attribute("occi.compute.cores", true, true);
+ attributes.add(a);
+ a = new Attribute("occi.compute.speed");
+ attributes.add(a);
+ a = new Attribute("occi.compute.memory", false, true);
+ attributes.add(a);
+ m = new Mixin(new URI("https://occi.localhost/occi/infrastructure/resource_tpl#"), "larger", "Larger Instance - 4 cores and 10 GB of RAM", new URI("/mixins/larger/"), attributes);
+ m.addRelation(resourcetpl);
+ mixins.add(m);
+
+ attributes.clear();
+ m = new Mixin(new URI("https://occi.localhost/occi/infrastructure/os_tpl#"), "debianvm", "debianvm", new URI("/mixins/debianvm/"), attributes);
+ m.addRelation(ostpl);
+ mixins.add(m);
+
+ return mixins;
+ }
+
+ public static List<Action> getMinimalAction() throws URISyntaxException {
+ List<Action> actions = new ArrayList<>();
+ Action ac = new Action(new URI("http://schemas.ogf.org/occi/infrastructure/network/action#"), "up");
+ actions.add(ac);
+
+ return actions;
+ }
+
+ public static List<Action> getFiveActions() throws URISyntaxException {
+ List<Action> actions = new ArrayList<>();
+ Set<Attribute> attributes = new HashSet<>();
+
+ attributes.clear();
+ Attribute a = new Attribute("method");
+ attributes.add(a);
+ Action ac = new Action(new URI("http://schemas.ogf.org/occi/infrastructure/compute/action#"), "restart", "Restart Compute instance", attributes);
+ actions.add(ac);
+
+ attributes.clear();
+ a = new Attribute("method");
+ attributes.add(a);
+ ac = new Action(new URI("http://schemas.ogf.org/occi/infrastructure/compute/action#"), "suspend", "Suspend Compute instance", attributes);
+ actions.add(ac);
+
+ ac = new Action(new URI("http://schemas.ogf.org/occi/infrastructure/network/action#"), "up", "Activate network", null);
+ actions.add(ac);
+
+ ac = new Action(new URI("http://schemas.ogf.org/occi/infrastructure/network/action#"), "down", "Deactivate network", null);
+ actions.add(ac);
+
+ ac = new Action(new URI("http://schemas.ogf.org/occi/infrastructure/storage/action#"), "backup", "Backup Storage", null);
+ actions.add(ac);
+
+ return actions;
+ }
+
+ public static List<URI> getLocations() throws URISyntaxException {
+ List<URI> locations = new ArrayList<>();
+ locations.add(new URI("http://rocci-server-1-1-x.herokuapp.com:80/compute/87f3bfc3-42d4-4474-b45c-757e55e093e9"));
+ locations.add(new URI("http://rocci-server-1-1-x.herokuapp.com:80/compute/17679ebd-975f-4ea0-b42b-47405178c360"));
+ locations.add(new URI("http://rocci-server-1-1-x.herokuapp.com:80/compute/509afbd3-abff-427c-9b25-7913d17e5102"));
+
+ return locations;
+ }
+
+ public static Resource getResource() throws InvalidAttributeValueException, URISyntaxException {
+ Kind k = new Kind(new URI("http://schemas.ogf.org/occi/infrastructure#"), "compute", "compute resource", new URI("/compute/"), null);
+ Resource r = new Resource("87f3bfc3-42d4-4474-b45c-757e55e093e9", k);
+ r.setTitle("compute1");
+ r.addAttribute(Compute.ARCHITECTURE_ATTRIBUTE_NAME, "x86");
+ r.addAttribute(Compute.HOSTNAME_ATTRIBUTE_NAME, "compute1.example.org");
+ r.addAttribute(Compute.MEMORY_ATTRIBUTE_NAME, "1.7");
+ r.addAttribute(Compute.SPEED_ATTRIBUTE_NAME, "1.0");
+ r.addAttribute(Compute.STATE_ATTRIBUTE_NAME, "active");
+
+ List<Mixin> mixins = getFiveMixins();
+ for (Mixin mixin : mixins) {
+ r.addMixin(mixin);
+ }
+
+ List<Link> links = getLinks();
+ for (Link link : links) {
+ link.setSource(r);
+ r.addLink(link);
+ }
+
+ List<Action> actions = getActions();
+ for (Action action : actions) {
+ r.addAction(action);
+ }
+
+ return r;
+ }
+
+ public static List<Action> getActions() throws URISyntaxException {
+ List<Action> actions = new ArrayList<>();
+ actions.add(new Action(new URI("http://schemas.ogf.org/occi/infrastructure/compute/action#"), "start"));
+ actions.add(new Action(new URI("http://schemas.ogf.org/occi/infrastructure/compute/action#"), "stop"));
+
+ return actions;
+ }
+
+ public static List<Link> getLinks() throws URISyntaxException, InvalidAttributeValueException {
+ List<Link> links = new ArrayList<>();
+
+ Kind k = new Kind(new URI("http://schemas.ogf.org/occi/infrastructure#"), "networkinterface", null, new URI("/link/networkinterface/"), null);
+ Link l = new Link("456", k);
+ l.addAttribute(NetworkInterface.INTERFACE_ATTRIBUTE_NAME, "eth0");
+ l.addAttribute(NetworkInterface.MAC_ATTRIBUTE_NAME, "00:11:22:33:44:55");
+ l.addAttribute(NetworkInterface.STATE_ATTRIBUTE_NAME, "active");
+ l.setTarget("/network/123");
+ l.setRelation("http://schemas.ogf.org/occi/infrastructure#network");
+ links.add(l);
+
+ k = new Kind(new URI("http://schemas.ogf.org/occi/infrastructure#"), "storagelink", null, new URI("/link/storagelink/"), null);
+ l = new Link("789", k);
+ l.addAttribute(StorageLink.DEVICE_ID_ATTRIBUTE_NAME, "1234qwerty");
+ l.addAttribute(StorageLink.MOUNTPOINT_ATTRIBUTE_NAME, "/mnt/somewhere/");
+ l.addAttribute(StorageLink.STATE_ATTRIBUTE_NAME, "active");
+ l.setTarget("/storage/852");
+ l.setRelation("http://schemas.ogf.org/occi/infrastructure#storage");
+ links.add(l);
+
+ return links;
+ }
+
+ public static Link getLink() throws InvalidAttributeValueException, URISyntaxException {
+ Kind k = new Kind(new URI("http://schemas.ogf.org/occi/infrastructure#"), "networkinterface", null, null, null);
+ Link l = new Link("87f3bfc3-42d4-4474-b45c-757e55e093e9", k);
+ l.addAttribute(NetworkInterface.INTERFACE_ATTRIBUTE_NAME, "eth0");
+ l.addAttribute(NetworkInterface.MAC_ATTRIBUTE_NAME, "00:11:22:33:44:55");
+ l.addAttribute(NetworkInterface.STATE_ATTRIBUTE_NAME, "active");
+ l.setSource("/vms/foo/vm1");
+ l.setTarget("/network/123");
+
+ List<Mixin> mixins = getFiveMixins();
+ for (Mixin mixin : mixins) {
+ l.addMixin(mixin);
+ }
+
+ return l;
+ }
+
+ public static ActionInstance getAction() throws InvalidAttributeValueException, URISyntaxException {
+ Action a = new Action(new URI("http://schemas.ogf.org/occi/infrastructure/storage/action#"), "backup", "Backup Storage", null);
+ ActionInstance ai = new ActionInstance(a);
+ ai.addAttribute(new Attribute(Entity.ID_ATTRIBUTE_NAME), "87f3bfc3-42d4-4474-b45c-757e55e093e9");
+ ai.addAttribute(new Attribute(NetworkInterface.INTERFACE_ATTRIBUTE_NAME), "eth0");
+ ai.addAttribute(new Attribute(NetworkInterface.MAC_ATTRIBUTE_NAME), "00:11:22:33:44:55");
+ ai.addAttribute(new Attribute(NetworkInterface.STATE_ATTRIBUTE_NAME), "active");
+ ai.addAttribute(new Attribute(Link.SOURCE_ATTRIBUTE_NAME), "/vms/foo/vm1");
+ ai.addAttribute(new Attribute(Link.TARGET_ATTRIBUTE_NAME), "/network/123");
+
+ return ai;
+ }
+
+ public static Kind getCustomComputeKind() throws URISyntaxException {
+ return new Kind(new URI("http://custom.testing.org/occi/infra#"), "compute", null, null, null);
+ }
+
+ public static Kind getCustomStorageKind() throws URISyntaxException {
+ return new Kind(new URI("http://custom.testing.org/occi/infra#"), "storage", null, null, null);
+ }
+
+ public static Kind getCustomNetworkKind() throws URISyntaxException {
+ return new Kind(new URI("http://custom.testing.org/occi/infra#"), "network", null, null, null);
+ }
+
+ public static Kind getCustomStorageLinkKind() throws URISyntaxException {
+ return new Kind(new URI("http://custom.testing.org/occi/infra#"), "storagelink", null, null, null);
+ }
+
+ public static Kind getCustomNetworkInterfaceKind() throws URISyntaxException {
+ return new Kind(new URI("http://custom.testing.org/occi/infra#"), "networkinterface", null, null, null);
+ }
+
+ public static Mixin getCustomIPNetworkMixin() throws URISyntaxException {
+ return new Mixin(new URI("http://custom.testing.org/occi/infra#"), "ipnetwork", null, null, null);
+ }
+
+ public static Mixin getCustomIPNetworkInterfaceMixin() throws URISyntaxException {
+ return new Mixin(new URI("http://custom.testing.org/occi/infra#"), "ipnetworkinterface", null, null, null);
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api;
+
+import cz.cesnet.cloud.occi.DataGenerator;
+import cz.cesnet.cloud.occi.Model;
+import cz.cesnet.cloud.occi.api.exception.EntityBuildingException;
+import cz.cesnet.cloud.occi.core.Action;
+import cz.cesnet.cloud.occi.core.ActionInstance;
+import cz.cesnet.cloud.occi.core.Kind;
+import cz.cesnet.cloud.occi.core.Link;
+import cz.cesnet.cloud.occi.core.Mixin;
+import cz.cesnet.cloud.occi.core.Resource;
+import cz.cesnet.cloud.occi.infrastructure.Compute;
+import cz.cesnet.cloud.occi.infrastructure.IPNetwork;
+import cz.cesnet.cloud.occi.infrastructure.IPNetworkInterface;
+import cz.cesnet.cloud.occi.infrastructure.Network;
+import cz.cesnet.cloud.occi.infrastructure.NetworkInterface;
+import cz.cesnet.cloud.occi.infrastructure.Storage;
+import cz.cesnet.cloud.occi.infrastructure.StorageLink;
+import java.net.URI;
+import java.net.URISyntaxException;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class EntityBuilderTest {
+
+ private Model model;
+ private EntityBuilder eb;
+
+ @Before
+ public void setUp() throws Exception {
+ model = new Model();
+
+ for (Kind kind : DataGenerator.getFiveKinds()) {
+ model.addKind(kind);
+ }
+
+ for (Mixin mixin : DataGenerator.getFiveMixins()) {
+ model.addMixin(mixin);
+ }
+
+ for (Action action : DataGenerator.getFiveActions()) {
+ model.addAction(action);
+ }
+
+ eb = new EntityBuilder(model);
+ }
+
+ private void setUpCustom() throws URISyntaxException {
+ model.addKind(DataGenerator.getCustomComputeKind());
+ model.addKind(DataGenerator.getCustomNetworkKind());
+ model.addKind(DataGenerator.getCustomStorageKind());
+ model.addKind(DataGenerator.getCustomNetworkInterfaceKind());
+ model.addKind(DataGenerator.getCustomStorageLinkKind());
+ model.addMixin(DataGenerator.getCustomIPNetworkInterfaceMixin());
+ model.addMixin(DataGenerator.getCustomIPNetworkMixin());
+ }
+
+ @Test
+ public void testConstructor() {
+ EntityBuilder eb = new EntityBuilder(model);
+
+ assertEquals(model, eb.getModel());
+ }
+
+ @Test
+ public void testInvalidConstructor() {
+ try {
+ new EntityBuilder(null);
+ fail();
+ } catch (NullPointerException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testGetResourceWithString() throws Exception {
+ Kind kind = DataGenerator.getFiveKinds().get(3);
+ Resource resource = eb.getResource("compute");
+
+ assertEquals(kind, resource.getKind());
+ assertNotNull(resource.getId());
+ }
+
+ @Test
+ public void testInvalidGetResourceWithString() throws Exception {
+ try {
+ eb.getResource("nonexisting");
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+
+ try {
+ Kind k = new Kind(new URI("http://different.uri.same/term/infrastructure#"), "compute", "Compute Resource", new URI("/compute/"), null);
+ model.addKind(k);
+ eb.getResource("compute");
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testGetResourceWithURI() throws Exception {
+ Kind kind = DataGenerator.getFiveKinds().get(3);
+ Resource resource = eb.getResource(URI.create("http://schemas.ogf.org/occi/infrastructure#compute"));
+
+ assertEquals(kind, resource.getKind());
+ assertNotNull(resource.getId());
+ }
+
+ @Test
+ public void testInvalidGetResourceWithURI() throws Exception {
+ try {
+ eb.getResource(URI.create("http://nonexisting.abc.org/icco/infrastructure#compute"));
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testGetLinkWithString() throws Exception {
+ Kind kind = DataGenerator.getFiveKinds().get(4);
+ Link link = eb.getLink("storagelink");
+
+ assertEquals(kind, link.getKind());
+ assertNotNull(link.getId());
+ }
+
+ @Test
+ public void testInvalidGetLinkWithString() throws Exception {
+ try {
+ eb.getLink("nonexisting");
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+
+ try {
+ Kind k = new Kind(new URI("http://different.uri.same/term/infrastructure#"), "storagelink", "Storage Link", new URI("/storagelink/"), null);
+ model.addKind(k);
+ eb.getLink("storagelink");
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testGetLinkWithURI() throws Exception {
+ Kind kind = DataGenerator.getFiveKinds().get(4);
+ Link link = eb.getLink(URI.create("http://schemas.ogf.org/occi/infrastructure#storagelink"));
+
+ assertEquals(kind, link.getKind());
+ assertNotNull(link.getId());
+ }
+
+ @Test
+ public void testInvalidLinkWithURI() throws Exception {
+ try {
+ eb.getLink(URI.create("http://nonexisting.abc.org/icco/infrastructure#storagelink"));
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testGetActionInstanceWithString() throws Exception {
+ Action action = DataGenerator.getFiveActions().get(2);
+ ActionInstance ai = eb.getActionInstance("up");
+
+ assertEquals(new ActionInstance(action), ai);
+ }
+
+ @Test
+ public void testInvalidGetActionInstanceWithString() throws Exception {
+ try {
+ eb.getActionInstance("nonexisting");
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+
+ try {
+ Action ac = new Action(new URI("http://different.uri.same/term/infrastructure/network/action#"), "up", "Activate network", null);
+ model.addAction(ac);
+ eb.getActionInstance("up");
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testGetActionInstanceWithURI() throws Exception {
+ Action action = DataGenerator.getFiveActions().get(2);
+ ActionInstance ai = eb.getActionInstance(URI.create("http://schemas.ogf.org/occi/infrastructure/network/action#up"));
+
+ assertEquals(new ActionInstance(action), ai);
+ }
+
+ @Test
+ public void testInvalidGetActionInstanceWithURI() throws Exception {
+ try {
+ eb.getActionInstance(URI.create("http://nonexisting.abc.org/icco/infrastructure/network/action#up"));
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testGetComputeWithURI() throws Exception {
+ setUpCustom();
+ Kind kind = DataGenerator.getCustomComputeKind();
+ Compute compute = eb.getCompute(URI.create("http://custom.testing.org/occi/infra#compute"));
+
+ assertEquals(kind, compute.getKind());
+ assertNotNull(compute.getId());
+ }
+
+ @Test
+ public void testInvalidGetComputeWithURI() throws Exception {
+ try {
+ eb.getCompute(URI.create("http://nonexisting.abc.org/icco/infra#compute"));
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testGetCompute() throws Exception {
+ setUpCustom();
+ model = new Model();
+ model.addKind(Compute.getDefaultKind());
+
+ Compute compute = eb.getCompute();
+ assertEquals(Compute.getDefaultKind(), compute.getKind());
+ assertNotNull(compute.getId());
+ }
+
+ @Test
+ public void testGetNetworkWithURI() throws Exception {
+ setUpCustom();
+ Kind kind = DataGenerator.getCustomNetworkKind();
+ Network network = eb.getNetwork(URI.create("http://custom.testing.org/occi/infra#network"));
+
+ assertEquals(kind, network.getKind());
+ assertNotNull(network.getId());
+ }
+
+ @Test
+ public void testInvalidGetNetworkWithURI() throws Exception {
+ try {
+ eb.getNetwork(URI.create("http://nonexisting.abc.org/icco/infra#network"));
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testGetNetwork() throws Exception {
+ setUpCustom();
+ model = new Model();
+ model.addKind(Network.getDefaultKind());
+
+ Network network = eb.getNetwork();
+ assertEquals(Network.getDefaultKind(), network.getKind());
+ assertNotNull(network.getId());
+ }
+
+ @Test
+ public void testGetStorageWithURI() throws Exception {
+ setUpCustom();
+ Kind kind = DataGenerator.getCustomStorageKind();
+ Storage storage = eb.getStorage(URI.create("http://custom.testing.org/occi/infra#storage"));
+
+ assertEquals(kind, storage.getKind());
+ assertNotNull(storage.getId());
+ }
+
+ @Test
+ public void testInvalidGetStorageWithURI() throws Exception {
+ try {
+ eb.getStorage(URI.create("http://nonexisting.abc.org/icco/infra#storage"));
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testGetStorage() throws Exception {
+ setUpCustom();
+ model = new Model();
+ model.addKind(Storage.getDefaultKind());
+
+ Storage storage = eb.getStorage();
+ assertEquals(Storage.getDefaultKind(), storage.getKind());
+ assertNotNull(storage.getId());
+ }
+
+ @Test
+ public void testGetStorageLinkWithURI() throws Exception {
+ setUpCustom();
+ Kind kind = DataGenerator.getCustomStorageLinkKind();
+ StorageLink storagelink = eb.getStorageLink(URI.create("http://custom.testing.org/occi/infra#storagelink"));
+
+ assertEquals(kind, storagelink.getKind());
+ assertNotNull(storagelink.getId());
+ }
+
+ @Test
+ public void testInvalidGetStorageLinkWithURI() throws Exception {
+ try {
+ eb.getStorageLink(URI.create("http://nonexisting.abc.org/icco/infra#storagelink"));
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testGetStorageLink() throws Exception {
+ setUpCustom();
+ model = new Model();
+ model.addKind(StorageLink.getDefaultKind());
+
+ StorageLink storagelink = eb.getStorageLink();
+ assertEquals(StorageLink.getDefaultKind(), storagelink.getKind());
+ assertNotNull(storagelink.getId());
+ }
+
+ @Test
+ public void testGetNetworkInterfaceWithURI() throws Exception {
+ setUpCustom();
+ Kind kind = DataGenerator.getCustomNetworkInterfaceKind();
+ NetworkInterface networkinterface = eb.getNetworkInterface(URI.create("http://custom.testing.org/occi/infra#networkinterface"));
+
+ assertEquals(kind, networkinterface.getKind());
+ assertNotNull(networkinterface.getId());
+ }
+
+ @Test
+ public void testInvalidGetNetworkInterfaceWithURI() throws Exception {
+ try {
+ eb.getNetworkInterface(URI.create("http://nonexisting.abc.org/icco/infra#networkinterface"));
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testGetNetworkInterface() throws Exception {
+ setUpCustom();
+ model = new Model();
+ model.addKind(NetworkInterface.getDefaultKind());
+
+ NetworkInterface networkinterface = eb.getNetworkInterface();
+ assertEquals(NetworkInterface.getDefaultKind(), networkinterface.getKind());
+ assertNotNull(networkinterface.getId());
+ }
+
+ @Test
+ public void testGetIPNetworkWithURI() throws Exception {
+ setUpCustom();
+ Kind kind = DataGenerator.getCustomNetworkKind();
+ Mixin mixin = DataGenerator.getCustomIPNetworkMixin();
+ IPNetwork ipNetwork = eb.getIPNetwork(URI.create("http://custom.testing.org/occi/infra#network"), URI.create("http://custom.testing.org/occi/infra#ipnetwork"));
+
+ assertEquals(kind, ipNetwork.getKind());
+ assertEquals(mixin, ipNetwork.getMixin("http://custom.testing.org/occi/infra#ipnetwork"));
+ assertNotNull(ipNetwork.getId());
+ }
+
+ @Test
+ public void testInvalidGetIPNetworkWithURI() throws Exception {
+ try {
+ eb.getIPNetwork(URI.create("http://nonexisting.abc.org/icco/infra#network"), URI.create("http://nonexisting.abc.org/icco/infra#ipnetwork"));
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testGetIPNetwork() throws Exception {
+ setUpCustom();
+ model = new Model();
+ model.addKind(Network.getDefaultKind());
+ model.addMixin(IPNetwork.getDefaultMixin());
+
+ IPNetwork ipNetwork = eb.getIPNetwork();
+ assertEquals(Network.getDefaultKind(), ipNetwork.getKind());
+ assertEquals(IPNetwork.getDefaultMixin(), ipNetwork.getMixin(IPNetwork.MIXIN_IDENTIFIER_DEFAULT));
+ assertNotNull(ipNetwork.getId());
+ }
+
+ @Test
+ public void testGetIPNetworkInterfaceWithURI() throws Exception {
+ setUpCustom();
+ Kind kind = DataGenerator.getCustomNetworkInterfaceKind();
+ Mixin mixin = DataGenerator.getCustomIPNetworkInterfaceMixin();
+ IPNetworkInterface iPNetworkInterface = eb.getIPNetworkInterface(URI.create("http://custom.testing.org/occi/infra#networkinterface"), URI.create("http://custom.testing.org/occi/infra#ipnetworkinterface"));
+
+ assertEquals(kind, iPNetworkInterface.getKind());
+ assertEquals(mixin, iPNetworkInterface.getMixin("http://custom.testing.org/occi/infra#ipnetworkinterface"));
+ assertNotNull(iPNetworkInterface.getId());
+ }
+
+ @Test
+ public void testInvalidGetIPNetworkInterfaceWithURI() throws Exception {
+ try {
+ eb.getIPNetworkInterface(URI.create("http://nonexisting.abc.org/icco/infra#networkinterface"), URI.create("http://nonexisting.abc.org/icco/infra#ipnetworkinterface"));
+ } catch (EntityBuildingException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testGetIPNetworkInterface() throws Exception {
+ setUpCustom();
+ model = new Model();
+ model.addKind(NetworkInterface.getDefaultKind());
+ model.addMixin(IPNetworkInterface.getDefaultMixin());
+
+ System.out.println(model.getMixins());
+
+ IPNetworkInterface iPNetworkInterface = eb.getIPNetworkInterface();
+ assertEquals(NetworkInterface.getDefaultKind(), iPNetworkInterface.getKind());
+ assertEquals(IPNetworkInterface.getDefaultMixin(), iPNetworkInterface.getMixin(IPNetworkInterface.MIXIN_IDENTIFIER_DEFAULT));
+ assertNotNull(iPNetworkInterface.getId());
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.http;
+
+import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import cz.cesnet.cloud.occi.Model;
+import cz.cesnet.cloud.occi.api.EntityBuilder;
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+import cz.cesnet.cloud.occi.api.http.auth.BasicAuthentication;
+import cz.cesnet.cloud.occi.api.http.auth.NoAuthentication;
+import cz.cesnet.cloud.occi.core.ActionInstance;
+import cz.cesnet.cloud.occi.core.Attribute;
+import cz.cesnet.cloud.occi.core.Entity;
+import cz.cesnet.cloud.occi.core.Kind;
+import cz.cesnet.cloud.occi.core.Link;
+import cz.cesnet.cloud.occi.core.Mixin;
+import cz.cesnet.cloud.occi.core.Resource;
+import cz.cesnet.cloud.occi.infrastructure.Compute;
+import cz.cesnet.cloud.occi.infrastructure.Network;
+import cz.cesnet.cloud.occi.infrastructure.NetworkInterface;
+import cz.cesnet.cloud.occi.infrastructure.Storage;
+import cz.cesnet.cloud.occi.infrastructure.enumeration.Architecture;
+import cz.cesnet.cloud.occi.infrastructure.enumeration.ComputeState;
+import cz.cesnet.cloud.occi.infrastructure.enumeration.NetworkState;
+import cz.cesnet.cloud.occi.infrastructure.enumeration.StorageState;
+import cz.cesnet.cloud.occi.parser.MediaType;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.Rule;
+
+/**
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class HTTPClientTest {
+
+ @Rule
+ public WireMockRule wireMockRule = new WireMockRule(8123);
+
+ private HTTPClient client;
+
+ @Before
+ public void setUp() throws Exception {
+ client = new HTTPClient(URI.create("http://localhost:8123"), null, MediaType.TEXT_PLAIN, false);
+ }
+
+ @Test
+ public void testFullConstructor() throws Exception {
+ HTTPClient client = new HTTPClient(URI.create("http://localhost:8123"), null, MediaType.TEXT_PLAIN, true);
+
+ assertEquals(client.getMediaType(), "text/plain");
+ assertTrue(client.getAuthentication() instanceof NoAuthentication);
+ assertTrue(client.isConnected());
+
+ client = new HTTPClient(URI.create("http://localhost:8123"), new BasicAuthentication("username", "password"), MediaType.TEXT_OCCI, false);
+
+ assertEquals(client.getMediaType(), MediaType.TEXT_OCCI);
+ assertTrue(client.getAuthentication() instanceof BasicAuthentication);
+ assertFalse(client.isConnected());
+ }
+
+ @Test
+ public void testPartialConstructor() throws Exception {
+ HTTPClient client = new HTTPClient(URI.create("http://localhost:8123"), new NoAuthentication());
+
+ assertEquals(client.getMediaType(), MediaType.TEXT_PLAIN);
+ assertTrue(client.getAuthentication() instanceof NoAuthentication);
+ assertTrue(client.isConnected());
+ }
+
+ @Test
+ public void testMinimalConstructor() throws Exception {
+ HTTPClient client = new HTTPClient(URI.create("http://localhost:8123"));
+
+ assertEquals(client.getMediaType(), MediaType.TEXT_PLAIN);
+ assertTrue(client.getAuthentication() instanceof NoAuthentication);
+ assertFalse(client.isConnected());
+ }
+
+ @Test
+ public void testSetMediaType() {
+ client.setMediaType("xyz/uvw");
+ assertEquals(client.getMediaType(), "xyz/uvw");
+ }
+
+ @Test
+ public void testConnect() throws Exception {
+ client.connect();
+
+ assertTrue(client.isConnected());
+ }
+
+ @Test
+ public void testList() throws Exception {
+ List<URI> list = listOfAll();
+ client.connect();
+
+ assertEquals(list, client.list());
+ client.setMediaType(MediaType.TEXT_OCCI);
+ assertEquals(list, client.list());
+ }
+
+ @Test
+ public void testListWithString() throws Exception {
+ List<URI> list = listOfComputes();
+ client.connect();
+
+ assertEquals(list, client.list("compute"));
+ client.setMediaType(MediaType.TEXT_OCCI);
+ assertEquals(list, client.list("compute"));
+ }
+
+ @Test
+ public void testInvalidListWithString() throws Exception {
+ client.connect();
+ try {
+ client.list("unknown");
+ } catch (CommunicationException ex) {
+ //cool
+ }
+
+ try {
+ Kind kind = new Kind(URI.create("http://different.uri.same/term/infrastructure#"), "compute");
+ client.getModel().addKind(kind);
+ client.list("compute");
+ } catch (CommunicationException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testListWithURI() throws Exception {
+ List<URI> list = listOfComputes();
+ client.connect();
+
+ assertEquals(list, client.list(URI.create("http://schemas.ogf.org/occi/infrastructure#compute")));
+ client.setMediaType(MediaType.TEXT_OCCI);
+ assertEquals(list, client.list(URI.create("http://schemas.ogf.org/occi/infrastructure#compute")));
+ }
+
+ @Test
+ public void testInvalidListWithURI() throws Exception {
+ client.connect();
+ try {
+ client.list(URI.create("http://nonexisting.abc.org/icco/infrastructure#compute"));
+ } catch (CommunicationException ex) {
+ //cool
+ }
+ }
+
+ private List<URI> listOfComputes() {
+ List<URI> list = new ArrayList<>();
+ list.add(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/compute/0054b25a-ddb9-412e-869e-7b800a13aa46"));
+ list.add(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/compute/29ce3084-23b6-44e0-b53e-55a34b924920"));
+ list.add(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/compute/987654321"));
+ list.add(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/compute/9b36c234-7e4a-400d-bab8-58dead9e0ef8"));
+ list.add(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/compute/29b814ad-c5b2-4bc4-888b-470f769a2930"));
+ list.add(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/compute/123456789"));
+
+ return list;
+ }
+
+ private List<URI> listOfNetworks() {
+ List<URI> list = new ArrayList<>();
+ list.add(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/network/05940332-7926-4cf5-b1fc-7479b529524a"));
+ list.add(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/network/1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619"));
+ list.add(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/network/24b94558-c46a-41e3-981d-16600f71cddb"));
+
+ return list;
+ }
+
+ private List<URI> listOfStorages() {
+ List<URI> list = new ArrayList<>();
+ list.add(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/storage/8f423fd4-0fdb-4422-a01b-fb6594173fbb"));
+ list.add(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/storage/1902326a-2092-4cb6-b998-6d6e73be6212"));
+ list.add(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/storage/a7eeebf0-a93f-4187-bd86-dab2725d5bfa"));
+
+ return list;
+ }
+
+ private List<URI> listOfAll() {
+ List<URI> list = listOfComputes();
+ list.addAll(listOfNetworks());
+ list.addAll(listOfStorages());
+
+ return list;
+ }
+
+ @Test
+ public void testDescribe() throws Exception {
+ Set<Entity> expectedSet = new HashSet<>(descriptionOfAll());
+ client.connect();
+
+ Set<Entity> clientSet = new HashSet<>(client.describe());
+ assertEquals(expectedSet, clientSet);
+ client.setMediaType(MediaType.TEXT_OCCI);
+ assertEquals(expectedSet, clientSet);
+
+ }
+
+ @Test
+ public void testDescribeWithString() throws Exception {
+ Set<Entity> expectedSet = new HashSet<>(descriptionOfComputes());
+ client.connect();
+
+ Set<Entity> clientSet = new HashSet<>(client.describe("compute"));
+ assertEquals(expectedSet, clientSet);
+ client.setMediaType(MediaType.TEXT_OCCI);
+ assertEquals(expectedSet, clientSet);
+ }
+
+ @Test
+ public void testInvalidDescribeWithString() throws Exception {
+ client.connect();
+ try {
+ client.describe("unknown");
+ } catch (CommunicationException ex) {
+ //cool
+ }
+
+ try {
+ Kind kind = new Kind(URI.create("http://different.uri.same/term/infrastructure#"), "compute");
+ client.getModel().addKind(kind);
+ client.describe("compute");
+ } catch (CommunicationException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testDescribeWithURI() throws Exception {
+ Set<Entity> expectedSet = new HashSet<>(descriptionOfComputes());
+ client.connect();
+
+ Set<Entity> clientSet = new HashSet<>(client.describe(URI.create("http://schemas.ogf.org/occi/infrastructure#compute")));
+ assertEquals(expectedSet, clientSet);
+ client.setMediaType(MediaType.TEXT_OCCI);
+ assertEquals(expectedSet, clientSet);
+
+ client.setMediaType(MediaType.TEXT_PLAIN);
+ expectedSet = new HashSet<>(descriptionOfSpecificCompute());
+ clientSet = new HashSet<>(client.describe(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/compute/9b36c234-7e4a-400d-bab8-58dead9e0ef8")));
+ assertEquals(expectedSet, clientSet);
+ client.setMediaType(MediaType.TEXT_OCCI);
+ assertEquals(expectedSet, clientSet);
+ }
+
+ @Test
+ public void testInvalidDescribeWithURI() throws Exception {
+ client.connect();
+ try {
+ client.describe(URI.create("http://nonexisting.abc.org/icco/infrastructure#compute"));
+ } catch (CommunicationException ex) {
+ //cool
+ }
+
+ try {
+ client.describe(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/compute/nonexistent-id"));
+ } catch (CommunicationException ex) {
+ //cool
+ }
+ }
+
+ private List<Entity> descriptionOfComputes() throws Exception {
+ List<Entity> entities = new ArrayList<>();
+ List<Attribute> computeAttributes = new ArrayList<>();
+ computeAttributes.add(new Attribute(Compute.ID_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.TITLE_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.SUMMARY_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.ARCHITECTURE_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.CORES_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.HOSTNAME_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.MEMORY_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.SPEED_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.STATE_ATTRIBUTE_NAME));
+ Kind compute = new Kind(URI.create("http://schemas.ogf.org/occi/infrastructure#"), "compute", "compute resource", URI.create("/compute/"), computeAttributes);
+ Mixin debian6 = new Mixin(URI.create("http://occi.example.org/occi/infrastructure/os_tpl#"), "debian6", "debian", URI.create("/mixin/os_tpl/debian6/"), null);
+ Mixin small = new Mixin(URI.create("http://occi.example.org/occi/infrastructure/resource_tpl#"), "small", "Small Instance - 1 core and 2 GB RAM", URI.create("/mixin/resource_tpl/small/"), null);
+ Mixin sl6golden = new Mixin(URI.create("http://occi.example.org/occi/infrastructure/os_tpl#"), "sl6golden", "monitoring", URI.create("/mixin/os_tpl/sl6golden/"), null);
+ Mixin mammoth = new Mixin(URI.create("http://occi.example.org/occi/infrastructure/resource_tpl#"), "mammoth", "Mammoth Instance - 8 cores and 32 GB RAM", URI.create("/mixin/resource_tpl/mammoth/"), null);
+ Kind networkinterface = new Kind(URI.create("http://schemas.ogf.org/occi/infrastructure#"), "networkinterface");
+
+ Compute c = new Compute("0054b25a-ddb9-412e-869e-7b800a13aa46", compute);
+ c.setTitle("test_title");
+ c.setArchitecture(Architecture.X_86);
+ c.setCores(1);
+ c.setMemory(2);
+ c.setSpeed(1);
+ c.setState(ComputeState.ACTIVE);
+ c.addAttribute("eu.egi.fedcloud.appdb.uuid", "appdb:uuid:debian6");
+ c.addMixin(debian6);
+ c.addMixin(small);
+ entities.add(c);
+
+ c = new Compute("29ce3084-23b6-44e0-b53e-55a34b924920", compute);
+ c.setTitle("fhkgf");
+ c.setArchitecture(Architecture.X_86);
+ c.setCores(8);
+ c.setMemory(32);
+ c.setSpeed(1);
+ c.setState(ComputeState.ACTIVE);
+ c.addAttribute("eu.egi.fedcloud.appdb.uuid", "appdb:uuid:sl6golden");
+ c.addMixin(sl6golden);
+ c.addMixin(mammoth);
+ entities.add(c);
+
+ Link link = new Link("e5f8f7bd-7d84-4c46-9a4e-325cc950f0ed", networkinterface);
+ link.setTarget("http://rocci-server-1-1-x.herokuapp.com:80/network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14");
+ link.setRelation("http://schemas.ogf.org/occi/core#link");
+ link.setSource("http://rocci-server-1-1-x.herokuapp.com:80/compute/987654321");
+
+ c = new Compute("987654321", compute);
+ c.setTitle("vm_test02");
+ c.setArchitecture(Architecture.X_86);
+ c.setCores(1);
+ c.setMemory(2);
+ c.setSpeed(1);
+ c.setState(ComputeState.ACTIVE);
+ c.addMixin(debian6);
+ c.addMixin(small);
+ c.addLink(link);
+ entities.add(c);
+
+ link = new Link("31f185d5-9379-4479-9809-b4cce6bcfdee", networkinterface);
+ link.setTarget("/network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14");
+ link.setRelation("http://schemas.ogf.org/occi/core#link");
+ link.setSource("/compute/9b36c234-7e4a-400d-bab8-58dead9e0ef8");
+ link.addAttribute(NetworkInterface.INTERFACE_ATTRIBUTE_NAME, "eth0");
+ link.addAttribute(NetworkInterface.MAC_ATTRIBUTE_NAME, "00:11:22:33:44:55");
+ link.addAttribute(NetworkInterface.STATE_ATTRIBUTE_NAME, NetworkState.ACTIVE.toString());
+
+ c = new Compute("9b36c234-7e4a-400d-bab8-58dead9e0ef8", compute);
+ c.setTitle("VMTest");
+ c.setArchitecture(Architecture.X_86);
+ c.setCores(1);
+ c.setMemory(2);
+ c.setSpeed(1);
+ c.setState(ComputeState.ACTIVE);
+ c.addMixin(debian6);
+ c.addMixin(small);
+ c.addLink(link);
+ entities.add(c);
+
+ link = new Link("920ad837-1fa3-40a2-8810-fb8f2dc1wrt7", networkinterface);
+ link.setTarget("/network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14");
+ link.setRelation("http://schemas.ogf.org/occi/core#link");
+ link.setSource("/compute/29b814ad-c5b2-4bc4-888b-470f769a2930");
+
+ c = new Compute("29b814ad-c5b2-4bc4-888b-470f769a2930", compute);
+ c.setTitle("VMTest2");
+ c.setArchitecture(Architecture.X_86);
+ c.setCores(1);
+ c.setMemory(2);
+ c.setSpeed(1);
+ c.setState(ComputeState.ACTIVE);
+ c.addMixin(debian6);
+ c.addMixin(small);
+ c.addLink(link);
+ entities.add(c);
+
+ link = new Link("9e9aced1-a2a8-459e-8fc8-690beb3f1533", networkinterface);
+ link.setTarget("/network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14");
+ link.setRelation("http://schemas.ogf.org/occi/core#link");
+ link.setSource("/compute/123456789");
+ link.addAttribute(NetworkInterface.INTERFACE_ATTRIBUTE_NAME, "eth0");
+ link.addAttribute(NetworkInterface.MAC_ATTRIBUTE_NAME, "00:11:22:33:44:55");
+ link.addAttribute(NetworkInterface.STATE_ATTRIBUTE_NAME, NetworkState.ACTIVE.toString());
+
+ c = new Compute("123456789", compute);
+ c.setTitle("vm_test01");
+ c.setArchitecture(Architecture.X_86);
+ c.setCores(1);
+ c.setMemory(2);
+ c.setSpeed(1);
+ c.setState(ComputeState.ACTIVE);
+ c.addMixin(debian6);
+ c.addMixin(small);
+ c.addLink(link);
+ entities.add(c);
+
+ return entities;
+ }
+
+ private List<Entity> descriptionOfSpecificCompute() throws Exception {
+ List<Entity> entities = new ArrayList<>();
+ List<Attribute> computeAttributes = new ArrayList<>();
+ computeAttributes.add(new Attribute(Compute.ID_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.TITLE_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.SUMMARY_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.ARCHITECTURE_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.CORES_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.HOSTNAME_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.MEMORY_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.SPEED_ATTRIBUTE_NAME));
+ computeAttributes.add(new Attribute(Compute.STATE_ATTRIBUTE_NAME));
+ Kind compute = new Kind(URI.create("http://schemas.ogf.org/occi/infrastructure#"), "compute", "compute resource", URI.create("/compute/"), computeAttributes);
+ Mixin debian6 = new Mixin(URI.create("http://occi.example.org/occi/infrastructure/os_tpl#"), "debian6", "debian", URI.create("/mixin/os_tpl/debian6/"), null);
+ Mixin small = new Mixin(URI.create("http://occi.example.org/occi/infrastructure/resource_tpl#"), "small", "Small Instance - 1 core and 2 GB RAM", URI.create("/mixin/resource_tpl/small/"), null);
+ Kind networkinterface = new Kind(URI.create("http://schemas.ogf.org/occi/infrastructure#"), "networkinterface");
+
+ Link link = new Link("31f185d5-9379-4479-9809-b4cce6bcfdee", networkinterface);
+ link.setTarget("/network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14");
+ link.setRelation("http://schemas.ogf.org/occi/core#link");
+ link.setSource("/compute/9b36c234-7e4a-400d-bab8-58dead9e0ef8");
+ link.addAttribute(NetworkInterface.INTERFACE_ATTRIBUTE_NAME, "eth0");
+ link.addAttribute(NetworkInterface.MAC_ATTRIBUTE_NAME, "00:11:22:33:44:55");
+ link.addAttribute(NetworkInterface.STATE_ATTRIBUTE_NAME, NetworkState.ACTIVE.toString());
+
+ Compute c = new Compute("9b36c234-7e4a-400d-bab8-58dead9e0ef8", compute);
+ c.setTitle("VMTest");
+ c.setArchitecture(Architecture.X_86);
+ c.setCores(1);
+ c.setMemory(2);
+ c.setSpeed(1);
+ c.setState(ComputeState.ACTIVE);
+ c.addMixin(debian6);
+ c.addMixin(small);
+ c.addLink(link);
+ entities.add(c);
+
+ return entities;
+ }
+
+ private List<Entity> descriptionOfNetworks() throws Exception {
+ List<Entity> entities = new ArrayList<>();
+ List<Attribute> networkAttributes = new ArrayList<>();
+ networkAttributes.add(new Attribute(Network.ID_ATTRIBUTE_NAME));
+ networkAttributes.add(new Attribute(Network.STATE_ATTRIBUTE_NAME));
+ Kind network = new Kind(URI.create("http://schemas.ogf.org/occi/infrastructure#"), "network", "network resource", URI.create("/network/"), networkAttributes);
+
+ Network n = new Network("05940332-7926-4cf5-b1fc-7479b529524a", network);
+ n.setState(NetworkState.INACTIVE);
+ entities.add(n);
+
+ n = new Network("1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619", network);
+ n.setState(NetworkState.INACTIVE);
+ entities.add(n);
+
+ n = new Network("24b94558-c46a-41e3-981d-16600f71cddb", network);
+ n.setState(NetworkState.INACTIVE);
+ entities.add(n);
+
+ return entities;
+ }
+
+ private List<Entity> descriptionOfStorages() throws Exception {
+ List<Entity> entities = new ArrayList<>();
+ List<Attribute> storageAttributes = new ArrayList<>();
+ storageAttributes.add(new Attribute(Storage.ID_ATTRIBUTE_NAME));
+ storageAttributes.add(new Attribute(Storage.STATE_ATTRIBUTE_NAME));
+ Kind storage = new Kind(URI.create("http://schemas.ogf.org/occi/infrastructure#"), "storage", "storage resource", URI.create("/storage/"), storageAttributes);
+
+ Storage s = new Storage("1902326a-2092-4cb6-b998-6d6e73be6212", storage);
+ s.setState(StorageState.OFFLINE);
+ entities.add(s);
+
+ s = new Storage("8f423fd4-0fdb-4422-a01b-fb6594173fbb", storage);
+ s.setState(StorageState.OFFLINE);
+ entities.add(s);
+
+ s = new Storage("a7eeebf0-a93f-4187-bd86-dab2725d5bfa", storage);
+ s.setState(StorageState.OFFLINE);
+ entities.add(s);
+
+ return entities;
+ }
+
+ private List<Entity> descriptionOfAll() throws Exception {
+ List<Entity> entities = descriptionOfComputes();
+ entities.addAll(descriptionOfNetworks());
+ entities.addAll(descriptionOfStorages());
+
+ return entities;
+ }
+
+ @Test
+ public void testCreate() throws Exception {
+ client.connect();
+ Model model = client.getModel();
+ EntityBuilder eb = new EntityBuilder(model);
+ Resource r = eb.getResource("compute");
+ r.setId("157754bb-af01-40be-853a-6a1f1b5ac500");
+ r.addMixin(model.findMixin("debian6", "os_tpl"));
+ r.addMixin(model.findMixin("small"));
+
+ assertEquals(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/compute/157754bb-af01-40be-853a-6a1f1b5ac500"), client.create(r));
+ client.setMediaType(MediaType.TEXT_OCCI);
+ r.setId("5537b49a-bb2e-4302-bf8b-da38611247ca");
+ assertEquals(URI.create("http://rocci-server-1-1-x.herokuapp.com/compute/5537b49a-bb2e-4302-bf8b-da38611247ca"), client.create(r));
+ }
+
+ @Test
+ public void testUpdate() throws Exception {
+ client.connect();
+ Model model = client.getModel();
+ EntityBuilder eb = new EntityBuilder(model);
+ Resource r = eb.getResource("compute");
+ r.setId("157754bb-af01-40be-853a-6a1f1b5ac500");
+
+ assertEquals(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/compute/157754bb-af01-40be-853a-6a1f1b5ac500"), client.update(r));
+ client.setMediaType(MediaType.TEXT_OCCI);
+ r.setId("5537b49a-bb2e-4302-bf8b-da38611247ca");
+ assertEquals(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/compute/5537b49a-bb2e-4302-bf8b-da38611247ca"), client.update(r));
+ }
+
+ @Test
+ public void testDeleteWithString() throws Exception {
+ client.connect();
+
+ assertTrue(client.delete("network"));
+ client.setMediaType(MediaType.TEXT_OCCI);
+ assertTrue(client.delete("network"));
+ }
+
+ @Test
+ public void testInvalidDeleteWithString() throws Exception {
+ client.connect();
+ try {
+ client.delete("unknown");
+ } catch (CommunicationException ex) {
+ //cool
+ }
+
+ try {
+ Kind kind = new Kind(URI.create("http://different.uri.same/term/infrastructure#"), "network");
+ client.getModel().addKind(kind);
+ client.delete("network");
+ } catch (CommunicationException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testDeleteWithURI() throws Exception {
+ client.connect();
+
+ assertTrue(client.delete(URI.create("http://schemas.ogf.org/occi/infrastructure#storage")));
+ client.setMediaType(MediaType.TEXT_OCCI);
+ assertTrue(client.delete(URI.create("http://schemas.ogf.org/occi/infrastructure#storage")));
+
+ client.setMediaType(MediaType.TEXT_PLAIN);
+ assertTrue(client.delete(URI.create("http://rocci-server-1-1-x.herokuapp.com/compute/157754bb-af01-40be-853a-6a1f1b5ac500")));
+ client.setMediaType(MediaType.TEXT_OCCI);
+ assertTrue(client.delete(URI.create("http://rocci-server-1-1-x.herokuapp.com/compute/5537b49a-bb2e-4302-bf8b-da38611247ca")));
+ }
+
+ @Test
+ public void testInvalidDeleteWithURI() throws Exception {
+ client.connect();
+ try {
+ client.delete(URI.create("http://nonexisting.abc.org/icco/infrastructure#network"));
+ } catch (CommunicationException ex) {
+ //cool
+ }
+
+ try {
+ client.delete(URI.create("http://rocci-server-1-1-x.herokuapp.com/compute/nonexisting-id"));
+ } catch (CommunicationException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testTriggerWithStringAndActionInstance() throws Exception {
+ client.connect();
+ Model model = client.getModel();
+ EntityBuilder eb = new EntityBuilder(model);
+ ActionInstance a = eb.getActionInstance("start");
+
+ assertTrue(client.trigger("compute", a));
+ client.setMediaType(MediaType.TEXT_OCCI);
+ assertTrue(client.trigger("compute", a));
+ }
+
+ @Test
+ public void testInvalidTriggerWithStringAndActionInstance() throws Exception {
+ client.connect();
+ Model model = client.getModel();
+ EntityBuilder eb = new EntityBuilder(model);
+ ActionInstance a = eb.getActionInstance("start");
+ try {
+ client.trigger("unknown", a);
+ } catch (CommunicationException ex) {
+ //cool
+ }
+
+ try {
+ Kind kind = new Kind(URI.create("http://different.uri.same/term/infrastructure#"), "compute");
+ model.addKind(kind);
+ client.trigger("compute", a);
+ } catch (CommunicationException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testTriggerWithURIAndActionInstance() throws Exception {
+ client.connect();
+ Model model = client.getModel();
+ EntityBuilder eb = new EntityBuilder(model);
+ ActionInstance a = eb.getActionInstance("start");
+
+ assertTrue(client.trigger(URI.create("http://schemas.ogf.org/occi/infrastructure#compute"), a));
+ client.setMediaType(MediaType.TEXT_OCCI);
+ assertTrue(client.trigger(URI.create("http://schemas.ogf.org/occi/infrastructure#compute"), a));
+
+ client.setMediaType(MediaType.TEXT_PLAIN);
+ assertTrue(client.trigger(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/compute/29b814ad-c5b2-4bc4-888b-470f769a2930"), a));
+ client.setMediaType(MediaType.TEXT_OCCI);
+ assertTrue(client.trigger(URI.create("http://rocci-server-1-1-x.herokuapp.com:80/compute/29b814ad-c5b2-4bc4-888b-470f769a2930"), a));
+ }
+
+ @Test
+ public void testInvalidTriggerWithURIAndActionInstance() throws Exception {
+ client.connect();
+ Model model = client.getModel();
+ EntityBuilder eb = new EntityBuilder(model);
+ ActionInstance a = eb.getActionInstance("start");
+ try {
+ client.trigger(URI.create("http://rocci-server-1-1-x.herokuapp.com/compute/nonexisting-id"), a);
+ } catch (CommunicationException ex) {
+ //cool
+ }
+
+ try {
+ client.trigger(URI.create("http://nonexisting.abc.org/icco/infrastructure#network"), a);
+ } catch (CommunicationException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testRefresh() throws Exception {
+ client.connect();
+ Model model = client.getModel();
+ Kind kind = new Kind(URI.create("http://different.uri.same/term/infrastructure#"), "network");
+ model.addKind(kind);
+
+ client.refresh();
+ assertFalse(model.equals(client.getModel()));
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.http;
+
+import org.apache.http.HttpHeaders;
+import org.apache.http.message.BasicHeader;
+import static org.junit.Assert.assertEquals;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class HTTPConnectionTest {
+
+ HTTPConnection con;
+
+ @Before
+ public void setUp() {
+ con = new HTTPConnection();
+ con.addHeader(new BasicHeader(HttpHeaders.AGE, "aaa"));
+ con.addHeader(new BasicHeader(HttpHeaders.DEPTH, "ddd"));
+ con.addHeader(new BasicHeader(HttpHeaders.FROM, "fff"));
+ }
+
+ @Test
+ public void testGetHeaders() {
+ assertEquals(3, con.getHeaders().length);
+ assertEquals(HttpHeaders.AGE, con.getHeaders()[0].getName());
+ assertEquals("aaa", con.getHeaders()[0].getValue());
+ assertEquals(HttpHeaders.DEPTH, con.getHeaders()[1].getName());
+ assertEquals("ddd", con.getHeaders()[1].getValue());
+ assertEquals(HttpHeaders.FROM, con.getHeaders()[2].getName());
+ assertEquals("fff", con.getHeaders()[2].getValue());
+ }
+
+ @Test
+ public void testAddHeader() {
+ con.addHeader(new BasicHeader(HttpHeaders.TE, "ttt"));
+
+ assertEquals(4, con.getHeaders().length);
+ assertEquals(HttpHeaders.AGE, con.getHeaders()[0].getName());
+ assertEquals("aaa", con.getHeaders()[0].getValue());
+ assertEquals(HttpHeaders.DEPTH, con.getHeaders()[1].getName());
+ assertEquals("ddd", con.getHeaders()[1].getValue());
+ assertEquals(HttpHeaders.FROM, con.getHeaders()[2].getName());
+ assertEquals("fff", con.getHeaders()[2].getValue());
+ assertEquals(HttpHeaders.TE, con.getHeaders()[3].getName());
+ assertEquals("ttt", con.getHeaders()[3].getValue());
+ }
+
+ @Test
+ public void testClearHeaders() {
+ assertEquals(3, con.getHeaders().length);
+ con.clearHeaders();
+ assertEquals(0, con.getHeaders().length);
+ }
+
+ @Test
+ public void testSetMediaType() {
+ assertEquals(3, con.getHeaders().length);
+ con.setMediaType("mediaType");
+ assertEquals(5, con.getHeaders().length);
+ assertEquals(HttpHeaders.CONTENT_TYPE, con.getHeaders()[3].getName());
+ assertEquals("mediaType", con.getHeaders()[3].getValue());
+ assertEquals(HttpHeaders.ACCEPT, con.getHeaders()[4].getName());
+ assertEquals("mediaType", con.getHeaders()[4].getValue());
+ }
+}
--- /dev/null
+package cz.cesnet.cloud.occi.api.http;
+
+import java.net.URI;
+import org.apache.http.Header;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.protocol.HttpContext;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import org.junit.Before;
+import org.junit.Test;
+import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import cz.cesnet.cloud.occi.api.exception.CommunicationException;
+import org.apache.http.HttpHost;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import org.junit.Rule;
+
+/**
+ *
+ * @author Michal Kimle <kimle.michal@gmail.com>
+ */
+public class HTTPHelperTest {
+
+ private Header[] headers;
+ private String uri;
+ private URI uuri;
+ private CloseableHttpClient client;
+ private HttpContext context;
+ private int[] statuses;
+ private HttpHost target;
+ private String prefix;
+
+ @Rule
+ public WireMockRule wireMockRule = new WireMockRule(8123);
+
+ @Before
+ public void setUp() {
+ headers = new Header[2];
+ headers[0] = new BasicHeader(HttpHeaders.ACCEPT, "text/plain");
+ headers[1] = new BasicHeader(HttpHeaders.CONTENT_TYPE, "text/plain");
+ uri = "/some/path";
+ uuri = URI.create(uri);
+ client = HttpClients.createDefault();
+ context = HttpClientContext.create();
+ statuses = new int[]{HttpStatus.SC_ACCEPTED};
+ target = new HttpHost("localhost", 8123, "http");
+ prefix = "/prefix";
+ }
+
+ @Test
+ public void testPrepareGetWithStringAndHeaders() {
+ HttpGet message = HTTPHelper.prepareGet(uri, headers, "");
+
+ assertArrayEquals(headers, message.getAllHeaders());
+ assertEquals(uri, message.getURI().toString());
+ }
+
+ @Test
+ public void testPrepareGetWithString() {
+ HttpGet message = HTTPHelper.prepareGet(uri);
+
+ assertEquals(0, message.getAllHeaders().length);
+ assertEquals(uri, message.getURI().toString());
+ }
+
+ @Test
+ public void testPrepareHeadWithStringAndHeaders() {
+ HttpHead message = HTTPHelper.prepareHead(uri, headers, prefix);
+
+ assertArrayEquals(headers, message.getAllHeaders());
+ assertEquals(prefix + uri, message.getURI().toString());
+ }
+
+ @Test
+ public void testPrepareHeadWithString() {
+ HttpHead message = HTTPHelper.prepareHead(uri);
+
+ assertEquals(0, message.getAllHeaders().length);
+ assertEquals(uri, message.getURI().toString());
+ }
+
+ @Test
+ public void testPrepareGetWithURIAndHeaders() {
+ HttpGet message = HTTPHelper.prepareGet(uuri, headers, "");
+
+ assertArrayEquals(headers, message.getAllHeaders());
+ assertEquals(uuri, message.getURI());
+ }
+
+ @Test
+ public void testPrepareGetWithURI() {
+ HttpGet message = HTTPHelper.prepareGet(uuri);
+
+ assertEquals(0, message.getAllHeaders().length);
+ assertEquals(uuri, message.getURI());
+ }
+
+ @Test
+ public void testPrepareHeadWithURIAndHeaders() {
+ HttpHead message = HTTPHelper.prepareHead(uuri, headers, prefix);
+
+ assertArrayEquals(headers, message.getAllHeaders());
+ assertEquals(prefix + uuri, message.getURI().toString());
+ }
+
+ @Test
+ public void testPrepareHeadWithURI() {
+ HttpHead message = HTTPHelper.prepareHead(uuri);
+
+ assertEquals(0, message.getAllHeaders().length);
+ assertEquals(uuri, message.getURI());
+ }
+
+ @Test
+ public void testPrepareDeleteWithStringAndHeaders() {
+ HttpDelete message = HTTPHelper.prepareDelete(uri, headers, "");
+
+ assertArrayEquals(headers, message.getAllHeaders());
+ assertEquals(uri, message.getURI().toString());
+ }
+
+ @Test
+ public void testPrepareDeleteWithString() {
+ HttpDelete message = HTTPHelper.prepareDelete(uri);
+
+ assertEquals(0, message.getAllHeaders().length);
+ assertEquals(uri, message.getURI().toString());
+ }
+
+ @Test
+ public void testPrepareDeleteWithURIAndHeaders() {
+ HttpDelete message = HTTPHelper.prepareDelete(uuri, headers, prefix);
+
+ assertArrayEquals(headers, message.getAllHeaders());
+ assertEquals(prefix + uuri, message.getURI().toString());
+ }
+
+ @Test
+ public void testPrepareDeleteWithURI() {
+ HttpDelete message = HTTPHelper.prepareDelete(uuri);
+
+ assertEquals(0, message.getAllHeaders().length);
+ assertEquals(uuri, message.getURI());
+ }
+
+ @Test
+ public void testPreparePostWithStringAndHeaders() {
+ HttpPost message = HTTPHelper.preparePost(uri, headers, "");
+
+ assertArrayEquals(headers, message.getAllHeaders());
+ assertEquals(uri, message.getURI().toString());
+ }
+
+ @Test
+ public void testPreparePostWithString() {
+ HttpPost message = HTTPHelper.preparePost(uri);
+
+ assertEquals(0, message.getAllHeaders().length);
+ assertEquals(uri, message.getURI().toString());
+ }
+
+ @Test
+ public void testPreparePostWithURIAndHeaders() {
+ HttpPost message = HTTPHelper.preparePost(uuri, headers, prefix);
+
+ assertArrayEquals(headers, message.getAllHeaders());
+ assertEquals(prefix + uuri, message.getURI().toString());
+ }
+
+ @Test
+ public void testPreparePostWithURI() {
+ HttpPost message = HTTPHelper.preparePost(uuri);
+
+ assertEquals(0, message.getAllHeaders().length);
+ assertEquals(uuri, message.getURI());
+ }
+
+ @Test
+ public void testRunRequestWithStatus() throws Exception {
+ HttpRequest httpRequest = HTTPHelper.prepareGet("/differentcode/", headers, "");
+ CloseableHttpResponse response = HTTPHelper.runRequest(httpRequest, target, client, context, statuses);
+
+ assertNotNull(response);
+ assertEquals(HttpStatus.SC_ACCEPTED, response.getStatusLine().getStatusCode());
+ }
+
+ @Test
+ public void testInvalidRunRequestWithStatus() throws Exception {
+ HttpRequest httpRequest = HTTPHelper.prepareGet("/xyz/", headers, "");
+ try {
+ CloseableHttpResponse response = HTTPHelper.runRequest(httpRequest, target, client, context, statuses);
+ } catch (CommunicationException ex) {
+ //cool
+ }
+
+ target = new HttpHost("nonexisting", 8123, "http");
+ try {
+ CloseableHttpResponse response = HTTPHelper.runRequest(httpRequest, target, client, context, statuses);
+ } catch (CommunicationException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testRunRequestWithoutStatus() throws Exception {
+ HttpRequest httpRequest = HTTPHelper.prepareGet("/", headers, "");
+ CloseableHttpResponse response = HTTPHelper.runRequest(httpRequest, target, client, context);
+
+ assertNotNull(response);
+ assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
+ }
+
+ @Test
+ public void testInvalidRunRequestWithoutStatus() throws Exception {
+ HttpRequest httpRequest = HTTPHelper.prepareGet("/xyz/", headers, "");
+ try {
+ CloseableHttpResponse response = HTTPHelper.runRequest(httpRequest, target, client, context);
+ } catch (CommunicationException ex) {
+ //cool
+ }
+
+ target = new HttpHost("nonexisting", 8123, "http");
+ try {
+ CloseableHttpResponse response = HTTPHelper.runRequest(httpRequest, target, client, context);
+ } catch (CommunicationException ex) {
+ //cool
+ }
+ }
+
+ @Test
+ public void testRunRequestForStatusWithStatus() throws Exception {
+ HttpRequest httpRequest = HTTPHelper.prepareGet("/differentcode/", headers, "");
+ boolean isOk = HTTPHelper.runRequestForStatus(httpRequest, target, client, context, statuses);
+ assertTrue(isOk);
+
+ httpRequest = HTTPHelper.prepareGet("/", headers, "");
+ isOk = HTTPHelper.runRequestForStatus(httpRequest, target, client, context, statuses);
+ assertFalse(isOk);
+ }
+
+ @Test
+ public void testRunRequestForStatusWithoutStatus() throws Exception {
+ HttpRequest httpRequest = HTTPHelper.prepareGet("/", headers, "");
+ boolean isOk = HTTPHelper.runRequestForStatus(httpRequest, target, client, context);
+ assertTrue(isOk);
+
+ httpRequest = HTTPHelper.prepareGet("/differentcode/", headers, "");
+ isOk = HTTPHelper.runRequestForStatus(httpRequest, target, client, context);
+ assertFalse(isOk);
+ }
+}
--- /dev/null
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/0054b25a-ddb9-412e-869e-7b800a13aa46
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/29ce3084-23b6-44e0-b53e-55a34b924920
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/987654321
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/9b36c234-7e4a-400d-bab8-58dead9e0ef8
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/29b814ad-c5b2-4bc4-888b-470f769a2930
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/123456789
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/network/05940332-7926-4cf5-b1fc-7479b529524a
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/network/1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/network/24b94558-c46a-41e3-981d-16600f71cddb
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/storage/8f423fd4-0fdb-4422-a01b-fb6594173fbb
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/storage/1902326a-2092-4cb6-b998-6d6e73be6212
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/storage/a7eeebf0-a93f-4187-bd86-dab2725d5bfa
\ No newline at end of file
--- /dev/null
+Category: entity;scheme="http://schemas.ogf.org/occi/core#";class="kind";title="entity";location="/entity/";attributes="occi.core.id{immutable required} occi.core.title"
+Category: resource;scheme="http://schemas.ogf.org/occi/core#";class="kind";title="resource";rel="http://schemas.ogf.org/occi/core#entity";location="/resource/";attributes="occi.core.id{immutable required} occi.core.title occi.core.summary"
+Category: link;scheme="http://schemas.ogf.org/occi/core#";class="kind";title="link";rel="http://schemas.ogf.org/occi/core#entity";location="/link/";attributes="occi.core.id{immutable required} occi.core.title occi.core.target occi.core.source{required}"
+Category: compute;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";title="compute resource";rel="http://schemas.ogf.org/occi/core#resource";location="/compute/";attributes="occi.core.id{immutable required} occi.core.title occi.core.summary occi.compute.architecture occi.compute.cores occi.compute.hostname occi.compute.memory occi.compute.speed occi.compute.state{immutable}";actions="http://schemas.ogf.org/occi/infrastructure/compute/action#start http://schemas.ogf.org/occi/infrastructure/compute/action#stop http://schemas.ogf.org/occi/infrastructure/compute/action#restart http://schemas.ogf.org/occi/infrastructure/compute/action#suspend"
+Category: storage;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";title="storage resource";rel="http://schemas.ogf.org/occi/core#resource";location="/storage/";attributes="occi.core.id{immutable required} occi.core.title occi.core.summary occi.storage.size occi.storage.state";actions="http://schemas.ogf.org/occi/infrastructure/storage/action#online http://schemas.ogf.org/occi/infrastructure/storage/action#offline http://schemas.ogf.org/occi/infrastructure/storage/action#backup http://schemas.ogf.org/occi/infrastructure/storage/action#snapshot http://schemas.ogf.org/occi/infrastructure/storage/action#resize"
+Category: network;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";title="network resource";rel="http://schemas.ogf.org/occi/core#resource";location="/network/";attributes="occi.core.id{immutable required} occi.core.title occi.core.summary occi.network.vlan occi.network.label occi.network.state{immutable}";actions="http://schemas.ogf.org/occi/infrastructure/network/action#up http://schemas.ogf.org/occi/infrastructure/network/action#down"
+Category: networkinterface;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";title="networkinterface link";rel="http://schemas.ogf.org/occi/core#link";location="/link/networkinterface/";attributes="occi.core.id{immutable required} occi.core.title occi.core.target occi.core.source{required} occi.networkinterface.interface{immutable} occi.networkinterface.mac occi.networkinterface.state{immutable}";actions="http://schemas.ogf.org/occi/infrastructure/networkinterface/action#up http://schemas.ogf.org/occi/infrastructure/networkinterface/action#down"
+Category: storagelink;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";title="storage link";rel="http://schemas.ogf.org/occi/core#link";location="/link/storagelink/";attributes="occi.core.id{immutable required} occi.core.title occi.core.target occi.core.source{required} occi.storagelink.deviceid occi.storagelink.mountpoint occi.storagelink.state{immutable}";actions="http://schemas.ogf.org/occi/infrastructure/storagelink/action#online http://schemas.ogf.org/occi/infrastructure/storagelink/action#offline"
+Category: resource_tpl;scheme="http://schemas.ogf.org/occi/infrastructure#";class="mixin";title="resource template";location="/mixin/resource_tpl/"
+Category: os_tpl;scheme="http://schemas.ogf.org/occi/infrastructure#";class="mixin";title="operating system template";location="/mixin/os_tpl/"
+Category: ipnetwork;scheme="http://schemas.ogf.org/occi/infrastructure/network#";class="mixin";title="IP network mixin";location="/mixin/ipnetwork/";attributes="occi.network.address occi.network.gateway occi.network.allocation"
+Category: ipnetworkinterface;scheme="http://schemas.ogf.org/occi/infrastructure/networkinterface#";class="mixin";title="IP network interface mixin";location="/mixin/ipnetworkinterface/";attributes="occi.networkinterface.address occi.networkinterface.gateway occi.networkinterface.allocation"
+Category: debian6;scheme="http://occi.example.org/occi/infrastructure/os_tpl#";class="mixin";title="debian";rel="http://schemas.ogf.org/occi/infrastructure#os_tpl";location="/mixin/os_tpl/debian6/";attributes="eu.egi.fedcloud.appdb.uuid{immutable required}"
+Category: sl6golden;scheme="http://occi.example.org/occi/infrastructure/os_tpl#";class="mixin";title="monitoring";rel="http://schemas.ogf.org/occi/infrastructure#os_tpl";location="/mixin/os_tpl/sl6golden/";attributes="eu.egi.fedcloud.appdb.uuid{immutable required}"
+Category: goliath;scheme="http://occi.example.org/occi/infrastructure/resource_tpl#";class="mixin";title="Goliath Instance - 16 cores and 64 GB RAM";rel="http://schemas.ogf.org/occi/infrastructure#resource_tpl";location="/mixin/resource_tpl/goliath/";attributes="occi.compute.architecture{immutable} occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}"
+Category: mammoth;scheme="http://occi.example.org/occi/infrastructure/resource_tpl#";class="mixin";title="Mammoth Instance - 8 cores and 32 GB RAM";rel="http://schemas.ogf.org/occi/infrastructure#resource_tpl";location="/mixin/resource_tpl/mammoth/";attributes="occi.compute.architecture{immutable} occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}"
+Category: extra_large;scheme="http://occi.example.org/occi/infrastructure/resource_tpl#";class="mixin";title="Extra Large Instance - 4 cores and 16 GB RAM";rel="http://schemas.ogf.org/occi/infrastructure#resource_tpl";location="/mixin/resource_tpl/extra_large/";attributes="occi.compute.architecture{immutable} occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}"
+Category: large;scheme="http://occi.example.org/occi/infrastructure/resource_tpl#";class="mixin";title="Large Instance - 4 cores and 8 GB RAM";rel="http://schemas.ogf.org/occi/infrastructure#resource_tpl";location="/mixin/resource_tpl/large/";attributes="occi.compute.architecture{immutable} occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}"
+Category: medium;scheme="http://occi.example.org/occi/infrastructure/resource_tpl#";class="mixin";title="Medium Instance - 2 cores and 4 GB RAM";rel="http://schemas.ogf.org/occi/infrastructure#resource_tpl";location="/mixin/resource_tpl/medium/";attributes="occi.compute.architecture occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}"
+Category: small;scheme="http://occi.example.org/occi/infrastructure/resource_tpl#";class="mixin";title="Small Instance - 1 core and 2 GB RAM";rel="http://schemas.ogf.org/occi/infrastructure#resource_tpl";location="/mixin/resource_tpl/small/";attributes="occi.compute.architecture occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}"
+Category: start;scheme="http://schemas.ogf.org/occi/infrastructure/compute/action#";class="action";title="start compute instance"
+Category: stop;scheme="http://schemas.ogf.org/occi/infrastructure/compute/action#";class="action";title="stop compute instance";attributes="method"
+Category: restart;scheme="http://schemas.ogf.org/occi/infrastructure/compute/action#";class="action";title="restart compute instance";attributes="method"
+Category: suspend;scheme="http://schemas.ogf.org/occi/infrastructure/compute/action#";class="action";title="suspend compute instance";attributes="method"
+Category: online;scheme="http://schemas.ogf.org/occi/infrastructure/storage/action#";class="action";title="activate storage"
+Category: offline;scheme="http://schemas.ogf.org/occi/infrastructure/storage/action#";class="action";title="deactivate storage"
+Category: backup;scheme="http://schemas.ogf.org/occi/infrastructure/storage/action#";class="action";title="backup storage"
+Category: snapshot;scheme="http://schemas.ogf.org/occi/infrastructure/storage/action#";class="action";title="snapshot storage"
+Category: resize;scheme="http://schemas.ogf.org/occi/infrastructure/storage/action#";class="action";title="resize storage";attributes="size{required}"
+Category: up;scheme="http://schemas.ogf.org/occi/infrastructure/network/action#";class="action";title="activate network"
+Category: down;scheme="http://schemas.ogf.org/occi/infrastructure/network/action#";class="action";title="deactivate network"
+Category: up;scheme="http://schemas.ogf.org/occi/infrastructure/networkinterface/action#";class="action";title="activate networkinterface"
+Category: down;scheme="http://schemas.ogf.org/occi/infrastructure/networkinterface/action#";class="action";title="deactivate networkinterface"
+Category: online;scheme="http://schemas.ogf.org/occi/infrastructure/storagelink/action#";class="action";title="activate storagelink"
+Category: offline;scheme="http://schemas.ogf.org/occi/infrastructure/storagelink/action#";class="action";title="deactivate storagelink"
--- /dev/null
+Category: compute;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";location="/compute/";title="compute resource"
+Category: debian6;scheme="http://occi.example.org/occi/infrastructure/os_tpl#";class="mixin";location="/mixin/os_tpl/debian6/";title="debian"
+Category: small;scheme="http://occi.example.org/occi/infrastructure/resource_tpl#";class="mixin";location="/mixin/resource_tpl/small/";title="Small Instance - 1 core and 2 GB RAM"
+X-OCCI-Attribute: occi.core.id="0054b25a-ddb9-412e-869e-7b800a13aa46"
+X-OCCI-Attribute: occi.core.title="test_title"
+X-OCCI-Attribute: occi.compute.architecture="x86"
+X-OCCI-Attribute: occi.compute.cores=1
+X-OCCI-Attribute: occi.compute.memory=2
+X-OCCI-Attribute: occi.compute.speed=1
+X-OCCI-Attribute: occi.compute.state="active"
+X-OCCI-Attribute: eu.egi.fedcloud.appdb.uuid="appdb:uuid:debian6"
\ No newline at end of file
--- /dev/null
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/157754bb-af01-40be-853a-6a1f1b5ac500
\ No newline at end of file
--- /dev/null
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/0054b25a-ddb9-412e-869e-7b800a13aa46
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/29ce3084-23b6-44e0-b53e-55a34b924920
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/987654321
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/9b36c234-7e4a-400d-bab8-58dead9e0ef8
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/29b814ad-c5b2-4bc4-888b-470f769a2930
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/123456789
\ No newline at end of file
--- /dev/null
+Category: compute;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";location="/compute/";title="compute resource"
+Category: debian6;scheme="http://occi.example.org/occi/infrastructure/os_tpl#";class="mixin";location="/mixin/os_tpl/debian6/";title="debian"
+Category: small;scheme="http://occi.example.org/occi/infrastructure/resource_tpl#";class="mixin";location="/mixin/resource_tpl/small/";title="Small Instance - 1 core and 2 GB RAM"
+X-OCCI-Attribute: occi.core.id="123456789"
+X-OCCI-Attribute: occi.core.title="vm_test01"
+X-OCCI-Attribute: occi.compute.architecture="x86"
+X-OCCI-Attribute: occi.compute.cores=1
+X-OCCI-Attribute: occi.compute.hostname="vm_test01"
+X-OCCI-Attribute: occi.compute.memory=2
+X-OCCI-Attribute: occi.compute.speed=1
+X-OCCI-Attribute: occi.compute.state="active"
+Link: </network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14>;rel="http://schemas.ogf.org/occi/core#link";self="/link/networkinterface/9e9aced1-a2a8-459e-8fc8-690beb3f1533";category="http://schemas.ogf.org/occi/infrastructure#networkinterface";occi.core.id="9e9aced1-a2a8-459e-8fc8-690beb3f1533";occi.core.target="/network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14";occi.core.source="/compute/123456789";occi.networkinterface.interface="eth0";occi.networkinterface.mac="00:11:22:33:44:55";occi.networkinterface.state="active"
\ No newline at end of file
--- /dev/null
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/157754bb-af01-40be-853a-6a1f1b5ac500
--- /dev/null
+Category: compute;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";location="/compute/";title="compute resource"
+Category: debian6;scheme="http://occi.example.org/occi/infrastructure/os_tpl#";class="mixin";location="/mixin/os_tpl/debian6/";title="debian"
+Category: small;scheme="http://occi.example.org/occi/infrastructure/resource_tpl#";class="mixin";location="/mixin/resource_tpl/small/";title="Small Instance - 1 core and 2 GB RAM"
+X-OCCI-Attribute: occi.core.id="29b814ad-c5b2-4bc4-888b-470f769a2930"
+X-OCCI-Attribute: occi.core.title="VMTest2"
+X-OCCI-Attribute: occi.compute.architecture="x86"
+X-OCCI-Attribute: occi.compute.cores=1
+X-OCCI-Attribute: occi.compute.hostname="VMTest2"
+X-OCCI-Attribute: occi.compute.memory=2
+X-OCCI-Attribute: occi.compute.speed=1
+X-OCCI-Attribute: occi.compute.state="active"
+Link: </network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14>;rel="http://schemas.ogf.org/occi/core#link";self="/link/networkinterface/920ad837-1fa3-40a2-8810-fb8f2dc1wrt7";category="http://schemas.ogf.org/occi/infrastructure#networkinterface";occi.core.id="920ad837-1fa3-40a2-8810-fb8f2dc1wrt7";occi.core.target="/network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14";occi.core.source="/compute/29b814ad-c5b2-4bc4-888b-470f769a2930"
\ No newline at end of file
--- /dev/null
+Category: compute;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";location="/compute/";title="compute resource"
+Category: sl6golden;scheme="http://occi.example.org/occi/infrastructure/os_tpl#";class="mixin";location="/mixin/os_tpl/sl6golden/";title="monitoring"
+Category: mammoth;scheme="http://occi.example.org/occi/infrastructure/resource_tpl#";class="mixin";location="/mixin/resource_tpl/mammoth/";title="Mammoth Instance - 8 cores and 32 GB RAM"
+X-OCCI-Attribute: occi.core.id="29ce3084-23b6-44e0-b53e-55a34b924920"
+X-OCCI-Attribute: occi.core.title="fhkgf"
+X-OCCI-Attribute: occi.compute.architecture="x64"
+X-OCCI-Attribute: occi.compute.cores=8
+X-OCCI-Attribute: occi.compute.memory=32
+X-OCCI-Attribute: occi.compute.speed=1
+X-OCCI-Attribute: occi.compute.state="active"
+X-OCCI-Attribute: eu.egi.fedcloud.appdb.uuid="appdb:uuid:sl6golden"
\ No newline at end of file
--- /dev/null
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/5537b49a-bb2e-4302-bf8b-da38611247ca
--- /dev/null
+Category: compute;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";location="/compute/";title="compute resource"
+Category: debian6;scheme="http://occi.example.org/occi/infrastructure/os_tpl#";class="mixin";location="/mixin/os_tpl/debian6/";title="debian"
+Category: small;scheme="http://occi.example.org/occi/infrastructure/resource_tpl#";class="mixin";location="/mixin/resource_tpl/small/";title="Small Instance - 1 core and 2 GB RAM"
+X-OCCI-Attribute: occi.core.id="987654321"
+X-OCCI-Attribute: occi.core.title="vm_test02"
+X-OCCI-Attribute: occi.compute.architecture="x86"
+X-OCCI-Attribute: occi.compute.cores=1
+X-OCCI-Attribute: occi.compute.hostname="vm_test02"
+X-OCCI-Attribute: occi.compute.memory=2
+X-OCCI-Attribute: occi.compute.speed=1
+X-OCCI-Attribute: occi.compute.state="active"
+Link: <http://rocci-server-1-1-x.herokuapp.com:80/network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14>;rel="http://schemas.ogf.org/occi/core#link";self="/link/networkinterface/e5f8f7bd-7d84-4c46-9a4e-325cc950f0ed";category="http://schemas.ogf.org/occi/infrastructure#networkinterface";occi.core.id="e5f8f7bd-7d84-4c46-9a4e-325cc950f0ed";occi.core.target="http://rocci-server-1-1-x.herokuapp.com:80/network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14";occi.core.source="http://rocci-server-1-1-x.herokuapp.com:80/compute/987654321"
\ No newline at end of file
--- /dev/null
+Category: compute;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";location="/compute/";title="compute resource"
+Category: debian6;scheme="http://occi.example.org/occi/infrastructure/os_tpl#";class="mixin";location="/mixin/os_tpl/debian6/";title="debian"
+Category: small;scheme="http://occi.example.org/occi/infrastructure/resource_tpl#";class="mixin";location="/mixin/resource_tpl/small/";title="Small Instance - 1 core and 2 GB RAM"
+X-OCCI-Attribute: occi.core.id="9b36c234-7e4a-400d-bab8-58dead9e0ef8"
+X-OCCI-Attribute: occi.core.title="VMTest"
+X-OCCI-Attribute: occi.compute.architecture="x86"
+X-OCCI-Attribute: occi.compute.cores=1
+X-OCCI-Attribute: occi.compute.hostname="VMTest"
+X-OCCI-Attribute: occi.compute.memory=2
+X-OCCI-Attribute: occi.compute.speed=1
+X-OCCI-Attribute: occi.compute.state="active"
+Link: </network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14>;rel="http://schemas.ogf.org/occi/core#link";self="/link/networkinterface/31f185d5-9379-4479-9809-b4cce6bcfdee";category="http://schemas.ogf.org/occi/infrastructure#networkinterface";occi.core.id="31f185d5-9379-4479-9809-b4cce6bcfdee";occi.core.target="/network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14";occi.core.source="/compute/9b36c234-7e4a-400d-bab8-58dead9e0ef8";occi.networkinterface.interface="eth0";occi.networkinterface.mac="00:11:22:33:44:55";occi.networkinterface.state="active"
\ No newline at end of file
--- /dev/null
+OK
\ No newline at end of file
--- /dev/null
+Category: network;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";location="/network/";title="network resource"
+X-OCCI-Attribute: occi.core.id="05940332-7926-4cf5-b1fc-7479b529524a"
+X-OCCI-Attribute: occi.network.state="inactive"
\ No newline at end of file
--- /dev/null
+Category: network;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";location="/network/";title="network resource"
+X-OCCI-Attribute: occi.core.id="1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619"
+X-OCCI-Attribute: occi.network.state="inactive"
\ No newline at end of file
--- /dev/null
+Category: network;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";location="/network/";title="network resource"
+X-OCCI-Attribute: occi.core.id="24b94558-c46a-41e3-981d-16600f71cddb"
+X-OCCI-Attribute: occi.network.state="inactive"
\ No newline at end of file
--- /dev/null
+Category: storage;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";location="/storage/";title="storage resource"
+X-OCCI-Attribute: occi.core.id="1902326a-2092-4cb6-b998-6d6e73be6212"
+X-OCCI-Attribute: occi.storage.state="offline"
\ No newline at end of file
--- /dev/null
+Category: storage;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";location="/storage/";title="storage resource"
+X-OCCI-Attribute: occi.core.id="8f423fd4-0fdb-4422-a01b-fb6594173fbb"
+X-OCCI-Attribute: occi.storage.state="offline"
\ No newline at end of file
--- /dev/null
+Category: storage;scheme="http://schemas.ogf.org/occi/infrastructure#";class="kind";location="/storage/";title="storage resource"
+X-OCCI-Attribute: occi.core.id="a7eeebf0-a93f-4187-bd86-dab2725d5bfa"
+X-OCCI-Attribute: occi.storage.state="offline"
\ No newline at end of file
--- /dev/null
+# Root logger option
+log4j.rootLogger=INFO, stdout
+
+# Redirect log messages to console
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
+
--- /dev/null
+{
+ "request" : {
+ "url" : "/",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-(root)-E94qA.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Location" : "http://rocci-server-1-1-x.herokuapp.com:80/compute/0054b25a-ddb9-412e-869e-7b800a13aa46,http://rocci-server-1-1-x.herokuapp.com:80/compute/29ce3084-23b6-44e0-b53e-55a34b924920,http://rocci-server-1-1-x.herokuapp.com:80/compute/987654321,http://rocci-server-1-1-x.herokuapp.com:80/compute/9b36c234-7e4a-400d-bab8-58dead9e0ef8,http://rocci-server-1-1-x.herokuapp.com:80/compute/29b814ad-c5b2-4bc4-888b-470f769a2930,http://rocci-server-1-1-x.herokuapp.com:80/compute/123456789,http://rocci-server-1-1-x.herokuapp.com:80/network/05940332-7926-4cf5-b1fc-7479b529524a,http://rocci-server-1-1-x.herokuapp.com:80/network/1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619,http://rocci-server-1-1-x.herokuapp.com:80/network/24b94558-c46a-41e3-981d-16600f71cddb,http://rocci-server-1-1-x.herokuapp.com:80/storage/8f423fd4-0fdb-4422-a01b-fb6594173fbb,http://rocci-server-1-1-x.herokuapp.com:80/storage/1902326a-2092-4cb6-b998-6d6e73be6212,http://rocci-server-1-1-x.herokuapp.com:80/storage/a7eeebf0-a93f-4187-bd86-dab2725d5bfa",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "8a4ba6f1-9bb6-4a1b-89fb-bc52787aae58",
+ "X-Runtime" : "0.600644",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:05:20 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-(root)-Gshly.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"132f9df32f84af7727f20a929cc4dfb2\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "5a7a37e1-d179-4e12-a291-59a967e517ef",
+ "X-Runtime" : "0.483129",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:21 GMT",
+ "Content-Length" : "1205",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/-/",
+ "method" : "HEAD",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body---KvCEW.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Category" : "entity;scheme=\"http://schemas.ogf.org/occi/core#\";class=\"kind\";title=\"entity\";location=\"/entity/\";attributes=\"occi.core.id{immutable required} occi.core.title\",resource;scheme=\"http://schemas.ogf.org/occi/core#\";class=\"kind\";title=\"resource\";rel=\"http://schemas.ogf.org/occi/core#entity\";location=\"/resource/\";attributes=\"occi.core.id{immutable required} occi.core.title occi.core.summary\",link;scheme=\"http://schemas.ogf.org/occi/core#\";class=\"kind\";title=\"link\";rel=\"http://schemas.ogf.org/occi/core#entity\";location=\"/link/\";attributes=\"occi.core.id{immutable required} occi.core.title occi.core.target occi.core.source{required}\",compute;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";title=\"compute resource\";rel=\"http://schemas.ogf.org/occi/core#resource\";location=\"/compute/\";attributes=\"occi.core.id{immutable required} occi.core.title occi.core.summary occi.compute.architecture occi.compute.cores occi.compute.hostname occi.compute.memory occi.compute.speed occi.compute.state{immutable}\";actions=\"http://schemas.ogf.org/occi/infrastructure/compute/action#start http://schemas.ogf.org/occi/infrastructure/compute/action#stop http://schemas.ogf.org/occi/infrastructure/compute/action#restart http://schemas.ogf.org/occi/infrastructure/compute/action#suspend\",storage;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";title=\"storage resource\";rel=\"http://schemas.ogf.org/occi/core#resource\";location=\"/storage/\";attributes=\"occi.core.id{immutable required} occi.core.title occi.core.summary occi.storage.size occi.storage.state\";actions=\"http://schemas.ogf.org/occi/infrastructure/storage/action#online http://schemas.ogf.org/occi/infrastructure/storage/action#offline http://schemas.ogf.org/occi/infrastructure/storage/action#backup http://schemas.ogf.org/occi/infrastructure/storage/action#snapshot http://schemas.ogf.org/occi/infrastructure/storage/action#resize\",network;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";title=\"network resource\";rel=\"http://schemas.ogf.org/occi/core#resource\";location=\"/network/\";attributes=\"occi.core.id{immutable required} occi.core.title occi.core.summary occi.network.vlan occi.network.label occi.network.state{immutable}\";actions=\"http://schemas.ogf.org/occi/infrastructure/network/action#up http://schemas.ogf.org/occi/infrastructure/network/action#down\",networkinterface;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";title=\"networkinterface link\";rel=\"http://schemas.ogf.org/occi/core#link\";location=\"/link/networkinterface/\";attributes=\"occi.core.id{immutable required} occi.core.title occi.core.target occi.core.source{required} occi.networkinterface.interface{immutable} occi.networkinterface.mac occi.networkinterface.state{immutable}\";actions=\"http://schemas.ogf.org/occi/infrastructure/networkinterface/action#up http://schemas.ogf.org/occi/infrastructure/networkinterface/action#down\",storagelink;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";title=\"storage link\";rel=\"http://schemas.ogf.org/occi/core#link\";location=\"/link/storagelink/\";attributes=\"occi.core.id{immutable required} occi.core.title occi.core.target occi.core.source{required} occi.storagelink.deviceid occi.storagelink.mountpoint occi.storagelink.state{immutable}\";actions=\"http://schemas.ogf.org/occi/infrastructure/storagelink/action#online http://schemas.ogf.org/occi/infrastructure/storagelink/action#offline\",resource_tpl;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"mixin\";title=\"resource template\";location=\"/mixin/resource_tpl/\",os_tpl;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"mixin\";title=\"operating system template\";location=\"/mixin/os_tpl/\",ipnetwork;scheme=\"http://schemas.ogf.org/occi/infrastructure/network#\";class=\"mixin\";title=\"IP network mixin\";location=\"/mixin/ipnetwork/\";attributes=\"occi.network.address occi.network.gateway occi.network.allocation\",ipnetworkinterface;scheme=\"http://schemas.ogf.org/occi/infrastructure/networkinterface#\";class=\"mixin\";title=\"IP network interface mixin\";location=\"/mixin/ipnetworkinterface/\";attributes=\"occi.networkinterface.address occi.networkinterface.gateway occi.networkinterface.allocation\",debian6;scheme=\"http://occi.example.org/occi/infrastructure/os_tpl#\";class=\"mixin\";title=\"debian\";rel=\"http://schemas.ogf.org/occi/infrastructure#os_tpl\";location=\"/mixin/os_tpl/debian6/\";attributes=\"eu.egi.fedcloud.appdb.uuid{immutable required}\",sl6golden;scheme=\"http://occi.example.org/occi/infrastructure/os_tpl#\";class=\"mixin\";title=\"monitoring\";rel=\"http://schemas.ogf.org/occi/infrastructure#os_tpl\";location=\"/mixin/os_tpl/sl6golden/\";attributes=\"eu.egi.fedcloud.appdb.uuid{immutable required}\",goliath;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";title=\"Goliath Instance - 16 cores and 64 GB RAM\";rel=\"http://schemas.ogf.org/occi/infrastructure#resource_tpl\";location=\"/mixin/resource_tpl/goliath/\";attributes=\"occi.compute.architecture{immutable} occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}\",mammoth;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";title=\"Mammoth Instance - 8 cores and 32 GB RAM\";rel=\"http://schemas.ogf.org/occi/infrastructure#resource_tpl\";location=\"/mixin/resource_tpl/mammoth/\";attributes=\"occi.compute.architecture{immutable} occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}\",extra_large;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";title=\"Extra Large Instance - 4 cores and 16 GB RAM\";rel=\"http://schemas.ogf.org/occi/infrastructure#resource_tpl\";location=\"/mixin/resource_tpl/extra_large/\";attributes=\"occi.compute.architecture{immutable} occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}\",large;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";title=\"Large Instance - 4 cores and 8 GB RAM\";rel=\"http://schemas.ogf.org/occi/infrastructure#resource_tpl\";location=\"/mixin/resource_tpl/large/\";attributes=\"occi.compute.architecture{immutable} occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}\",medium;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";title=\"Medium Instance - 2 cores and 4 GB RAM\";rel=\"http://schemas.ogf.org/occi/infrastructure#resource_tpl\";location=\"/mixin/resource_tpl/medium/\";attributes=\"occi.compute.architecture occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}\",small;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";title=\"Small Instance - 1 core and 2 GB RAM\";rel=\"http://schemas.ogf.org/occi/infrastructure#resource_tpl\";location=\"/mixin/resource_tpl/small/\";attributes=\"occi.compute.architecture occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}\",start;scheme=\"http://schemas.ogf.org/occi/infrastructure/compute/action#\";class=\"action\";title=\"start compute instance\",stop;scheme=\"http://schemas.ogf.org/occi/infrastructure/compute/action#\";class=\"action\";title=\"stop compute instance\",restart;scheme=\"http://schemas.ogf.org/occi/infrastructure/compute/action#\";class=\"action\";title=\"restart compute instance\",suspend;scheme=\"http://schemas.ogf.org/occi/infrastructure/compute/action#\";class=\"action\";title=\"suspend compute instance\",online;scheme=\"http://schemas.ogf.org/occi/infrastructure/storage/action#\";class=\"action\";title=\"activate storage\",offline;scheme=\"http://schemas.ogf.org/occi/infrastructure/storage/action#\";class=\"action\";title=\"deactivate storage\",backup;scheme=\"http://schemas.ogf.org/occi/infrastructure/storage/action#\";class=\"action\";title=\"backup storage\",snapshot;scheme=\"http://schemas.ogf.org/occi/infrastructure/storage/action#\";class=\"action\";title=\"snapshot storage\",resize;scheme=\"http://schemas.ogf.org/occi/infrastructure/storage/action#\";class=\"action\";title=\"resize storage\",up;scheme=\"http://schemas.ogf.org/occi/infrastructure/network/action#\";class=\"action\";title=\"activate network\",down;scheme=\"http://schemas.ogf.org/occi/infrastructure/network/action#\";class=\"action\";title=\"deactivate network\",up;scheme=\"http://schemas.ogf.org/occi/infrastructure/networkinterface/action#\";class=\"action\";title=\"activate networkinterface\",down;scheme=\"http://schemas.ogf.org/occi/infrastructure/networkinterface/action#\";class=\"action\";title=\"deactivate networkinterface\",online;scheme=\"http://schemas.ogf.org/occi/infrastructure/storagelink/action#\";class=\"action\";title=\"activate storagelink\",offline;scheme=\"http://schemas.ogf.org/occi/infrastructure/storagelink/action#\";class=\"action\";title=\"deactivate storagelink\"",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "23ac6670-d53f-4e43-8cd2-2ebc1ff5f24e",
+ "X-Runtime" : "0.296923",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:11:22 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/-/",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body---crGY7.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Category" : "entity;scheme=\"http://schemas.ogf.org/occi/core#\";class=\"kind\";title=\"entity\";location=\"/entity/\";attributes=\"occi.core.id{immutable required} occi.core.title\",resource;scheme=\"http://schemas.ogf.org/occi/core#\";class=\"kind\";title=\"resource\";rel=\"http://schemas.ogf.org/occi/core#entity\";location=\"/resource/\";attributes=\"occi.core.id{immutable required} occi.core.title occi.core.summary\",link;scheme=\"http://schemas.ogf.org/occi/core#\";class=\"kind\";title=\"link\";rel=\"http://schemas.ogf.org/occi/core#entity\";location=\"/link/\";attributes=\"occi.core.id{immutable required} occi.core.title occi.core.target occi.core.source{required}\",compute;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";title=\"compute resource\";rel=\"http://schemas.ogf.org/occi/core#resource\";location=\"/compute/\";attributes=\"occi.core.id{immutable required} occi.core.title occi.core.summary occi.compute.architecture occi.compute.cores occi.compute.hostname occi.compute.memory occi.compute.speed occi.compute.state{immutable}\";actions=\"http://schemas.ogf.org/occi/infrastructure/compute/action#start http://schemas.ogf.org/occi/infrastructure/compute/action#stop http://schemas.ogf.org/occi/infrastructure/compute/action#restart http://schemas.ogf.org/occi/infrastructure/compute/action#suspend\",storage;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";title=\"storage resource\";rel=\"http://schemas.ogf.org/occi/core#resource\";location=\"/storage/\";attributes=\"occi.core.id{immutable required} occi.core.title occi.core.summary occi.storage.size occi.storage.state\";actions=\"http://schemas.ogf.org/occi/infrastructure/storage/action#online http://schemas.ogf.org/occi/infrastructure/storage/action#offline http://schemas.ogf.org/occi/infrastructure/storage/action#backup http://schemas.ogf.org/occi/infrastructure/storage/action#snapshot http://schemas.ogf.org/occi/infrastructure/storage/action#resize\",network;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";title=\"network resource\";rel=\"http://schemas.ogf.org/occi/core#resource\";location=\"/network/\";attributes=\"occi.core.id{immutable required} occi.core.title occi.core.summary occi.network.vlan occi.network.label occi.network.state{immutable}\";actions=\"http://schemas.ogf.org/occi/infrastructure/network/action#up http://schemas.ogf.org/occi/infrastructure/network/action#down\",networkinterface;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";title=\"networkinterface link\";rel=\"http://schemas.ogf.org/occi/core#link\";location=\"/link/networkinterface/\";attributes=\"occi.core.id{immutable required} occi.core.title occi.core.target occi.core.source{required} occi.networkinterface.interface{immutable} occi.networkinterface.mac occi.networkinterface.state{immutable}\";actions=\"http://schemas.ogf.org/occi/infrastructure/networkinterface/action#up http://schemas.ogf.org/occi/infrastructure/networkinterface/action#down\",storagelink;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";title=\"storage link\";rel=\"http://schemas.ogf.org/occi/core#link\";location=\"/link/storagelink/\";attributes=\"occi.core.id{immutable required} occi.core.title occi.core.target occi.core.source{required} occi.storagelink.deviceid occi.storagelink.mountpoint occi.storagelink.state{immutable}\";actions=\"http://schemas.ogf.org/occi/infrastructure/storagelink/action#online http://schemas.ogf.org/occi/infrastructure/storagelink/action#offline\",resource_tpl;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"mixin\";title=\"resource template\";location=\"/mixin/resource_tpl/\",os_tpl;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"mixin\";title=\"operating system template\";location=\"/mixin/os_tpl/\",ipnetwork;scheme=\"http://schemas.ogf.org/occi/infrastructure/network#\";class=\"mixin\";title=\"IP network mixin\";location=\"/mixin/ipnetwork/\";attributes=\"occi.network.address occi.network.gateway occi.network.allocation\",ipnetworkinterface;scheme=\"http://schemas.ogf.org/occi/infrastructure/networkinterface#\";class=\"mixin\";title=\"IP network interface mixin\";location=\"/mixin/ipnetworkinterface/\";attributes=\"occi.networkinterface.address occi.networkinterface.gateway occi.networkinterface.allocation\",debian6;scheme=\"http://occi.example.org/occi/infrastructure/os_tpl#\";class=\"mixin\";title=\"debian\";rel=\"http://schemas.ogf.org/occi/infrastructure#os_tpl\";location=\"/mixin/os_tpl/debian6/\";attributes=\"eu.egi.fedcloud.appdb.uuid{immutable required}\",sl6golden;scheme=\"http://occi.example.org/occi/infrastructure/os_tpl#\";class=\"mixin\";title=\"monitoring\";rel=\"http://schemas.ogf.org/occi/infrastructure#os_tpl\";location=\"/mixin/os_tpl/sl6golden/\";attributes=\"eu.egi.fedcloud.appdb.uuid{immutable required}\",goliath;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";title=\"Goliath Instance - 16 cores and 64 GB RAM\";rel=\"http://schemas.ogf.org/occi/infrastructure#resource_tpl\";location=\"/mixin/resource_tpl/goliath/\";attributes=\"occi.compute.architecture{immutable} occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}\",mammoth;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";title=\"Mammoth Instance - 8 cores and 32 GB RAM\";rel=\"http://schemas.ogf.org/occi/infrastructure#resource_tpl\";location=\"/mixin/resource_tpl/mammoth/\";attributes=\"occi.compute.architecture{immutable} occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}\",extra_large;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";title=\"Extra Large Instance - 4 cores and 16 GB RAM\";rel=\"http://schemas.ogf.org/occi/infrastructure#resource_tpl\";location=\"/mixin/resource_tpl/extra_large/\";attributes=\"occi.compute.architecture{immutable} occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}\",large;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";title=\"Large Instance - 4 cores and 8 GB RAM\";rel=\"http://schemas.ogf.org/occi/infrastructure#resource_tpl\";location=\"/mixin/resource_tpl/large/\";attributes=\"occi.compute.architecture{immutable} occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}\",medium;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";title=\"Medium Instance - 2 cores and 4 GB RAM\";rel=\"http://schemas.ogf.org/occi/infrastructure#resource_tpl\";location=\"/mixin/resource_tpl/medium/\";attributes=\"occi.compute.architecture occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}\",small;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";title=\"Small Instance - 1 core and 2 GB RAM\";rel=\"http://schemas.ogf.org/occi/infrastructure#resource_tpl\";location=\"/mixin/resource_tpl/small/\";attributes=\"occi.compute.architecture occi.compute.cores{immutable} occi.compute.speed{immutable} occi.compute.memory{immutable}\",start;scheme=\"http://schemas.ogf.org/occi/infrastructure/compute/action#\";class=\"action\";title=\"start compute instance\",stop;scheme=\"http://schemas.ogf.org/occi/infrastructure/compute/action#\";class=\"action\";title=\"stop compute instance\",restart;scheme=\"http://schemas.ogf.org/occi/infrastructure/compute/action#\";class=\"action\";title=\"restart compute instance\",suspend;scheme=\"http://schemas.ogf.org/occi/infrastructure/compute/action#\";class=\"action\";title=\"suspend compute instance\",online;scheme=\"http://schemas.ogf.org/occi/infrastructure/storage/action#\";class=\"action\";title=\"activate storage\",offline;scheme=\"http://schemas.ogf.org/occi/infrastructure/storage/action#\";class=\"action\";title=\"deactivate storage\",backup;scheme=\"http://schemas.ogf.org/occi/infrastructure/storage/action#\";class=\"action\";title=\"backup storage\",snapshot;scheme=\"http://schemas.ogf.org/occi/infrastructure/storage/action#\";class=\"action\";title=\"snapshot storage\",resize;scheme=\"http://schemas.ogf.org/occi/infrastructure/storage/action#\";class=\"action\";title=\"resize storage\",up;scheme=\"http://schemas.ogf.org/occi/infrastructure/network/action#\";class=\"action\";title=\"activate network\",down;scheme=\"http://schemas.ogf.org/occi/infrastructure/network/action#\";class=\"action\";title=\"deactivate network\",up;scheme=\"http://schemas.ogf.org/occi/infrastructure/networkinterface/action#\";class=\"action\";title=\"activate networkinterface\",down;scheme=\"http://schemas.ogf.org/occi/infrastructure/networkinterface/action#\";class=\"action\";title=\"deactivate networkinterface\",online;scheme=\"http://schemas.ogf.org/occi/infrastructure/storagelink/action#\";class=\"action\";title=\"activate storagelink\",offline;scheme=\"http://schemas.ogf.org/occi/infrastructure/storagelink/action#\";class=\"action\";title=\"deactivate storagelink\"",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "23ac6670-d53f-4e43-8cd2-2ebc1ff5f24e",
+ "X-Runtime" : "0.296923",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:11:22 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
--- /dev/null
+{
+ "request" : {
+ "url" : "/-/",
+ "method" : "HEAD",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body---lLtvH.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"bc0008dd6f5d47c9920e541d863366a3\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "5e8d4d72-b137-4879-95f1-cb9f569b978c",
+ "X-Runtime" : "0.293953",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:20 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/-/",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body---xaO7k.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"bc0008dd6f5d47c9920e541d863366a3\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "25ecea6a-bbf7-4490-97da-026512db6674",
+ "X-Runtime" : "0.308337",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:20 GMT",
+ "Content-Length" : "9204",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/0054b25a-ddb9-412e-869e-7b800a13aa46",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-0054b25a-ddb9-412e-869e-7b800a13aa46-BzixR.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Category" : "compute;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";location=\"/compute/\";title=\"compute resource\",debian6;scheme=\"http://occi.example.org/occi/infrastructure/os_tpl#\";class=\"mixin\";location=\"/mixin/os_tpl/debian6/\";title=\"debian\",small;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";location=\"/mixin/resource_tpl/small/\";title=\"Small Instance - 1 core and 2 GB RAM\"",
+ "X-Occi-Attribute" : "occi.core.id=\"0054b25a-ddb9-412e-869e-7b800a13aa46\",occi.core.title=\"test_title\",occi.compute.architecture=\"x86\",occi.compute.cores=1,occi.compute.memory=2,occi.compute.speed=1,occi.compute.state=\"active\",eu.egi.fedcloud.appdb.uuid=\"appdb:uuid:debian6\"",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "030003f0-6fb6-47a2-8d1f-a4f2aa75a042",
+ "X-Runtime" : "0.528609",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:05:23 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/0054b25a-ddb9-412e-869e-7b800a13aa46",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-0054b25a-ddb9-412e-869e-7b800a13aa46-xAARc.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"86f5a67710c3bad29b5bbf3640a3eb86\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "99390bbd-ac0b-4261-8aaa-c81ea3b1b66c",
+ "X-Runtime" : "0.543592",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:24 GMT",
+ "Content-Length" : "848",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/",
+ "method" : "POST",
+ "bodyPatterns" : [ {
+ "equalTo" : "Category: compute;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\"\nCategory: debian6;scheme=\"http://occi.example.org/occi/infrastructure/os_tpl#\";class=\"mixin\"\nCategory: small;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\"\nX-OCCI-Attribute: occi.core.id=\"157754bb-af01-40be-853a-6a1f1b5ac500\""
+ } ],
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 201,
+ "bodyFileName" : "body-compute-04cby.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"62cb748543771cffda40eefb5da68908\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "00e62bf2-4969-45ad-9066-f0eba14d7c2d",
+ "X-Runtime" : "0.960055",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:54 GMT",
+ "Content-Length" : "104",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-0P01F.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"caa5c2bd701e64535813367c279f3557\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "cec660f0-0d7d-4063-8ac4-31393da6d5d2",
+ "X-Runtime" : "0.524701",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:22 GMT",
+ "Content-Length" : "575",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/123456789",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-123456789-9rQpm.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Category" : "compute;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";location=\"/compute/\";title=\"compute resource\",debian6;scheme=\"http://occi.example.org/occi/infrastructure/os_tpl#\";class=\"mixin\";location=\"/mixin/os_tpl/debian6/\";title=\"debian\",small;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";location=\"/mixin/resource_tpl/small/\";title=\"Small Instance - 1 core and 2 GB RAM\"",
+ "X-Occi-Attribute" : "occi.core.id=\"123456789\",occi.core.title=\"vm_test01\",occi.compute.architecture=\"x86\",occi.compute.cores=1,occi.compute.hostname=\"vm_test01\",occi.compute.memory=2,occi.compute.speed=1,occi.compute.state=\"active\"",
+ "Link" : "</network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14>;rel=\"http://schemas.ogf.org/occi/core#link\";self=\"/link/networkinterface/9e9aced1-a2a8-459e-8fc8-690beb3f1533\";category=\"http://schemas.ogf.org/occi/infrastructure#networkinterface\";occi.core.id=\"9e9aced1-a2a8-459e-8fc8-690beb3f1533\";occi.core.target=\"/network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14\";occi.core.source=\"/compute/123456789\";occi.networkinterface.interface=\"eth0\";occi.networkinterface.mac=\"00:11:22:33:44:55\";occi.networkinterface.state=\"active\"",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "131ded70-d45f-4e25-a787-cb20c2cbdb02",
+ "X-Runtime" : "0.471766",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:05:27 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/123456789",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-123456789-Ibs9H.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"680ddc890c6f4fad4b1f6f59901a26df\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "3be70369-52a6-4653-9dd6-9fada62794be",
+ "X-Runtime" : "0.367248",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:27 GMT",
+ "Content-Length" : "1319",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/157754bb-af01-40be-853a-6a1f1b5ac500",
+ "method" : "PUT",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-157754bb-af01-40be-853a-6a1f1b5ac500-vGYhq.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"62cb748543771cffda40eefb5da68908\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "00e62bf2-4969-45ad-9066-f0eba14d7c2d",
+ "X-Runtime" : "0.960055",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:54 GMT",
+ "Content-Length" : "104",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/157754bb-af01-40be-853a-6a1f1b5ac500",
+ "method" : "DELETE",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-157754bb-af01-40be-853a-6a1f1b5ac500-vGYhr.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "fd30f963-d880-4151-9d89-a01061dcb605",
+ "X-Runtime" : "1.058328",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:56 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/29b814ad-c5b2-4bc4-888b-470f769a2930?action=start",
+ "method" : "POST",
+ "bodyPatterns" : [ {
+ "equalTo" : "Category: start;scheme=\"http://schemas.ogf.org/occi/infrastructure/compute/action#\";class=\"action\";title=\"start compute instance\";"
+ } ],
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-5oA1q.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "b72f4e4a-c409-4793-bd82-a41d570f2a46",
+ "X-Runtime" : "1.824386",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:58:43 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/29b814ad-c5b2-4bc4-888b-470f769a2930?action=start",
+ "method" : "POST",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ },
+ "Category" : {
+ "equalTo" : "start;scheme=\"http://schemas.ogf.org/occi/infrastructure/compute/action#\";class=\"action\";title=\"start compute instance\";"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-XStRo.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "534eeb75-9d4e-45c4-b826-e7a80c606feb",
+ "X-Runtime" : "1.583949",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:06:52 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/29b814ad-c5b2-4bc4-888b-470f769a2930",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-puPyB.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Category" : "compute;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";location=\"/compute/\";title=\"compute resource\",debian6;scheme=\"http://occi.example.org/occi/infrastructure/os_tpl#\";class=\"mixin\";location=\"/mixin/os_tpl/debian6/\";title=\"debian\",small;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";location=\"/mixin/resource_tpl/small/\";title=\"Small Instance - 1 core and 2 GB RAM\"",
+ "X-Occi-Attribute" : "occi.core.id=\"29b814ad-c5b2-4bc4-888b-470f769a2930\",occi.core.title=\"VMTest2\",occi.compute.architecture=\"x86\",occi.compute.cores=1,occi.compute.hostname=\"VMTest2\",occi.compute.memory=2,occi.compute.speed=1,occi.compute.state=\"active\"",
+ "Link" : "</network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14>;rel=\"http://schemas.ogf.org/occi/core#link\";self=\"/link/networkinterface/920ad837-1fa3-40a2-8810-fb8f2dc1wrt7\";category=\"http://schemas.ogf.org/occi/infrastructure#networkinterface\";occi.core.id=\"920ad837-1fa3-40a2-8810-fb8f2dc1wrt7\";occi.core.target=\"/network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14\";occi.core.source=\"/compute/29b814ad-c5b2-4bc4-888b-470f769a2930\"",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "f411697f-2934-42fc-a2bf-812e19647d12",
+ "X-Runtime" : "0.567034",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:05:27 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/29b814ad-c5b2-4bc4-888b-470f769a2930",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-uJec6.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"5c3498edec928219441bdc3bc565c14f\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "994fe98a-7885-4c4c-9670-692fcb2b2be9",
+ "X-Runtime" : "0.436634",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:26 GMT",
+ "Content-Length" : "1247",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/29ce3084-23b6-44e0-b53e-55a34b924920",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-29ce3084-23b6-44e0-b53e-55a34b924920-88kQ3.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Category" : "compute;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";location=\"/compute/\";title=\"compute resource\",sl6golden;scheme=\"http://occi.example.org/occi/infrastructure/os_tpl#\";class=\"mixin\";location=\"/mixin/os_tpl/sl6golden/\";title=\"monitoring\",mammoth;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";location=\"/mixin/resource_tpl/mammoth/\";title=\"Mammoth Instance - 8 cores and 32 GB RAM\"",
+ "X-Occi-Attribute" : "occi.core.id=\"29ce3084-23b6-44e0-b53e-55a34b924920\",occi.core.title=\"fhkgf\",occi.compute.architecture=\"x64\",occi.compute.cores=8,occi.compute.memory=32,occi.compute.speed=1,occi.compute.state=\"active\",eu.egi.fedcloud.appdb.uuid=\"appdb:uuid:sl6golden\"",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "3dfcfb19-048e-40ec-a1ac-050406ab21fa",
+ "X-Runtime" : "0.696259",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:05:24 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/29ce3084-23b6-44e0-b53e-55a34b924920",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-29ce3084-23b6-44e0-b53e-55a34b924920-NMuFo.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"27a56e1fb13da66d889e8fc4e050ff04\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "e7b147bd-bbb0-4b39-a2fa-434b4e347477",
+ "X-Runtime" : "0.352273",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:24 GMT",
+ "Content-Length" : "862",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/5537b49a-bb2e-4302-bf8b-da38611247ca",
+ "method" : "PUT",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-5537b49a-bb2e-4302-bf8b-da38611247ca-dbOPq.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"62cb748543771cffda40eefb5da68908\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "00e62bf2-4969-45ad-9066-f0eba14d7c2d",
+ "X-Runtime" : "0.960055",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:54 GMT",
+ "Content-Length" : "104",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/5537b49a-bb2e-4302-bf8b-da38611247ca",
+ "method" : "DELETE",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-5537b49a-bb2e-4302-bf8b-da38611247ca-dbOPy.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "72f8dbf8-b3da-424a-b77f-3d8744513470",
+ "X-Runtime" : "0.990166",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:06:04 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/987654321",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-987654321-9r3vy.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"4e4a7128e211b48263a6aca4b00da476\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "cc7ae28c-fed1-46fd-9bf6-f6a3a2794f58",
+ "X-Runtime" : "0.540705",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:25 GMT",
+ "Content-Length" : "1323",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/987654321",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-987654321-i3STU.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Category" : "compute;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";location=\"/compute/\";title=\"compute resource\",debian6;scheme=\"http://occi.example.org/occi/infrastructure/os_tpl#\";class=\"mixin\";location=\"/mixin/os_tpl/debian6/\";title=\"debian\",small;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";location=\"/mixin/resource_tpl/small/\";title=\"Small Instance - 1 core and 2 GB RAM\"",
+ "X-Occi-Attribute" : "occi.core.id=\"987654321\",occi.core.title=\"vm_test02\",occi.compute.architecture=\"x86\",occi.compute.cores=1,occi.compute.hostname=\"vm_test02\",occi.compute.memory=2,occi.compute.speed=1,occi.compute.state=\"active\"",
+ "Link" : "<http://rocci-server-1-1-x.herokuapp.com:80/network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14>;rel=\"http://schemas.ogf.org/occi/core#link\";self=\"/link/networkinterface/e5f8f7bd-7d84-4c46-9a4e-325cc950f0ed\";category=\"http://schemas.ogf.org/occi/infrastructure#networkinterface\";occi.core.id=\"e5f8f7bd-7d84-4c46-9a4e-325cc950f0ed\";occi.core.target=\"http://rocci-server-1-1-x.herokuapp.com:80/network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14\";occi.core.source=\"http://rocci-server-1-1-x.herokuapp.com:80/compute/987654321\"",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "ac6789cf-a232-4d93-a5b1-83669c1f727b",
+ "X-Runtime" : "0.641783",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:05:25 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/9b36c234-7e4a-400d-bab8-58dead9e0ef8",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-9b36c234-7e4a-400d-bab8-58dead9e0ef8-H43R7.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Category" : "compute;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";location=\"/compute/\";title=\"compute resource\",debian6;scheme=\"http://occi.example.org/occi/infrastructure/os_tpl#\";class=\"mixin\";location=\"/mixin/os_tpl/debian6/\";title=\"debian\",small;scheme=\"http://occi.example.org/occi/infrastructure/resource_tpl#\";class=\"mixin\";location=\"/mixin/resource_tpl/small/\";title=\"Small Instance - 1 core and 2 GB RAM\"",
+ "X-Occi-Attribute" : "occi.core.id=\"9b36c234-7e4a-400d-bab8-58dead9e0ef8\",occi.core.title=\"VMTest\",occi.compute.architecture=\"x86\",occi.compute.cores=1,occi.compute.hostname=\"VMTest\",occi.compute.memory=2,occi.compute.speed=1,occi.compute.state=\"active\"",
+ "Link" : "</network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14>;rel=\"http://schemas.ogf.org/occi/core#link\";self=\"/link/networkinterface/31f185d5-9379-4479-9809-b4cce6bcfdee\";category=\"http://schemas.ogf.org/occi/infrastructure#networkinterface\";occi.core.id=\"31f185d5-9379-4479-9809-b4cce6bcfdee\";occi.core.target=\"/network/e36ee51c-bfb6-4264-a5bf-2e71b9145b14\";occi.core.source=\"/compute/9b36c234-7e4a-400d-bab8-58dead9e0ef8\";occi.networkinterface.interface=\"eth0\";occi.networkinterface.mac=\"00:11:22:33:44:55\";occi.networkinterface.state=\"active\"",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "8174db1f-b4d5-4823-b085-f4227a21b1f2",
+ "X-Runtime" : "1.078980",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:05:26 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/9b36c234-7e4a-400d-bab8-58dead9e0ef8",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-9b36c234-7e4a-400d-bab8-58dead9e0ef8-hCQg9.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"14850def0bf74261d2b505d7d2812f40\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "0f3d98e8-1298-4c2f-83b9-cfa713d11a10",
+ "X-Runtime" : "0.438533",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:25 GMT",
+ "Content-Length" : "1367",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/?action=start",
+ "method" : "POST",
+ "bodyPatterns" : [ {
+ "equalTo" : "Category: start;scheme=\"http://schemas.ogf.org/occi/infrastructure/compute/action#\";class=\"action\";title=\"start compute instance\";"
+ } ],
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-NiEMH.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "ffc26f39-b019-4984-9fbc-f9cbda3f2963",
+ "X-Runtime" : "22.703227",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:58:18 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-SSKim.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Location" : "http://rocci-server-1-1-x.herokuapp.com:80/compute/0054b25a-ddb9-412e-869e-7b800a13aa46,http://rocci-server-1-1-x.herokuapp.com:80/compute/29ce3084-23b6-44e0-b53e-55a34b924920,http://rocci-server-1-1-x.herokuapp.com:80/compute/987654321,http://rocci-server-1-1-x.herokuapp.com:80/compute/9b36c234-7e4a-400d-bab8-58dead9e0ef8,http://rocci-server-1-1-x.herokuapp.com:80/compute/29b814ad-c5b2-4bc4-888b-470f769a2930,http://rocci-server-1-1-x.herokuapp.com:80/compute/123456789",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "28b0f1ae-d66b-4cb2-bd43-ba42e9b8069b",
+ "X-Runtime" : "0.454154",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:05:21 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/?action=start",
+ "method" : "POST",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ },
+ "Category" : {
+ "equalTo" : "start;scheme=\"http://schemas.ogf.org/occi/infrastructure/compute/action#\";class=\"action\";title=\"start compute instance\";"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-compute-XyVfC.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "485966dc-b448-4503-b638-0d3268d06114",
+ "X-Runtime" : "23.324720",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:06:27 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/compute/",
+ "method" : "POST",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ },
+ "X-occi-attribute" : {
+ "equalTo" : "occi.core.id=\"5537b49a-bb2e-4302-bf8b-da38611247ca\""
+ },
+ "Category" : {
+ "equalTo" : "compute;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\""
+ }
+ }
+ },
+ "response" : {
+ "status" : 201,
+ "bodyFileName" : "body-compute-sp6h4.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Location" : "http://rocci-server-1-1-x.herokuapp.com/compute/5537b49a-bb2e-4302-bf8b-da38611247ca",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Etag" : "\"e0aa021e21dddbd6d8cecec71e9cf564\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "f852c03f-c126-40cb-a4e1-fcb20014ffb9",
+ "X-Runtime" : "1.462187",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:06:01 GMT",
+ "Content-Length" : "2",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/differentcode/",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 202,
+ "bodyFileName" : "body-differentcode-setN7.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"bc0008dd6f5d47c9920e541d863366a3\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "ac049323-b17b-4f59-a586-364e14174418",
+ "X-Runtime" : "0.224121",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Mon, 16 Feb 2015 14:56:54 GMT",
+ "Content-Length" : "9204",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/network/05940332-7926-4cf5-b1fc-7479b529524a",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-network-05940332-7926-4cf5-b1fc-7479b529524a-Afwh7.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"6687c39b014cb3f76458a8b9e64c302f\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "4a0566a6-b1ba-4b67-a67d-4dc32267b55d",
+ "X-Runtime" : "0.268990",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:32 GMT",
+ "Content-Length" : "247",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/network/05940332-7926-4cf5-b1fc-7479b529524a",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-network-05940332-7926-4cf5-b1fc-7479b529524a-JM2hP.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Category" : "network;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";location=\"/network/\";title=\"network resource\"",
+ "X-Occi-Attribute" : "occi.core.id=\"05940332-7926-4cf5-b1fc-7479b529524a\",occi.network.state=\"inactive\"",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "f79ce6d1-8495-4d9a-bf39-9fdd2f9531e3",
+ "X-Runtime" : "0.336790",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:05:34 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/network/",
+ "method" : "DELETE",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-network-0ZkNd.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "837b691a-9c72-4a15-80cb-6d31a53e0632",
+ "X-Runtime" : "0.456651",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:06:02 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/network/1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-network-1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619-hzqeF.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"cf86aa8f600c995a492daa317831b324\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "b3840859-c086-4b4b-a4bb-f95006cd71e3",
+ "X-Runtime" : "0.245372",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:32 GMT",
+ "Content-Length" : "247",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/network/1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-network-1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619-qjnCY.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Category" : "network;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";location=\"/network/\";title=\"network resource\"",
+ "X-Occi-Attribute" : "occi.core.id=\"1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619\",occi.network.state=\"inactive\"",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "0b520dc0-e35d-4361-bee3-aadc95fb489c",
+ "X-Runtime" : "0.561691",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:05:35 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/network/24b94558-c46a-41e3-981d-16600f71cddb",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-network-24b94558-c46a-41e3-981d-16600f71cddb-61PLg.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Category" : "network;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";location=\"/network/\";title=\"network resource\"",
+ "X-Occi-Attribute" : "occi.core.id=\"24b94558-c46a-41e3-981d-16600f71cddb\",occi.network.state=\"inactive\"",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "235dab6c-3c1a-4f0c-ad68-44665b9e85a2",
+ "X-Runtime" : "0.462286",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:05:34 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/network/24b94558-c46a-41e3-981d-16600f71cddb",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-network-24b94558-c46a-41e3-981d-16600f71cddb-OL4Ab.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"577516f0cba12577bfd1ddc6039b46de\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "094cab50-6344-439c-8dc6-118b4478e3d5",
+ "X-Runtime" : "0.248099",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:33 GMT",
+ "Content-Length" : "247",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/network/",
+ "method" : "DELETE",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-network-Tkd5S.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "87e181ea-6988-4ff5-b115-98db5f0f9895",
+ "X-Runtime" : "0.224711",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:54 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/storage/1902326a-2092-4cb6-b998-6d6e73be6212",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-storage-1902326a-2092-4cb6-b998-6d6e73be6212-B8aRd.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"f2e7f49e58aee5803c0f680c9b9071fb\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "26884831-fbe1-49ed-8b1e-de46d034724f",
+ "X-Runtime" : "0.289782",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:33 GMT",
+ "Content-Length" : "246",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/storage/1902326a-2092-4cb6-b998-6d6e73be6212",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-storage-1902326a-2092-4cb6-b998-6d6e73be6212-naAXd.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Category" : "storage;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";location=\"/storage/\";title=\"storage resource\"",
+ "X-Occi-Attribute" : "occi.core.id=\"1902326a-2092-4cb6-b998-6d6e73be6212\",occi.storage.state=\"offline\"",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "1f4fa81c-3b83-4a24-a2ca-791462d65ae5",
+ "X-Runtime" : "0.437640",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:05:37 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/storage/",
+ "method" : "DELETE",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-storage-3DT6z.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "8646cdb3-0ee9-47b3-9cab-bfff18ce0ff0",
+ "X-Runtime" : "0.254896",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:54 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/storage/8f423fd4-0fdb-4422-a01b-fb6594173fbb",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-storage-8f423fd4-0fdb-4422-a01b-fb6594173fbb-b6DVv.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Category" : "storage;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";location=\"/storage/\";title=\"storage resource\"",
+ "X-Occi-Attribute" : "occi.core.id=\"8f423fd4-0fdb-4422-a01b-fb6594173fbb\",occi.storage.state=\"offline\"",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "0089a5e0-f57d-4426-9ef8-e008a4e2f4de",
+ "X-Runtime" : "0.479163",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:05:36 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/storage/8f423fd4-0fdb-4422-a01b-fb6594173fbb",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-storage-8f423fd4-0fdb-4422-a01b-fb6594173fbb-uPiUB.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"8b54581448175d04004acff7b9579b44\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "6a8a5b9f-39f5-4487-bcaa-e80fe175982c",
+ "X-Runtime" : "0.244130",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:33 GMT",
+ "Content-Length" : "246",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/storage/a7eeebf0-a93f-4187-bd86-dab2725d5bfa",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-storage-a7eeebf0-a93f-4187-bd86-dab2725d5bfa-M22T3.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Category" : "storage;scheme=\"http://schemas.ogf.org/occi/infrastructure#\";class=\"kind\";location=\"/storage/\";title=\"storage resource\"",
+ "X-Occi-Attribute" : "occi.core.id=\"a7eeebf0-a93f-4187-bd86-dab2725d5bfa\",occi.storage.state=\"offline\"",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "c1b3d5a2-a257-4fd8-9197-e00e7584f75e",
+ "X-Runtime" : "0.432960",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:05:36 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/storage/a7eeebf0-a93f-4187-bd86-dab2725d5bfa",
+ "method" : "GET",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/plain"
+ },
+ "Accept" : {
+ "equalTo" : "text/plain"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-storage-a7eeebf0-a93f-4187-bd86-dab2725d5bfa-MGDwo.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/plain; charset=utf-8",
+ "Etag" : "\"6845923790f239556c70518d828a1853\"",
+ "Cache-Control" : "max-age=0, private, must-revalidate",
+ "X-Request-Id" : "a0c35e5f-60af-4d44-bddf-4d1df3581c3a",
+ "X-Runtime" : "0.249227",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 08:57:34 GMT",
+ "Content-Length" : "246",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "request" : {
+ "url" : "/storage/",
+ "method" : "DELETE",
+ "headers" : {
+ "Content-Type" : {
+ "equalTo" : "text/occi"
+ },
+ "Accept" : {
+ "equalTo" : "text/occi"
+ }
+ }
+ },
+ "response" : {
+ "status" : 200,
+ "bodyFileName" : "body-storage-dpXcr.json",
+ "headers" : {
+ "Connection" : "keep-alive",
+ "X-Frame-Options" : "SAMEORIGIN",
+ "X-Xss-Protection" : "1; mode=block",
+ "X-Content-Type-Options" : "nosniff",
+ "Content-Type" : "text/occi; charset=utf-8",
+ "Cache-Control" : "no-cache",
+ "X-Request-Id" : "acc60993-f723-4d90-a1ca-2f9707c902dd",
+ "X-Runtime" : "0.484805",
+ "Server" : "WEBrick/1.3.1 (Ruby/2.0.0/2014-09-19)",
+ "Date" : "Thu, 19 Feb 2015 09:06:03 GMT",
+ "Content-Length" : "0",
+ "Via" : "1.1 vegur"
+ }
+ }
+}
\ No newline at end of file