diff options
-rw-r--r-- | verigraph/build.xml | 126 | ||||
-rw-r--r-- | verigraph/gRPC-build.xml | 74 | ||||
-rwxr-xr-x | verigraph/pom.xml | 16 | ||||
-rw-r--r-- | verigraph/schema/README.rst | 4 | ||||
-rw-r--r-- | verigraph/schema/tosca/TOSCA-v1.0.xsd | 790 | ||||
-rw-r--r-- | verigraph/schema/tosca/ToscaTypes_XMLconfig.xsd | 280 | ||||
-rw-r--r-- | verigraph/schema/tosca/ToscaVerigraphDefinitions.xml | 77 | ||||
-rw-r--r-- | verigraph/schema/tosca/yamlToscaDefinitions.yaml | 157 | ||||
-rw-r--r-- | verigraph/src/it/polito/verigraph/grpc/client/ToscaClient.java | 299 | ||||
-rw-r--r-- | verigraph/src/it/polito/verigraph/grpc/server/GrpcUtils.java | 29 | ||||
-rw-r--r-- | verigraph/src/it/polito/verigraph/grpc/server/Service.java | 169 | ||||
-rw-r--r-- | verigraph/src/it/polito/verigraph/grpc/tosca/test/GrpcToscaTest.java | 425 | ||||
-rw-r--r-- | verigraph/src/it/polito/verigraph/tosca/converter/grpc/GraphToGrpc.java | 101 | ||||
-rw-r--r-- | verigraph/src/it/polito/verigraph/tosca/converter/grpc/GrpcToGraph.java | 150 | ||||
-rw-r--r-- | verigraph/src/main/proto/verigraph.proto | 113 |
15 files changed, 2743 insertions, 67 deletions
diff --git a/verigraph/build.xml b/verigraph/build.xml index dae4678..ba576a7 100644 --- a/verigraph/build.xml +++ b/verigraph/build.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (c) 2017 Politecnico di Torino and others. + Copyright (c) 2017/18 Politecnico di Torino and others. All rights reserved. This program and the accompanying materials are made available under the terms of the Apache License, Version 2.0 @@ -14,6 +14,9 @@ <property name="root.location" location="." /> <!-- The location to be used for class files --> + <property name="docker-grpc.dir" value="${root.location}/docker/gRPC" /> + <property name="docker-rest.dir" value="${root.location}/docker/REST" /> + <property name="cli.dir" value="${root.location}/VerigraphCLI" /> <property name="src.dir" location="${root.location}/src" /> <property name="gen.dir" location="${root.location}/gen-src" /> <property name="war.dir" location="${root.location}/war" /> @@ -23,6 +26,9 @@ <property name="lib.dir" location="${root.location}/lib" /> <property name="schemadir" location="${root.location}/schema" /> <property name="schemafile" value="xml_components.xsd" /> + <property name="toscaschemadir" location="${root.location}/schema/tosca" /> + <property name="toscaschemafile" value="TOSCA-v1.0.xsd" /> + <property name="toscaverigraphschemafile" value="ToscaTypes_XMLconfig.xsd" /> <property name="testfile" value="test.py" /> <property name="target" value="1.8" /> <property name="source" value="1.8" /> @@ -86,22 +92,38 @@ <delete file="${lib.dir}/z3-4.5.0-x86-win.zip" /> </target> - - <target name="-chk-bindings"> - <uptodate property="generate-bindings.notRequired" targetfile="${src.dir}/.flagfile"> - <srcfiles dir="${schemadir}" includes="${schemafile}" /> + + <target name="chk-bindings"> + <uptodate property="generate-bindings.notRequired" targetfile="${gen.dir}/.flagfile"> + <srcresources> + <fileset dir="${schemadir}" includes="${schemafile}" /> + <fileset dir="${toscaschemadir}" includes="${toscaschemafile}" /> + <fileset dir="${toscaschemadir}" includes="${toscaverigraphschemafile}" /> + </srcresources> </uptodate> </target> - - <target name="generate-bindings" unless="generate-bindings.notRequired" depends="init" description="Create the value classes"> + <target name="generate-bindings" unless="generate-bindings.notRequired" depends="init, chk-bindings" description="Create the value classes"> <exec executable="xjc" failonerror="true"> <arg line="-d ${gen.dir} -p it.polito.neo4j.jaxb ${schemadir}/${schemafile}" /> </exec> - <touch file="${src.dir}/.flagfile" /> + <exec executable="xjc" failonerror="true"> + <arg line="-d ${gen.dir} -p it.polito.tosca.jaxb ${toscaschemadir}/${toscaschemafile}" /> + </exec> + <mkdir dir="${root.location}/temp-gen" /> + <exec executable="xjc" failonerror="true"> + <arg line="-d ${root.location}/temp-gen -p it.polito.tosca.jaxb ${toscaschemadir}/${toscaverigraphschemafile}" /> + </exec> + + <copy toDir="${gen.dir}/it/polito/tosca/jaxb" overwrite="true"> + <file name="${root.location}/temp-gen/it/polito/tosca/jaxb/Configuration.java" /> + </copy> + <delete dir="${root.location}/temp-gen" /> + + <touch file="${gen.dir}/.flagfile" /> </target> - + <!-- The target for compiling the Verigraph application --> <target name="build-service" depends="init, generate-bindings, mvn-init"> <echo>Building verigraph (if needed)...</echo> @@ -166,12 +188,10 @@ </sequential> </macrodef> - <target name="war-exploded" depends="build-service"> <war-exploded /> </target> - <target name="generate-war" depends="war-exploded"> <war destfile="${gen-war.dir}/${serviceName}.war" basedir="${gen-tomcat-service.dir}"> <exclude name="protoc-dependencies/" /> @@ -181,7 +201,80 @@ </war> </target> - + <target name="docker-rest-build" depends="generate-war"> + <delete file="${docker-rest.dir}/verigraph.war" /> + + <copy file="${gen-war.dir}/verigraph.war" toDir="${docker-rest.dir}" /> + </target> + + <target name="docker-grpc-build" depends="build-service"> + <delete dir="${docker-grpc.dir}/service_lib" /> + <mkdir dir="${docker-grpc.dir}/service_lib" /> + + <copy toDir="${docker-grpc.dir}/service_lib" flatten="true" overwrite="true"> + <fileset refid="runtime.fileset" /> + </copy> + <copy file="${lib.dir}/com.microsoft.z3.jar" todir="${docker-grpc.dir}/service_lib" /> + + <delete file="${docker-grpc.dir}/server.properties" /> + <delete dir="${docker-grpc.dir}/jsonschema" /> + <copy file="${root.location}/server.properties" todir="${docker-grpc.dir}" /> + <copydir src="${root.location}/jsonschema" dest="${docker-grpc.dir}/jsonschema" /> + + <path id="jars.path"> + <fileset dir="${docker-grpc.dir}"> + <include name="service_lib/*.jar" /> + </fileset> + </path> + + <pathconvert property="jars.mf" pathsep=" "> + <path refid="jars.path" /> + <flattenmapper /> + <map from="" to="service_lib/" /> + </pathconvert> + + <delete file="${docker-grpc.dir}/service.jar"/> + <jar destfile="${docker-grpc.dir}/service.jar"> + <manifest> + <attribute name="Main-Class" value="it.polito.verigraph.grpc.server.Service"/> + <attribute name="Class-Path" value="${jars.mf}"/> + </manifest> + <fileset dir="${root.location}/build"/> + </jar> + </target> + + + <target name="build-cli-jar" depends="build-service"> + <delete dir="${cli.dir}" /> + <mkdir dir="${cli.dir}" /> + + <copy toDir="${cli.dir}/service_lib" flatten="true" overwrite="true"> + <fileset refid="runtime.fileset" /> + </copy> + <copy file="${src.dir}/it/polito/verigraph/tosca/README_CLI.txt" todir="${cli.dir}" /> + + <path id="jars.path"> + <fileset dir="${cli.dir}"> + <include name="service_lib/*.jar" /> + </fileset> + </path> + + <pathconvert property="jars.mf" pathsep=" "> + <path refid="jars.path" /> + <flattenmapper /> + <map from="" to="service_lib/" /> + </pathconvert> + + <delete file="${cli.dir}/VerigraphCLI.jar"/> + <jar destfile="${cli.dir}/VerigraphCLI.jar"> + <manifest> + <attribute name="Main-Class" value="it.polito.verigraph.tosca.ToscaCLI"/> + <attribute name="Class-Path" value="${jars.mf}"/> + </manifest> + <fileset dir="${root.location}/build"/> + </jar> + </target> + <!-- launch test python test --> <target name="run-test"> <exec dir="${test.dir}" executable="python"> @@ -191,8 +284,6 @@ </exec> </target> - - <!-- target for cleaning --> <target name="clean"> <delete dir="${build.dir}" /> @@ -200,7 +291,12 @@ <delete dir="${gen-tomcat-service.dir}" /> <delete dir="${war.dir}" /> <delete dir="${lib.dir}" /> + <delete dir="${docker-grpc.dir}/service_lib" /> + <delete dir="${docker-grpc.dir}/jsonschema" /> + <delete file="${docker-grpc.dir}/server.properties" /> + <delete file="${docker-grpc.dir}/service.jar" /> + <delete file="${docker-rest.dir}/verigraph.war" /> + <delete dir="${cli.dir}" /> </target> - </project>
\ No newline at end of file diff --git a/verigraph/gRPC-build.xml b/verigraph/gRPC-build.xml index 7ff5549..50483c8 100644 --- a/verigraph/gRPC-build.xml +++ b/verigraph/gRPC-build.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- Copyright (c) 2017 Politecnico di Torino and others. - All rights reserved. This program and the accompanying materials are made available under the terms of the Apache License, Version 2.0 which accompanies this distribution, and is available at @@ -31,6 +30,8 @@ <property name="test2.class" value="it.polito.verigraph.grpc.test.GrpcTest" /> <property name="test3.class" value="it.polito.verigraph.grpc.test.MultiThreadTest" /> <property name="test4.class" value="it.polito.verigraph.grpc.test.ReachabilityTest" /> + <!-- Tosca grpc test class --> + <property name="testToscaGrpc.class" value="it.polito.verigraph.grpc.tosca.test.GrpcToscaTest" /> <!-- The name to be given to the final zip --> <property name="sol.zip" value="grpc.zip" /> <!-- Java compiler settings --> @@ -43,7 +44,7 @@ <path id="test.classpath"> <pathelement path="${build.dir}" /> <fileset dir="${grpc.location}/lib"> - <include name="com.microsoft.z3.jar" /> + <include name="com.microsoft.z3.jar" /> </fileset> <fileset refid="mvn-dependencies" /> </path> @@ -65,7 +66,7 @@ </artifact:dependencies>--> <path id="build.classpath"> - <fileset refid="mvn-dependencies" /> + <fileset refid="mvn-dependencies" /> </path> <!-- target name="init"> @@ -77,7 +78,7 @@ <!--target name="gRPC-build" depends="init" description="Build the sources"--> <target name="gRPC-build" description="Build the sources"> <echo>Building gRPC (if needed)...</echo> - <javac + <javac debug="${debug}" debuglevel="${debuglevel}" source="${source}" @@ -85,18 +86,18 @@ destdir="${build.dir}" classpathref="build.classpath" includeantruntime="false"> - <src path="${generated.dir}" /> - <src path="${src.dir}" /> - <src path="${grpc.location}/gen-src"/> - <compilerarg value="-Xlint:unchecked"/> - <classpath> - <pathelement path="${grpc.location}/lib/com.microsoft.z3.jar"/> - </classpath> - <include name="$it/polito/**/**/*.java"/> - <!-- classpath> + <src path="${generated.dir}" /> + <src path="${src.dir}" /> + <src path="${grpc.location}/gen-src"/> + <compilerarg value="-Xlint:unchecked"/> + <classpath> + <pathelement path="${grpc.location}/lib/com.microsoft.z3.jar"/> + </classpath> + <include name="$it/polito/**/**/*.java"/> + <!-- classpath> <pathelement path="${other_lib.dir}/qjutils.jar"/> </classpath--> - </javac> + </javac> <echo>Done.</echo> </target> @@ -104,20 +105,21 @@ <!-- The target for running the gRPC application --> <target name="gRPC-run" depends="gRPC-build" description="Run gRPC"> <parallel> - <sequential> - <java classname="it.polito.verigraph.grpc.Service" failonerror="true" classpathref="build.classpath" fork="yes"> - <classpath> - <pathelement path="${build.dir}"/> - </classpath> - </java> - </sequential> - <sequential> - <sleep milliseconds="500"/> - <java classname="it.polito.verigraph.grpc.Client" failonerror="true" classpathref="build.classpath" fork="yes"> - <classpath> - <pathelement path="${build.dir}"/> - </classpath> - </java> + <sequential> + <java classname="it.polito.verigraph.grpc.Service" failonerror="true" classpathref="build.classpath" fork="yes"> + <classpath> + <pathelement path="${build.dir}"/> + <path refid="test.classpath" /> + </classpath> + </java> + </sequential> + <sequential> + <sleep milliseconds="500"/> + <java classname="it.polito.verigraph.grpc.Client" failonerror="true" classpathref="build.classpath" fork="yes"> + <classpath> + <pathelement path="${build.dir}"/> + </classpath> + </java> </sequential> </parallel> </target> @@ -136,6 +138,7 @@ <java classname="it.polito.verigraph.grpc.server.Service" failonerror="true" classpathref="build.classpath" fork="yes"> <classpath> <pathelement path="${build.dir}"/> + <path refid="test.classpath" /> </classpath> </java> </target> @@ -151,6 +154,19 @@ </antcall> </target> + <!-- Run Tosca Grpc Tests --> + <target name="gRPC-tosca-run-tests" description="Run tests for Tosca implementation of gRPC"> + <echo>Running grpc tests...</echo> + <junit printsummary="yes" dir="." fork="yes" haltonfailure="no" showoutput="yes" filtertrace="true" timeout="120000"> + <jvmarg value="-Djava.awt.headless=true" /> + <formatter type="brief" usefile="false" /> + <test haltonfailure="no" failureproperty="test_failed" name="${testToscaGrpc.class}" /> + <classpath> + <path refid="test.classpath" /> + </classpath> + </junit> + <fail if="test_failed" message="*** JUnit tests for gRPC Tosca completed: some Tests FAILED ***" /> + </target> <!-- Target runFuncTest.real --> <target name="runFuncTest.real" depends="gRPC-build"> @@ -213,4 +229,4 @@ <!-- target name="clean"> <delete dir="${build.dir}" /> </target--> -</project>
\ No newline at end of file +</project> diff --git a/verigraph/pom.xml b/verigraph/pom.xml index cfa21e9..9684667 100755 --- a/verigraph/pom.xml +++ b/verigraph/pom.xml @@ -37,8 +37,8 @@ <version>3.0</version>
<inherited>true</inherited>
<configuration>
- <source>1.7</source>
- <target>1.7</target>
+ <source>1.8</source>
+ <target>1.8</target>
</configuration>
</plugin>
<plugin>
@@ -218,6 +218,16 @@ <artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-yaml</artifactId>
+ <version>2.9.2</version>
+ </dependency>
+ <!-- Trying to make jaxb work -->
+ <dependency>
+ <groupId>org.eclipse.persistence</groupId>
+ <artifactId>org.eclipse.persistence.core</artifactId>
+ <version>2.6.0</version>
+ </dependency>
</dependencies>
-
</project>
\ No newline at end of file diff --git a/verigraph/schema/README.rst b/verigraph/schema/README.rst new file mode 100644 index 0000000..c3e7a22 --- /dev/null +++ b/verigraph/schema/README.rst @@ -0,0 +1,4 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 +The XML Schema files in this folder are used by VeriGraph to +automatically generate Java XML Bindings (JAXB) diff --git a/verigraph/schema/tosca/TOSCA-v1.0.xsd b/verigraph/schema/tosca/TOSCA-v1.0.xsd new file mode 100644 index 0000000..ebfcaa6 --- /dev/null +++ b/verigraph/schema/tosca/TOSCA-v1.0.xsd @@ -0,0 +1,790 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Topology and Orchestration Specification for Cloud Applications Version 1.0 + OASIS Standard + 25 November 2013 + Copyright (c) OASIS Open 2013. All rights reserved. + Source: http://docs.oasis-open.org/tosca/TOSCA/v1.0/os/schemas/ +--> +<xs:schema targetNamespace="http://docs.oasis-open.org/tosca/ns/2011/12" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns="http://docs.oasis-open.org/tosca/ns/2011/12" xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/> + <xs:element name="documentation" type="tDocumentation"/> + <xs:complexType name="tDocumentation" mixed="true"> + <xs:sequence> + <xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute name="source" type="xs:anyURI"/> + <xs:attribute ref="xml:lang"/> + </xs:complexType> + <xs:complexType name="tExtensibleElements"> + <xs:sequence> + <xs:element ref="documentation" minOccurs="0" maxOccurs="unbounded"/> + <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + <xs:anyAttribute namespace="##other" processContents="lax"/> + </xs:complexType> + <xs:complexType name="tImport"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:attribute name="namespace" type="xs:anyURI"/> + <xs:attribute name="location" type="xs:anyURI"/> + <xs:attribute name="importType" type="importedURI" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:element name="Definitions"> + <xs:complexType> + <xs:complexContent> + <xs:extension base="tDefinitions"/> + </xs:complexContent> + </xs:complexType> + </xs:element> + <xs:complexType name="tDefinitions"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Extensions" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Extension" type="tExtension" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Import" type="tImport" minOccurs="0" maxOccurs="unbounded"/> + <xs:element name="Types" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:choice maxOccurs="unbounded"> + <xs:element name="ServiceTemplate" type="tServiceTemplate"/> + <xs:element name="NodeType" type="tNodeType"/> + <xs:element name="NodeTypeImplementation" type="tNodeTypeImplementation"/> + <xs:element name="RelationshipType" type="tRelationshipType"/> + <xs:element name="RelationshipTypeImplementation" type="tRelationshipTypeImplementation"/> + <xs:element name="RequirementType" type="tRequirementType"/> + <xs:element name="CapabilityType" type="tCapabilityType"/> + <xs:element name="ArtifactType" type="tArtifactType"/> + <xs:element name="ArtifactTemplate" type="tArtifactTemplate"/> + <xs:element name="PolicyType" type="tPolicyType"/> + <xs:element name="PolicyTemplate" type="tPolicyTemplate"/> + </xs:choice> + </xs:sequence> + <xs:attribute name="id" type="xs:ID" use="required"/> + <xs:attribute name="name" type="xs:string" use="optional"/> + <xs:attribute name="targetNamespace" type="xs:anyURI" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tServiceTemplate"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Tags" type="tTags" minOccurs="0"/> + <xs:element name="BoundaryDefinitions" type="tBoundaryDefinitions" minOccurs="0"/> + <xs:element name="TopologyTemplate" type="tTopologyTemplate"/> + <xs:element name="Plans" type="tPlans" minOccurs="0"/> + </xs:sequence> + <xs:attribute name="id" type="xs:ID" use="required"/> + <xs:attribute name="name" type="xs:string" use="optional"/> + <xs:attribute name="targetNamespace" type="xs:anyURI"/> + <xs:attribute name="substitutableNodeType" type="xs:QName" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tTags"> + <xs:sequence> + <xs:element name="Tag" type="tTag" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="tTag"> + <xs:attribute name="name" type="xs:string" use="required"/> + <xs:attribute name="value" type="xs:string" use="required"/> + </xs:complexType> + <xs:complexType name="tBoundaryDefinitions"> + <xs:sequence> + <xs:element name="Properties" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:any namespace="##other"/> + <xs:element name="PropertyMappings" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="PropertyMapping" type="tPropertyMapping" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="PropertyConstraints" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="PropertyConstraint" type="tPropertyConstraint" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Requirements" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Requirement" type="tRequirementRef" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Capabilities" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Capability" type="tCapabilityRef" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Policies" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Policy" type="tPolicy" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Interfaces" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Interface" type="tExportedInterface" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="tPropertyMapping"> + <xs:attribute name="serviceTemplatePropertyRef" type="xs:string" use="required"/> + <xs:attribute name="targetObjectRef" type="xs:IDREF" use="required"/> + <xs:attribute name="targetPropertyRef" type="xs:string" use="required"/> + </xs:complexType> + <xs:complexType name="tRequirementRef"> + <xs:attribute name="name" type="xs:string" use="optional"/> + <xs:attribute name="ref" type="xs:IDREF" use="required"/> + </xs:complexType> + <xs:complexType name="tCapabilityRef"> + <xs:attribute name="name" type="xs:string" use="optional"/> + <xs:attribute name="ref" type="xs:IDREF" use="required"/> + </xs:complexType> + <xs:complexType name="tEntityType" abstract="true"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Tags" type="tTags" minOccurs="0"/> + <xs:element name="DerivedFrom" minOccurs="0"> + <xs:complexType> + <xs:attribute name="typeRef" type="xs:QName" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="PropertiesDefinition" minOccurs="0"> + <xs:complexType> + <xs:attribute name="element" type="xs:QName"/> + <xs:attribute name="type" type="xs:QName"/> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="name" type="xs:NCName" use="required"/> + <xs:attribute name="abstract" type="tBoolean" default="no"/> + <xs:attribute name="final" type="tBoolean" default="no"/> + <xs:attribute name="targetNamespace" type="xs:anyURI" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tEntityTemplate" abstract="true"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Properties" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:any namespace="##other" processContents="lax"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="PropertyConstraints" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="PropertyConstraint" type="tPropertyConstraint" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="id" type="xs:ID" use="required"/> + <xs:attribute name="type" type="xs:QName" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tNodeTemplate"> + <xs:complexContent> + <xs:extension base="tEntityTemplate"> + <xs:sequence> + <xs:element name="Requirements" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Requirement" type="tRequirement" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Capabilities" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Capability" type="tCapability" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Policies" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Policy" type="tPolicy" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="DeploymentArtifacts" type="tDeploymentArtifacts" minOccurs="0"/> + </xs:sequence> + <xs:attribute name="name" type="xs:string" use="optional"/> + <xs:attribute name="minInstances" type="xs:int" use="optional" default="1"/> + <xs:attribute name="maxInstances" use="optional" default="1"> + <xs:simpleType> + <xs:union> + <xs:simpleType> + <xs:restriction base="xs:nonNegativeInteger"> + <xs:pattern value="([1-9]+[0-9]*)"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="unbounded"/> + </xs:restriction> + </xs:simpleType> + </xs:union> + </xs:simpleType> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tTopologyTemplate"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:choice maxOccurs="unbounded"> + <xs:element name="NodeTemplate" type="tNodeTemplate"/> + <xs:element name="RelationshipTemplate" type="tRelationshipTemplate"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tRelationshipType"> + <xs:complexContent> + <xs:extension base="tEntityType"> + <xs:sequence> + <xs:element name="InstanceStates" type="tTopologyElementInstanceStates" minOccurs="0"/> + <xs:element name="SourceInterfaces" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Interface" type="tInterface" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="TargetInterfaces" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Interface" type="tInterface" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="ValidSource" minOccurs="0"> + <xs:complexType> + <xs:attribute name="typeRef" type="xs:QName" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="ValidTarget" minOccurs="0"> + <xs:complexType> + <xs:attribute name="typeRef" type="xs:QName" use="required"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tRelationshipTypeImplementation"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Tags" type="tTags" minOccurs="0"/> + <xs:element name="DerivedFrom" minOccurs="0"> + <xs:complexType> + <xs:attribute name="relationshipTypeImplementationRef" type="xs:QName" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="RequiredContainerFeatures" type="tRequiredContainerFeatures" minOccurs="0"/> + <xs:element name="ImplementationArtifacts" type="tImplementationArtifacts" minOccurs="0"/> + </xs:sequence> + <xs:attribute name="name" type="xs:NCName" use="required"/> + <xs:attribute name="targetNamespace" type="xs:anyURI" use="optional"/> + <xs:attribute name="relationshipType" type="xs:QName" use="required"/> + <xs:attribute name="abstract" type="tBoolean" use="optional" default="no"/> + <xs:attribute name="final" type="tBoolean" use="optional" default="no"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tRelationshipTemplate"> + <xs:complexContent> + <xs:extension base="tEntityTemplate"> + <xs:sequence> + <xs:element name="SourceElement"> + <xs:complexType> + <xs:attribute name="ref" type="xs:IDREF" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="TargetElement"> + <xs:complexType> + <xs:attribute name="ref" type="xs:IDREF" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="RelationshipConstraints" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="RelationshipConstraint" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:any namespace="##other" processContents="lax" minOccurs="0"/> + </xs:sequence> + <xs:attribute name="constraintType" type="xs:anyURI" use="required"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="name" type="xs:string" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tNodeType"> + <xs:complexContent> + <xs:extension base="tEntityType"> + <xs:sequence> + <xs:element name="RequirementDefinitions" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="RequirementDefinition" type="tRequirementDefinition" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="CapabilityDefinitions" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="CapabilityDefinition" type="tCapabilityDefinition" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="InstanceStates" type="tTopologyElementInstanceStates" minOccurs="0"/> + <xs:element name="Interfaces" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Interface" type="tInterface" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tNodeTypeImplementation"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Tags" type="tTags" minOccurs="0"/> + <xs:element name="DerivedFrom" minOccurs="0"> + <xs:complexType> + <xs:attribute name="nodeTypeImplementationRef" type="xs:QName" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="RequiredContainerFeatures" type="tRequiredContainerFeatures" minOccurs="0"/> + <xs:element name="ImplementationArtifacts" type="tImplementationArtifacts" minOccurs="0"/> + <xs:element name="DeploymentArtifacts" type="tDeploymentArtifacts" minOccurs="0"/> + </xs:sequence> + <xs:attribute name="name" type="xs:NCName" use="required"/> + <xs:attribute name="targetNamespace" type="xs:anyURI" use="optional"/> + <xs:attribute name="nodeType" type="xs:QName" use="required"/> + <xs:attribute name="abstract" type="tBoolean" use="optional" default="no"/> + <xs:attribute name="final" type="tBoolean" use="optional" default="no"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tRequirementType"> + <xs:complexContent> + <xs:extension base="tEntityType"> + <xs:attribute name="requiredCapabilityType" type="xs:QName" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tRequirementDefinition"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Constraints" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Constraint" type="tConstraint" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="name" type="xs:string" use="required"/> + <xs:attribute name="requirementType" type="xs:QName" use="required"/> + <xs:attribute name="lowerBound" type="xs:int" use="optional" default="1"/> + <xs:attribute name="upperBound" use="optional" default="1"> + <xs:simpleType> + <xs:union> + <xs:simpleType> + <xs:restriction base="xs:nonNegativeInteger"> + <xs:pattern value="([1-9]+[0-9]*)"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="unbounded"/> + </xs:restriction> + </xs:simpleType> + </xs:union> + </xs:simpleType> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tRequirement"> + <xs:complexContent> + <xs:extension base="tEntityTemplate"> + <xs:attribute name="name" type="xs:string" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tCapabilityType"> + <xs:complexContent> + <xs:extension base="tEntityType"/> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tCapabilityDefinition"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Constraints" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Constraint" type="tConstraint" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="name" type="xs:string" use="required"/> + <xs:attribute name="capabilityType" type="xs:QName" use="required"/> + <xs:attribute name="lowerBound" type="xs:int" use="optional" default="1"/> + <xs:attribute name="upperBound" use="optional" default="1"> + <xs:simpleType> + <xs:union> + <xs:simpleType> + <xs:restriction base="xs:nonNegativeInteger"> + <xs:pattern value="([1-9]+[0-9]*)"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="unbounded"/> + </xs:restriction> + </xs:simpleType> + </xs:union> + </xs:simpleType> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tCapability"> + <xs:complexContent> + <xs:extension base="tEntityTemplate"> + <xs:attribute name="name" type="xs:string" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tArtifactType"> + <xs:complexContent> + <xs:extension base="tEntityType"/> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tArtifactTemplate"> + <xs:complexContent> + <xs:extension base="tEntityTemplate"> + <xs:sequence> + <xs:element name="ArtifactReferences" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="ArtifactReference" type="tArtifactReference" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="name" type="xs:string" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tDeploymentArtifacts"> + <xs:sequence> + <xs:element name="DeploymentArtifact" type="tDeploymentArtifact" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="tDeploymentArtifact"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:attribute name="name" type="xs:string" use="required"/> + <xs:attribute name="artifactType" type="xs:QName" use="required"/> + <xs:attribute name="artifactRef" type="xs:QName" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tImplementationArtifacts"> + <xs:sequence> + <xs:element name="ImplementationArtifact" maxOccurs="unbounded"> + <xs:complexType> + <xs:complexContent> + <xs:extension base="tImplementationArtifact"/> + </xs:complexContent> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="tImplementationArtifact"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:attribute name="interfaceName" type="xs:anyURI" use="optional"/> + <xs:attribute name="operationName" type="xs:NCName" use="optional"/> + <xs:attribute name="artifactType" type="xs:QName" use="required"/> + <xs:attribute name="artifactRef" type="xs:QName" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tPlans"> + <xs:sequence> + <xs:element name="Plan" type="tPlan" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute name="targetNamespace" type="xs:anyURI" use="optional"/> + </xs:complexType> + <xs:complexType name="tPlan"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Precondition" type="tCondition" minOccurs="0"/> + <xs:element name="InputParameters" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="InputParameter" type="tParameter" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="OutputParameters" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="OutputParameter" type="tParameter" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:choice> + <xs:element name="PlanModel"> + <xs:complexType> + <xs:sequence> + <xs:any namespace="##other" processContents="lax"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="PlanModelReference"> + <xs:complexType> + <xs:attribute name="reference" type="xs:anyURI" use="required"/> + </xs:complexType> + </xs:element> + </xs:choice> + </xs:sequence> + <xs:attribute name="id" type="xs:ID" use="required"/> + <xs:attribute name="name" type="xs:string" use="optional"/> + <xs:attribute name="planType" type="xs:anyURI" use="required"/> + <xs:attribute name="planLanguage" type="xs:anyURI" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tPolicyType"> + <xs:complexContent> + <xs:extension base="tEntityType"> + <xs:sequence> + <xs:element name="AppliesTo" type="tAppliesTo" minOccurs="0"/> + </xs:sequence> + <xs:attribute name="policyLanguage" type="xs:anyURI" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tPolicyTemplate"> + <xs:complexContent> + <xs:extension base="tEntityTemplate"> + <xs:attribute name="name" type="xs:string" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tAppliesTo"> + <xs:sequence> + <xs:element name="NodeTypeReference" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="typeRef" type="xs:QName" use="required"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="tPolicy"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:attribute name="name" type="xs:string" use="optional"/> + <xs:attribute name="policyType" type="xs:QName" use="required"/> + <xs:attribute name="policyRef" type="xs:QName" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tConstraint"> + <xs:sequence> + <xs:any namespace="##other" processContents="lax"/> + </xs:sequence> + <xs:attribute name="constraintType" type="xs:anyURI" use="required"/> + </xs:complexType> + <xs:complexType name="tPropertyConstraint"> + <xs:complexContent> + <xs:extension base="tConstraint"> + <xs:attribute name="property" type="xs:string" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tExtensions"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Extension" type="tExtension" maxOccurs="unbounded"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tExtension"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:attribute name="namespace" type="xs:anyURI" use="required"/> + <xs:attribute name="mustUnderstand" type="tBoolean" use="optional" default="yes"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tParameter"> + <xs:attribute name="name" type="xs:string" use="required"/> + <xs:attribute name="type" type="xs:string" use="required"/> + <xs:attribute name="required" type="tBoolean" use="optional" default="yes"/> + </xs:complexType> + <xs:complexType name="tInterface"> + <xs:sequence> + <xs:element name="Operation" type="tOperation" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute name="name" type="xs:anyURI" use="required"/> + </xs:complexType> + <xs:complexType name="tExportedInterface"> + <xs:sequence> + <xs:element name="Operation" type="tExportedOperation" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute name="name" type="xs:anyURI" use="required"/> + </xs:complexType> + <xs:complexType name="tOperation"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="InputParameters" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="InputParameter" type="tParameter" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="OutputParameters" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="OutputParameter" type="tParameter" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="name" type="xs:NCName" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tExportedOperation"> + <xs:choice> + <xs:element name="NodeOperation"> + <xs:complexType> + <xs:attribute name="nodeRef" type="xs:IDREF" use="required"/> + <xs:attribute name="interfaceName" type="xs:anyURI" use="required"/> + <xs:attribute name="operationName" type="xs:NCName" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="RelationshipOperation"> + <xs:complexType> + <xs:attribute name="relationshipRef" type="xs:IDREF" use="required"/> + <xs:attribute name="interfaceName" type="xs:anyURI" use="required"/> + <xs:attribute name="operationName" type="xs:NCName" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="Plan"> + <xs:complexType> + <xs:attribute name="planRef" type="xs:IDREF" use="required"/> + </xs:complexType> + </xs:element> + </xs:choice> + <xs:attribute name="name" type="xs:NCName" use="required"/> + </xs:complexType> + <xs:complexType name="tCondition"> + <xs:sequence> + <xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute name="expressionLanguage" type="xs:anyURI" use="required"/> + </xs:complexType> + <xs:complexType name="tTopologyElementInstanceStates"> + <xs:sequence> + <xs:element name="InstanceState" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="state" type="xs:anyURI" use="required"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="tArtifactReference"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="Include"> + <xs:complexType> + <xs:attribute name="pattern" type="xs:string" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="Exclude"> + <xs:complexType> + <xs:attribute name="pattern" type="xs:string" use="required"/> + </xs:complexType> + </xs:element> + </xs:choice> + <xs:attribute name="reference" type="xs:anyURI" use="required"/> + </xs:complexType> + <xs:complexType name="tRequiredContainerFeatures"> + <xs:sequence> + <xs:element name="RequiredContainerFeature" type="tRequiredContainerFeature" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="tRequiredContainerFeature"> + <xs:attribute name="feature" type="xs:anyURI" use="required"/> + </xs:complexType> + <xs:simpleType name="tBoolean"> + <xs:restriction base="xs:string"> + <xs:enumeration value="yes"/> + <xs:enumeration value="no"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="importedURI"> + <xs:restriction base="xs:anyURI"/> + </xs:simpleType> +</xs:schema> diff --git a/verigraph/schema/tosca/ToscaTypes_XMLconfig.xsd b/verigraph/schema/tosca/ToscaTypes_XMLconfig.xsd new file mode 100644 index 0000000..98751b4 --- /dev/null +++ b/verigraph/schema/tosca/ToscaTypes_XMLconfig.xsd @@ -0,0 +1,280 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2018 Politecnico di Torino and others. + + All rights reserved. This program and the accompanying materials + are made available under the terms of the Apache License, Version 2.0 + which accompanies this distribution, and is available at + http://www.apache.org/licenses/LICENSE-2.0 +--> + + +<xsd:schema xmlns="http://docs.oasis-open.org/tosca/ns/2011/12/ToscaVerigraphDefinition" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + targetNamespace="http://docs.oasis-open.org/tosca/ns/2011/12/ToscaVerigraphDefinition"> + + <!-- Generic Configuration type, contains a single configuration element --> + <xsd:element name="Configuration"> + <xsd:complexType> + <xsd:choice> + <xsd:element name="antispamConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="source" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="cacheConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="resource" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="dpiConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="notAllowed" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="endhostConfiguration"> + <xsd:complexType> + <xsd:attribute name="body" type="xsd:string" /> + <xsd:attribute name="sequence" type="xsd:integer" /> + <xsd:attribute name="protocol"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="HTTP_REQUEST" /> + <xsd:enumeration value="HTTP_RESPONSE" /> + <xsd:enumeration value="POP3_REQUEST" /> + <xsd:enumeration value="POP3_RESPONSE" /> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="email_from" type="xsd:string" /> + <xsd:attribute name="url" type="xsd:string" /> + <xsd:attribute name="options" type="xsd:string" /> + <xsd:attribute name="destination" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="endpointConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="fieldmodifierConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="firewallConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="elements" maxOccurs="unbounded"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="source" type="xsd:string" /> + <xsd:element name="destination" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="mailclientConfiguration"> + <xsd:complexType> + <xsd:attribute name="mailserver" type="xsd:string" + use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="mailserverConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="natConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="source" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="vpnaccessConfiguration"> + <xsd:complexType> + <xsd:attribute name="vpnexit" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="vpnexitConfiguration"> + <xsd:complexType> + <xsd:attribute name="vpnaccess" type="xsd:string" + use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="webclientConfiguration"> + <xsd:complexType> + <xsd:attribute name="nameWebServer" type="xsd:string" + use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="webserverConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + </xsd:choice> + <xsd:attribute name="confID" type="xsd:string" /> + <xsd:attribute name="confDescr" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + + <!-- <xsd:element name="firewallConfiguration"> + <xsd:complexType > + <xsd:sequence> + <xsd:element ref="elements" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="elements"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="source" type="xsd:string" /> + <xsd:element name="destination" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="endhostConfiguration"> + <xsd:complexType> + <xsd:attribute name="body" type="xsd:string" /> + <xsd:attribute name="sequence" type="xsd:integer" /> + <xsd:attribute name="protocol" type="protocolTypes" /> + <xsd:attribute name="email_from" type="xsd:string" /> + <xsd:attribute name="url" type="xsd:string" /> + <xsd:attribute name="options" type="xsd:string" /> + <xsd:attribute name="destination" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="endpointConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" + nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="antispamConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="source" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="cacheConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="resource" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="dpiConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="notAllowed" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="mailclientConfiguration"> + <xsd:complexType> + <xsd:attribute name="mailserver" type="xsd:string" + use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="mailserverConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" + nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="natConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="source" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="vpnaccessConfiguration"> + <xsd:complexType> + <xsd:attribute name="vpnexit" type="xsd:string" + use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="vpnexitConfiguration"> + <xsd:complexType> + <xsd:attribute name="vpnaccess" type="xsd:string" + use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="webclientConfiguration"> + <xsd:complexType> + <xsd:attribute name="nameWebServer" type="xsd:string" + use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="webserverConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" + nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="fieldmodifierConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" + nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:simpleType name="functionalTypes"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="FIREWALL" /> + <xsd:enumeration value="ENDHOST" /> + <xsd:enumeration value="ENDPOINT" /> + <xsd:enumeration value="ANTISPAM" /> + <xsd:enumeration value="CACHE" /> + <xsd:enumeration value="DPI" /> + <xsd:enumeration value="MAILCLIENT" /> + <xsd:enumeration value="MAILSERVER" /> + <xsd:enumeration value="NAT" /> + <xsd:enumeration value="VPNACCESS" /> + <xsd:enumeration value="VPNEXIT" /> + <xsd:enumeration value="WEBCLIENT" /> + <xsd:enumeration value="WEBSERVER" /> + <xsd:enumeration value="FIELDMODIFIER" /> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="protocolTypes"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="HTTP_REQUEST" /> + <xsd:enumeration value="HTTP_RESPONSE" /> + <xsd:enumeration value="POP3_REQUEST" /> + <xsd:enumeration value="POP3_RESPONSE" /> + </xsd:restriction> + </xsd:simpleType> + + --> + +</xsd:schema>
\ No newline at end of file diff --git a/verigraph/schema/tosca/ToscaVerigraphDefinitions.xml b/verigraph/schema/tosca/ToscaVerigraphDefinitions.xml new file mode 100644 index 0000000..4f49037 --- /dev/null +++ b/verigraph/schema/tosca/ToscaVerigraphDefinitions.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2018 Politecnico di Torino and others. + + All rights reserved. This program and the accompanying materials + are made available under the terms of the Apache License, Version 2.0 + which accompanies this distribution, and is available at + http://www.apache.org/licenses/LICENSE-2.0 +--> + +<Definitions id="Verigraph_Definitions" name="Verigraph Type Definition" + xmlns="http://docs.oasis-open.org/tosca/ns/2011/12" + targetNamespace="http://docs.oasis-open.org/tosca/ns/2011/12/ToscaVerigraphDefinition"> + + <import importType="http://www.w3.org/2001/XMLSchema" + namespace="http://docs.oasis-open.org/tosca/ns/2011/12/ToscaVerigraphDefinition" + location="./ToscaTypes_XMLconfig.xsd" /> + + <NodeType name="AntispamType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="CacheType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="DpiType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="EndhostType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="EndpointType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="FieldModifierType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="FirewallType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="MailclientType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="MailserverType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="NatType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="VpnAccessType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="VpnExitType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="WebclientType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="WebserverType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <RelationshipType name="linkedTo" /> + +</Definitions>
\ No newline at end of file diff --git a/verigraph/schema/tosca/yamlToscaDefinitions.yaml b/verigraph/schema/tosca/yamlToscaDefinitions.yaml new file mode 100644 index 0000000..e72a5da --- /dev/null +++ b/verigraph/schema/tosca/yamlToscaDefinitions.yaml @@ -0,0 +1,157 @@ +############################################################################## +# Copyright (c) 2018 Politecnico di Torino and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +#Tosca definitions for Verigraph extension in Tosca Yaml simple profile + +tosca_definitions_version: http://docs.oasis-open.org/tosca/ns/simple/yaml/1.0 + +description: node type definitions exetending tosca types for support to Verigraph verification system + +node_types: + verigraph.types.Antispam: + derived_from: tosca.nodes.Root + description: verigraph Antispam node + properties: + sources: + type: list + entry_schema: + type: string + + verigraph.types.Cache: + derived_from: tosca.nodes.Root + description: verigraph Cache node + properties: + resources: + type: list + entry_schema: + type: string + + verigraph.types.Dpi: + derived_from: tosca.nodes.Root + description: verigraph Dpi node + properties: + notAllowedList: + type: list + entry_schema: + type: string + + verigraph.types.Endhost: + derived_from: tosca.nodes.Root + description: verigraph endhost node + attributes: + body: + type: string + sequence: + type: integer + protocol: + type: string + constraints: + - valid_values: [ HTTP_REQUEST, HTTP_RESPONSE, POP3_REQUEST, POP3_RESOPONSE ] + email_from: + type: string + url: + type: string + options: + type: string + destination: + type: string + + verigraph.types.Endpoint: + derived_from: tosca.nodes.Root + description: verigraph Endpoint node + properties: + names: + type: list + entry_schema: + type: string + + verigraph.types.FieldModifier: + derived_from: tosca.nodes.Root + description: verigraph Field Modifier node + properties: + names: + type: list + entry_schema: + type: string + + verigraph.types.Firewall: + derived_from: tosca.nodes.Root + description: verigraph Firewall node + properties: + elements: + type: map + entry_schema: + description: "source : destination" firewall mapping + type: string + + verigraph.types.MailClient: + derived_from: tosca.nodes.Root + description: verigraph Mail Client node + attributes: + mailserver: + type: string + + verigraph.types.MailServer: + derived_from: tosca.nodes.Root + descrtiption: verigraph Mail Server node + properties: + names: + type: list + entry_schema: + type: string + + verigraph.types.Nat: + derived_from: tosca.nodes.Root + descrtiption: verigraph Nat node + properties: + sources: + type: list + entry_schema: + type: string + + verigraph.types.VpnAccess: + deriver_from: tosca.nodes.Root + descrtiption: verigraph Vpn Access node + attributes: + vpnexit: + type: string + + verigraph.types.VpnExit: + derived_from: tosca.nodes.Root + descrtiption: verigraph Vpn Exit node + attributes: + vpnaccess: + type: string + + verigraph.types.WebClient: + derived_from: tosca.nodes.Root + descrtiption: verigraph web Client node + attributes: + nameWebServer: + type: string + + verigraph.types.WebServer: + derived_from: tosca.nodes.Root + descrtiption: verigraph web Server node + properties: + names: + type: list + entry_schema: + type: string + +relationship_types: + verigraph.relationshipType.generic: + derived_from: tosca.relationships.Root + properties: + name: + type: string + source_id: + type: string + target_id: + type: string diff --git a/verigraph/src/it/polito/verigraph/grpc/client/ToscaClient.java b/verigraph/src/it/polito/verigraph/grpc/client/ToscaClient.java new file mode 100644 index 0000000..dbf8442 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/grpc/client/ToscaClient.java @@ -0,0 +1,299 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.grpc.client;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.StatusRuntimeException;
+import it.polito.verigraph.grpc.GetRequest;
+import it.polito.verigraph.grpc.GraphGrpc;
+import it.polito.verigraph.grpc.NewGraph;
+import it.polito.verigraph.grpc.NewTopologyTemplate;
+import it.polito.verigraph.grpc.NodeTemplateGrpc;
+import it.polito.verigraph.grpc.RequestID;
+import it.polito.verigraph.grpc.Status;
+import it.polito.verigraph.grpc.TopologyTemplateGrpc;
+import it.polito.verigraph.grpc.ToscaPolicy;
+import it.polito.verigraph.grpc.ToscaRequestID;
+import it.polito.verigraph.grpc.ToscaTestGrpc;
+import it.polito.verigraph.grpc.ToscaVerificationGrpc;
+import it.polito.verigraph.grpc.VerigraphGrpc;
+
+public class ToscaClient {
+
+ private final ManagedChannel channel;
+ private final VerigraphGrpc.VerigraphBlockingStub blockingStub;
+
+ public ToscaClient(String host, int port) {
+ this(ManagedChannelBuilder.forAddress(host, port).usePlaintext(true));
+ }
+
+ /** Construct client for accessing toscaVerigraph server using the existing channel. */
+ public ToscaClient(ManagedChannelBuilder<?> channelBuilder) {
+ channel = channelBuilder.build();
+ blockingStub = VerigraphGrpc.newBlockingStub(channel);
+ }
+
+ /** Close the channel */
+ public void shutdown() throws InterruptedException {
+ channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
+ }
+
+ /** Obtain a list of the available TopologyTemplates*/
+ public List<TopologyTemplateGrpc> getTopologyTemplates(){
+ List<TopologyTemplateGrpc> templates = new ArrayList<TopologyTemplateGrpc>();
+ GetRequest request = GetRequest.newBuilder().build();
+ boolean response_ok = true;
+
+ /*Iterates on received topology templates, prints on log file in case of errors*/
+ Iterator<TopologyTemplateGrpc> receivedTemplates;
+ try {
+ receivedTemplates = blockingStub.getTopologyTemplates(request);
+ System.out.println("++ Receiving TopologyTemplates...");
+ while(receivedTemplates.hasNext()) {
+ TopologyTemplateGrpc received = receivedTemplates.next();
+ if(received.getErrorMessage().equals("")) {
+ System.out.println("++ Correctly received TopologyTemplate --> id:" + received.getId());
+ templates.add(received);
+ } else
+ System.out.println("-- Received a TopologyTemplate with error: " + received.getErrorMessage());
+ }
+ } catch (StatusRuntimeException ex) {
+ System.out.println("-- RPC failed: " + ex.getMessage());
+ response_ok = false;
+ }
+ if(response_ok) {
+ System.out.println("++ All TopologyTemplates correctly received.");
+ return templates;
+ } else {
+ return null; //Function returns null in case of error to differentiate from empty list case.
+ }
+ }
+
+
+ /** Obtain a TopologyTemplate by ID */
+ public TopologyTemplateGrpc getTopologyTemplate(String id) {
+ ToscaRequestID request = ToscaRequestID.newBuilder().setIdTopologyTemplate(id).build();
+ TopologyTemplateGrpc response = TopologyTemplateGrpc.newBuilder().build();
+ try {
+ System.out.println("++ Receiving TopologyTemplate...");
+ response = blockingStub.getTopologyTemplate(request);
+ if(response.getErrorMessage().equals("")){
+ System.out.println("++ Received TopologyTemplate --> id:" + response.getId());
+ return response;
+ } else {
+ System.out.println("-- Error: " + response.getErrorMessage());
+ return response;
+ }
+ } catch (StatusRuntimeException ex) {
+ System.out.println("-- RPC failed: " + ex.getStatus());
+ return TopologyTemplateGrpc.newBuilder().setErrorMessage(ex.getStatus().getDescription()).build();
+ }
+ }
+
+
+ /** Creates a new TopologyTemplate, takes in input a TopologyTemplateGrpc */
+ public NewTopologyTemplate createTopologyTemplate(TopologyTemplateGrpc topol) {
+ try {
+ //Sending new Topology and analyzing response
+ System.out.println("++ Sending the new TopologyTemplate...");
+ NewTopologyTemplate response = blockingStub.createTopologyTemplate(topol);
+ if(response.getSuccess())
+ System.out.println("++ TopologyTemplate successfully created with id: "+ response.getTopologyTemplate().getId());
+ else
+ System.out.println("-- TopologyTemplate creation failed: " + response.getErrorMessage());
+ return response;
+
+ } catch (StatusRuntimeException ex) {
+ System.out.println("-- RPC failed: " + ex.getStatus());
+ return NewTopologyTemplate.newBuilder().setSuccess(false).setErrorMessage(ex.getStatus().getDescription()).build();
+ //getDescription may be empty
+ }
+ }
+
+
+ /** Update a TopologyTemplate, takes in input a TopologyTemplateGrpc and the Topology's ID to be updated*/
+ public NewTopologyTemplate updateTopologyTemplate(TopologyTemplateGrpc topol, String id) {
+ //Checking if the inserted string is an object
+ try {
+ Long.valueOf(id);
+ } catch (NumberFormatException ex) {
+ System.out.println("-- The ID must a number according to Verigraph implementation.");
+ return NewTopologyTemplate.newBuilder().setSuccess(false)
+ .setErrorMessage("The ID must a number according to Verigraph implementation.").build();
+ }
+
+ //Update the topology ID
+ TopologyTemplateGrpc.Builder updTopol = TopologyTemplateGrpc.newBuilder();
+ try {
+ updTopol.setId(id)
+ .addAllNodeTemplate(topol.getNodeTemplateList())
+ .addAllRelationshipTemplate(topol.getRelationshipTemplateList());
+ } catch (Exception ex) {
+ System.out.println("-- Error: Incorrect fields implementation.");
+ return NewTopologyTemplate.newBuilder().setSuccess(false).setErrorMessage("Error: Incorrect fields implementation.").build();
+ }
+
+ //Sending updated Topology and analyzing response
+ try {
+
+ System.out.println("++ Sending the updated TopologyTemplate...");
+ NewTopologyTemplate response = blockingStub.updateTopologyTemplate(updTopol.build());
+ if(response.getSuccess())
+ System.out.println("++ TopologyTemplate successfully updated.");
+ else
+ System.out.println("-- TopologyTemplate not updated: " + response.getErrorMessage());
+ return response;
+
+ } catch (StatusRuntimeException ex) {
+ System.out.println("-- RPC failed: " + ex.getStatus());
+ return NewTopologyTemplate.newBuilder().setSuccess(false).setErrorMessage(ex.getStatus().getDescription()).build();
+ }
+ }
+
+
+ /** Delete a TopologyTemplate by ID */
+ public Status deleteTopologyTemplate(String id) {
+ try {
+ Long.valueOf(id);
+ } catch (NumberFormatException ex) {
+ System.out.println("-- The ID must a number according to Verigraph implementation.");
+ return Status.newBuilder().setSuccess(false)
+ .setErrorMessage("The ID must a number according to Verigraph implementation.").build();
+ }
+ ToscaRequestID request = ToscaRequestID.newBuilder().setIdTopologyTemplate(id).build();
+ try {
+ System.out.println("++ Sending delete request...");
+ Status response = blockingStub.deleteTopologyTemplate(request);
+ if(response.getSuccess())
+ System.out.println("++ TopologyTemplate successfully deleted.");
+ else
+ System.out.println("-- Error deleting TopologyTemplate : " + response.getErrorMessage());
+ return response;
+
+ } catch (StatusRuntimeException ex) {
+ System.out.println("-- RPC failed: " + ex.getStatus());
+ return Status.newBuilder().setSuccess(false).setErrorMessage(ex.getStatus().getDescription()).build();
+ }
+ }
+
+
+ /** VerifyPolicy */
+ public ToscaVerificationGrpc verifyPolicy(ToscaPolicy policy){
+ ToscaVerificationGrpc response;
+ try {
+ System.out.println("++ Sending ToscaPolicy...");
+ response = blockingStub.verifyToscaPolicy(policy);
+ if(!response.getErrorMessage().equals("")){
+ System.out.println("-- Error in operation: " + response.getErrorMessage());
+ }
+ else {
+ System.out.println("++ Result: " + response.getResult());
+ System.out.println("++ Comment: " + response.getComment());
+
+ for(ToscaTestGrpc test : response.getTestList()){
+ System.out.println("++ Traversed nodes:");
+ for(NodeTemplateGrpc node : test.getNodeTemplateList()){
+ System.out.println("\t Node "+node.getName());
+ }
+ }
+ }
+ return response;
+ } catch (StatusRuntimeException e) {
+ System.out.println("-- RPC failed: " + e.getStatus());
+ return ToscaVerificationGrpc.newBuilder().setSuccessOfOperation(false)
+ .setErrorMessage(e.getStackTrace().toString()).build();
+ }
+ }
+
+
+ //Methods added for backward compatibility with JSON grpc, only create and update methods need to be redefined
+ //The reason is that the tosca Grpc converter requires a coherent numbering of IDs while the previous
+ //implementations exploits names to identify nodes and can considers IDs as not strictly required attributes.
+
+ public NewGraph createGraph(GraphGrpc gr) {
+ NewGraph response;
+ try {
+ response = blockingStub.createGraph(gr);
+ if(response.getSuccess())
+ System.out.println("++ TopologyTemplate successfully created with id: "+ response.getGraph().getId());
+ else
+ System.out.println("-- TopologyTemplate creation failed: " + response.getErrorMessage());
+ return response;
+ } catch (StatusRuntimeException e) {
+ System.err.println("-- RPC failed: " + e.getStatus());
+ return NewGraph.newBuilder().setSuccess(false).setErrorMessage(e.getStatus().getDescription()).build();
+ }
+
+ }
+
+ public NewGraph updateGraph(long idGraph, GraphGrpc newGraph) {
+
+ GraphGrpc gr = GraphGrpc.newBuilder(newGraph).setId(idGraph).build();
+ NewGraph response;
+ try {
+ response = blockingStub.updateGraph(gr);
+ if(response.getSuccess())
+ System.out.println("++ TopologyTemplate successfully created with id: "+ response.getGraph().getId());
+ else
+ System.out.println("-- TopologyTemplate creation failed: " + response.getErrorMessage());
+ return response;
+ } catch (StatusRuntimeException e) {
+ System.err.println("-- RPC failed: " + e.getStatus());
+ return NewGraph.newBuilder().setSuccess(false).setErrorMessage(e.getStatus().getDescription()).build();
+ }
+ }
+
+ public GraphGrpc getGraph(long idGraph) {
+
+ RequestID request = RequestID.newBuilder().setIdGraph(idGraph).build() ;
+ try {
+ System.out.println("++ Receiving TopologyTemplate...");
+ GraphGrpc graph = blockingStub.getGraph(request);
+ System.out.println("++ Received TopologyTemplate --> id:" + graph.getId());
+ if(!graph.getErrorMessage().equals("")){
+ System.out.println("-- Error : " + graph.getErrorMessage());
+ return graph;
+ }
+ return graph;
+ } catch (StatusRuntimeException ex) {
+ System.err.println("-- RPC failed: " + ex.getStatus());
+ return null;
+ }
+ }
+
+
+ public List<GraphGrpc> getGraphs() {
+ List<GraphGrpc> graphsReceived = new ArrayList<GraphGrpc>();
+ GetRequest request = GetRequest.newBuilder().build();
+ Iterator<GraphGrpc> graphs;
+ try {
+ graphs = blockingStub.getGraphs(request);
+ System.out.println("++ Receiving TopologyTemplates...");
+ while (graphs.hasNext()) {
+ GraphGrpc graph = graphs.next();
+ if(graph.getErrorMessage().equals("")){
+ System.out.println("++ Correctly received graph --> id:" + graph.getId());
+ graphsReceived.add(graph);
+ }else{
+ System.out.println("-- Received a graph with error : " + graph.getErrorMessage());
+ }
+ }
+ } catch (StatusRuntimeException ex) {
+ System.err.println("-- RPC failed : " + ex.getStatus());
+ return null;
+ }
+ return graphsReceived;
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/grpc/server/GrpcUtils.java b/verigraph/src/it/polito/verigraph/grpc/server/GrpcUtils.java index 43859db..96c52a5 100644 --- a/verigraph/src/it/polito/verigraph/grpc/server/GrpcUtils.java +++ b/verigraph/src/it/polito/verigraph/grpc/server/GrpcUtils.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Politecnico di Torino and others. + * Copyright (c) 2017/18 Politecnico di Torino and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Apache License, Version 2.0 @@ -12,16 +12,18 @@ import java.io.IOException; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Splitter; + import it.polito.verigraph.grpc.ConfigurationGrpc; import it.polito.verigraph.grpc.GraphGrpc; import it.polito.verigraph.grpc.NeighbourGrpc; import it.polito.verigraph.grpc.NodeGrpc; +import it.polito.verigraph.grpc.NodeGrpc.FunctionalType; import it.polito.verigraph.grpc.TestGrpc; import it.polito.verigraph.grpc.VerificationGrpc; -import it.polito.verigraph.grpc.NodeGrpc.FunctionalType; import it.polito.verigraph.model.Configuration; import it.polito.verigraph.model.Graph; import it.polito.verigraph.model.Neighbour; @@ -29,6 +31,7 @@ import it.polito.verigraph.model.Node; import it.polito.verigraph.model.Test; import it.polito.verigraph.model.Verification; + public class GrpcUtils { private static final Logger logger = Logger.getLogger(GrpcUtils.class.getName()); @@ -43,6 +46,7 @@ public class GrpcUtils { //id is not present Neighbour ne = new Neighbour(); ne.setName(request.getName()); + ne.setId(request.getId()); return ne; } @@ -86,13 +90,17 @@ public class GrpcUtils { } public static Node deriveNode(NodeGrpc request) { - //id is not present + //id is not present Node node = new Node(); node.setName(request.getName()); node.setFunctional_type(request.getFunctionalType().toString()); Configuration conf = deriveConfiguration(request.getConfiguration()); node.setConfiguration(conf); + //Modification for Tosca CLI + Long id = request.getId(); + if( id != null) node.setId(request.getId()); + Map<Long,Neighbour> neighours = node.getNeighbours(); long i = 1; for(NeighbourGrpc neighbour:request.getNeighbourList()){ @@ -106,7 +114,7 @@ public class GrpcUtils { public static GraphGrpc obtainGraph(Graph graph){ GraphGrpc.Builder gr = GraphGrpc.newBuilder(); gr.setId(graph.getId()); - for(Node node:graph.getNodes().values()){ + for(Node node : graph.getNodes().values()){ NodeGrpc ng = obtainNode(node); gr.addNode(ng); } @@ -116,14 +124,16 @@ public class GrpcUtils { public static Graph deriveGraph(GraphGrpc request) { //id is not present Graph graph = new Graph(); - + //Modification for Tosca CLI + Long id = request.getId(); + if( id != null) graph.setId(request.getId()); + long i=1; Map<Long, Node> nodes= graph.getNodes(); for(NodeGrpc node:request.getNodeList()){ Node ng = deriveNode(node); - nodes.put(i++, ng); + nodes.put(i++, ng); } - return graph; } @@ -142,12 +152,13 @@ public class GrpcUtils { return ver.build(); } - /**Intended for string that begins with "?" - * */ + + /** Intended for string that begins with "?" */ public static Map<String,String> getParamGivenString(String str){ String string = str.substring(1); final Map<String, String> map = Splitter.on('&').trimResults().withKeyValueSeparator("="). split(string); return map; } + } diff --git a/verigraph/src/it/polito/verigraph/grpc/server/Service.java b/verigraph/src/it/polito/verigraph/grpc/server/Service.java index 1839b7e..c6b69b0 100644 --- a/verigraph/src/it/polito/verigraph/grpc/server/Service.java +++ b/verigraph/src/it/polito/verigraph/grpc/server/Service.java @@ -15,9 +15,13 @@ import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; + import io.grpc.Server; import io.grpc.ServerBuilder; import io.grpc.stub.StreamObserver; +import it.polito.verigraph.exception.BadRequestException; +import it.polito.verigraph.exception.DataNotFoundException; +import it.polito.verigraph.exception.ForbiddenException; import it.polito.verigraph.grpc.ConfigurationGrpc; import it.polito.verigraph.grpc.GetRequest; import it.polito.verigraph.grpc.GraphGrpc; @@ -25,15 +29,17 @@ import it.polito.verigraph.grpc.NeighbourGrpc; import it.polito.verigraph.grpc.NewGraph; import it.polito.verigraph.grpc.NewNeighbour; import it.polito.verigraph.grpc.NewNode; +import it.polito.verigraph.grpc.NewTopologyTemplate; import it.polito.verigraph.grpc.NodeGrpc; import it.polito.verigraph.grpc.Policy; import it.polito.verigraph.grpc.RequestID; import it.polito.verigraph.grpc.Status; +import it.polito.verigraph.grpc.TopologyTemplateGrpc; +import it.polito.verigraph.grpc.ToscaPolicy; +import it.polito.verigraph.grpc.ToscaRequestID; +import it.polito.verigraph.grpc.ToscaVerificationGrpc; import it.polito.verigraph.grpc.VerificationGrpc; import it.polito.verigraph.grpc.VerigraphGrpc; -import it.polito.verigraph.exception.BadRequestException; -import it.polito.verigraph.exception.DataNotFoundException; -import it.polito.verigraph.exception.ForbiddenException; import it.polito.verigraph.model.Configuration; import it.polito.verigraph.model.Graph; import it.polito.verigraph.model.Neighbour; @@ -44,6 +50,8 @@ import it.polito.verigraph.service.GraphService; import it.polito.verigraph.service.NeighbourService; import it.polito.verigraph.service.NodeService; import it.polito.verigraph.service.VerificationService; +import it.polito.verigraph.tosca.converter.grpc.GraphToGrpc; +import it.polito.verigraph.tosca.converter.grpc.GrpcToGraph; public class Service { /** Port on which the server should run. */ @@ -107,7 +115,7 @@ public class Service { } } - /**Here start method of my implementation*/ + /** Here start methods */ private class VerigraphImpl extends VerigraphGrpc.VerigraphImplBase{ /** Here start methods of GraphResource*/ @@ -307,8 +315,7 @@ public class Service { @Override public void updateNode(NodeGrpc request, StreamObserver<NewNode> responseObserver) { - NewNode.Builder response = NewNode.newBuilder(); - try{ + NewNode.Builder response = NewNode.newBuilder(); try{ Node node = GrpcUtils.deriveNode(request); node.setId(request.getId()); Node newNode = nodeService.updateNode(request.getIdGraph(), node); @@ -340,7 +347,8 @@ public class Service { } Node node = nodeService.getNode(request.getIdGraph(), request.getIdNode()); if (node == null){ - throw new BadRequestException("Node with id " + request.getIdNode() + " not found in graph with id " + request.getIdGraph()); + throw new BadRequestException("Node with id " + request.getIdNode() + + " not found in graph with id " + request.getIdGraph()); } Configuration nodeConfiguration = GrpcUtils.deriveConfiguration(request); Node nodeCopy = new Node(); @@ -386,8 +394,7 @@ public class Service { NeighbourGrpc nr = NeighbourGrpc.newBuilder().setErrorMessage(internalError).build(); responseObserver.onNext(nr); logger.log(Level.WARNING, ex.getMessage()); - } - responseObserver.onCompleted(); + } responseObserver.onCompleted(); } @Override @@ -462,5 +469,149 @@ public class Service { responseObserver.onNext(response.build()); responseObserver.onCompleted(); } + + /** Here start methods of TOSCA gRPC server */ @Override + public void getTopologyTemplates (GetRequest request, StreamObserver<TopologyTemplateGrpc> responseObserver) { + boolean not_correct = false; + try { + for(Graph item : graphService.getAllGraphs()) { + TopologyTemplateGrpc topol = GraphToGrpc.obtainTopologyTemplate(item); + responseObserver.onNext(topol); + } + } catch(Exception ex){ + logger.log(Level.WARNING, ex.getMessage()); + not_correct = true; + } + if(not_correct) + responseObserver.onNext(TopologyTemplateGrpc.newBuilder() + .setErrorMessage("Internal Server Error while retrieving TopologyTemplate").build()); + responseObserver.onCompleted(); + } + + @Override + public void getTopologyTemplate (ToscaRequestID request, StreamObserver<TopologyTemplateGrpc> responseObserver) { + try { + Long graphID = Long.valueOf(request.getIdTopologyTemplate()); + //this method will throw a NumberFormatException in case the ID is not representable as a long + Graph graph = graphService.getGraph(graphID); + TopologyTemplateGrpc topol = GraphToGrpc.obtainTopologyTemplate(graph); + responseObserver.onNext(topol); + } catch(ForbiddenException | DataNotFoundException ex) { + TopologyTemplateGrpc topolError = TopologyTemplateGrpc.newBuilder().setErrorMessage(ex.getMessage()).build(); + responseObserver.onNext(topolError); + logger.log(Level.WARNING, ex.getMessage()); + } catch(NumberFormatException ex) { + TopologyTemplateGrpc topolError = TopologyTemplateGrpc.newBuilder() + .setErrorMessage("The TopologyTemplate ID must be a long value.").build(); + responseObserver.onNext(topolError); + logger.log(Level.WARNING, ex.getMessage()); + } catch(Exception ex) { + TopologyTemplateGrpc topolError = TopologyTemplateGrpc.newBuilder().setErrorMessage(internalError).build(); + responseObserver.onNext(topolError); + logger.log(Level.WARNING, ex.getMessage()); + } + responseObserver.onCompleted(); + } + + @Override + public void createTopologyTemplate (TopologyTemplateGrpc request, StreamObserver<NewTopologyTemplate> responseObserver) { + NewTopologyTemplate.Builder response = NewTopologyTemplate.newBuilder(); + try{ + Graph graph = GrpcToGraph.deriveGraph(request); + Graph newGraph = graphService.addGraph(graph); + response.setSuccess(true).setTopologyTemplate(GraphToGrpc.obtainTopologyTemplate(newGraph)); + } catch(BadRequestException ex) { + ex.printStackTrace(); + response.setSuccess(false).setErrorMessage("Provided invalid request to the service."); + logger.log(Level.WARNING, ex.getClass().toString()); + logger.log(Level.WARNING, ex.getMessage()); + } catch(Exception ex) { + ex.printStackTrace(); + response.setSuccess(false).setErrorMessage(internalError); + logger.log(Level.WARNING, ex.getClass().toString()); + logger.log(Level.WARNING, ex.getMessage()); + } + responseObserver.onNext(response.build()); + responseObserver.onCompleted(); + } + + + @Override + public void updateTopologyTemplate (TopologyTemplateGrpc request, StreamObserver<NewTopologyTemplate> responseObserver) { + NewTopologyTemplate.Builder response = NewTopologyTemplate.newBuilder(); + try{ + Graph graph = GrpcToGraph.deriveGraph(request); + Graph newGraph = graphService.updateGraph(graph); + response.setSuccess(true).setTopologyTemplate(GraphToGrpc.obtainTopologyTemplate(newGraph)); + } catch(ForbiddenException | DataNotFoundException | BadRequestException ex){ + response.setSuccess(false).setErrorMessage(ex.getMessage()); + logger.log(Level.WARNING, ex.getMessage()); + } catch(Exception ex){ + response.setSuccess(false).setErrorMessage(internalError); + logger.log(Level.WARNING, ex.getMessage()); + } + responseObserver.onNext(response.build()); + responseObserver.onCompleted(); + } + + + @Override + public void deleteTopologyTemplate (ToscaRequestID request, StreamObserver<Status> responseObserver) { + Status.Builder response = Status.newBuilder(); + Long graphID = null; + try{ + graphID = Long.valueOf(request.getIdTopologyTemplate()); + //this method will throw a NumberFormatException in case the ID is not representable as a long + graphService.removeGraph(graphID); + response.setSuccess(true); + } catch(ForbiddenException | DataNotFoundException ex) { + response.setSuccess(false).setErrorMessage(ex.getMessage()); + logger.log(Level.WARNING, ex.getMessage()); + } catch(NumberFormatException ex) { + response.setSuccess(false).setErrorMessage("The TopologyTemplate ID must be a long value."); + logger.log(Level.WARNING, ex.getMessage()); + } catch(Exception ex) { + response.setSuccess(false).setErrorMessage(internalError); + logger.log(Level.WARNING, ex.getMessage()); + } + responseObserver.onNext(response.build()); + responseObserver.onCompleted(); + } + + + @Override + public void verifyToscaPolicy(ToscaPolicy request, StreamObserver<ToscaVerificationGrpc> responseObserver) { + try{ + //Convert request + VerificationBean verify = new VerificationBean(); + verify.setDestination(request.getDestination()); + verify.setSource(request.getSource()); + verify.setType(request.getType().toString()); + verify.setMiddlebox(request.getMiddlebox()); + + //Convert Response + Long graphID = Long.valueOf(request.getIdTopologyTemplate()); + //this method will throw a NumberFormatException in case the ID is not representable as a long + Verification ver = verificationService.verify(graphID, verify); + responseObserver.onNext(GraphToGrpc.obtainToscaVerification(ver)); + } catch(ForbiddenException | DataNotFoundException | BadRequestException ex) { + ToscaVerificationGrpc verError = ToscaVerificationGrpc.newBuilder().setSuccessOfOperation(false) + .setErrorMessage(ex.getMessage()).build(); + responseObserver.onNext(verError); + logger.log(Level.WARNING, ex.getMessage()); + } catch(NumberFormatException ex) { + ToscaVerificationGrpc verError = ToscaVerificationGrpc.newBuilder().setSuccessOfOperation(false) + .setErrorMessage("The TopologyTemplate ID must be a long value.").build(); + responseObserver.onNext(verError); + logger.log(Level.WARNING, ex.getMessage()); + } catch(Exception ex) { + ToscaVerificationGrpc verError = ToscaVerificationGrpc.newBuilder().setSuccessOfOperation(false) + .setErrorMessage(internalError).build(); + responseObserver.onNext(verError); + logger.log(Level.WARNING, ex.getMessage()); + } responseObserver.onCompleted(); + } + + } } diff --git a/verigraph/src/it/polito/verigraph/grpc/tosca/test/GrpcToscaTest.java b/verigraph/src/it/polito/verigraph/grpc/tosca/test/GrpcToscaTest.java new file mode 100644 index 0000000..5771406 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/grpc/tosca/test/GrpcToscaTest.java @@ -0,0 +1,425 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.grpc.tosca.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.junit.runners.MethodSorters;
+
+import it.polito.verigraph.grpc.NewTopologyTemplate;
+import it.polito.verigraph.grpc.NodeTemplateGrpc;
+import it.polito.verigraph.grpc.NodeTemplateGrpc.Type;
+import it.polito.verigraph.grpc.RelationshipTemplateGrpc;
+import it.polito.verigraph.grpc.Status;
+import it.polito.verigraph.grpc.TopologyTemplateGrpc;
+import it.polito.verigraph.grpc.ToscaConfigurationGrpc;
+import it.polito.verigraph.grpc.ToscaPolicy;
+import it.polito.verigraph.grpc.ToscaPolicy.PolicyType;
+import it.polito.verigraph.grpc.ToscaVerificationGrpc;
+import it.polito.verigraph.grpc.client.ToscaClient;
+import it.polito.verigraph.grpc.server.Service;
+
+@RunWith(JUnit4.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class GrpcToscaTest {
+ private Service server;
+ private ToscaClient client;
+ private TopologyTemplateGrpc testTemplate, simpleTestTemplate;
+
+ public GrpcToscaTest() {
+ this.generateTestTemplate();
+ }
+
+ @Before
+ public void setUpBeforeClass() throws Exception {
+ client = new ToscaClient("localhost" , 50051);
+ server = new Service(50051);
+ server.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ server.stop();
+ client.shutdown();
+ }
+
+
+ @Test
+ public void test0Creation() {
+ System.out.println("\nTest A: Graph Creation.");
+
+ NewTopologyTemplate response = client.createTopologyTemplate(testTemplate);
+ assertNotNull("Returned a NULL graph", response);
+ assertEquals(response.getSuccess(), true);
+ assertEquals("Error report: " + response.getErrorMessage(), "", response.getErrorMessage());
+
+ Status resp = client.deleteTopologyTemplate(response.getTopologyTemplate().getId());
+ assertEquals("Error while deleting testTemplate.", true, resp.getSuccess());
+
+ System.out.println("Test A completed\n");
+
+ return;
+ }
+
+
+ @Test
+ public void test1Reading() {
+ System.out.println("\nTest B: Graph Reading.");
+
+ //Creating a test graph on remote repository
+ System.out.println("Phase B.1 -- Creating a test graph.");
+ NewTopologyTemplate response = client.createTopologyTemplate(simpleTestTemplate);
+ assertNotNull("Returned a NULL graph", response);
+ assertEquals(true, response.getSuccess());
+ assertEquals("Error report: " + response.getErrorMessage(), "", response.getErrorMessage());
+
+ //Reading remote graph.
+ System.out.println("Phase B.2 -- Reading remote graph.");
+ TopologyTemplateGrpc retrieved = client.getTopologyTemplate(response.getTopologyTemplate().getId());
+ assertNotNull("Retrieved a NULL graph", retrieved);
+ assertEquals(retrieved.getId(), response.getTopologyTemplate().getId());
+
+ //Nodes checking
+ System.out.println("Phase B.3 -- Checking graph's nodes.");
+ assertEquals(retrieved.getNodeTemplateCount(), 3);
+ assertEquals("Node1 name error", response.getTopologyTemplate().getNodeTemplateList().get(0).getName(),
+ retrieved.getNodeTemplateList().get(0).getName());
+ assertEquals("Node2 name error", response.getTopologyTemplate().getNodeTemplateList().get(1).getName(),
+ retrieved.getNodeTemplateList().get(1).getName());
+ assertEquals("Node3 name error", response.getTopologyTemplate().getNodeTemplateList().get(2).getName(),
+ retrieved.getNodeTemplateList().get(2).getName());
+
+ //Relationships checking
+ System.out.println("Phase B.4 -- Checking graph's relationships.");
+ assertEquals(retrieved.getRelationshipTemplateCount(), 4);
+ String source1=null, target1=null;
+ String source2=null, target2=null;
+ String source3=null, target3=null;
+ String source4=null, target4=null;
+ for (NodeTemplateGrpc node : retrieved.getNodeTemplateList()){
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(0).getIdSourceNodeTemplate()))
+ source1=node.getName();
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(0).getIdTargetNodeTemplate()))
+ target1=node.getName();
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(1).getIdSourceNodeTemplate()))
+ source2=node.getName();
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(1).getIdTargetNodeTemplate()))
+ target2=node.getName();
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(2).getIdSourceNodeTemplate()))
+ source3=node.getName();
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(2).getIdTargetNodeTemplate()))
+ target3=node.getName();
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(3).getIdSourceNodeTemplate()))
+ source4=node.getName();
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(3).getIdTargetNodeTemplate()))
+ target4=node.getName();
+ }
+
+ assertEquals("Relat1 name error", retrieved.getRelationshipTemplateList().get(0).getName(), source1+"to"+target1);
+ assertEquals("Relat2 name error", retrieved.getRelationshipTemplateList().get(1).getName(), source2+"to"+target2);
+ assertEquals("Relat3 name error", retrieved.getRelationshipTemplateList().get(2).getName(), source3+"to"+target3);
+ assertEquals("Relat4 name error", retrieved.getRelationshipTemplateList().get(3).getName(), source4+"to"+target4);
+
+ System.out.println("Phase B.5 -- Deleting graph.");
+ Status resp = client.deleteTopologyTemplate(response.getTopologyTemplate().getId());
+ assertEquals("Error while deleting simpleTestTemplate", true, resp.getSuccess());
+
+
+ System.out.println("Test B completed.\n");
+ return;
+ }
+
+ @Test
+ public void test2Update() {
+ System.out.println("\nTest C: Update.");
+
+ //Creating a test graph on remote repository
+ System.out.println("Phase C.1 -- Creating a test graph.");
+ NewTopologyTemplate response = client.createTopologyTemplate(simpleTestTemplate);
+ assertNotNull("Returned a NULL graph", response);
+ assertEquals(true, response.getSuccess());
+ assertEquals("Error report: " + response.getErrorMessage(), "", response.getErrorMessage());
+
+ //Reading remote graph.
+ System.out.println("Phase C.2 -- Reading remote graph.");
+ TopologyTemplateGrpc retrieved = client.getTopologyTemplate(response.getTopologyTemplate().getId());
+ assertNotNull("Retrieved a NULL graph", retrieved);
+ assertEquals(retrieved.getId(), response.getTopologyTemplate().getId());
+
+ //Updating a TopologyTemplateGrpc
+ System.out.println("Phase C.3 -- Updating a test graph.");
+ TopologyTemplateGrpc.Builder templ = TopologyTemplateGrpc.newBuilder();
+ List<NodeTemplateGrpc> nodes = new ArrayList<NodeTemplateGrpc>();
+ List<RelationshipTemplateGrpc> relats = new ArrayList<RelationshipTemplateGrpc>();
+
+ ToscaConfigurationGrpc node1conf = ToscaConfigurationGrpc.newBuilder().setDescription("node1configuration")
+ .setId("15").setConfiguration("[]").build();
+ NodeTemplateGrpc node1 = NodeTemplateGrpc.newBuilder().setConfiguration(node1conf).setId("999")
+ .setName("webserver1").setType(Type.webserver).build();
+ nodes.add(node1);
+
+ ToscaConfigurationGrpc node2conf = ToscaConfigurationGrpc.newBuilder().setDescription("node2configuration")
+ .setId("16").setConfiguration("[{\r\n\"protocol\":\"HTTP_REQUEST\",\r\n \"url\":\"www.facebook.com\"\r\n }]").build();
+ NodeTemplateGrpc node2 = NodeTemplateGrpc.newBuilder().setConfiguration(node2conf).setId("888")
+ .setName("host2").setType(Type.endhost).build();
+ nodes.add(node2);
+
+ RelationshipTemplateGrpc rel0 = RelationshipTemplateGrpc.newBuilder().setId("1001")
+ .setIdSourceNodeTemplate("999").setIdTargetNodeTemplate("888").setName("webserver1tohost2").build();
+ relats.add(rel0);
+
+ RelationshipTemplateGrpc rel1 = RelationshipTemplateGrpc.newBuilder().setId("1002")
+ .setIdSourceNodeTemplate("888").setIdTargetNodeTemplate("999").setName("host2towebserver1").build();
+ relats.add(rel1);
+
+ TopologyTemplateGrpc newTestTemplate = templ.addAllNodeTemplate(nodes).addAllRelationshipTemplate(relats).setId("9").build();
+ NewTopologyTemplate updated = client.updateTopologyTemplate(newTestTemplate, response.getTopologyTemplate().getId());
+ assertNotNull("Returned a NULL graph", updated);
+ assertEquals(true, updated.getSuccess());
+ assertEquals("Error report: " + updated.getErrorMessage(), "", updated.getErrorMessage());
+
+ //Reading remote graph.
+ System.out.println("Phase C.4 -- Reading remote graph.");
+ TopologyTemplateGrpc retrieved2 = client.getTopologyTemplate(response.getTopologyTemplate().getId());
+ assertNotNull("Retrieved a NULL graph", retrieved2);
+ assertEquals(retrieved2.getId(), response.getTopologyTemplate().getId());
+
+ //Nodes checking
+ System.out.println("Phase C.5 -- Checking updated graph's nodes.");
+ assertEquals(retrieved2.getNodeTemplateCount(), 2);
+ assertEquals("Node1 name error", updated.getTopologyTemplate().getNodeTemplateList().get(0).getName(),
+ retrieved2.getNodeTemplateList().get(0).getName());
+ assertEquals("Node2 name error", updated.getTopologyTemplate().getNodeTemplateList().get(1).getName(),
+ retrieved2.getNodeTemplateList().get(1).getName());
+
+ //Relationships checking
+ System.out.println("Phase C.6 -- Checking updated graph's relationships.");
+ assertEquals(retrieved2.getRelationshipTemplateCount(), 2);
+ String source1=null, target1=null;
+ String source2=null, target2=null;
+ for (NodeTemplateGrpc node : retrieved2.getNodeTemplateList()){
+ if(node.getId().equals(retrieved2.getRelationshipTemplateList().get(0).getIdSourceNodeTemplate()))
+ source1=node.getName();
+ if(node.getId().equals(retrieved2.getRelationshipTemplateList().get(0).getIdTargetNodeTemplate()))
+ target1=node.getName();
+ if(node.getId().equals(retrieved2.getRelationshipTemplateList().get(1).getIdSourceNodeTemplate()))
+ source2=node.getName();
+ if(node.getId().equals(retrieved2.getRelationshipTemplateList().get(1).getIdTargetNodeTemplate()))
+ target2=node.getName();
+ }
+
+ assertEquals("Relat1 name error", retrieved2.getRelationshipTemplateList().get(0).getName(), source1+"to"+target1);
+ assertEquals("Relat2 name error", retrieved2.getRelationshipTemplateList().get(1).getName(), source2+"to"+target2);
+
+ System.out.println("Phase C.6 -- Deleting graph.");
+ Status resp = client.deleteTopologyTemplate(updated.getTopologyTemplate().getId());
+ assertEquals("Error while deleting simpleTestTemplate", true, resp.getSuccess());
+
+ System.out.println("Test C completed.\n");
+ return;
+ }
+
+
+ @Test
+ public void test3Verification() {
+ System.out.println("\nTest D: Verification.");
+ NewTopologyTemplate response = client.createTopologyTemplate(testTemplate);
+ if(response == null | response.getSuccess() != true) {
+ fail("Test failed, unable to load the graph.");
+ return;
+ }
+
+ //The Id of the graph on which we are going to perform tests
+ String testTemplateId = response.getTopologyTemplate().getId();
+
+ //REACHABILITY test
+ System.out.println("Phase 1.1 - Reachability SAT.");
+ ToscaPolicy policy = ToscaPolicy.newBuilder().setIdTopologyTemplate(testTemplateId)
+ .setType(PolicyType.reachability).setSource("host2").setDestination("host1").build();
+ ToscaVerificationGrpc result = client.verifyPolicy(policy);
+ assertNotNull("There was no response", result);
+ assertEquals("Unexpected result : " + result.getResult() + " - " + result.getComment(), "SAT", result.getResult());
+ assertEquals("Error report: " + result.getErrorMessage(), "", result.getErrorMessage());
+
+ result = null;
+ System.out.println("Phase 1.2 - Reachability UNSAT.");
+ policy = ToscaPolicy.newBuilder().setIdTopologyTemplate(testTemplateId)
+ .setType(PolicyType.reachability).setSource("host1").setDestination("antispamNode1").build();
+ result = client.verifyPolicy(policy);
+ assertNotNull("There was no response", result);
+ assertEquals("Unexpected result : " + result.getResult() + " - " + result.getComment(), "UNSAT", result.getResult());
+ assertEquals("Error report: " + result.getErrorMessage(), "", result.getErrorMessage());
+
+ //ISOLATION test
+ result = null;
+ System.out.println("Phase 2.1 - Isolation SAT.");
+ policy = ToscaPolicy.newBuilder().setIdTopologyTemplate(testTemplateId)
+ .setType(PolicyType.isolation).setSource("host2").setDestination("host1").setMiddlebox("webserver1").build();
+ result = client.verifyPolicy(policy);
+ assertNotNull("There was no response", result);
+ assertEquals("Unexpected result : " + result.getResult() + " - " + result.getComment(), "SAT", result.getResult());
+ assertEquals("Error report: " + result.getErrorMessage(), "", result.getErrorMessage());
+
+ System.out.println("Phase 2.2 - Isolation UNSAT.");
+ policy = ToscaPolicy.newBuilder().setIdTopologyTemplate(testTemplateId)
+ .setType(PolicyType.isolation).setSource("host2").setDestination("host1").setMiddlebox("fw").build();
+ result = client.verifyPolicy(policy);
+ assertNotNull("There was no response", result);
+ assertEquals("Unexpected result : " + result.getResult() + " - " + result.getComment(), "UNSAT", result.getResult());
+ assertEquals("Error report: " + result.getErrorMessage(), "", result.getErrorMessage());
+
+ //TRAVERSAL test
+ result = null;
+ System.out.println("Phase 3.1 - Traversal SAT.");
+ policy = ToscaPolicy.newBuilder().setIdTopologyTemplate(testTemplateId)
+ .setType(PolicyType.traversal).setSource("host2").setDestination("host1").setMiddlebox("fw").build();
+ result = client.verifyPolicy(policy);
+ assertNotNull("There was no response", result);
+ assertEquals("Unexpected result : " + result.getResult() + " - " + result.getComment(), "SAT", result.getResult());
+ assertEquals("Error report: " + result.getErrorMessage(), "", result.getErrorMessage());
+
+ System.out.println("Phase 3.2 - Traversal UNSAT.");
+ policy = ToscaPolicy.newBuilder().setIdTopologyTemplate(testTemplateId)
+ .setType(PolicyType.traversal).setSource("host2").setDestination("webserver1").setMiddlebox("fw").build();
+ result = client.verifyPolicy(policy);
+ assertNotNull("There was no response", result);
+ assertEquals("Unexpected result : " + result.getResult() + " - " + result.getComment(), "UNSAT", result.getResult());
+ assertEquals("Error report: " + result.getErrorMessage(), "", result.getErrorMessage());
+
+ Status resp = client.deleteTopologyTemplate(testTemplateId);
+ assertEquals("Error while deleting testTemplate", true, resp.getSuccess());
+
+ System.out.println("Test D completed.\n");
+ return;
+ }
+
+
+ @Test
+ public void test4Deletion() {
+ System.out.println("\nTest E: Deletion");
+ NewTopologyTemplate templ = client.createTopologyTemplate(testTemplate);
+
+ if(templ.getSuccess() != true) {
+ fail("Unable to create the graph.");
+ return;
+ }else {
+ Status resp = client.deleteTopologyTemplate(templ.getTopologyTemplate().getId());
+ assertEquals("Error while deleting testTemplate", true, resp.getSuccess());
+ }
+
+ System.out.println("Test E completed.\n");
+ return;
+ }
+
+
+ //Generates a correct instance of a TopologyTemplateGrpc to be used in tests
+ public void generateTestTemplate() {
+ TopologyTemplateGrpc.Builder templ = TopologyTemplateGrpc.newBuilder();
+ List<NodeTemplateGrpc> nodes = new ArrayList<NodeTemplateGrpc>();
+ List<RelationshipTemplateGrpc> relats = new ArrayList<RelationshipTemplateGrpc>();
+
+ //Definition of nodes
+ ToscaConfigurationGrpc node0conf = ToscaConfigurationGrpc.newBuilder().setDescription("node0configuration")
+ .setId("100").setConfiguration("[{\r\n\"webserver1\":\"host2\"\r\n}]").build();
+ NodeTemplateGrpc node0 = NodeTemplateGrpc.newBuilder().setConfiguration(node0conf).setId("100")
+ .setName("fw").setType(Type.firewall).build();
+ nodes.add(node0);
+
+ ToscaConfigurationGrpc node1conf = ToscaConfigurationGrpc.newBuilder().setDescription("node1configuration")
+ .setId("101").setConfiguration("[]").build();
+ NodeTemplateGrpc node1 = NodeTemplateGrpc.newBuilder().setConfiguration(node1conf).setId("101")
+ .setName("webserver1").setType(Type.webserver).build();
+ nodes.add(node1);
+
+ ToscaConfigurationGrpc node2conf = ToscaConfigurationGrpc.newBuilder().setDescription("node2configuration")
+ .setId("102").setConfiguration("[{\r\n\"protocol\":\"HTTP_REQUEST\",\r\n \"url\":\"www.facebook.com\"\r\n }]").build();
+ NodeTemplateGrpc node2 = NodeTemplateGrpc.newBuilder().setConfiguration(node2conf).setId("102")
+ .setName("host2").setType(Type.endhost).build();
+ nodes.add(node2);
+
+ ToscaConfigurationGrpc node3conf = ToscaConfigurationGrpc.newBuilder().setDescription("node3configuration")
+ .setId("103").setConfiguration("[ {\r\n\"protocol\":\"HTTP_REQUEST\",\r\n\"url\":\"www.google.com\",\r\n\"destination\":\"server1\"\r\n}]").build();
+ NodeTemplateGrpc node3 = NodeTemplateGrpc.newBuilder().setConfiguration(node3conf).setId("103")
+ .setName("host1").setType(Type.endhost).build();
+ nodes.add(node3);
+
+ ToscaConfigurationGrpc node4conf = ToscaConfigurationGrpc.newBuilder().setDescription("node4configuration")
+ .setId("104").setConfiguration("[\"host1\",\"host2\"]").build();
+ NodeTemplateGrpc node4 = NodeTemplateGrpc.newBuilder().setConfiguration(node4conf).setId("104")
+ .setName("antispamNode1").setType(Type.antispam).build();
+ nodes.add(node4);
+
+ //Building relationships
+ RelationshipTemplateGrpc rel0 = RelationshipTemplateGrpc.newBuilder().setId("1001")
+ .setIdSourceNodeTemplate("100").setIdTargetNodeTemplate("101").setName("fwToServ1").build();
+ relats.add(rel0);
+
+ RelationshipTemplateGrpc rel1 = RelationshipTemplateGrpc.newBuilder().setId("1002")
+ .setIdSourceNodeTemplate("101").setIdTargetNodeTemplate("100").setName("serv1ToFw").build();
+ relats.add(rel1);
+
+ RelationshipTemplateGrpc rel2 = RelationshipTemplateGrpc.newBuilder().setId("1003")
+ .setIdSourceNodeTemplate("100").setIdTargetNodeTemplate("103").setName("fwToHost1").build();
+ relats.add(rel2);
+
+ RelationshipTemplateGrpc rel3 = RelationshipTemplateGrpc.newBuilder().setId("1004")
+ .setIdSourceNodeTemplate("100").setIdTargetNodeTemplate("102").setName("fwToHost2").build();
+ relats.add(rel3);
+
+ RelationshipTemplateGrpc rel4 = RelationshipTemplateGrpc.newBuilder().setId("1005")
+ .setIdSourceNodeTemplate("102").setIdTargetNodeTemplate("100").setName("Host2Tofw").build();
+ relats.add(rel4);
+
+ RelationshipTemplateGrpc rel5 = RelationshipTemplateGrpc.newBuilder().setId("1006")
+ .setIdSourceNodeTemplate("103").setIdTargetNodeTemplate("100").setName("Host1Tofw").build();
+ relats.add(rel5);
+
+ this.testTemplate = templ.addAllNodeTemplate(nodes).addAllRelationshipTemplate(relats).setId("0").build();
+
+ TopologyTemplateGrpc.Builder templ2 = TopologyTemplateGrpc.newBuilder();
+ List<NodeTemplateGrpc> nodes2 = new ArrayList<NodeTemplateGrpc>();
+ List<RelationshipTemplateGrpc> relats2 = new ArrayList<RelationshipTemplateGrpc>();
+ nodes2.add(node0);
+ nodes2.add(node1);
+ nodes2.add(node2);
+ relats2.add(rel0);
+ relats2.add(rel1);
+ relats2.add(rel3);
+ relats2.add(rel4);
+
+ this.simpleTestTemplate = templ2.addAllNodeTemplate(nodes2).addAllRelationshipTemplate(relats2).setId("1").build();
+
+ }
+
+ /*class NodeTemplateGrpcComparator implements Comparator<NodeTemplateGrpc> {
+ public int compare(NodeTemplateGrpc n0, NodeTemplateGrpc n1) {
+ return n0.getName().compareTo(n1.getName());
+ }
+ }
+
+ class RelationshipTemplateGrpcComparator implements Comparator<RelationshipTemplateGrpc> {
+ public int compare(RelationshipTemplateGrpc n0, RelationshipTemplateGrpc n1) {
+ int source = n0.getIdSourceNodeTemplate().compareTo(n1.getIdSourceNodeTemplate());
+ int target = n0.getIdTargetNodeTemplate().compareTo(n1.getIdTargetNodeTemplate());
+ return source + target;
+ }
+ }*/
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GraphToGrpc.java b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GraphToGrpc.java new file mode 100644 index 0000000..fb52c7b --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GraphToGrpc.java @@ -0,0 +1,101 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.converter.grpc;
+
+import java.util.Map;
+
+import it.polito.verigraph.grpc.NodeTemplateGrpc;
+import it.polito.verigraph.grpc.RelationshipTemplateGrpc;
+import it.polito.verigraph.grpc.TopologyTemplateGrpc;
+import it.polito.verigraph.grpc.ToscaConfigurationGrpc;
+import it.polito.verigraph.grpc.ToscaTestGrpc;
+import it.polito.verigraph.grpc.ToscaVerificationGrpc;
+import it.polito.verigraph.model.Configuration;
+import it.polito.verigraph.model.Graph;
+import it.polito.verigraph.model.Neighbour;
+import it.polito.verigraph.model.Node;
+import it.polito.verigraph.model.Test;
+import it.polito.verigraph.model.Verification;
+
+public class GraphToGrpc {
+
+ /** Mapping method --> from model Graph to grpc TopologyTemplate */
+ public static TopologyTemplateGrpc obtainTopologyTemplate(Graph graph) {
+ TopologyTemplateGrpc.Builder topol = TopologyTemplateGrpc.newBuilder();
+ topol.setId(String.valueOf(graph.getId()));
+
+ //NodeTemplate
+ for(Node node : graph.getNodes().values()) {
+ NodeTemplateGrpc nt = obtainNodeTemplate(node);
+ topol.addNodeTemplate(nt);
+ //RelationshipTemplate
+ Map<Long,Neighbour> neighMap = node.getNeighbours();
+ for (Map.Entry<Long, Neighbour> myentry : neighMap.entrySet()) {
+ Neighbour neigh = myentry.getValue();
+ RelationshipTemplateGrpc relat = obtainRelationshipTemplate(neigh, node);
+ topol.addRelationshipTemplate(relat);
+ }
+ }
+ return topol.build();
+ }
+
+
+ /** Mapping method --> from model Node to grpc NodeTemplate */
+ private static NodeTemplateGrpc obtainNodeTemplate(Node node){
+ NodeTemplateGrpc.Builder nodegrpc = NodeTemplateGrpc.newBuilder();
+
+ nodegrpc.setId(String.valueOf(node.getId()));
+ nodegrpc.setName(node.getName());
+ nodegrpc.setType(NodeTemplateGrpc.Type.valueOf(node.getFunctional_type().toLowerCase()));
+
+ ToscaConfigurationGrpc config = obtainToscaConfiguration(node.getConfiguration());
+ nodegrpc.setConfiguration(config);
+
+ return nodegrpc.build();
+ }
+
+
+ /** Mapping method --> from model Neighbour to grpc RelationshipTemplate */
+ private static RelationshipTemplateGrpc obtainRelationshipTemplate(Neighbour neigh, Node sourceNode) {
+ RelationshipTemplateGrpc.Builder relat = RelationshipTemplateGrpc.newBuilder();
+ relat.setId(String.valueOf(sourceNode.getId()));
+ //Neighbour does not have a neighbourID! RelationshipTemplate does, so it is set to sourceNodeID
+ relat.setIdSourceNodeTemplate(String.valueOf(sourceNode.getId()));
+ relat.setIdTargetNodeTemplate(String.valueOf(neigh.getId()));
+ relat.setName(sourceNode.getName()+"to"+neigh.getName());
+ return relat.build();
+ }
+
+
+ /** Mapping method --> from model Configuration to grpc ToscaConfigurationGrpc */
+ private static ToscaConfigurationGrpc obtainToscaConfiguration(Configuration conf) {
+ return ToscaConfigurationGrpc.newBuilder()
+ .setId(conf.getId())
+ .setDescription(conf.getDescription())
+ .setConfiguration(conf.getConfiguration().toString())
+ .build();
+ }
+
+ /** Mapping method --> from model Verification to grpc ToscaVerificationGrpc */
+ public static ToscaVerificationGrpc obtainToscaVerification(Verification verify){
+ ToscaVerificationGrpc.Builder ver = ToscaVerificationGrpc.newBuilder();
+ ver.setComment(verify.getComment());
+ ver.setResult(verify.getResult());
+ for(Test test:verify.getTests()){
+ ToscaTestGrpc.Builder tst = ToscaTestGrpc.newBuilder().setResult(test.getResult());
+ for(Node node:test.getPath()){
+ NodeTemplateGrpc nodetempl = obtainNodeTemplate(node);
+ tst.addNodeTemplate(nodetempl);
+ }
+ ver.addTest(tst);
+ }
+ return ver.build();
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GrpcToGraph.java b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GrpcToGraph.java new file mode 100644 index 0000000..76906b3 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GrpcToGraph.java @@ -0,0 +1,150 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.converter.grpc;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import it.polito.verigraph.exception.BadRequestException;
+import it.polito.verigraph.grpc.NodeTemplateGrpc;
+import it.polito.verigraph.grpc.RelationshipTemplateGrpc;
+import it.polito.verigraph.grpc.TopologyTemplateGrpc;
+import it.polito.verigraph.grpc.ToscaConfigurationGrpc;
+import it.polito.verigraph.model.Configuration;
+import it.polito.verigraph.model.Graph;
+import it.polito.verigraph.model.Neighbour;
+import it.polito.verigraph.model.Node;
+
+public class GrpcToGraph {
+
+ /** Mapping method --> from grpc TopologyTemplateGrpc to model Graph */
+ public static Graph deriveGraph(TopologyTemplateGrpc request) throws BadRequestException, JsonProcessingException, IOException {
+ Graph graph = new Graph();
+ Map<Long, Node> nodes = new HashMap<>();
+
+ try {
+ //Create a list of Node without Neighbour
+ for(NodeTemplateGrpc nodetempl : request.getNodeTemplateList()){
+ Node node = deriveNode(nodetempl);
+ //It necessary to check uniqueness here otherwise a .put with the same key will overwrite the old node
+ if(nodes.containsKey(node.getId()))
+ throw new BadRequestException("The NodeTemplate ID must be unique.");
+ else
+ nodes.put(node.getId(), node);
+ }
+
+ //Add Neighbour to the Node of the list
+ List<RelationshipTemplateGrpc> relatList = request.getRelationshipTemplateList();
+ nodes = deriveNeighboursNode(nodes, relatList);
+
+ //Add Node and ID to the graph
+ graph.setNodes(nodes);
+ try {
+ graph.setId(Long.valueOf(request.getId()));
+ } catch(NumberFormatException ex) {
+ throw new BadRequestException("If you want to store your TopologyTemplate on this server,"
+ + "the TopologyTemplate ID must be a number.");
+ }
+
+ return graph;
+
+ } catch (NullPointerException e) {
+ throw new BadRequestException("The TopologyTemplate received has invalid fields.");
+ }
+
+ }
+
+
+ /** Mapping method --> from grpc NodeTemplate to model Node (with no Neighbour) */
+ private static Node deriveNode(NodeTemplateGrpc nodegrpc) throws BadRequestException, JsonProcessingException, IOException {
+ Node node = new Node();
+ try {
+ try {
+ node.setId(Long.valueOf(nodegrpc.getId()));
+ } catch(NumberFormatException ex) {
+ throw new BadRequestException("The NodeTemplate ID must be a number.");
+ }
+
+ node.setName(nodegrpc.getName());
+ Configuration conf = deriveConfiguration(nodegrpc.getConfiguration());
+ node.setConfiguration(conf);
+ node.setFunctional_type(nodegrpc.getType().toString());
+
+ } catch(NullPointerException ex) {
+ throw new BadRequestException("A NodeTemplate has wrong fields representation.");
+ }
+
+ return node;
+ }
+
+
+
+ /** Mapping method --> from a list of model Node to a list of model Node with their Neighbour */
+ private static Map<Long,Node> deriveNeighboursNode(Map<Long,Node> nodes, List<RelationshipTemplateGrpc> relatList)
+ throws BadRequestException{
+ Map<Long,Node> updNodes = nodes; //new list to be filled with updated Node (update = Node + its Neighbour)
+ for(RelationshipTemplateGrpc relat : relatList) {
+ try {
+ //Retrieve the target Node name and generate a new Neighbour
+ String neighName = updNodes.get(Long.valueOf(relat.getIdTargetNodeTemplate())).getName();
+ Neighbour neigh = new Neighbour();
+ neigh.setName(neighName);
+ neigh.setId(Long.valueOf(relat.getId()));
+
+ //Retrieve the Neighbour map of the source Node and add the Neighbour
+ Node source = updNodes.get(Long.valueOf(relat.getIdSourceNodeTemplate()));
+ Map<Long,Neighbour> sourceNodeNeighMap = source.getNeighbours();
+ if(sourceNodeNeighMap.containsKey(neigh.getId()))
+ throw new BadRequestException("The RelationshipTemplate ID must be unique.");
+ else
+ sourceNodeNeighMap.put(neigh.getId(), neigh);
+ source.setNeighbours(sourceNodeNeighMap);
+
+ //Update the Node list
+ updNodes.put(Long.valueOf(relat.getIdSourceNodeTemplate()), source);
+ } catch(NullPointerException | NumberFormatException ex) {
+ throw new BadRequestException("A RelationshipTemplate has wrong fields representation.");
+ }
+ }
+ return updNodes;
+ }
+
+ /** Mapping method --> from ToscaConfiguration to model Configuration */
+ private static Configuration deriveConfiguration(ToscaConfigurationGrpc request)
+ throws BadRequestException, JsonProcessingException, IOException {
+ Configuration conf = new Configuration();
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode rootNode = null;
+
+ try {
+ conf.setId(request.getId());
+ } catch (NullPointerException e) {}
+
+ try {
+ conf.setDescription(request.getDescription());
+ } catch (NullPointerException e) {}
+
+ try {
+ if ("".equals(request.getConfiguration()))
+ rootNode=mapper.readTree("[]");
+ else
+ rootNode = mapper.readTree(request.getConfiguration());
+ } catch (NullPointerException e) {
+ rootNode=mapper.readTree("[]");
+ }
+ conf.setConfiguration(rootNode);
+ return conf;
+ }
+}
diff --git a/verigraph/src/main/proto/verigraph.proto b/verigraph/src/main/proto/verigraph.proto index feb8ff0..e8e9ccc 100644 --- a/verigraph/src/main/proto/verigraph.proto +++ b/verigraph/src/main/proto/verigraph.proto @@ -1,3 +1,13 @@ +/* This Protocol Buffer has been updated for supporting TOSCA-based objects. + * The only granularity for executing CRUD operations is at the TopologyTemplate level. + * + * The names of the objects are assigned according to the TOSCA standard, and can be + * mapped as follows in the Verigraph domain: + * TopologyTemplate -> Graph + * NodeTemplate -> Node + * RelationshipTemplate -> Neighbour (partial) +*/ + syntax = "proto3"; package verigraph; @@ -6,7 +16,7 @@ option java_multiple_files = true; option java_package = "it.polito.verigraph.grpc"; option java_outer_classname = "VerigraphProto"; -// The service definition. +/** gRPC */ service Verigraph { // Obtains a list of graphs rpc GetGraphs (GetRequest) returns (stream GraphGrpc) {} @@ -45,8 +55,24 @@ service Verigraph { rpc DeleteNeighbour (RequestID) returns (Status) {} // Updates a neighbour rpc UpdateNeighbour (NeighbourGrpc) returns (NewNeighbour) {} + + /** TOSCA gRPC */ + // Obtain a list of topology templates + rpc GetTopologyTemplates (GetRequest) returns (stream TopologyTemplateGrpc) {} + // Obtain a topology template + rpc GetTopologyTemplate (ToscaRequestID) returns (TopologyTemplateGrpc) {} + // Create a TopologyTemplate + rpc CreateTopologyTemplate (TopologyTemplateGrpc) returns (NewTopologyTemplate) {} + // Delete a TopologyTemplate + rpc DeleteTopologyTemplate (ToscaRequestID) returns (Status) {} + // Update a TopologyTemplate + rpc UpdateTopologyTemplate (TopologyTemplateGrpc) returns (NewTopologyTemplate) {} + // Verify a ToscaPolicy + rpc VerifyToscaPolicy (ToscaPolicy) returns (ToscaVerificationGrpc) {} } + +/** Messages */ message GetRequest { } @@ -151,4 +177,87 @@ string errorMessage = 5; message Status{ bool success = 1; string errorMessage = 2; -}
\ No newline at end of file +} + +/** TOSCA Messages */ +message ToscaRequestID { + string idTopologyTemplate = 1; +} + +message TopologyTemplateGrpc{ + string id = 1; + string name = 2; + repeated NodeTemplateGrpc nodeTemplate = 3; + repeated RelationshipTemplateGrpc relationshipTemplate = 4; + string errorMessage = 5; +} + +message NewTopologyTemplate{ + bool success = 1; + TopologyTemplateGrpc topologyTemplate = 2; + string errorMessage = 3; +} + +message NodeTemplateGrpc{ + string id = 1; + string name = 2; + enum Type { + antispam = 0; + cache = 1; + dpi = 2; + endhost = 3; + endpoint = 4; + fieldmodifier = 5; + firewall = 6; + mailclient = 7; + mailserver = 8; + nat = 9; + vpnaccess = 10; + vpnexit = 11; + webclient = 12; + webserver = 13; + } + Type type = 3; + ToscaConfigurationGrpc configuration = 4; + string errorMessage = 5; +} + +message RelationshipTemplateGrpc{ + string idSourceNodeTemplate = 1; + string idTargetNodeTemplate = 2; + string id = 3; + string name = 4; + string errorMessage = 5; +} + +message ToscaPolicy{ + string idTopologyTemplate = 1; + string source = 2; + string destination = 3; + enum PolicyType { + reachability = 0; + isolation = 1; + traversal = 2; + } + PolicyType type = 4; + string middlebox = 5; +} + +message ToscaConfigurationGrpc{ + string id = 1; + string description = 2; + string configuration = 3; +} + +message ToscaTestGrpc { + repeated NodeTemplateGrpc nodeTemplate = 1; + string result = 2; +} + +message ToscaVerificationGrpc{ + bool successOfOperation = 1; + string result = 2; + string comment = 3; + repeated ToscaTestGrpc test = 4; + string errorMessage = 5; +} |