jOCCI-api: original sources
authorFrantišek Dvořák <valtri@civ.zcu.cz>
Tue, 1 Nov 2016 14:16:47 +0000 (15:16 +0100)
committerFrantišek Dvořák <valtri@civ.zcu.cz>
Tue, 1 Nov 2016 14:16:47 +0000 (15:16 +0100)
128 files changed:
jOCCI-api/.gitignore [new file with mode: 0644]
jOCCI-api/.travis.yml [new file with mode: 0644]
jOCCI-api/LICENSE [new file with mode: 0644]
jOCCI-api/README.md [new file with mode: 0644]
jOCCI-api/pom.xml [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/Authentication.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/Client.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/EntityBuilder.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/AdvancedUsageExample.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/BasicAuthenticationExample.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/DigestAuthenticationExample.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/SimpleUsageExample.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/VOMSAuthenticationExample.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/X509AuthenticationExample.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/exception/AuthenticationException.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/exception/CommunicationException.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/exception/EntityBuildingException.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/HTTPClient.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/HTTPConnection.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/HTTPHelper.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/BasicAuthentication.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/CertificateAuthentication.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/DigestAuthentication.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/HTTPAuthentication.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/KeystoneAuthentication.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/NoAuthentication.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/VOMSAuthentication.java [new file with mode: 0644]
jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/X509Authentication.java [new file with mode: 0644]
jOCCI-api/src/test/java/cz/cesnet/cloud/occi/DataGenerator.java [new file with mode: 0644]
jOCCI-api/src/test/java/cz/cesnet/cloud/occi/api/EntityBuilderTest.java [new file with mode: 0644]
jOCCI-api/src/test/java/cz/cesnet/cloud/occi/api/http/HTTPClientTest.java [new file with mode: 0644]
jOCCI-api/src/test/java/cz/cesnet/cloud/occi/api/http/HTTPConnectionTest.java [new file with mode: 0644]
jOCCI-api/src/test/java/cz/cesnet/cloud/occi/api/http/HTTPHelperTest.java [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-(root)-E94qA.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-(root)-Gshly.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body---KvCEW.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body---crGY7.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body---lLtvH.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body---xaO7k.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-0054b25a-ddb9-412e-869e-7b800a13aa46-BzixR.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-0054b25a-ddb9-412e-869e-7b800a13aa46-xAARc.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-04cby.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-0P01F.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-123456789-9rQpm.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-123456789-Ibs9H.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-157754bb-af01-40be-853a-6a1f1b5ac500-vGYhq.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-157754bb-af01-40be-853a-6a1f1b5ac500-vGYhr.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-5oA1q.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-XStRo.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-puPyB.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-uJec6.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-29ce3084-23b6-44e0-b53e-55a34b924920-88kQ3.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-29ce3084-23b6-44e0-b53e-55a34b924920-NMuFo.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-5537b49a-bb2e-4302-bf8b-da38611247ca-dbOPq.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-5537b49a-bb2e-4302-bf8b-da38611247ca-dbOPy.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-987654321-9r3vy.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-987654321-i3STU.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-9b36c234-7e4a-400d-bab8-58dead9e0ef8-H43R7.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-9b36c234-7e4a-400d-bab8-58dead9e0ef8-hCQg9.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-NiEMH.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-SSKim.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-XyVfC.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-compute-sp6h4.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-differentcode-setN7.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-network-05940332-7926-4cf5-b1fc-7479b529524a-Afwh7.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-network-05940332-7926-4cf5-b1fc-7479b529524a-JM2hP.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-network-0ZkNd.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-network-1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619-hzqeF.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-network-1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619-qjnCY.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-network-24b94558-c46a-41e3-981d-16600f71cddb-61PLg.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-network-24b94558-c46a-41e3-981d-16600f71cddb-OL4Ab.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-network-Tkd5S.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-storage-1902326a-2092-4cb6-b998-6d6e73be6212-B8aRd.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-storage-1902326a-2092-4cb6-b998-6d6e73be6212-naAXd.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-storage-3DT6z.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-storage-8f423fd4-0fdb-4422-a01b-fb6594173fbb-b6DVv.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-storage-8f423fd4-0fdb-4422-a01b-fb6594173fbb-uPiUB.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-storage-a7eeebf0-a93f-4187-bd86-dab2725d5bfa-M22T3.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-storage-a7eeebf0-a93f-4187-bd86-dab2725d5bfa-MGDwo.json [new file with mode: 0644]
jOCCI-api/src/test/resources/__files/body-storage-dpXcr.json [new file with mode: 0644]
jOCCI-api/src/test/resources/log4j.properties [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-(root)-E94qA.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-(root)-Gshly.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping---KvCEW.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping---crGY7.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping---lLtvH.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping---xaO7k.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-0054b25a-ddb9-412e-869e-7b800a13aa46-BzixR.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-0054b25a-ddb9-412e-869e-7b800a13aa46-xAARc.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-04cby.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-0P01F.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-123456789-9rQpm.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-123456789-Ibs9H.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-157754bb-af01-40be-853a-6a1f1b5ac500-vGYhq.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-157754bb-af01-40be-853a-6a1f1b5ac500-vGYhr.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-5oA1q.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-XStRo.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-puPyB.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-uJec6.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-29ce3084-23b6-44e0-b53e-55a34b924920-88kQ3.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-29ce3084-23b6-44e0-b53e-55a34b924920-NMuFo.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-5537b49a-bb2e-4302-bf8b-da38611247ca-dbOPq.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-5537b49a-bb2e-4302-bf8b-da38611247ca-dbOPy.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-987654321-9r3vy.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-987654321-i3STU.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-9b36c234-7e4a-400d-bab8-58dead9e0ef8-H43R7.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-9b36c234-7e4a-400d-bab8-58dead9e0ef8-hCQg9.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-NiEMH.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-SSKim.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-XyVfC.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-compute-sp6h4.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-differentcode-setN7.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-network-05940332-7926-4cf5-b1fc-7479b529524a-Afwh7.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-network-05940332-7926-4cf5-b1fc-7479b529524a-JM2hP.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-network-0ZkNd.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-network-1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619-hzqeF.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-network-1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619-qjnCY.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-network-24b94558-c46a-41e3-981d-16600f71cddb-61PLg.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-network-24b94558-c46a-41e3-981d-16600f71cddb-OL4Ab.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-network-Tkd5S.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-storage-1902326a-2092-4cb6-b998-6d6e73be6212-B8aRd.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-storage-1902326a-2092-4cb6-b998-6d6e73be6212-naAXd.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-storage-3DT6z.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-storage-8f423fd4-0fdb-4422-a01b-fb6594173fbb-b6DVv.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-storage-8f423fd4-0fdb-4422-a01b-fb6594173fbb-uPiUB.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-storage-a7eeebf0-a93f-4187-bd86-dab2725d5bfa-M22T3.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-storage-a7eeebf0-a93f-4187-bd86-dab2725d5bfa-MGDwo.json [new file with mode: 0644]
jOCCI-api/src/test/resources/mappings/mapping-storage-dpXcr.json [new file with mode: 0644]

diff --git a/jOCCI-api/.gitignore b/jOCCI-api/.gitignore
new file mode 100644 (file)
index 0000000..25c2a1e
--- /dev/null
@@ -0,0 +1,5 @@
+build.xml
+/nbproject
+nb-configuration.xml
+/target/
+nbactions.xml
diff --git a/jOCCI-api/.travis.yml b/jOCCI-api/.travis.yml
new file mode 100644 (file)
index 0000000..11846ed
--- /dev/null
@@ -0,0 +1,10 @@
+language: java
+
+jdk:
+  - openjdk7
+  - oraclejdk7
+  - oraclejdk8
+
+bracnhes:
+  only:
+    - master
diff --git a/jOCCI-api/LICENSE b/jOCCI-api/LICENSE
new file mode 100644 (file)
index 0000000..f73d873
--- /dev/null
@@ -0,0 +1,17 @@
+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.
diff --git a/jOCCI-api/README.md b/jOCCI-api/README.md
new file mode 100644 (file)
index 0000000..d68bffb
--- /dev/null
@@ -0,0 +1,36 @@
+jOCCI-api - A Java OCCI Framework
+==================================
+
+[![Build Status](https://secure.travis-ci.org/EGI-FCTF/jOCCI-api.png)](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
diff --git a/jOCCI-api/pom.xml b/jOCCI-api/pom.xml
new file mode 100644 (file)
index 0000000..ba0002f
--- /dev/null
@@ -0,0 +1,211 @@
+<?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
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/Authentication.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/Authentication.java
new file mode 100644 (file)
index 0000000..581c668
--- /dev/null
@@ -0,0 +1,33 @@
+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;
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/Client.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/Client.java
new file mode 100644 (file)
index 0000000..f4c6aa5
--- /dev/null
@@ -0,0 +1,322 @@
+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;
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/EntityBuilder.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/EntityBuilder.java
new file mode 100644 (file)
index 0000000..70f2ee5
--- /dev/null
@@ -0,0 +1,500 @@
+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;
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/AdvancedUsageExample.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/AdvancedUsageExample.java
new file mode 100644 (file)
index 0000000..16db5d8
--- /dev/null
@@ -0,0 +1,124 @@
+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);
+        }
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/BasicAuthenticationExample.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/BasicAuthenticationExample.java
new file mode 100644 (file)
index 0000000..a182d47
--- /dev/null
@@ -0,0 +1,31 @@
+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);
+        }
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/DigestAuthenticationExample.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/DigestAuthenticationExample.java
new file mode 100644 (file)
index 0000000..77b59d9
--- /dev/null
@@ -0,0 +1,32 @@
+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);
+        }
+    }
+
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/SimpleUsageExample.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/SimpleUsageExample.java
new file mode 100644 (file)
index 0000000..fecdf4a
--- /dev/null
@@ -0,0 +1,31 @@
+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);
+        }
+    }
+
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/VOMSAuthenticationExample.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/VOMSAuthenticationExample.java
new file mode 100644 (file)
index 0000000..5dcbb6e
--- /dev/null
@@ -0,0 +1,36 @@
+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);
+        }
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/X509AuthenticationExample.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/example/X509AuthenticationExample.java
new file mode 100644 (file)
index 0000000..0ebddf9
--- /dev/null
@@ -0,0 +1,36 @@
+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);
+        }
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/exception/AuthenticationException.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/exception/AuthenticationException.java
new file mode 100644 (file)
index 0000000..ce8f492
--- /dev/null
@@ -0,0 +1,20 @@
+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);
+    }
+
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/exception/CommunicationException.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/exception/CommunicationException.java
new file mode 100644 (file)
index 0000000..3d4b7bb
--- /dev/null
@@ -0,0 +1,19 @@
+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);
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/exception/EntityBuildingException.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/exception/EntityBuildingException.java
new file mode 100644 (file)
index 0000000..27b6d81
--- /dev/null
@@ -0,0 +1,19 @@
+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);
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/HTTPClient.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/HTTPClient.java
new file mode 100644 (file)
index 0000000..a7c2228
--- /dev/null
@@ -0,0 +1,630 @@
+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();
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/HTTPConnection.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/HTTPConnection.java
new file mode 100644 (file)
index 0000000..d49575c
--- /dev/null
@@ -0,0 +1,87 @@
+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));
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/HTTPHelper.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/HTTPHelper.java
new file mode 100644 (file)
index 0000000..6a5ca81
--- /dev/null
@@ -0,0 +1,190 @@
+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;
+        }
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/BasicAuthentication.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/BasicAuthentication.java
new file mode 100644 (file)
index 0000000..ee50d67
--- /dev/null
@@ -0,0 +1,103 @@
+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();
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/CertificateAuthentication.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/CertificateAuthentication.java
new file mode 100644 (file)
index 0000000..6275c22
--- /dev/null
@@ -0,0 +1,230 @@
+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();
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/DigestAuthentication.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/DigestAuthentication.java
new file mode 100644 (file)
index 0000000..9915e34
--- /dev/null
@@ -0,0 +1,34 @@
+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;
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/HTTPAuthentication.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/HTTPAuthentication.java
new file mode 100644 (file)
index 0000000..e08967f
--- /dev/null
@@ -0,0 +1,282 @@
+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);
+        }
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/KeystoneAuthentication.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/KeystoneAuthentication.java
new file mode 100644 (file)
index 0000000..da12c1e
--- /dev/null
@@ -0,0 +1,280 @@
+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;
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/NoAuthentication.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/NoAuthentication.java
new file mode 100644 (file)
index 0000000..70b4f67
--- /dev/null
@@ -0,0 +1,24 @@
+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;
+    }
+
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/VOMSAuthentication.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/VOMSAuthentication.java
new file mode 100644 (file)
index 0000000..3ef73c8
--- /dev/null
@@ -0,0 +1,45 @@
+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);
+    }
+}
diff --git a/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/X509Authentication.java b/jOCCI-api/src/main/java/cz/cesnet/cloud/occi/api/http/auth/X509Authentication.java
new file mode 100644 (file)
index 0000000..df8211d
--- /dev/null
@@ -0,0 +1,64 @@
+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);
+    }
+}
diff --git a/jOCCI-api/src/test/java/cz/cesnet/cloud/occi/DataGenerator.java b/jOCCI-api/src/test/java/cz/cesnet/cloud/occi/DataGenerator.java
new file mode 100644 (file)
index 0000000..2655e47
--- /dev/null
@@ -0,0 +1,319 @@
+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);
+    }
+}
diff --git a/jOCCI-api/src/test/java/cz/cesnet/cloud/occi/api/EntityBuilderTest.java b/jOCCI-api/src/test/java/cz/cesnet/cloud/occi/api/EntityBuilderTest.java
new file mode 100644 (file)
index 0000000..0f05d77
--- /dev/null
@@ -0,0 +1,431 @@
+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());
+    }
+}
diff --git a/jOCCI-api/src/test/java/cz/cesnet/cloud/occi/api/http/HTTPClientTest.java b/jOCCI-api/src/test/java/cz/cesnet/cloud/occi/api/http/HTTPClientTest.java
new file mode 100644 (file)
index 0000000..b383291
--- /dev/null
@@ -0,0 +1,649 @@
+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()));
+    }
+}
diff --git a/jOCCI-api/src/test/java/cz/cesnet/cloud/occi/api/http/HTTPConnectionTest.java b/jOCCI-api/src/test/java/cz/cesnet/cloud/occi/api/http/HTTPConnectionTest.java
new file mode 100644 (file)
index 0000000..6a06714
--- /dev/null
@@ -0,0 +1,68 @@
+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());
+    }
+}
diff --git a/jOCCI-api/src/test/java/cz/cesnet/cloud/occi/api/http/HTTPHelperTest.java b/jOCCI-api/src/test/java/cz/cesnet/cloud/occi/api/http/HTTPHelperTest.java
new file mode 100644 (file)
index 0000000..3d20d98
--- /dev/null
@@ -0,0 +1,263 @@
+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);
+    }
+}
diff --git a/jOCCI-api/src/test/resources/__files/body-(root)-E94qA.json b/jOCCI-api/src/test/resources/__files/body-(root)-E94qA.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-(root)-Gshly.json b/jOCCI-api/src/test/resources/__files/body-(root)-Gshly.json
new file mode 100644 (file)
index 0000000..2c7e982
--- /dev/null
@@ -0,0 +1,12 @@
+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
diff --git a/jOCCI-api/src/test/resources/__files/body---KvCEW.json b/jOCCI-api/src/test/resources/__files/body---KvCEW.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body---crGY7.json b/jOCCI-api/src/test/resources/__files/body---crGY7.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body---lLtvH.json b/jOCCI-api/src/test/resources/__files/body---lLtvH.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body---xaO7k.json b/jOCCI-api/src/test/resources/__files/body---xaO7k.json
new file mode 100644 (file)
index 0000000..50b7514
--- /dev/null
@@ -0,0 +1,35 @@
+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"
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-0054b25a-ddb9-412e-869e-7b800a13aa46-BzixR.json b/jOCCI-api/src/test/resources/__files/body-compute-0054b25a-ddb9-412e-869e-7b800a13aa46-BzixR.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-0054b25a-ddb9-412e-869e-7b800a13aa46-xAARc.json b/jOCCI-api/src/test/resources/__files/body-compute-0054b25a-ddb9-412e-869e-7b800a13aa46-xAARc.json
new file mode 100644 (file)
index 0000000..b68ca1a
--- /dev/null
@@ -0,0 +1,11 @@
+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
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-04cby.json b/jOCCI-api/src/test/resources/__files/body-compute-04cby.json
new file mode 100644 (file)
index 0000000..3b4ef92
--- /dev/null
@@ -0,0 +1 @@
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/157754bb-af01-40be-853a-6a1f1b5ac500
\ No newline at end of file
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-0P01F.json b/jOCCI-api/src/test/resources/__files/body-compute-0P01F.json
new file mode 100644 (file)
index 0000000..ebae604
--- /dev/null
@@ -0,0 +1,6 @@
+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
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-123456789-9rQpm.json b/jOCCI-api/src/test/resources/__files/body-compute-123456789-9rQpm.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-123456789-Ibs9H.json b/jOCCI-api/src/test/resources/__files/body-compute-123456789-Ibs9H.json
new file mode 100644 (file)
index 0000000..8853a2b
--- /dev/null
@@ -0,0 +1,12 @@
+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
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-157754bb-af01-40be-853a-6a1f1b5ac500-vGYhq.json b/jOCCI-api/src/test/resources/__files/body-compute-157754bb-af01-40be-853a-6a1f1b5ac500-vGYhq.json
new file mode 100644 (file)
index 0000000..b239c6f
--- /dev/null
@@ -0,0 +1 @@
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/157754bb-af01-40be-853a-6a1f1b5ac500
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-157754bb-af01-40be-853a-6a1f1b5ac500-vGYhr.json b/jOCCI-api/src/test/resources/__files/body-compute-157754bb-af01-40be-853a-6a1f1b5ac500-vGYhr.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-5oA1q.json b/jOCCI-api/src/test/resources/__files/body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-5oA1q.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-XStRo.json b/jOCCI-api/src/test/resources/__files/body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-XStRo.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-puPyB.json b/jOCCI-api/src/test/resources/__files/body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-puPyB.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-uJec6.json b/jOCCI-api/src/test/resources/__files/body-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-uJec6.json
new file mode 100644 (file)
index 0000000..1392c4c
--- /dev/null
@@ -0,0 +1,12 @@
+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
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-29ce3084-23b6-44e0-b53e-55a34b924920-88kQ3.json b/jOCCI-api/src/test/resources/__files/body-compute-29ce3084-23b6-44e0-b53e-55a34b924920-88kQ3.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-29ce3084-23b6-44e0-b53e-55a34b924920-NMuFo.json b/jOCCI-api/src/test/resources/__files/body-compute-29ce3084-23b6-44e0-b53e-55a34b924920-NMuFo.json
new file mode 100644 (file)
index 0000000..5bf4c12
--- /dev/null
@@ -0,0 +1,11 @@
+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
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-5537b49a-bb2e-4302-bf8b-da38611247ca-dbOPq.json b/jOCCI-api/src/test/resources/__files/body-compute-5537b49a-bb2e-4302-bf8b-da38611247ca-dbOPq.json
new file mode 100644 (file)
index 0000000..600e4fe
--- /dev/null
@@ -0,0 +1 @@
+X-OCCI-Location: http://rocci-server-1-1-x.herokuapp.com:80/compute/5537b49a-bb2e-4302-bf8b-da38611247ca
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-5537b49a-bb2e-4302-bf8b-da38611247ca-dbOPy.json b/jOCCI-api/src/test/resources/__files/body-compute-5537b49a-bb2e-4302-bf8b-da38611247ca-dbOPy.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-987654321-9r3vy.json b/jOCCI-api/src/test/resources/__files/body-compute-987654321-9r3vy.json
new file mode 100644 (file)
index 0000000..7e794c6
--- /dev/null
@@ -0,0 +1,12 @@
+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
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-987654321-i3STU.json b/jOCCI-api/src/test/resources/__files/body-compute-987654321-i3STU.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-9b36c234-7e4a-400d-bab8-58dead9e0ef8-H43R7.json b/jOCCI-api/src/test/resources/__files/body-compute-9b36c234-7e4a-400d-bab8-58dead9e0ef8-H43R7.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-9b36c234-7e4a-400d-bab8-58dead9e0ef8-hCQg9.json b/jOCCI-api/src/test/resources/__files/body-compute-9b36c234-7e4a-400d-bab8-58dead9e0ef8-hCQg9.json
new file mode 100644 (file)
index 0000000..a666f71
--- /dev/null
@@ -0,0 +1,12 @@
+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
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-NiEMH.json b/jOCCI-api/src/test/resources/__files/body-compute-NiEMH.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-SSKim.json b/jOCCI-api/src/test/resources/__files/body-compute-SSKim.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-XyVfC.json b/jOCCI-api/src/test/resources/__files/body-compute-XyVfC.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-compute-sp6h4.json b/jOCCI-api/src/test/resources/__files/body-compute-sp6h4.json
new file mode 100644 (file)
index 0000000..a0aba93
--- /dev/null
@@ -0,0 +1 @@
+OK
\ No newline at end of file
diff --git a/jOCCI-api/src/test/resources/__files/body-differentcode-setN7.json b/jOCCI-api/src/test/resources/__files/body-differentcode-setN7.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-network-05940332-7926-4cf5-b1fc-7479b529524a-Afwh7.json b/jOCCI-api/src/test/resources/__files/body-network-05940332-7926-4cf5-b1fc-7479b529524a-Afwh7.json
new file mode 100644 (file)
index 0000000..fc82592
--- /dev/null
@@ -0,0 +1,3 @@
+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
diff --git a/jOCCI-api/src/test/resources/__files/body-network-05940332-7926-4cf5-b1fc-7479b529524a-JM2hP.json b/jOCCI-api/src/test/resources/__files/body-network-05940332-7926-4cf5-b1fc-7479b529524a-JM2hP.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-network-0ZkNd.json b/jOCCI-api/src/test/resources/__files/body-network-0ZkNd.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-network-1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619-hzqeF.json b/jOCCI-api/src/test/resources/__files/body-network-1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619-hzqeF.json
new file mode 100644 (file)
index 0000000..f90377e
--- /dev/null
@@ -0,0 +1,3 @@
+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
diff --git a/jOCCI-api/src/test/resources/__files/body-network-1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619-qjnCY.json b/jOCCI-api/src/test/resources/__files/body-network-1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619-qjnCY.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-network-24b94558-c46a-41e3-981d-16600f71cddb-61PLg.json b/jOCCI-api/src/test/resources/__files/body-network-24b94558-c46a-41e3-981d-16600f71cddb-61PLg.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-network-24b94558-c46a-41e3-981d-16600f71cddb-OL4Ab.json b/jOCCI-api/src/test/resources/__files/body-network-24b94558-c46a-41e3-981d-16600f71cddb-OL4Ab.json
new file mode 100644 (file)
index 0000000..84435eb
--- /dev/null
@@ -0,0 +1,3 @@
+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
diff --git a/jOCCI-api/src/test/resources/__files/body-network-Tkd5S.json b/jOCCI-api/src/test/resources/__files/body-network-Tkd5S.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-storage-1902326a-2092-4cb6-b998-6d6e73be6212-B8aRd.json b/jOCCI-api/src/test/resources/__files/body-storage-1902326a-2092-4cb6-b998-6d6e73be6212-B8aRd.json
new file mode 100644 (file)
index 0000000..f63a84f
--- /dev/null
@@ -0,0 +1,3 @@
+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
diff --git a/jOCCI-api/src/test/resources/__files/body-storage-1902326a-2092-4cb6-b998-6d6e73be6212-naAXd.json b/jOCCI-api/src/test/resources/__files/body-storage-1902326a-2092-4cb6-b998-6d6e73be6212-naAXd.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-storage-3DT6z.json b/jOCCI-api/src/test/resources/__files/body-storage-3DT6z.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-storage-8f423fd4-0fdb-4422-a01b-fb6594173fbb-b6DVv.json b/jOCCI-api/src/test/resources/__files/body-storage-8f423fd4-0fdb-4422-a01b-fb6594173fbb-b6DVv.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-storage-8f423fd4-0fdb-4422-a01b-fb6594173fbb-uPiUB.json b/jOCCI-api/src/test/resources/__files/body-storage-8f423fd4-0fdb-4422-a01b-fb6594173fbb-uPiUB.json
new file mode 100644 (file)
index 0000000..cc8428d
--- /dev/null
@@ -0,0 +1,3 @@
+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
diff --git a/jOCCI-api/src/test/resources/__files/body-storage-a7eeebf0-a93f-4187-bd86-dab2725d5bfa-M22T3.json b/jOCCI-api/src/test/resources/__files/body-storage-a7eeebf0-a93f-4187-bd86-dab2725d5bfa-M22T3.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/__files/body-storage-a7eeebf0-a93f-4187-bd86-dab2725d5bfa-MGDwo.json b/jOCCI-api/src/test/resources/__files/body-storage-a7eeebf0-a93f-4187-bd86-dab2725d5bfa-MGDwo.json
new file mode 100644 (file)
index 0000000..ee6fc9e
--- /dev/null
@@ -0,0 +1,3 @@
+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
diff --git a/jOCCI-api/src/test/resources/__files/body-storage-dpXcr.json b/jOCCI-api/src/test/resources/__files/body-storage-dpXcr.json
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jOCCI-api/src/test/resources/log4j.properties b/jOCCI-api/src/test/resources/log4j.properties
new file mode 100644 (file)
index 0000000..ee4b2c2
--- /dev/null
@@ -0,0 +1,9 @@
+# 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
+
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-(root)-E94qA.json b/jOCCI-api/src/test/resources/mappings/mapping-(root)-E94qA.json
new file mode 100644 (file)
index 0000000..a53fe42
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-(root)-Gshly.json b/jOCCI-api/src/test/resources/mappings/mapping-(root)-Gshly.json
new file mode 100644 (file)
index 0000000..7587db0
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping---KvCEW.json b/jOCCI-api/src/test/resources/mappings/mapping---KvCEW.json
new file mode 100644 (file)
index 0000000..4a29df8
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping---crGY7.json b/jOCCI-api/src/test/resources/mappings/mapping---crGY7.json
new file mode 100644 (file)
index 0000000..5f42389
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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"
+    }
+  }
+}
diff --git a/jOCCI-api/src/test/resources/mappings/mapping---lLtvH.json b/jOCCI-api/src/test/resources/mappings/mapping---lLtvH.json
new file mode 100644 (file)
index 0000000..d2608fb
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping---xaO7k.json b/jOCCI-api/src/test/resources/mappings/mapping---xaO7k.json
new file mode 100644 (file)
index 0000000..1d6204b
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-0054b25a-ddb9-412e-869e-7b800a13aa46-BzixR.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-0054b25a-ddb9-412e-869e-7b800a13aa46-BzixR.json
new file mode 100644 (file)
index 0000000..be36c90
--- /dev/null
@@ -0,0 +1,34 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-0054b25a-ddb9-412e-869e-7b800a13aa46-xAARc.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-0054b25a-ddb9-412e-869e-7b800a13aa46-xAARc.json
new file mode 100644 (file)
index 0000000..495b6f1
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-04cby.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-04cby.json
new file mode 100644 (file)
index 0000000..db2f6fa
--- /dev/null
@@ -0,0 +1,36 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-0P01F.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-0P01F.json
new file mode 100644 (file)
index 0000000..20eaa8a
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-123456789-9rQpm.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-123456789-9rQpm.json
new file mode 100644 (file)
index 0000000..e2fda04
--- /dev/null
@@ -0,0 +1,35 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-123456789-Ibs9H.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-123456789-Ibs9H.json
new file mode 100644 (file)
index 0000000..2ff7cf3
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-157754bb-af01-40be-853a-6a1f1b5ac500-vGYhq.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-157754bb-af01-40be-853a-6a1f1b5ac500-vGYhq.json
new file mode 100644 (file)
index 0000000..ff8d2b7
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-157754bb-af01-40be-853a-6a1f1b5ac500-vGYhr.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-157754bb-af01-40be-853a-6a1f1b5ac500-vGYhr.json
new file mode 100644 (file)
index 0000000..3af2a4b
--- /dev/null
@@ -0,0 +1,32 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-5oA1q.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-5oA1q.json
new file mode 100644 (file)
index 0000000..ec254d7
--- /dev/null
@@ -0,0 +1,35 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-XStRo.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-XStRo.json
new file mode 100644 (file)
index 0000000..ab5b96f
--- /dev/null
@@ -0,0 +1,35 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-puPyB.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-puPyB.json
new file mode 100644 (file)
index 0000000..212397a
--- /dev/null
@@ -0,0 +1,35 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-uJec6.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-29b814ad-c5b2-4bc4-888b-470f769a2930-uJec6.json
new file mode 100644 (file)
index 0000000..d6c529f
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-29ce3084-23b6-44e0-b53e-55a34b924920-88kQ3.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-29ce3084-23b6-44e0-b53e-55a34b924920-88kQ3.json
new file mode 100644 (file)
index 0000000..85ae95f
--- /dev/null
@@ -0,0 +1,34 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-29ce3084-23b6-44e0-b53e-55a34b924920-NMuFo.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-29ce3084-23b6-44e0-b53e-55a34b924920-NMuFo.json
new file mode 100644 (file)
index 0000000..c2d2848
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-5537b49a-bb2e-4302-bf8b-da38611247ca-dbOPq.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-5537b49a-bb2e-4302-bf8b-da38611247ca-dbOPq.json
new file mode 100644 (file)
index 0000000..3dae0ee
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-5537b49a-bb2e-4302-bf8b-da38611247ca-dbOPy.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-5537b49a-bb2e-4302-bf8b-da38611247ca-dbOPy.json
new file mode 100644 (file)
index 0000000..78ce9c9
--- /dev/null
@@ -0,0 +1,32 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-987654321-9r3vy.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-987654321-9r3vy.json
new file mode 100644 (file)
index 0000000..a1e7372
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-987654321-i3STU.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-987654321-i3STU.json
new file mode 100644 (file)
index 0000000..4abbc96
--- /dev/null
@@ -0,0 +1,35 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-9b36c234-7e4a-400d-bab8-58dead9e0ef8-H43R7.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-9b36c234-7e4a-400d-bab8-58dead9e0ef8-H43R7.json
new file mode 100644 (file)
index 0000000..cf8dfbf
--- /dev/null
@@ -0,0 +1,35 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-9b36c234-7e4a-400d-bab8-58dead9e0ef8-hCQg9.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-9b36c234-7e4a-400d-bab8-58dead9e0ef8-hCQg9.json
new file mode 100644 (file)
index 0000000..39f20a4
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-NiEMH.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-NiEMH.json
new file mode 100644 (file)
index 0000000..3a7d690
--- /dev/null
@@ -0,0 +1,35 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-SSKim.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-SSKim.json
new file mode 100644 (file)
index 0000000..9e9c464
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-XyVfC.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-XyVfC.json
new file mode 100644 (file)
index 0000000..232aa0c
--- /dev/null
@@ -0,0 +1,35 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-compute-sp6h4.json b/jOCCI-api/src/test/resources/mappings/mapping-compute-sp6h4.json
new file mode 100644 (file)
index 0000000..7169267
--- /dev/null
@@ -0,0 +1,40 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-differentcode-setN7.json b/jOCCI-api/src/test/resources/mappings/mapping-differentcode-setN7.json
new file mode 100644 (file)
index 0000000..7718b2c
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-network-05940332-7926-4cf5-b1fc-7479b529524a-Afwh7.json b/jOCCI-api/src/test/resources/mappings/mapping-network-05940332-7926-4cf5-b1fc-7479b529524a-Afwh7.json
new file mode 100644 (file)
index 0000000..830b1c7
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-network-05940332-7926-4cf5-b1fc-7479b529524a-JM2hP.json b/jOCCI-api/src/test/resources/mappings/mapping-network-05940332-7926-4cf5-b1fc-7479b529524a-JM2hP.json
new file mode 100644 (file)
index 0000000..6488ca5
--- /dev/null
@@ -0,0 +1,34 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-network-0ZkNd.json b/jOCCI-api/src/test/resources/mappings/mapping-network-0ZkNd.json
new file mode 100644 (file)
index 0000000..3d86156
--- /dev/null
@@ -0,0 +1,32 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-network-1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619-hzqeF.json b/jOCCI-api/src/test/resources/mappings/mapping-network-1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619-hzqeF.json
new file mode 100644 (file)
index 0000000..fc7ab2c
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-network-1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619-qjnCY.json b/jOCCI-api/src/test/resources/mappings/mapping-network-1bdff9e2-7a5d-4e87-b2e3-9a6cfb7b6619-qjnCY.json
new file mode 100644 (file)
index 0000000..c8ed51e
--- /dev/null
@@ -0,0 +1,34 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-network-24b94558-c46a-41e3-981d-16600f71cddb-61PLg.json b/jOCCI-api/src/test/resources/mappings/mapping-network-24b94558-c46a-41e3-981d-16600f71cddb-61PLg.json
new file mode 100644 (file)
index 0000000..9a0081e
--- /dev/null
@@ -0,0 +1,34 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-network-24b94558-c46a-41e3-981d-16600f71cddb-OL4Ab.json b/jOCCI-api/src/test/resources/mappings/mapping-network-24b94558-c46a-41e3-981d-16600f71cddb-OL4Ab.json
new file mode 100644 (file)
index 0000000..13c63a8
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-network-Tkd5S.json b/jOCCI-api/src/test/resources/mappings/mapping-network-Tkd5S.json
new file mode 100644 (file)
index 0000000..c48d752
--- /dev/null
@@ -0,0 +1,32 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-storage-1902326a-2092-4cb6-b998-6d6e73be6212-B8aRd.json b/jOCCI-api/src/test/resources/mappings/mapping-storage-1902326a-2092-4cb6-b998-6d6e73be6212-B8aRd.json
new file mode 100644 (file)
index 0000000..a4b67e3
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-storage-1902326a-2092-4cb6-b998-6d6e73be6212-naAXd.json b/jOCCI-api/src/test/resources/mappings/mapping-storage-1902326a-2092-4cb6-b998-6d6e73be6212-naAXd.json
new file mode 100644 (file)
index 0000000..b453f17
--- /dev/null
@@ -0,0 +1,34 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-storage-3DT6z.json b/jOCCI-api/src/test/resources/mappings/mapping-storage-3DT6z.json
new file mode 100644 (file)
index 0000000..3e5b4cc
--- /dev/null
@@ -0,0 +1,32 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-storage-8f423fd4-0fdb-4422-a01b-fb6594173fbb-b6DVv.json b/jOCCI-api/src/test/resources/mappings/mapping-storage-8f423fd4-0fdb-4422-a01b-fb6594173fbb-b6DVv.json
new file mode 100644 (file)
index 0000000..041a6d9
--- /dev/null
@@ -0,0 +1,34 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-storage-8f423fd4-0fdb-4422-a01b-fb6594173fbb-uPiUB.json b/jOCCI-api/src/test/resources/mappings/mapping-storage-8f423fd4-0fdb-4422-a01b-fb6594173fbb-uPiUB.json
new file mode 100644 (file)
index 0000000..7a28c89
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-storage-a7eeebf0-a93f-4187-bd86-dab2725d5bfa-M22T3.json b/jOCCI-api/src/test/resources/mappings/mapping-storage-a7eeebf0-a93f-4187-bd86-dab2725d5bfa-M22T3.json
new file mode 100644 (file)
index 0000000..d2880d7
--- /dev/null
@@ -0,0 +1,34 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-storage-a7eeebf0-a93f-4187-bd86-dab2725d5bfa-MGDwo.json b/jOCCI-api/src/test/resources/mappings/mapping-storage-a7eeebf0-a93f-4187-bd86-dab2725d5bfa-MGDwo.json
new file mode 100644 (file)
index 0000000..9972b3e
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "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
diff --git a/jOCCI-api/src/test/resources/mappings/mapping-storage-dpXcr.json b/jOCCI-api/src/test/resources/mappings/mapping-storage-dpXcr.json
new file mode 100644 (file)
index 0000000..3042b8f
--- /dev/null
@@ -0,0 +1,32 @@
+{
+  "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