Merge "Add verigraph code base"
authorZhipeng (Howard) Huang <huangzhipeng@huawei.com>
Mon, 27 Feb 2017 13:08:54 +0000 (13:08 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Mon, 27 Feb 2017 13:08:54 +0000 (13:08 +0000)
157 files changed:
verigraph/LICENSE [new file with mode: 0644]
verigraph/README.rst [new file with mode: 0644]
verigraph/buildVeriGraph_gRPC.xml [new file with mode: 0644]
verigraph/pom.xml [new file with mode: 0644]
verigraph/service/src/mcnet/components/Checker.java [new file with mode: 0644]
verigraph/service/src/mcnet/components/Core.java [new file with mode: 0644]
verigraph/service/src/mcnet/components/DataIsolationResult.java [new file with mode: 0644]
verigraph/service/src/mcnet/components/IsolationResult.java [new file with mode: 0644]
verigraph/service/src/mcnet/components/NetContext.java [new file with mode: 0644]
verigraph/service/src/mcnet/components/Network.java [new file with mode: 0644]
verigraph/service/src/mcnet/components/NetworkObject.java [new file with mode: 0644]
verigraph/service/src/mcnet/components/Result.java [new file with mode: 0644]
verigraph/service/src/mcnet/components/Tuple.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/AclFirewall.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/DumbNode.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/EndHost.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/PacketModel.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/PolitoAntispam.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/PolitoCache.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/PolitoEndHost.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/PolitoErrFunction.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/PolitoFieldModifier.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/PolitoIDS.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/PolitoMailClient.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/PolitoMailServer.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/PolitoNF.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/PolitoNat.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/PolitoVpnAccess.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/PolitoVpnExit.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/PolitoWebClient.java [new file with mode: 0644]
verigraph/service/src/mcnet/netobjs/PolitoWebServer.java [new file with mode: 0644]
verigraph/service/src/tests/j-verigraph-generator/README.rst [new file with mode: 0644]
verigraph/service/src/tests/j-verigraph-generator/__init__.py [new file with mode: 0644]
verigraph/service/src/tests/j-verigraph-generator/batch_generator.py [new file with mode: 0644]
verigraph/service/src/tests/j-verigraph-generator/code_generator.py [new file with mode: 0644]
verigraph/service/src/tests/j-verigraph-generator/config.py [new file with mode: 0644]
verigraph/service/src/tests/j-verigraph-generator/json_generator.py [new file with mode: 0644]
verigraph/service/src/tests/j-verigraph-generator/routing_generator.py [new file with mode: 0644]
verigraph/service/src/tests/j-verigraph-generator/test_class_generator.py [new file with mode: 0644]
verigraph/service/src/tests/j-verigraph-generator/test_generator.py [new file with mode: 0644]
verigraph/service/src/tests/j-verigraph-generator/utility.py [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/client/Neo4jManagerClient.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/client/VerifyClient.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/client/VerifyClientException.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/database/DatabaseClass.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/deserializer/ConfigurationCustomDeserializer.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/deserializer/GraphCustomDeserializer.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/deserializer/NodeCustomDeserializer.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/deserializer/PathsMessageBodyReader.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/exception/BadRequestException.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/exception/BadRequestExceptionMapper.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/exception/DataNotFoundException.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/exception/DataNotFoundExceptionMapper.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/exception/ForbiddenException.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/exception/ForbiddenExceptionMapper.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/exception/GenericExceptionMapper.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/exception/InternalServerErrorException.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/exception/InternalServerErrorExceptionMapper.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/model/Configuration.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/model/Entry.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/model/ErrorMessage.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/model/Graph.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/model/Link.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/model/Neighbour.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/model/Node.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/model/Test.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/model/Verification.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/model/jaxb.properties [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/resources/GraphResource.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/resources/NeighbourResource.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/resources/NodeResource.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/resources/beans/VerificationBean.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/serializer/CustomConfigurationSerializer.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/serializer/CustomMapSerializer.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/service/GraphService.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/service/JsonValidationService.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/service/NeighbourService.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/service/NodeService.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/service/ValidationUtils.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/service/VerificationService.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/test/MultiThreadedTestCase.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/test/Scalability.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/test/TestCase.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/test/TestExecutionException.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/test/Tester.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/validation/DpiValidator.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/validation/EndhostValidator.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/validation/ValidationInterface.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/validation/VpnaccessValidator.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/validation/VpnexitValidator.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/escape/verify/validation/exception/ValidationException.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/grpc/Client.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/grpc/GrpcUtils.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/grpc/README.rst [new file with mode: 0644]
verigraph/src/main/java/it/polito/grpc/Service.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/grpc/test/GrpcServerTest.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/grpc/test/GrpcTest.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/grpc/test/MultiThreadTest.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/grpc/test/ReachabilityTest.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ActionEnumType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ActionType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ActionsType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CiType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CpType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CpointsType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CtrlInterfacesType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpCpType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpointsType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpsCpsType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/FlowrulesType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/HttpMessage.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/MonParamsType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NeType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NelementsType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NfType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/Nffg.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NffgSet.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NfunctionsType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ObjectFactory.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/Paths.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/PortDirEnumType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/PortType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/Property.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/SpecType.java [new file with mode: 0644]
verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/package-info.java [new file with mode: 0644]
verigraph/src/main/proto/verigraph.proto [new file with mode: 0644]
verigraph/src/main/schema/net_types.xsd [new file with mode: 0644]
verigraph/src/main/schema/nffg.xsd [new file with mode: 0644]
verigraph/src/main/webapp/json/antispam.json [new file with mode: 0644]
verigraph/src/main/webapp/json/cache.json [new file with mode: 0644]
verigraph/src/main/webapp/json/database.json [new file with mode: 0644]
verigraph/src/main/webapp/json/dpi.json [new file with mode: 0644]
verigraph/src/main/webapp/json/endhost.json [new file with mode: 0644]
verigraph/src/main/webapp/json/endpoint.json [new file with mode: 0644]
verigraph/src/main/webapp/json/fieldmodifier.json [new file with mode: 0644]
verigraph/src/main/webapp/json/firewall.json [new file with mode: 0644]
verigraph/src/main/webapp/json/mailclient.json [new file with mode: 0644]
verigraph/src/main/webapp/json/mailserver.json [new file with mode: 0644]
verigraph/src/main/webapp/json/nat.json [new file with mode: 0644]
verigraph/src/main/webapp/json/vpnaccess.json [new file with mode: 0644]
verigraph/src/main/webapp/json/vpnexit.json [new file with mode: 0644]
verigraph/src/main/webapp/json/webclient.json [new file with mode: 0644]
verigraph/src/main/webapp/json/webserver.json [new file with mode: 0644]
verigraph/target/m2e-wtp/web-resources/META-INF/MANIFEST.MF [new file with mode: 0644]
verigraph/target/m2e-wtp/web-resources/META-INF/maven/it.polito.escape/verify/pom.properties [new file with mode: 0644]
verigraph/target/m2e-wtp/web-resources/META-INF/maven/it.polito.escape/verify/pom.xml [new file with mode: 0644]
verigraph/tester/README.rst [new file with mode: 0644]
verigraph/tester/test.py [new file with mode: 0644]
verigraph/tester/testcase_schema.json [new file with mode: 0644]
verigraph/tester/testcases/test_budapest_sap1_webserver_sat.json [new file with mode: 0644]
verigraph/tester/testcases/test_budapest_sap1_webserver_unsat.json [new file with mode: 0644]
verigraph/tester/testcases/test_user_nat_dpi_webserver_trafficAllowed.json [new file with mode: 0644]
verigraph/tester/testcases/test_user_nat_dpi_webserver_trafficBlocked.json [new file with mode: 0644]
verigraph/tester/testcases/test_user_nat_vpn_fieldmod_webserver_unsat.json [new file with mode: 0644]
verigraph/tester/testcases/test_user_nat_vpn_webserver_sat.json [new file with mode: 0644]
verigraph/tester/testcases/test_webserver_vpn_nat_user_unsat.json [new file with mode: 0644]

diff --git a/verigraph/LICENSE b/verigraph/LICENSE
new file mode 100644 (file)
index 0000000..79a7d4f
--- /dev/null
@@ -0,0 +1,13 @@
+Copyright 2017 Politecnico di Torino and others.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/verigraph/README.rst b/verigraph/README.rst
new file mode 100644 (file)
index 0000000..947e893
--- /dev/null
@@ -0,0 +1,258 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+
+| Let’s look at how to deploy **VeriGraph** on Apache Tomcat. If you’re
+  only interested in creating gRPC API and ``neo4jmanager`` is already
+  deployed, you can skip this section and go straight to the
+  `documentation <https://gitlab.com/serena.spinoso/DP2.2017.SpecialProject2.gRPC/tree/master/src/main/java/it/polito/grpc>`__
+| (though you might find it useful if Tomcat is not yet installed!).
+
+**Windows**
+
+-  install ``jdk1.8.X_YY``
+   `here <http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html>`__
+-  set ambient variable ``JAVA_HOME`` to where you installed the jdk
+   (e.g. ``C:\Program Files\Java\jdk1.8.X_YY``)
+-  install Apache Tomcat 8
+   `here <https://tomcat.apache.org/download-80.cgi>`__
+-  install a pre-compiled distribution of Z3 from
+   `here <https://github.com/Z3Prover/bin/tree/master/releases>`__
+   and save the ``[z3_root]/bin`` content under ``[verigraph]/service/build``
+-  create the ``mcnet.jar`` of the ``mcnet.*`` packages and put into the ``[verigraph]/service/build`` directory
+-  download the qjutils library
+   `here <https://github.com/quanla/classreloading/tree/master/src/main/java/qj/util>`__
+   and create a jar file (i.e. qjutils.jat) in ``[verigrap]/service/build``
+-  set ambient variable ``CATALINA_HOME`` to the directory where you
+   installed Apache (e.g.
+   ``C:\Program Files\Java\apache-tomcat-8.0.30``)
+-  create ``shared`` folder under ``%CATALINA_HOME%``
+-  add previously created folder to the Windows ``Path`` system variable
+   (i.e. append the following string at the end:
+   ``;%CATALINA_HOME%\shared``)
+-  copy ``[verigraph]/lib/mcnet.jar``, ``[verigraph]/service/build/com.microsoft.z3.jar`` and ``[verigraph]/service/build/qjutils.jar``
+   to ``%CATALINA_HOME%\shared``
+-  to correctly compile the code you have to put the path of ``com.microsoft.z3.jar``
+   and the libraries it refers to as environment variable. i.e. is enough
+   to add the project subfolder ``build`` to the PATH environment variable (i.e., ``[verigraph]/build``)
+-  create custom file setenv.bat under ``%CATALINA_HOME%\bin`` with the
+   following content:
+
+   .. code:: bat
+
+       set CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\shared\qjutils.jar;%CATALINA_HOME%\shared\mcnet.jar;%CATALINA_HOME%\shared\com.microsoft.z3.jar;.;%CATALINA_HOME%\webapps\verify\WEB-INF\classes\tests
+
+-  download ``neo4jmanager.war`` from
+   `here <https://github.com/netgroup-polito/verigraph/tree/master/dist>`__
+   and copy into into ``%CATALINA_HOME%\webapps``
+-  export the ``verify.war`` file from the project and copy into ``%CATALINA_HOME%\webapps``
+-  (optional) configure Tomcat Manager:
+-  open the file ``%CATALINA_HOME%\conf\tomcat-users.xml``
+-  under the ``tomcat-users`` tag place the following content:
+   ``xml   <role rolename="tomcat"/>   <role rolename="role1"/>   <user username="tomcat" password="tomcat" roles="tomcat,manager-gui"/>   <user username="both" password="tomcat" roles="tomcat,role1"/>   <user username="role1" password="tomcat" roles="role1"/>``
+-  launch Tomcat 8 with the startup script
+   ``%CATALINA_HOME%\bin\startup.bat``
+-  (optional) if you previously configured Tomcat Manager you can open a
+   browser and navigate to `this link <http://localhost:8080/manager>`__
+   and login using ``tomcat/tomcat`` as username/password
+-  (optional) you can deploy/undeploy/redeploy the downloaded WARs
+   through the web interface
+
+**Unix**
+
+-  install ``jdk1.8.X_YY`` from the command line:
+-  go to `this
+   link <http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html>`__
+   to check the appropriate version for you OS and architecture
+-  copy the desired version to the clipboard (e.g.
+   ``http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.tar.gz``)
+-  open a terminal windows and paste the following command (replace
+   ``link`` with the previously copied link):
+   ``wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" 'link'``
+   e.g.
+   ``wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.tar.gz``
+-  untar the archive with the following command (replace 'jdk' to match
+   the name of the downloaded archive):
+   ``tar zxvf 'jdk'.tar.gz``
+   e.g.
+   ``tar zxvf jdk-7u<version>-linux-x64.tar.gz``
+-  delete the ``.tar.gz`` file if you want to save disk space
+-  install and configure Apache Tomcat 8 with the following commands:
+-  go to `this URL <http://it.apache.contactlab.it/tomcat/tomcat-8/>`__
+   and see what the latest available version is
+-  download the archive (substitute every occurrence of '8.0.32' in the
+   following command with the latest available version):
+   ``wget http://it.apache.contactlab.it/tomcat/tomcat-8/v8.0.32/bin/apache-tomcat-8.0.32.tar.gz``
+-  extract downloaded archive:
+   ``tar xvf apache-tomcat-8.0.32.tar.gz``
+-  edit configuration:
+   ``nano ./apache-tomcat-8.0.32/conf/tomcat-users.xml``
+-  under the ``tomcat-users`` tag place the following content
+   ``xml   <role rolename="tomcat"/>   <role rolename="role1"/>   <user username="tomcat" password="tomcat" roles="tomcat,manager-gui"/>   <user username="both" password="tomcat" roles="tomcat,role1"/>   <user username="role1" password="tomcat" roles="role1"/>   </tomcat-users>``
+-  set a few environment variables:
+   ``sudo nano ~/.bashrc``
+-  paste the following content at the end of the file
+   ``export CATALINA_HOME='/path/to/apache/tomcat/folder'``
+   e.g.
+   ``export CATALINA_HOME=/home/mininet/apache-tomcat-8.0.33``
+   ``export JRE_HOME='/path/to/jdk/folder'``
+   e.g.
+   ``export JRE_HOME=/home/mininet/jdk1.8.0_92/jre``
+   ``export JDK_HOME='/path/to/jdk/folder'``
+   e.g.
+   ``export JDK_HOME=/home/mininet/jdk1.8.0_92``
+   ``export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CATALINA_HOME/shared``
+   ``export JAVA_OPTS="-Djava.library.path=$CATALINA_HOME/shared"``
+-  ``exec bash``
+-  install a pre-compiled distribution of Z3 from
+   `here <https://github.com/Z3Prover/bin/tree/master/releases>`__
+   and save [z3_root]/bin content under ``[verigraph]/service/build``
+-  download the qjutils library
+   `here <https://github.com/quanla/classreloading/tree/master/src/main/java/qj/util>`__
+   and create a jar file (i.e. qjutils.jar) in ``[verigrap]/service/build``
+-  create the ``mcnet.jar`` of the ``mcnet.*`` packages and put into the ``[verigraph]/service/build`` directory
+-  copy ``[verigraph]/service/build/mcnet.jar``, ``[verigraph]/service/build/com.microsoft.z3.jar``
+   and ``[verigraph]/service/build/qjutils.jar`` to ``$CATALINA_HOME/shared``
+-  customize Tomcat classpath
+   ``nano $CATALINA_HOME/bin/setenv.sh``
+-  paste the following content and save file:
+   ``bash   #!/bin/sh   export CLASSPATH=$CLASSPATH:$CATALINA_HOME/shared/qjutils.jar:$CATALINA_HOME/shared/mcnet.jar:$CATALINA_HOME/shared/com.microsoft.z3.jar:.:$CATALINA_HOME/webapps/verify/WEB-INF/classes/tests``
+-  save and close the file (``CTRL+O``, ``CTRL+X``)
+   ``sudo chmod +x $CATALINA_HOME/bin/setenv.sh``
+-  download ``neo4jmanager.war`` from
+   `here <https://github.com/netgroup-polito/verigraph/tree/master/dist>`__
+   and copy into into ``%CATALINA_HOME%\webapps``
+-  export the ``verify.war`` file from the project and copy into ``%CATALINA_HOME%\webapps``
+-  launch Tomcat 8 with the startup script
+   ``$CATALINA_HOME/bin/startup.sh``
+-  open a browser and navigate to `this
+   link <http://localhost:8080/manager>`__ and login using
+   ``tomcat/tomcat`` as username/password
+-  you can deploy/undeploy/redeploy the downloaded WARs through the web
+   interface
+
+**Eclipse**
+
+-  clone project onto your hard drive with this command:
+   ``git clone git@github.com:netgroup-polito/verigraph.git``
+-  Download Apache Tomcat 8 (see instructions above for Windows and
+   Unix)
+-  Download JDK (see instructions above for Windows and Unix)
+-  Configure runtime environment in Eclipse with `the following
+   incstructions <http://crunchify.com/step-by-step-guide-to-setup-and-install-apache-tomcat-server-in-eclipse-development-environment-ide/>`__
+-  Add new Tomcat server on port ``8080``
+-  Configure Tomcat server:
+
+   -  double-click on the newly created server in the ``Servers`` tab
+   -  make sure under ``Server Locations`` ``Use Tomcat installation``
+      is selected
+   -  Open ``Launch Configuration``->``Classpath``
+   -  add the required JARS (``mcnet.jar``, ``com.microsoft.z3.jar`` and
+      ``qjutils.jar``) under ``User Entries``
+   -  Hit ``Apply`` and ``Ok``
+
+-  Run the server
+
+**How to add you own function ``<type>``**
+
+#. under the the ``mcnet.netobjs`` package (i.e. under
+   ``/verify/service/src/mcnet/netobjs``) create a new class
+   ``<Type>.java``, where ``<type>`` is the desired function name (i.e.
+   ``<type>`` will be added to the supported node functional types)
+   which extends ``NetworkObject`` and implement the desired logic
+
+#. regenerate ``mcnet.jar`` selecting the packages ``mcnet.components``
+   and ``mcnet.netobjs`` and exporting the generated JAR to
+   ``/verify/service/build`` (overwrite the existing file)
+
+#. under ``/verify/src/main/webapp/json/`` create a file
+   ``<type>.json``. This file represents a JSON schema (see
+   `here <http://json-schema.org/>`__ the official documentation). For
+   compatibility with the other functions it is mandatory to support an
+   array as the root of the configuration, but feel free to specify all
+   the other constraints as needed. A sample of ``<type>.json`` to
+   describe an empty configuration could be the following:
+
+``json   {       "$schema": "http://json-schema.org/draft-04/schema#",       "title": "Type",       "description": "This is a generic type",       "type": "array",       "items": {           "type": "object"       },       "minItems": 0,       "maxItems": 0,       "uniqueItems": true   }``
+
+#. in the package ``it.polito.escape.verify.validation`` (i.e. under
+   ``src/main/java/it/polito/escape/verify/validation``) create a new
+   class file named ``<Type>Validator.java`` (please pay attention to
+   the naming convention here: ``<Type>`` is the function type used in
+   the previous step capitalized, followed by the suffix ``Validator``)
+   which implements ``ValidationInterface``. This class represents a
+   custom validator for the newly introduced type and allows for more
+   complex constraints, which is not possible to express through a JSON
+   schema file. The validate method that has to be implemented is given
+   the following objects:
+
+-  ``Graph graph`` represents the nffg that the object node belongs to;
+-  ``Node node`` represents the node that the object configuration
+   belongs to;
+-  ``Configuration configuration`` represents the parsed configuration.
+   It is sufficient to call the method ``getConfiguration`` on the
+   ``configuration`` object to get a ``JsonNode`` (Jackson's class) and
+   iterate over the various fields.
+   In case a configuration is not valid please throw a new
+   ``ValidationException`` passing a descriptive failure message.
+   Adding a custom validator is not strictly necessary whenever a JSON
+   schema is thought to be sufficient. Note though that, other than the
+   mandatory validation against a schema, whenever a custom validator is
+   not found a default validation is triggered, i.e. the value of every
+   JSON property must refer to the name of an existing node in the
+   working graph/nffg. If this is not the desired behavior it is
+   suggested to write a custom validator with looser constraints.
+
+#. customize the class generator and add the support for the newly
+   introduced type:
+
+-  open the file
+   ``/verify/service/src/tests/j-verigraph-generator/config.py`` and
+   edit the following dictionaries:
+
+   -  ``devices_to_classes`` --> add the following entry:
+      ``"<type>" : "<Type>"``
+      if you followed these instructions carefully the name of the class
+      implementing the function ``<type>`` should be ``<Type>.java``
+      under the package ``mcnet.netobjs``.
+   -  ``devices_to_configuration_methods`` --> add the following entry:
+      ``"<type>" : "configurationMethod"``
+      if ``<type>`` is a middlebox it should have a configuration method
+      contained in the implementation ``<Type>.java`` under the package
+      ``mcnet.netobjs``.
+   -  ``devices_initialization``: add the following entry:
+      ``"<type>" : ["param1", "param2"]``
+      if ``<type>`` requires any parameter when it gets instanciated
+      please enter them in the form of a list. Make sure that these
+      parameters refer to existing keys contained in the configuration
+      schema file (see step 3). For instance the type ``webclient``
+      requires the name of a webserver it wants to communicate with.
+      This parameter is passed in the configuration of a weblient by
+      setting a property ``webserver`` to the name of the desired
+      webserver. The value of this property gets extracted and used by
+      the test generator automatically.
+   -  ``convert_configuration_property_to_ip`` --> add the following
+      entry: ``"<type>" : ["key", "value"]``
+      Note that both ``key`` and ``value`` are optional and it is
+      critical to set them only if needed. Since the Z3 provider used
+      for testing works with IP addresses in this dictionary you have to
+      indicate whether it is needed an automatic convertion from names
+      to IP addresses:
+   -  in case the keyword ``key`` is used every key of the JSON
+      configuration parsed will be prepended with the string ``ip_``;
+   -  in case the keyword ``value`` is used every value of the JSON
+      configuration parsed will be prepended with the string ``ip_``;
+   -  in case the list does not contain neither ``key`` nor ``value``
+      the original configuration won't be touched.
+
+-  open the file
+   ``/verify/service/src/tests/j-verigraph-generator/test_class_generator.py``
+   and under the "switch" case in the form of a series of ifs used to
+   configure middle-boxes that starts at line #239 add a branch like the
+   following with the logic to generate the Java code for -->
+   ``elif nodes_types[i] == "<type>":``
+   You can take inspiration from the other branches to see how to
+   serialize Java code. Note that this addition to the "switch"
+   statement is not needed if ``<type>`` is not a middlebox or it does
+   not need to be configured.
+
+#. Restart the web service.
diff --git a/verigraph/buildVeriGraph_gRPC.xml b/verigraph/buildVeriGraph_gRPC.xml
new file mode 100644 (file)
index 0000000..d23daa0
--- /dev/null
@@ -0,0 +1,210 @@
+<?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
+ http://www.apache.org/licenses/LICENSE-2.0
+-->
+
+<project name="gRPC-Verigraph" default="run-tests" basedir="."  xmlns:artifact="antlib:org.apache.maven.artifact.ant">
+       <description>
+                       Script for gRPC-Verigraph
+       </description>
+
+       <!-- The location of this assignment -->
+       <property name="grpc.location" location="." />
+
+       <!-- The location to be used for class files -->
+       <property name="build.dir" location="${grpc.location}/build" />
+       <!-- The location for source files -->
+       <property name="src.dir" location="${grpc.location}/src/main/java" />
+       <!-- The location for solutions -->
+       <property name="grpc.dir" value="src/main/java/it/polito/grpc" />
+       <!-- The location for jar files -->
+       <property name="lib.dir" location="${grpc.location}/lib" />
+       <!-- The location for jar files -->
+       <property name="other_lib.dir" location="${grpc.location}/service/build" />
+       <!-- The location for generated files -->
+       <property name="generated.dir" location="${basedir}/target/generated-sources" />
+       <!-- The default test class -->
+       <property name="test1.class" value="it.polito.grpc.test.GrpcServerTest" />
+       <property name="test2.class" value="it.polito.grpc.test.GrpcTest" />
+       <property name="test3.class" value="it.polito.grpc.test.MultiThreadTest" />
+       <property name="test4.class" value="it.polito.grpc.test.ReachabilityTest" />
+
+       <!-- The name to be given to the final zip -->
+       <property name="sol.zip" value="grpc.zip" />
+
+       <!-- Java compiler settings -->
+       <property name="debug" value="true" />
+       <property name="debuglevel" value="source,lines,vars" />
+       <property name="target" value="1.8" />
+       <property name="source" value="1.8" />
+
+       <!-- The classpath to be used for running the tests -->
+       <path id="test.classpath">
+               <pathelement path="${build.dir}" />
+               <fileset dir="${grpc.location}/lib">
+                   <include name="*.jar" />
+               </fileset>
+               <fileset refid="mvn-dependencies" />
+       </path>
+
+       <!-- Here starts part for Maven -->
+       <path id="maven-ant-tasks.classpath" path="lib/maven-ant-tasks-2.1.3.jar" />
+       <typedef resource="org/apache/maven/artifact/ant/antlib.xml"
+                  uri="antlib:org.apache.maven.artifact.ant"
+                  classpathref="maven-ant-tasks.classpath" />
+       <property file="build.properties"/>
+
+       <!-- Load pom.xml for dependencies -->
+       <artifact:pom id="pomfile" file="pom.xml" />
+       <artifact:dependencies filesetId="mvn-dependencies" pomRefId="pomfile" />
+
+       <!-- Grab the HSQLDB jar and add it to the classpath
+       <artifact:dependencies filesetId="warDeps">
+               <dependency groupId="org.glassfish.jersey" artifactId="jersey-bom" version="2.22.1" />
+       </artifact:dependencies>-->
+
+       <path id="build.classpath">
+           <fileset refid="mvn-dependencies" />
+       </path>
+
+       <target name="init">
+               <mkdir dir="${build.dir}" />
+       </target>
+
+       <!-- The target for compiling the gRPC application -->
+       <target name="build" depends="init" description="Build the sources">
+               <echo>Building gRPC (if needed)...</echo>
+                       <javac
+                               debug="${debug}"
+                               debuglevel="${debuglevel}"
+                               source="${source}"
+                               target="${target}"
+                               destdir="${build.dir}"
+                               classpathref="build.classpath"
+                               includeantruntime="false">
+                               <src path="${generated.dir}" />
+                               <src path="${src.dir}" />
+                               <compilerarg value="-Xlint:unchecked"/>
+                               <classpath>
+                                       <pathelement path="${other_lib.dir}/qjutils.jar"/>
+                               </classpath>
+                       </javac>
+               <echo>Done.</echo>
+       </target>
+
+       <!-- The target for running the gRPC application -->
+       <target name="run" depends="build" description="Run gRPC">
+               <parallel>
+                       <sequential>
+                       <java classname="it.polito.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.grpc.Client" failonerror="true" classpathref="build.classpath" fork="yes">
+                               <classpath>
+                                       <pathelement path="${build.dir}"/>
+                               </classpath>
+                               </java>
+                       </sequential>
+               </parallel>
+       </target>
+
+       <target name="run-client" depends="build" description="Run gRPC client">
+               <java classname="it.polito.grpc.Client" failonerror="true" classpathref="build.classpath" fork="yes">
+                       <classpath>
+                               <pathelement path="${build.dir}"/>
+                       </classpath>
+               </java>
+       </target>
+
+       <target name="run-server" depends="build" description="Run gRPC server">
+               <java classname="it.polito.grpc.Service" failonerror="true" classpathref="build.classpath" fork="yes">
+                       <classpath>
+                               <pathelement path="${build.dir}"/>
+                       </classpath>
+               </java>
+       </target>
+
+       <target name="run-tests" description="Run tests for gRPC">
+               <echo>Running functional tests</echo>
+               
+               <antcall target="runFuncTest.real">
+                       <param name="exit.code1" value="126" />
+                       <param name="exit.code2" value="125" />
+                       <param name="exit.code3" value="124" />
+                       <param name="exit.code4" value="123" />
+               </antcall>
+       </target>
+
+       <!-- Target runFuncTest.real    -->
+       <target name="runFuncTest.real" depends="build">
+
+               <echo>Running First set of Junit tests...</echo>
+               <junit printsummary="yes" dir="." fork="yes" haltonfailure="no" showoutput="no" filtertrace="true" timeout="120000">
+                       <jvmarg value="-Djava.awt.headless=true" />
+                       <formatter type="brief" usefile="false"/>
+                       <test haltonfailure="no" failureproperty="test_failed" name="${test1.class}"/>
+                       <classpath>
+                               <path refid="test.classpath" />
+                       </classpath>
+               </junit>
+               <fail if="test_failed" status="${exit.code1}" message="*** First set of Junit tests: Some Tests FAILED ***"/>
+               <echo>*** First set of Junit tests: All Tests PASSED  ***</echo>
+               
+               <echo>Running Second set of Junit tests...</echo>
+               <junit printsummary="yes" dir="." fork="yes" haltonfailure="no" showoutput="no" filtertrace="true" timeout="120000">
+                       <jvmarg value="-Djava.awt.headless=true" />
+                       <formatter type="brief" usefile="false"/>
+                       <test haltonfailure="no" failureproperty="test_failed" name="${test2.class}"/>
+                       <classpath>
+                               <path refid="test.classpath" />
+                       </classpath>
+               </junit>
+               <fail if="test_failed" status="${exit.code2}" message="*** Second set of Junit tests: Some Tests FAILED ***"/>
+               <echo>*** Second set of Junit tests: All Tests PASSED  ***</echo>
+               
+               <echo>Running Third set of Junit tests...</echo>
+               <junit printsummary="yes" dir="." fork="yes" haltonfailure="no" showoutput="no" filtertrace="true" timeout="120000">
+                       <jvmarg value="-Djava.awt.headless=true" />
+                       <formatter type="brief" usefile="false"/>
+                       <test haltonfailure="no" failureproperty="test_failed" name="${test3.class}"/>
+                       <classpath>
+                               <path refid="test.classpath" />
+                       </classpath>
+               </junit>
+               <fail if="test_failed" status="${exit.code3}" message="*** Third set of Junit tests: Some Tests FAILED ***"/>
+               <echo>*** Third set of Junit tests: All Tests PASSED  ***</echo>
+
+               <echo>Running Fourth set of Junit tests...</echo>
+               <junit printsummary="yes" dir="." fork="yes" haltonfailure="no" showoutput="no" filtertrace="true" timeout="120000">
+                       <jvmarg value="-Djava.awt.headless=true" />
+                       <jvmarg value="-Djava.library.path=${other_lib.dir}" />
+                       <formatter type="brief" usefile="false"/>
+                       <test haltonfailure="no" failureproperty="test_failed" name="${test4.class}"/>
+                       <classpath>
+                               <path refid="test.classpath" />
+                               <fileset dir="${other_lib.dir}">
+                                       <include name="*.jar" />
+                               </fileset>
+                       </classpath>
+               </junit>
+               <fail if="test_failed" status="${exit.code4}" message="*** Fourth set of Junit tests: Some Tests FAILED ***"/>
+               <echo>*** Fourth set of Junit tests: All Tests PASSED  ***</echo>
+               <echo>***************************************************</echo>
+               <echo>*************** All Tests PASSED  *****************</echo>
+       </target>
+
+       <!-- target for cleaning -->
+       <target name="clean">
+               <delete dir="${build.dir}" />
+       </target>
+</project>
diff --git a/verigraph/pom.xml b/verigraph/pom.xml
new file mode 100644 (file)
index 0000000..63603a7
--- /dev/null
@@ -0,0 +1,213 @@
+<!-- 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 http://www.apache.org/licenses/LICENSE-2.0 -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+       <modelVersion>4.0.0</modelVersion>
+
+       <groupId>it.polito.escape</groupId>
+       <artifactId>verify</artifactId>
+       <packaging>war</packaging>
+       <version>0.0.1-SNAPSHOT</version>
+       <name>verify</name>
+       <url>http://maven.apache.org</url>
+       <properties>
+               <grpc.version>1.0.3</grpc.version><!-- CURRENT_GRPC_VERSION -->
+               <jersey.version>2.22.1</jersey.version>
+               <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+       </properties>
+       <build>
+               <finalName>verify</finalName>
+               <extensions>
+                       <extension>
+                               <groupId>kr.motd.maven</groupId>
+                               <artifactId>os-maven-plugin</artifactId>
+                               <version>1.4.1.Final</version>
+                       </extension>
+               </extensions>
+               <plugins>
+                       <plugin>
+                               <groupId>org.xolstice.maven.plugins</groupId>
+                               <artifactId>protobuf-maven-plugin</artifactId>
+                               <version>0.5.0</version>
+                               <configuration>
+                                       <protocArtifact>com.google.protobuf:protoc:3.1.0:exe:${os.detected.classifier}</protocArtifact>
+                                       <pluginId>grpc-java</pluginId>
+                                       <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
+                               </configuration>
+                               <executions>
+                                       <execution>
+                                               <goals>
+                                                       <goal>compile</goal>
+                                                       <goal>compile-custom</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                               <version>2.5.1</version>
+                               <inherited>true</inherited>
+                               <configuration>
+                                       <source>1.8</source>
+                                       <target>1.8</target>
+                               </configuration>
+                       </plugin>
+               </plugins>
+               <pluginManagement>
+                       <plugins>
+                               <plugin>
+                                       <groupId>org.eclipse.m2e</groupId>
+                                       <artifactId>lifecycle-mapping</artifactId>
+                                       <version>1.0.0</version>
+                                       <configuration>
+                                               <lifecycleMappingMetadata>
+                                                       <pluginExecutions>
+                                                               <pluginExecution>
+                                                                       <pluginExecutionFilter>
+                                                                               <groupId>org.apache.maven.plugins</groupId>
+                                                                               <artifactId>maven-enforcer-plugin</artifactId>
+                                                                               <versionRange>[1.0.0,)</versionRange>
+                                                                               <goals>
+                                                                                       <goal>enforce</goal>
+                                                                               </goals>
+                                                                       </pluginExecutionFilter>
+                                                                       <action>
+                                                                               <ignore />
+                                                                       </action>
+                                                               </pluginExecution>
+                                                       </pluginExecutions>
+                                               </lifecycleMappingMetadata>
+                                       </configuration>
+                               </plugin>
+                       </plugins>
+               </pluginManagement>
+       </build>
+
+       <dependencyManagement>
+               <dependencies>
+                       <dependency>
+                               <groupId>org.glassfish.jersey</groupId>
+                               <artifactId>jersey-bom</artifactId>
+                               <version>${jersey.version}</version>
+                               <type>pom</type>
+                               <scope>import</scope>
+                       </dependency>
+               </dependencies>
+       </dependencyManagement>
+
+       <dependencies>
+               <dependency>
+                       <groupId>org.glassfish.jersey.containers</groupId>
+                       <artifactId>jersey-container-servlet-core</artifactId>
+                       <!-- use the following artifactId if you don't need servlet 2.x compatibility -->
+                       <!-- artifactId>jersey-container-servlet</artifactId -->
+               </dependency>
+
+               <dependency>
+                       <groupId>org.glassfish.jersey.bundles</groupId>
+                       <artifactId>jaxrs-ri</artifactId>
+               </dependency>
+
+               <!-- <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-moxy</artifactId>
+                       </dependency> -->
+
+               <dependency>
+                       <groupId>org.glassfish.jersey.media</groupId>
+                       <artifactId>jersey-media-json-jackson</artifactId>
+               </dependency>
+
+               <dependency>
+                       <groupId>io.swagger</groupId>
+                       <artifactId>swagger-jersey2-jaxrs</artifactId>
+                       <version>1.5.0</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>com.googlecode.json-simple</groupId>
+                       <artifactId>json-simple</artifactId>
+                       <version>1.1</version>
+               </dependency>
+
+               <!-- added to retrieve server path -->
+               <!-- <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId>
+                       <version>3.1.0</version> <scope>provided</scope> </dependency> -->
+
+               <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
+               <dependency>
+                       <groupId>org.slf4j</groupId>
+                       <artifactId>slf4j-log4j12</artifactId>
+                       <version>1.5.6</version>
+               </dependency>
+
+
+               <dependency>
+                       <groupId>com.github.fge</groupId>
+                       <artifactId>json-schema-validator</artifactId>
+                       <version>2.2.6</version>
+               </dependency>
+
+               <!-- http://mvnrepository.com/artifact/org.json/json -->
+               <dependency>
+                       <groupId>org.json</groupId>
+                       <artifactId>json</artifactId>
+                       <version>20160212</version>
+               </dependency>
+
+               <!-- https://mvnrepository.com/artifact/junit/junit -->
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <version>4.12</version>
+               </dependency>
+
+
+               <dependency>
+                       <groupId>javax.servlet</groupId>
+                       <artifactId>javax.servlet-api</artifactId>
+                       <version>3.1.0</version>
+                       <scope>provided</scope>
+               </dependency>
+
+               <!-- here start dependencies for grpc -->
+               <dependency>
+                       <groupId>org.apache.thrift</groupId>
+                       <artifactId>libthrift</artifactId>
+                       <version>0.9.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>io.grpc</groupId>
+                       <artifactId>grpc-netty</artifactId>
+                       <version>${grpc.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>io.grpc</groupId>
+                       <artifactId>grpc-protobuf</artifactId>
+                       <version>${grpc.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>io.grpc</groupId>
+                       <artifactId>grpc-stub</artifactId>
+                       <version>${grpc.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.mockito</groupId>
+                       <artifactId>mockito-core</artifactId>
+                       <version>1.9.5</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>com.google.protobuf</groupId>
+                       <artifactId>protobuf-java</artifactId>
+                       <version>3.0.2</version>
+               </dependency>
+
+
+
+       </dependencies>
+
+</project>
diff --git a/verigraph/service/src/mcnet/components/Checker.java b/verigraph/service/src/mcnet/components/Checker.java
new file mode 100644 (file)
index 0000000..3c13d28
--- /dev/null
@@ -0,0 +1,363 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Model;
+import com.microsoft.z3.Solver;
+import com.microsoft.z3.Status;
+
+/**Various checks for specific properties in the network.
+ *
+ */
+public class Checker {
+
+       Context ctx;
+       Network net;
+       NetContext nctx;
+       Solver solver;
+       ArrayList<BoolExpr> constraints;
+       public BoolExpr [] assertions;
+       public Status result;
+       public Model model;
+
+
+   public Checker(Context context,NetContext nctx,Network network){
+        this.ctx = context;
+        this.net = network;
+        this.nctx = nctx;
+        this.solver = ctx.mkSolver();
+        this.constraints = new ArrayList<BoolExpr>();
+   }
+
+   /**Resets the constraints
+    *
+    */
+    public void clearState (){
+        this.solver.reset();
+        this.constraints = new ArrayList<BoolExpr>();
+    }
+
+       /**Checks whether the source provided can reach the destination
+        *
+        * @param src
+        * @param dest
+        * @return
+        */
+       public IsolationResult checkIsolationProperty (NetworkObject src, NetworkObject dest){
+               assert(net.elements.contains(src));
+           assert(net.elements.contains(dest));
+           solver.push ();
+           addConstraints();
+
+           Expr p0 = ctx.mkConst("check_isolation_p0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+           Expr p1 = ctx.mkConst("check_isolation_p1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+           Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+           Expr n_1 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+           IntExpr t_0 = ctx.mkIntConst("check_isolation_t0_"+src.getZ3Node()+"_"+dest.getZ3Node());
+           IntExpr t_1 = ctx.mkIntConst("check_isolation_t1_"+src.getZ3Node()+"_"+dest.getZ3Node());
+
+       //              Constraint1             recv(n_0,destNode,p0,t_0)
+           this.solver.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p0, t_0));
+
+       //              Constraint2             send(srcNode,n_1,p1,t_1)
+           this.solver.add((BoolExpr)nctx.send.apply(src.getZ3Node(), n_1, p1, t_1));
+
+       //              Constraint3             nodeHasAddr(srcNode,p1.srcAddr)
+           this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(src.getZ3Node(), nctx.pf.get("src").apply(p1)));
+
+       //              Constraint4             p1.origin == srcNode
+           this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p1), src.getZ3Node()));
+
+       //              Constraint5             nodeHasAddr(destNode,p1.destAddr)
+           this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(dest.getZ3Node(), nctx.pf.get("dest").apply(p1)));
+
+               //NON sembrano necessari
+               //         this.solver.add(z3.Or(this.ctx.nodeHasAddr(src.getZ3Node(), this.ctx.packet.src(p0)),\
+               //                               this.ctx.nodeHasAddr(n_0, this.ctx.packet.src(p0)),\
+               //                               this.ctx.nodeHasAddr(n_1, this.ctx.packet.src(p0))))
+               //this.solver.add(this.ctx.packet.dest(p1) == this.ctx.packet.dest(p0))
+
+       //              Constraint6             p1.origin ==  p0.origin
+           this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p1),nctx.pf.get("origin").apply(p0)));
+
+       //              Constraint7             nodeHasAddr(destNode, p0.destAddr)
+           this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(dest.getZ3Node(), nctx.pf.get("dest").apply(p0)));
+
+           result = this.solver.check();
+           model = null;
+           assertions = this.solver.getAssertions();
+           if (result == Status.SATISFIABLE){
+               model = this.solver.getModel();
+           }
+           this.solver.pop();
+           return new IsolationResult(ctx,result, p0, n_0, t_1, t_0, nctx, assertions, model);
+       }
+
+
+
+       public IsolationResult CheckIsolationFlowProperty (NetworkObject src, NetworkObject dest){
+               assert(net.elements.contains(src));
+           assert(net.elements.contains(dest));
+           solver.push ();
+           addConstraints();
+
+           Expr p = ctx.mkConst("check_isolation_p_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+           Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+           Expr n_1 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+           Expr n_2 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+
+           IntExpr t_0 = ctx.mkIntConst("check_isolation_t0_"+src.getZ3Node()+"_"+dest.getZ3Node());
+           IntExpr t_1 = ctx.mkIntConst("check_isolation_t1_"+src.getZ3Node()+"_"+dest.getZ3Node());
+           IntExpr t_2 = ctx.mkIntConst("check_isolation_t2_"+src.getZ3Node()+"_"+dest.getZ3Node());
+
+       //              Constraint1             recv(n_0,destNode,p,t_0)
+           this.solver.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p, t_0));
+
+       //              Constraint2             send(srcNode,n_1,p1,t_1)
+           this.solver.add((BoolExpr)nctx.send.apply(src.getZ3Node(), n_1, p, t_1));
+
+       //              Constraint3             nodeHasAddr(srcNode,p.srcAddr)
+           this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(src.getZ3Node(), nctx.pf.get("src").apply(p)));
+
+       //              Constraint4             p.origin == srcNode
+           this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p), src.getZ3Node()));
+
+
+           Expr p_2 = ctx.mkConst("check_isolation_p_flow_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+
+           //      Constraint5         there does not exist p_2, n_2, t_2 :
+                                                       //                       send(destNode,n_2,p_2,t_2) &&
+                                                       //                   p_2.srcAddr == p. destAddr &&
+                                                       //                   p_2.srcPort == p.destPort &&
+                                                       //                   p_2.destPort == p.srcPort &&
+                                                       //                   p_2.destt == p.src &&
+                                                       //                   t_2 < t_0
+           this.solver.add(ctx.mkNot(ctx.mkExists(new Expr[]{p_2,n_2,t_2},
+                                       ctx.mkAnd(
+                                                       (BoolExpr)nctx.send.apply(dest.getZ3Node(), n_2, p_2, t_2),
+                                                       ctx.mkEq(nctx.pf.get("src").apply(p_2), nctx.pf.get("dest").apply(p)),
+                                                       ctx.mkEq(nctx.pf.get("src_port").apply(p_2), nctx.pf.get("dest_port").apply(p)),
+                                                       ctx.mkEq(nctx.pf.get("dest_port").apply(p_2), nctx.pf.get("src_port").apply(p)),
+                                                       ctx.mkEq(nctx.pf.get("dest").apply(p_2), nctx.pf.get("src").apply(p)),
+                                                       ctx.mkLt(t_2,t_0)),1,null,null,null,null)));
+
+
+           result = this.solver.check();
+           model = null;
+           assertions = this.solver.getAssertions();
+           if (result == Status.SATISFIABLE){
+               model = this.solver.getModel();
+           }
+           this.solver.pop();
+           return new IsolationResult(ctx,result, p, n_0, t_1, t_0, nctx, assertions, model);
+       }
+
+
+
+    public IsolationResult CheckNodeTraversalProperty (NetworkObject src, NetworkObject dest, NetworkObject node){
+               assert(net.elements.contains(src));
+           assert(net.elements.contains(dest));
+           solver.push ();
+           addConstraints();
+
+           Expr p = ctx.mkConst("check_isolation_p_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+
+           Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+           Expr n_1 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+           Expr n_2 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+
+           IntExpr t_0 = ctx.mkIntConst("check_isolation_t0_"+src.getZ3Node()+"_"+dest.getZ3Node());
+           IntExpr t_1 = ctx.mkIntConst("check_isolation_t1_"+src.getZ3Node()+"_"+dest.getZ3Node());
+           IntExpr t_2 = ctx.mkIntConst("check_isolation_t2_"+src.getZ3Node()+"_"+dest.getZ3Node());
+
+       //              Constraint1             recv(n_0,destNode,p,t_0)
+           this.solver.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p, t_0));
+
+       //              Constraint2             send(srcNode,n_1,p1,t_1)
+           this.solver.add((BoolExpr)nctx.send.apply(src.getZ3Node(), n_1, p, t_1));
+
+       //              Constraint3             nodeHasAddr(srcNode,p.srcAddr)
+           this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(src.getZ3Node(), nctx.pf.get("src").apply(p)));
+
+       //              Constraint4             p.origin == srcNode
+           this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p), src.getZ3Node()));
+
+
+       //                      Constraint5             there does not exist n_2, t_2 : recv(n_2,node,p,t_2) && t_2 < t_0
+           this.solver.add(ctx.mkNot(ctx.mkExists(new Expr[]{n_2,t_2},
+                                       ctx.mkAnd(
+                                                       (BoolExpr)nctx.recv.apply(n_2, node.getZ3Node(), p, t_2),
+                                                       ctx.mkLt(t_2,t_0)),1,null,null,null,null)));
+
+       //                      Constraint 6    there does not exist n_2, t_2 : send(node,n_2,p,t_2) && t_2 < t_0
+           this.solver.add(ctx.mkNot(ctx.mkExists(new Expr[]{n_2,t_2},
+                               ctx.mkAnd(
+                                               (BoolExpr)nctx.send.apply(node.getZ3Node(), n_2, p, t_2),
+                                               ctx.mkLt(t_2,t_0)),1,null,null,null,null)));
+
+
+           result = this.solver.check();
+           model = null;
+           assertions = this.solver.getAssertions();
+           if (result == Status.SATISFIABLE){
+               model = this.solver.getModel();
+           }
+           this.solver.pop();
+           return new IsolationResult(ctx,result, p, n_0, t_1, t_0, nctx, assertions, model);
+       
+    }
+
+    public IsolationResult CheckLinkTraversalProperty (NetworkObject src, NetworkObject dest, NetworkObject le0, NetworkObject le1){
+               assert(net.elements.contains(src));
+           assert(net.elements.contains(dest));
+           solver.push ();
+           addConstraints();
+
+           Expr p = ctx.mkConst("check_isolation_p_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+
+           Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+           Expr n_1 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+
+           IntExpr t_0 = ctx.mkIntConst("check_isolation_t0_"+src.getZ3Node()+"_"+dest.getZ3Node());
+           IntExpr t_1 = ctx.mkIntConst("check_isolation_t1_"+src.getZ3Node()+"_"+dest.getZ3Node());
+           IntExpr t_2 = ctx.mkIntConst("check_isolation_t2_"+src.getZ3Node()+"_"+dest.getZ3Node());
+
+       //              Constraint1             recv(n_0,destNode,p,t_0)
+           this.solver.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p, t_0));
+
+       //              Constraint2             send(srcNode,n_1,p1,t_1)
+           this.solver.add((BoolExpr)nctx.send.apply(src.getZ3Node(), n_1, p, t_1));
+
+       //              Constraint3             nodeHasAddr(srcNode,p.srcAddr)
+           this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(src.getZ3Node(), nctx.pf.get("src").apply(p)));
+
+       //              Constraint4             p.origin == srcNode
+           this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p), src.getZ3Node()));
+
+       //                      Constraint5             âˆƒ t_1, t_2 :
+                                               //          send(linkNode0,linkNode1,p,t_1) &&
+                                                       //          recv(linkNode0,linkNode1,p,t_2) &&
+                                                       //          t_1 < t_0 &&
+                                                       //          t_2 < t_0
+           this.solver.add(ctx.mkExists(new Expr[]{t_1,t_2},
+                                       ctx.mkAnd(
+                                                       (BoolExpr)nctx.send.apply(le0.getZ3Node(), le1.getZ3Node(), p, t_1),
+                                                       (BoolExpr)nctx.recv.apply(le0.getZ3Node(), le1.getZ3Node(), p, t_2),
+                                                       ctx.mkLt(t_1,t_0),
+                                                       ctx.mkLt(t_2,t_0)),1,null,null,null,null));
+
+
+           result = this.solver.check();
+           model = null;
+           assertions = this.solver.getAssertions();
+           if (result == Status.SATISFIABLE){
+               model = this.solver.getModel();
+           }
+           this.solver.pop();
+           return new IsolationResult(ctx,result, p, n_0, t_1, t_0, nctx, assertions, model);
+
+    }
+
+   public Result CheckDataIsolationPropertyCore (NetworkObject src, NetworkObject dest){
+               assert(net.elements.contains(src));
+           assert(net.elements.contains(dest));
+           List<BoolExpr> constr = this.getConstraints();
+           Expr p = ctx.mkConst("check_isolation_p_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+
+           Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+           IntExpr t = ctx.mkIntConst("check_isolation_t_"+src.getZ3Node()+"_"+dest.getZ3Node());
+
+       //              Constraint1             recv(n_0,destNode,p,t)
+           constr.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p, t));
+
+       //              Constraint2             p.origin == srcNode
+           this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p), src.getZ3Node()));
+
+           this.solver.push();
+
+    //            Constraint3          for each constraint( n -> constraint)
+           ArrayList<BoolExpr> names =new ArrayList<BoolExpr>();
+           for(BoolExpr con : constr){
+               BoolExpr n = ctx.mkBoolConst(""+con);
+               names.add(n);
+               this.solver.add(ctx.mkImplies(n, con));
+           }
+
+           BoolExpr[] nam = new BoolExpr[names.size()];
+           result = this.solver.check(names.toArray(nam));
+           Result ret =null;
+
+           if (result == Status.SATISFIABLE){
+               System.out.println("SAT");
+               ret = new Result(ctx,this.solver.getModel());
+           }else if(result == Status.UNSATISFIABLE){
+               System.out.println("unsat");
+               ret = new Result(ctx,this.solver.getUnsatCore());
+           }
+           this.solver.pop();
+           return ret;
+   }
+
+    public DataIsolationResult CheckDataIsolationProperty(NetworkObject src, NetworkObject dest){
+       assert(net.elements.contains(src));
+           assert(net.elements.contains(dest));
+           solver.push ();
+           addConstraints();
+
+           Expr p = ctx.mkConst("check_isolation_p_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+
+           Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+           IntExpr t = ctx.mkIntConst("check_isolation_t_"+src.getZ3Node()+"_"+dest.getZ3Node());
+
+       //              Constraint1             recv(n_0,destNode,p,t)
+           this.solver.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p, t));
+
+       //              Constraint2             p.origin == srcNode
+           this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p), src.getZ3Node()));
+
+           result = this.solver.check();
+           model = null;
+           assertions = this.solver.getAssertions();
+           if (result == Status.SATISFIABLE){
+               model = this.solver.getModel();
+           }
+           this.solver.pop();
+           return new DataIsolationResult(ctx,result, p, n_0, t, nctx, assertions, model);
+    }
+
+
+
+
+       public void addConstraints(){
+           nctx.addConstraints(solver);
+           net.addConstraints(solver);
+           for (NetworkObject el : net.elements)
+               el.addConstraints(solver);
+       }
+
+
+        public List<BoolExpr> getConstraints(){
+               Solver l = ctx.mkSolver();
+               nctx.addConstraints(l);
+               net.addConstraints(l);
+               for (NetworkObject el : net.elements)
+                   el.addConstraints(l);
+               return Arrays.asList(l.getAssertions());
+       }
+}
diff --git a/verigraph/service/src/mcnet/components/Core.java b/verigraph/service/src/mcnet/components/Core.java
new file mode 100644 (file)
index 0000000..c72b9e3
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.Solver;
+
+/**Core component for everything that matters
+ *
+ */
+public abstract class Core{
+
+               final int MAX_PORT = 512;
+
+          /**
+           * Base class for all objects in the modeling framework
+           * @param ctx
+           * @param args
+           */
+           public Core(Context ctx, Object[]... args){ // Object[]... -> The nearest way to implement variable length argument lists
+                                                                                               //in Java, in the most generic way.
+                   init(ctx,args);
+           }
+           /**
+            * Override _init for any constructor initialization. Avoids having to explicitly call super.__init__ every Time.class
+            * @param ctx
+            * @param args
+            */
+           abstract protected void init(Context ctx,Object[]... args);
+
+           /**
+            * Add constraints to solver
+            * @param solver
+            */
+           abstract protected void addConstraints(Solver solver);
+}
+
+
diff --git a/verigraph/service/src/mcnet/components/DataIsolationResult.java b/verigraph/service/src/mcnet/components/DataIsolationResult.java
new file mode 100644 (file)
index 0000000..b90a47f
--- /dev/null
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.Model;
+import com.microsoft.z3.Status;
+
+
+/**Data structure for the response to a check request for data isolation property
+ *
+ */
+public class DataIsolationResult {
+
+       Context ctx;
+       public NetContext nctx;
+       public Status result;
+       public Model model;
+       public Expr violating_packet,last_hop,last_time,t_1;
+       public BoolExpr [] assertions;
+
+       public DataIsolationResult(Context ctx,Status result, Expr violating_packet, Expr last_hop, Expr last_time, NetContext nctx, BoolExpr[] assertions, Model model){
+            this.ctx = ctx;
+            this.result = result;
+            this.violating_packet = violating_packet;
+            this.last_hop = last_hop;
+            this.model = model;
+            this.last_time = last_time;
+            this.assertions = assertions;
+       }
+}
+
diff --git a/verigraph/service/src/mcnet/components/IsolationResult.java b/verigraph/service/src/mcnet/components/IsolationResult.java
new file mode 100644 (file)
index 0000000..1ecaccc
--- /dev/null
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.Model;
+import com.microsoft.z3.Status;
+
+/**
+ * Data structure for the response to check requests for isolation properties
+ *
+ */
+public class IsolationResult {
+
+       Context ctx;
+       public NetContext nctx;
+       public Status result;
+       public Model model;
+       public Expr violating_packet,last_hop,last_send_time,last_recv_time,t_1;
+       public BoolExpr [] assertions;
+
+       public IsolationResult(Context ctx,Status result, Expr violating_packet, Expr last_hop, Expr last_send_time, Expr last_recv_time,NetContext nctx, BoolExpr[] assertions, Model model){
+            this.ctx = ctx;
+            this.result = result;
+            this.violating_packet = violating_packet;
+            this.last_hop = last_hop;
+            this.model = model;
+            this.last_send_time = last_send_time;
+            this.last_recv_time = last_recv_time;
+            this.assertions = assertions;
+       }
+}
+
diff --git a/verigraph/service/src/mcnet/components/NetContext.java b/verigraph/service/src/mcnet/components/NetContext.java
new file mode 100644 (file)
index 0000000..ece31c5
--- /dev/null
@@ -0,0 +1,340 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Constructor;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.DatatypeSort;
+import com.microsoft.z3.EnumSort;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+import com.microsoft.z3.Sort;
+
+import mcnet.netobjs.DumbNode;
+
+/**
+ * Basic fields and other things required for model checking.
+ *
+ */
+public class NetContext extends Core{
+
+
+               List<BoolExpr> constraints; 
+               List<Core> policies;
+
+           public HashMap<String,NetworkObject> nm; //list of nodes, callable by node name
+           public HashMap<String,DatatypeExpr> am; // list of addresses, callable by address name
+           public HashMap<String,FuncDecl> pf;
+           Context ctx;
+           public EnumSort node,address;
+           public FuncDecl src_port,dest_port,nodeHasAddr,addrToNode,send,recv;
+           public DatatypeSort packet;
+
+           /*     Constants definition
+               - used in the packet proto field */
+               public final int HTTP_REQUEST    = 1;
+               public final int HTTP_RESPONSE   = 2;
+               public final int POP3_REQUEST    = 3;
+               public final int POP3_RESPONSE   = 4;
+
+               /**
+                * Context for all of the rest that follows. Every network needs one of these
+                * @param ctx
+                * @param args
+                */
+               public NetContext(Context ctx,Object[]... args ){
+                       super(ctx,args);
+
+               }
+
+               @Override
+               protected void init(Context ctx, Object[]... args) {
+                       this.ctx = ctx;
+               nm = new HashMap<String,NetworkObject>(); //list of nodes, callable by node name
+                   am = new HashMap<String,DatatypeExpr>(); // list of addresses, callable by address name
+                   pf= new HashMap<String,FuncDecl>() ;
+
+                   mkTypes((String[])args[0],(String[])args[1]);
+
+                       constraints = new ArrayList<BoolExpr>();
+               policies = new ArrayList<Core>();
+
+               baseCondition();
+               }
+
+           /**
+            * A policy is a collection of shared algorithms or functions used by multiple components
+            * (for instance compression or DPI policies etc).
+            * @param policy
+            */
+           public void AddPolicy (NetworkObject policy){
+               policies.add(policy);
+           }
+
+               @Override
+               protected void addConstraints(Solver solver) {
+                       BoolExpr[] constr = new BoolExpr[constraints.size()];
+                   solver.add(constraints.toArray(constr));
+               for (Core policy : policies){
+                   policy.addConstraints(solver);
+               }
+               }
+
+           private void mkTypes (String[] nodes, String[] addresses){
+               //Nodes in a network
+               node = ctx.mkEnumSort("Node", nodes);
+               for(int i=0;i<node.getConsts().length;i++){
+                       DatatypeExpr fd  = (DatatypeExpr)node.getConst(i);
+                       DumbNode dn =new DumbNode(ctx,new Object[]{fd});
+                       nm.put(fd.toString(),dn);
+               }
+
+               //Addresses for this network
+               String[] new_addr = new String[addresses.length+1];
+               for(int k=0;k<addresses.length;k++)
+                       new_addr[k] = addresses[k];
+
+               new_addr[new_addr.length-1] = "null";
+               address = ctx.mkEnumSort("Address", new_addr);
+               for(int i=0;i<address.getConsts().length;i++){
+                       DatatypeExpr fd  = (DatatypeExpr)address.getConst(i);
+                       am.put(fd.toString(),fd);
+               }
+
+               // Type for packets, contains (some of these are currently represented as relations):
+               // -   src: Source address
+               // -   dest: Destination address
+               // -   origin: Node where the data originated. (Node)
+               // -   body: Packet contents. (Integer)
+               // -   seq: Sequence number for packets. (Integer)
+               // -   options: A representation for IP options. (Integer)
+
+               String[] fieldNames = new String[]{
+                               "src","dest","inner_src","inner_dest","origin","orig_body","body","seq","proto","emailFrom","url","options","encrypted"};
+               Sort[] srt = new Sort[]{
+                               address,address,address,address,node,ctx.mkIntSort(),ctx.mkIntSort(),ctx.mkIntSort(),
+                               ctx.mkIntSort(),ctx.mkIntSort(),ctx.mkIntSort(),ctx.mkIntSort(),ctx.mkBoolSort()};
+               Constructor packetcon = ctx.mkConstructor("packet", "is_packet", fieldNames, srt, null);
+               packet = ctx.mkDatatypeSort("packet",  new Constructor[] {packetcon});
+
+               for(int i=0;i<fieldNames.length;i++){
+                       pf.put(fieldNames[i], packet.getAccessors()[0][i]); // pf to get packet's function declarations by name
+                   }
+
+               src_port = ctx.mkFuncDecl("sport", packet, ctx.mkIntSort());
+               dest_port = ctx.mkFuncDecl("dport", packet, ctx.mkIntSort());
+
+               // Some commonly used relations
+
+               // nodeHasAddr: node -> address -> boolean
+               nodeHasAddr = ctx.mkFuncDecl("nodeHasAddr", new Sort[]{node, address},ctx.mkBoolSort());
+
+               // addrToNode: address -> node
+               addrToNode = ctx.mkFuncDecl("addrToNode", address, node);
+
+               // Send and receive both have the form:
+               // source-> destination -> packet-> int-> bool
+
+               // send: node -> node -> packet-> int-> bool
+               send = ctx.mkFuncDecl("send", new Sort[]{ node, node, packet, ctx.mkIntSort()},ctx.mkBoolSort());
+
+               // recv: node -> node -> packet-> int-> bool
+               recv = ctx.mkFuncDecl("recv", new Sort[]{ node, node, packet, ctx.mkIntSort()},ctx.mkBoolSort());
+
+           }
+
+           /**
+            * Set up base conditions for the network
+            */
+           private void baseCondition(){
+               // Basic constraints for the overall model
+               Expr n_0 = ctx.mkConst("ctx_base_n_0", node);
+               Expr n_1 = ctx.mkConst("ctx_base_n_1", node);
+               Expr n_2 = ctx.mkConst("ctx_base_n_2", node);
+               Expr p_0 = ctx.mkConst("ctx_base_p_0", packet);
+               Expr p_1 = ctx.mkConst("ctx_base_p_1", packet);
+               IntExpr t_0 = ctx.mkIntConst("ctx_base_t_0");
+               IntExpr t_1 = ctx.mkIntConst("ctx_base_t_1");
+
+               // Constraint1          send(n_0, n_1, p_0, t_0) -> n_0 != n_1
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+                           ctx.mkImplies((BoolExpr)send.apply(n_0, n_1, p_0, t_0),ctx.mkNot(ctx.mkEq( n_0, n_1))),1,null,null,null,null));
+
+               // Constraint2          recv(n_0, n_1, p_0, t_0) -> n_0 != n_1
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+                           ctx.mkImplies((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),ctx.mkNot(ctx.mkEq( n_0, n_1))),1,null,null,null,null));
+
+               // Constraint3          send(n_0, n_1, p_0, t_0) -> p_0.src != p_0.dest
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+                           ctx.mkImplies((BoolExpr)send.apply(n_0, n_1, p_0, t_0),
+                                       ctx.mkNot(ctx.mkEq(  pf.get("src").apply(p_0), pf.get("dest").apply(p_0)))),1,null,null,null,null));
+
+               // Constraint4          recv(n_0, n_1, p_0, t_0) -> p_0.src != p_0.dest
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+                           ctx.mkImplies((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),
+                                       ctx.mkNot(ctx.mkEq(pf.get("src").apply(p_0),pf.get("dest").apply(p_0)))),1,null,null,null,null));
+
+               // Constraint5          recv(n_0, n_1, p, t_0) -> send(n_0, n_1, p, t_1) && t_1 < t_0
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+                           ctx.mkImplies((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),
+                                       ctx.mkExists(new Expr[]{t_1},
+                                          ctx.mkAnd((BoolExpr)send.apply(n_0, n_1, p_0, t_1),
+                                               ctx.mkLt(t_1, t_0)),1,null,null,null,null)),1,null,null,null,null));
+
+               // Constraint6          send(n_0, n_1, p, t_0) -> p.src_port > 0 && p.dest_port < MAX_PORT
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+                           ctx.mkImplies((BoolExpr)send.apply(n_0, n_1, p_0, t_0),
+                                       ctx.mkAnd(      ctx.mkGe((IntExpr)src_port.apply(p_0),(IntExpr)ctx.mkInt(0)),
+                                                               ctx.mkLt((IntExpr)src_port.apply(p_0),(IntExpr) ctx.mkInt(MAX_PORT)))),1,null,null,null,null));
+
+               // Constraint7          recv(n_0, n_1, p, t_0) -> p.src_port > 0 && p.dest_port < MAX_PORT
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+                           ctx.mkImplies((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),
+                               ctx.mkAnd(      ctx.mkGe((IntExpr)dest_port.apply(p_0),(IntExpr)ctx.mkInt(0)),
+                                                       ctx.mkLt((IntExpr)dest_port.apply(p_0),(IntExpr) ctx.mkInt(MAX_PORT)))),1,null,null,null,null));
+
+               // Constraint8          recv(n_0, n_1, p_0, t_0) -> t_0 > 0
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+                           ctx.mkImplies((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),
+                                         ctx.mkGt(t_0,ctx.mkInt(0))),1,null,null,null,null));
+
+               // Constraint9          send(n_0, n_1, p_0, t_0) -> t_0 > 0
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+                           ctx.mkImplies((BoolExpr)send.apply(n_0, n_1, p_0, t_0),
+                                       ctx.mkGt(t_0,ctx.mkInt(0))),1,null,null,null,null));
+
+               // Extra constriants for supporting the VPN gateway
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+                           ctx.mkImplies(
+                               ctx.mkAnd((BoolExpr)send.apply(n_0, n_1, p_0, t_0),
+                                                 ctx.mkNot(ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.am.get("null")))),
+                               ctx.mkNot(ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0)))),1,null,null,null,null));
+
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+                           ctx.mkImplies(
+                               ctx.mkAnd((BoolExpr)send.apply(n_0, n_1, p_0, t_0),
+                                                 ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.am.get("null"))),
+                                                 ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0))),1,null,null,null,null));
+
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+                           ctx.mkImplies(
+                               ctx.mkAnd((BoolExpr)send.apply(n_0, n_1, p_0, t_0),
+                                                 ctx.mkEq(this.pf.get("inner_dest").apply(p_0), this.am.get("null"))),
+                                                 ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0))),1,null,null,null,null));
+
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+                           ctx.mkImplies(
+                               ctx.mkAnd((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),
+                                                 ctx.mkNot(ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.am.get("null")))),
+                                                 ctx.mkNot(ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0)))),1,null,null,null,null));
+
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+                           ctx.mkImplies(
+                               ctx.mkAnd((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),
+                                                 ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.am.get("null"))),
+                                                 ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0))),1,null,null,null,null));
+
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+                           ctx.mkImplies(
+                               ctx.mkAnd((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),
+                                                 ctx.mkEq(this.pf.get("inner_dest").apply(p_0), this.am.get("null"))),
+                                                 ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0))),1,null,null,null,null));
+
+               constraints.add(
+                               ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0, n_2, p_1, t_1},
+                                       ctx.mkImplies(
+                                               ctx.mkAnd(
+                                                       ctx.mkLt(t_1, t_0),
+                                                       (BoolExpr)send.apply(n_0, n_1, p_0, t_0),
+                                                       (BoolExpr)this.pf.get("encrypted").apply(p_1),
+                                                       (BoolExpr)recv.apply(n_2, n_0, p_1, t_1),
+                                                       (BoolExpr)this.pf.get("encrypted").apply(p_0)),
+                                               ctx.mkAnd(
+                                                       ctx.mkEq(this.pf.get("inner_src").apply(p_1), this.pf.get("inner_src").apply(p_0)),
+                                                       ctx.mkEq(this.pf.get("inner_dest").apply(p_1), this.pf.get("inner_dest").apply(p_0)),
+                                                       ctx.mkEq(this.pf.get("origin").apply(p_1), this.pf.get("origin").apply(p_0)),
+                                                           ctx.mkEq(this.pf.get("orig_body").apply(p_1), this.pf.get("orig_body").apply(p_0)),
+                                                           ctx.mkEq(this.pf.get("body").apply(p_1), this.pf.get("body").apply(p_0)),
+                                                           ctx.mkEq(this.pf.get("seq").apply(p_1), this.pf.get("seq").apply(p_0)),
+                                                           ctx.mkEq(this.pf.get("proto").apply(p_1), this.pf.get("proto").apply(p_0)),
+                                                           ctx.mkEq(this.pf.get("emailFrom").apply(p_1), this.pf.get("emailFrom").apply(p_0)),
+                                                           ctx.mkEq(this.pf.get("url").apply(p_1), this.pf.get("url").apply(p_0)),
+                                                           ctx.mkEq(this.pf.get("options").apply(p_1), this.pf.get("options").apply(p_0)))),1,null,null,null,null)
+                               );
+           }
+
+           /**
+            * Two packets have equal headers
+            * @param p1
+            * @param p2
+            * @return
+            */
+           public BoolExpr PacketsHeadersEqual(Expr p1, Expr p2){
+               return ctx.mkAnd(new BoolExpr[]{
+                               ctx.mkEq(pf.get("src").apply(p1),               pf.get("src").apply(p2)),
+                               ctx.mkEq(pf.get("dest").apply(p1),              pf.get("dest").apply(p2)),
+                                       ctx.mkEq(pf.get("origin").apply(p1),    pf.get("origin").apply(p2)),
+                                       ctx.mkEq(pf.get("seq").apply(p1),               pf.get("seq").apply(p2)),
+                                       ctx.mkEq(src_port.apply(p1),                    src_port.apply(p2)),
+                                       ctx.mkEq(dest_port.apply(p1),                   dest_port.apply(p2)),
+                                       ctx.mkEq(pf.get("options").apply(p1),   pf.get("options").apply(p2))});
+               }
+
+           /**
+            * Two packets have equal bodies
+            * @param p1
+            * @param p2
+            * @return
+            */
+           public BoolExpr PacketContentEqual(Expr p1, Expr p2){
+               return ctx.mkEq(pf.get("body").apply(p1),               pf.get("body").apply(p2));
+               }
+
+
+         /* seems to be useless
+          *
+       public Function failurePredicate (NetContext context)
+       {
+           return (NetworkObject node) -> ctx.mkNot(context.failed (node.z3Node));
+
+       }*/
+
+       public BoolExpr destAddrPredicate (Expr p, DatatypeExpr address){
+               return  ctx.mkEq(pf.get("dest").apply(p),address);
+       }
+
+       public  BoolExpr srcAddrPredicate (Expr p, DatatypeExpr address){
+               return  ctx.mkEq(pf.get("src").apply(p),address);
+       }
+
+}
\ No newline at end of file
diff --git a/verigraph/service/src/mcnet/components/Network.java b/verigraph/service/src/mcnet/components/Network.java
new file mode 100644 (file)
index 0000000..c04f771
--- /dev/null
@@ -0,0 +1,296 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+import com.microsoft.z3.Z3Exception;
+
+/**Model for a network, encompasses routing and wiring
+ * 
+ */
+public class Network extends Core{
+
+       Context ctx;
+       NetContext nctx;
+       List<BoolExpr> constraints; 
+       List<NetworkObject> elements;
+
+
+
+       public Network(Context ctx,Object[]... args) {
+               super(ctx, args);
+       }
+
+       @Override
+       protected void init(Context ctx, Object[]... args) {
+               this.ctx = ctx;
+               this.nctx = (NetContext) args[0][0];
+        constraints = new ArrayList<BoolExpr>();
+        elements = new ArrayList<NetworkObject>();
+
+       }
+
+       /**Composes the network linking the configured network objects
+        *
+        * @param elements
+        */
+       public void attach (NetworkObject ... elements){
+             for(NetworkObject el : elements)
+                 this.elements.add(el);
+       }
+
+       @Override
+       protected void addConstraints(Solver solver) {
+               try {
+                       BoolExpr[] constr = new BoolExpr[constraints.size()];
+                   solver.add(constraints.toArray(constr));
+               } catch (Z3Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       /**
+        * Specify host to address mapping.
+        * Handles the case in which we have more than one address for a node
+        * @param addrmap
+        */
+        public void setAddressMappings(ArrayList<Tuple<NetworkObject,ArrayList<DatatypeExpr>>> addrmap){
+                // Set address mapping for nodes.
+                for (Tuple<NetworkObject,ArrayList<DatatypeExpr>> entry : addrmap) {
+                   NetworkObject node=entry._1;
+                   List<DatatypeExpr> addr=entry._2;
+                   Expr a_0 = ctx.mkConst(node+"_address_mapping_a_0",nctx.address);
+                           ArrayList<BoolExpr> or_clause = new ArrayList<BoolExpr>();
+
+                          // Constraint 1                      addrToNode(foreach ad in addr) = node
+                   for (DatatypeExpr ad : addr){
+                     constraints.add(ctx.mkEq(nctx.addrToNode.apply(ad), node.getZ3Node()));
+                     or_clause.add(ctx.mkEq(a_0,ad));
+                       }
+                   BoolExpr[] orClause = new BoolExpr[or_clause.size()];
+
+                   // Constraint 2                     nodeHasAddr(node, a_0) == Or(foreach ad in addr (a_0 == ad))
+                       // Note we need the iff here to make sure that we set nodeHasAddr to false
+                       // for other addresses.
+                   constraints.add(ctx.mkForall(new Expr[]{a_0},
+                         ctx.mkEq(ctx.mkOr(or_clause.toArray(orClause)), nctx.nodeHasAddr.apply(node.getZ3Node(), a_0)),1,null,null,null,null));
+                       }
+        }
+
+
+
+       /**
+        * Don't forward packets addressed to node
+        * @param node
+        */
+        public void saneSend(NetworkObject node){
+            Expr n_0 = ctx.mkConst(node+"_saneSend_n_0", nctx.node);
+            Expr p_0 = ctx.mkConst(node+"_saneSend_p_0", nctx.packet);
+            IntExpr t_0 = ctx.mkIntConst(node+"_saneSend_t_0");
+               // Constant: node
+               //Constraint     send(node, n_0, p, t_0) -> !nodeHasAddr(node, p.dest)
+               constraints.add(
+                       ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                           ctx.mkImplies((BoolExpr)nctx.send.apply(node.getZ3Node(),n_0, p_0, t_0),
+                                       ctx.mkNot((BoolExpr)nctx.nodeHasAddr.apply( node.getZ3Node(),
+                                                       nctx.pf.get("dest").apply(p_0)))),1,null,null,null,null));
+           }
+
+        /**
+         * Node sends all traffic through gateway
+         * @param node
+         * @param gateway
+         */
+         public void setGateway (NetworkObject node, NetworkObject gateway){
+               // SetGateway(self, node, gateway): All packets from node are sent through gateway
+               Expr n_0 = ctx.mkConst(node+"_gateway_n_0", nctx.node);
+               Expr p_0 = ctx.mkConst(node+"_gateway_p_0", nctx.packet);
+               IntExpr t_0 = ctx.mkIntConst(node+"_gateway_t_0");
+
+               //Constraint     send(node, n_0, p_0, t_0) -> n_0 = gateway
+               constraints.add(
+                                ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                                                ctx.mkImplies(
+                                                                (BoolExpr)nctx.send.apply(node.getZ3Node(), n_0, p_0, t_0),
+                                                  ctx.mkEq(n_0,gateway.getZ3Node())),1,null,null,null,null));
+
+//             constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+//                 ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0, node.getZ3Node(),  p_0, t_0),
+//                                                 ctx.mkEq(n_0,gateway.getZ3Node())),1,null,null,null,null));
+         }
+
+         /**
+          * Assigns a specific routing table to a network object. Routing entries in the form: address -> node
+          * @param node
+          * @param routing_table
+          */
+       public void routingTable (NetworkObject node,ArrayList<Tuple<DatatypeExpr,NetworkObject>> routing_table){
+              compositionPolicy(node,routing_table);
+          }
+
+       /**
+        * Composition policies steer packets between middleboxes.
+        * @param node
+        * @param policy
+        */
+       public void compositionPolicy (NetworkObject node,ArrayList<Tuple<DatatypeExpr,NetworkObject>> policy){
+               //Policy is of the form predicate -> node
+               Expr p_0 = ctx.mkConst(node+"_composition_p_0", nctx.packet);
+               Expr n_0 = ctx.mkConst(node+"_composition_n_0", nctx.node);
+               Expr t_0 = ctx.mkIntConst(node+"_composition_t_0");
+
+               HashMap<String,ArrayList<BoolExpr>> collected = new HashMap<String,ArrayList<BoolExpr>>();
+               HashMap<String,NetworkObject> node_dict = new HashMap<String,NetworkObject>();
+            BoolExpr predicates;
+            for(int y=0;y<policy.size();y++){
+               Tuple<DatatypeExpr,NetworkObject> tp = policy.get(y);
+               if(collected.containsKey(""+tp._2))      collected.get(""+tp._2).add(nctx.destAddrPredicate(p_0,tp._1));
+               else{
+                       ArrayList<BoolExpr> alb = new ArrayList<BoolExpr>();
+                       alb.add(nctx.destAddrPredicate(p_0,tp._1));
+                       collected.put(""+tp._2,alb);
+               }
+               node_dict.put(""+tp._2, tp._2);
+            }
+
+           //Constraint                foreach rtAddr,rtNode in rt( send(node, n_0, p_0, t_0) &&
+           //                                  Or(foreach rtAddr in rt destAddrPredicate(p_0,rtAddr)) -> n_0 == rtNode )
+               for (Map.Entry<String,ArrayList<BoolExpr>> entry : collected.entrySet()) {
+                       BoolExpr[] pred = new BoolExpr[entry.getValue().size()];
+                   predicates = ctx.mkOr(entry.getValue().toArray(pred));
+
+                   constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(node.getZ3Node(), n_0, p_0, t_0), predicates),
+                                ctx.mkEq(n_0, node_dict.get(entry.getKey()).getZ3Node())),1,null,null,null,null));
+               }
+        }
+
+           /**
+            * Routing entries are in the form: address -> node. Also allows packet to be sent to another box for further processing
+            * @param node
+            * @param routing_table
+            * @param shunt_node
+            */
+          public void routingTableShunt (NetworkObject node,ArrayList<Tuple<DatatypeExpr,NetworkObject>> routing_table,NetworkObject shunt_node){
+                  compositionPolicyShunt(node,routing_table,shunt_node);
+                   }
+
+           /**
+            * Composition policies steer packets between middleboxes.Policy is in the form: predicate -> node
+            * @param node
+            * @param routing_table
+            * @param shunt_node
+            */
+          public void compositionPolicyShunt (NetworkObject node,ArrayList<Tuple<DatatypeExpr,NetworkObject>> routing_table,NetworkObject shunt_node){
+                   Expr p_0 = ctx.mkConst(node+"_composition_p_0", nctx.packet);
+               Expr n_0 = ctx.mkConst(node+"_composition_n_0", nctx.node);
+               Expr t_0 = ctx.mkIntConst(node+"_composition_t_0");
+
+               HashMap<String,ArrayList<BoolExpr>> collected = new HashMap<String,ArrayList<BoolExpr>>();
+               HashMap<String,NetworkObject> node_dict = new HashMap<String,NetworkObject>();
+               BoolExpr predicates;
+            for(int y=0;y<routing_table.size();y++){
+               Tuple<DatatypeExpr,NetworkObject> tp = routing_table.get(y);
+               if(collected.containsKey(""+tp._2))      collected.get(""+tp._2).add(nctx.destAddrPredicate(p_0,tp._1));
+               else{
+                       ArrayList<BoolExpr> alb = new ArrayList<BoolExpr>();
+                       alb.add(nctx.destAddrPredicate(p_0,tp._1));
+                       collected.put(""+tp._2,alb);
+               }
+               node_dict.put(""+tp._2, tp._2);
+            }
+
+            //Constraint               foreach rtAddr,rtNode in rt( send(node, n_0, p_0, t_0) &&
+            //                                 Or(foreach rtAddr in rt destAddrPredicate(p_0,rtAddr)) -> n_0 == rtNode )
+               for (Map.Entry<String,ArrayList<BoolExpr>> entry : collected.entrySet()) {
+                   BoolExpr[] pred = new BoolExpr[entry.getValue().size()];
+                   predicates = ctx.mkOr(entry.getValue().toArray(pred));
+
+                   constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(node.getZ3Node(), n_0, p_0, t_0), predicates),
+                               ctx.mkOr(ctx.mkEq(n_0, node_dict.get(entry.getKey()).getZ3Node()),ctx.mkEq(n_0, shunt_node.getZ3Node()))),1,null,null,null,null));
+               }
+
+           }
+
+//         public void SimpleIsolation (NetworkObject node, ArrayList<DatatypeExpr> addresses){
+//            Expr p = ctx.mkConst(node+"_s_p", nctx.packet);
+//            Expr n = ctx.mkConst(node+"_s_n", nctx.node);
+//            IntExpr t = ctx.mkInt(node+"_s_t");
+//
+//            BoolExpr[] a_pred= new BoolExpr[addresses.size()];
+//             for(int y=0;y<addresses.size();y++){
+//                     DatatypeExpr de = addresses.get(y);
+//                     a_pred[y] = ctx.mkOr(ctx.mkEq(nctx.pf.get("src").apply(p), de),ctx.mkEq(nctx.pf.get("dest").apply(p), de));
+//             }
+//
+//             constraints.add(
+//                     ctx.mkForall(new Expr[]{p, n, t},
+//                       ctx.mkImplies((BoolExpr)nctx.recv.apply(n, node.getZ3Node(), p, t),
+//                                 ctx.mkOr(a_pred)),1,null,null,null,null));
+//             constraints.add(
+//                     ctx.mkForall(new Expr[]{p, n, t},
+//                       ctx.mkImplies((BoolExpr)nctx.send.apply(node.getZ3Node(), n, p, t),
+//                                 ctx.mkOr(a_pred)),1,null,null,null,null));
+//         }
+
+
+          /**
+           * Set isolation constraints on a node.
+           * Doesn't need to be set but useful when interfering policies are in play.
+           * @param node
+           * @param adjacencies
+           *
+           */
+          public void SetIsolationConstraint ( NetworkObject node,  ArrayList<NetworkObject> adjacencies){
+
+                       Expr n_0 = ctx.mkConst(node+"_isolation_n_0", nctx.node);
+               Expr p_0 = ctx.mkConst(node+"_isolation_p_0", nctx.packet);
+               IntExpr t_0 = ctx.mkInt(node+"_isolation_t_0");
+
+               BoolExpr[] adj = new BoolExpr[adjacencies.size()];
+               for(int y=0;y<adjacencies.size();y++){
+                       NetworkObject no = adjacencies.get(y);
+                       adj[y] =  ctx.mkEq(n_0,no.getZ3Node());
+               }
+               BoolExpr clause = ctx.mkOr(adj);
+
+               constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                   ctx.mkImplies((BoolExpr)nctx.send.apply(node.getZ3Node(), n_0, p_0, t_0),
+                                           clause),1,null,null,null,null));
+               constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                   ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0, node.getZ3Node(), p_0, t_0),
+                                           clause),1,null,null,null,null));
+              }
+
+         /**
+          * Return all currently attached endhosts
+          * @return NetworkObject
+          */
+          public List<String> EndHosts(){
+                  List<String> att_nos = new ArrayList<String>();
+                  for(NetworkObject el :elements){
+                          if(el.isEndHost){
+                                  System.out.println("el: "+el);
+                                       att_nos.add(el.getZ3Node().toString());
+                               }
+                       }
+               return att_nos;
+          }
+}
diff --git a/verigraph/service/src/mcnet/components/NetworkObject.java b/verigraph/service/src/mcnet/components/NetworkObject.java
new file mode 100644 (file)
index 0000000..0de3937
--- /dev/null
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+
+/** Represents a generic network object.
+ *
+ */
+public abstract class NetworkObject extends Core{
+
+       public NetworkObject(Context ctx,Object[]... args) {
+               super(ctx,args);
+       }
+
+       protected DatatypeExpr z3Node;
+       protected boolean isEndHost;
+       /**
+        * Get a reference to the z3 node this class wraps around
+        * @return
+        */
+       abstract public DatatypeExpr getZ3Node();
+
+       public String toString(){
+               return z3Node.toString();
+       }
+
+       //There is probably an error: z3Node.hashCode = 0 because AST.hashCode() has always hash=0
+       /*public int hashCode(){
+               return z3Node.hashCode();
+       }*/
+
+       /**
+        * A simple way to determine the set of endhosts
+        * @return
+        */
+       public boolean isEndHost(){
+           return isEndHost;
+       }
+
+       /**
+        * Wrap methods to set policy
+        * @param policy
+        * @throws UnsupportedOperationException
+        */
+       void setPolicy (Object policy) throws UnsupportedOperationException{
+            throw new UnsupportedOperationException();
+       }
+}
diff --git a/verigraph/service/src/mcnet/components/Result.java b/verigraph/service/src/mcnet/components/Result.java
new file mode 100644 (file)
index 0000000..acb23f1
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.Model;
+
+/**Data structure for the core of the response to a check request for data isolation property
+ *
+ */
+public class Result {
+       Context ctx;
+       public Model model;
+       public BoolExpr[] unsat_core;
+
+/**
+ *
+ * @param ctx
+ * @param model
+ */
+    public Result(Context ctx, Model model){
+            this.ctx = ctx;
+            this.model = model;
+       }
+
+/**
+ *
+ * @param ctx
+ * @param unsat_core
+ */
+    public Result(Context ctx, BoolExpr[] unsat_core){
+        this.ctx = ctx;
+        this.unsat_core = unsat_core;
+}
+}
diff --git a/verigraph/service/src/mcnet/components/Tuple.java b/verigraph/service/src/mcnet/components/Tuple.java
new file mode 100644 (file)
index 0000000..849d607
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+
+/** A data structure which is an utility to make a generic couple of objects with different types in Java
+ *
+ */
+public class Tuple<T, U> {
+         public final T _1;
+         public final U _2;
+
+
+         public Tuple(T arg1,U arg2) {
+           super();
+           this._1 = arg1;
+           this._2 = arg2;
+         }
+
+         public Tuple(){
+                 this._1 = null;
+                   this._2 = null;
+         }
+
+         @Override
+         public String toString() {
+           return String.format("(%s, %s)", _1, _2);
+         }
+       }
\ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/AclFirewall.java b/verigraph/service/src/mcnet/netobjs/AclFirewall.java
new file mode 100644 (file)
index 0000000..4ae3421
--- /dev/null
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+import com.microsoft.z3.Sort;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+import mcnet.components.Tuple;
+
+/** Represents a Firewall with the associated Access Control List
+ *
+ */
+public class AclFirewall extends NetworkObject{
+
+       List<BoolExpr> constraints;
+       Context ctx;
+       DatatypeExpr fw;
+       ArrayList<Tuple<DatatypeExpr,DatatypeExpr>> acls;
+       Network net;
+       NetContext nctx;
+       FuncDecl acl_func;
+
+       public AclFirewall(Context ctx, Object[]... args) {
+               super(ctx, args);
+       }
+
+       @Override
+       protected void init(Context ctx, Object[]... args) {
+               this.ctx = ctx;
+               isEndHost=false;
+               constraints = new ArrayList<BoolExpr>();
+               acls = new ArrayList<Tuple<DatatypeExpr,DatatypeExpr>>();
+               z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+        fw = z3Node;
+           net = (Network)args[0][1];
+           nctx = (NetContext)args[0][2];
+           net.saneSend(this);
+               firewallSendRules();
+       }
+
+       /**
+        * Wrap add acls
+        * @param policy
+        */
+       public void setPolicy(ArrayList<Tuple<DatatypeExpr, DatatypeExpr>> policy){
+               addAcls(policy);
+       }
+
+       public void addAcls(ArrayList<Tuple<DatatypeExpr,DatatypeExpr>> acls){
+               this.acls.addAll(acls);
+       }
+
+       @Override
+       public DatatypeExpr getZ3Node() {
+               return fw;
+       }
+
+
+       @Override
+       protected void addConstraints(Solver solver) {
+                       BoolExpr[] constr = new BoolExpr[constraints.size()];
+                   solver.add(constraints.toArray(constr));
+                   aclConstraints(solver);
+       }
+
+    private void firewallSendRules (){
+       Expr p_0 = ctx.mkConst(fw+"_firewall_send_p_0", nctx.packet);
+       Expr n_0 = ctx.mkConst(fw+"_firewall_send_n_0", nctx.node);
+       Expr n_1 = ctx.mkConst(fw+"_firewall_send_n_1", nctx.node);
+       IntExpr t_0 = ctx.mkIntConst(fw+"_firewall_send_t_0");
+       IntExpr t_1 = ctx.mkIntConst(fw+"_firewall_send_t_1");
+       acl_func = ctx.mkFuncDecl(fw+"_acl_func", new Sort[]{nctx.address, nctx.address},ctx.mkBoolSort());
+
+       //Constraint1           send(fw, n_0, p, t_0)  -> (exist n_1,t_1 : (recv(n_1, fw, p, t_1) &&
+       //                              t_1 < t_0 && !acl_func(p.src,p.dest))
+       constraints.add(
+               ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                   ctx.mkImplies(
+                       (BoolExpr)nctx.send.apply(new Expr[]{ fw, n_0, p_0, t_0}),
+                       ctx.mkExists(new Expr[]{t_1},
+                                       ctx.mkAnd(ctx.mkLt(t_1,t_0),
+                                                               ctx.mkExists(new Expr[]{n_1},
+                                                                               nctx.recv.apply(n_1, fw, p_0, t_1),1,null,null,null,null),
+                                                               ctx.mkNot((BoolExpr)acl_func.apply(nctx.pf.get("src").apply(p_0), nctx.pf.get("dest").apply(p_0)))),1,null,null,null,null)),1,null,null,null,null));
+
+    }
+
+    private void aclConstraints(Solver solver){
+       if (acls.size() == 0)
+            return;
+        Expr a_0 = ctx.mkConst(fw+"_firewall_acl_a_0", nctx.address);
+        Expr a_1 = ctx.mkConst(fw+"_firewall_acl_a_1", nctx.address);
+        BoolExpr[] acl_map = new BoolExpr[acls.size()];
+        for(int y=0;y<acls.size();y++){
+               Tuple<DatatypeExpr,DatatypeExpr> tp = acls.get(y);
+               acl_map[y] = ctx.mkOr(ctx.mkAnd(ctx.mkEq(a_0,tp._1),ctx.mkEq(a_1,tp._2)), ctx.mkAnd(ctx.mkEq(a_0,tp._2),ctx.mkEq(a_1,tp._1)));
+        }
+        //Constraint2          acl_func(a_0,a_1) == or(foreach ip1,ip2 in acl_map ((a_0 == ip1 && a_1 == ip2)||(a_0 == ip2 && a_1 == ip1)))
+        solver.add(ctx.mkForall(new Expr[]{a_0, a_1},
+                                                       ctx.mkEq(
+                                                                       acl_func.apply(a_0, a_1),
+                                                                       ctx.mkOr(acl_map)),1,null,null,null,null));
+    }
+}
\ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/DumbNode.java b/verigraph/service/src/mcnet/netobjs/DumbNode.java
new file mode 100644 (file)
index 0000000..012ff40
--- /dev/null
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetworkObject;
+
+/**
+ * This is just a wrapper around z3 instances. The idea is that by using this we perhaps need to have
+ * fewer (or no) ifs to deal with the case where we don't instantiate an object for a node
+ *
+ */
+public class DumbNode extends NetworkObject {
+       public DumbNode(Context ctx, Object[]... args){
+               super(ctx,args);
+       }
+
+       @Override
+       protected void addConstraints(Solver solver) {
+               return;
+       }
+
+       @Override
+       protected void init(Context ctx, Object[]... args) {
+               isEndHost=true;
+               this.z3Node = (DatatypeExpr)args[0][0];
+       }
+       @Override
+       public DatatypeExpr getZ3Node() {
+               return z3Node;
+       }
+}
diff --git a/verigraph/service/src/mcnet/netobjs/EndHost.java b/verigraph/service/src/mcnet/netobjs/EndHost.java
new file mode 100644 (file)
index 0000000..99cf732
--- /dev/null
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+/**
+ * End host network objects
+ *
+ */
+public class EndHost extends NetworkObject{
+
+       List<BoolExpr> constraints;
+       Context ctx;
+       DatatypeExpr node;
+       Network net;
+       NetContext nctx;
+
+       public EndHost(Context ctx, Object[]... args) {
+               super(ctx, args);
+       }
+
+       @Override
+       protected void init(Context ctx, Object[]... args) {
+               this.ctx = ctx;
+               isEndHost=true;
+               constraints = new ArrayList<BoolExpr>();
+        z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+        node = z3Node;
+        net = (Network)args[0][1];
+        nctx = (NetContext)args[0][2];
+               endHostRules();
+       }
+
+       @Override
+       public DatatypeExpr getZ3Node() {
+               return node;
+       }
+
+       @Override
+       protected void addConstraints(Solver solver) {
+                       BoolExpr[] constr = new BoolExpr[constraints.size()];
+                   solver.add(constraints.toArray(constr));
+       }
+
+    public void endHostRules (){
+       Expr n_0 = ctx.mkConst("eh_"+node+"_n_0", nctx.node);
+        IntExpr t_0 = ctx.mkIntConst("eh_"+node+"_t_0");
+        Expr p_0 = ctx.mkConst("eh_"+node+"_p_0", nctx.packet);
+
+        //Constraint1          send(node, n_0, p, t_0) -> nodeHasAddr(node,p.src)
+        constraints.add(
+               ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                   ctx.mkImplies(
+                       (BoolExpr)nctx.send.apply(      new Expr[]{ node, n_0, p_0, t_0}),
+                       (BoolExpr)nctx.nodeHasAddr.apply(new Expr[]{node, nctx.pf.get("src").apply(p_0)})),1,null,null,null,null));
+        //Constraint2          send(node, n_0, p, t_0) -> p.origin == node
+        constraints.add(
+               ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                ctx.mkImplies(
+                               (BoolExpr)nctx.send.apply(      new Expr[]{ node, n_0, p_0, t_0}),
+                               ctx.mkEq(nctx.pf.get("origin").apply(p_0),node)),1,null,null,null,null));
+        //Constraint3      send(node, n_0, p, t_0) -> p.orig_body == p.body
+        constraints.add(
+               ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                ctx.mkImplies(
+                               (BoolExpr)nctx.send.apply(new Expr[]{ node, n_0, p_0, t_0}),
+                               ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),1,null,null,null,null));
+        //Constraint4          recv(n_0, node, p, t_0) -> nodeHasAddr(node,p.dest)
+        constraints.add(
+               ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                ctx.mkImplies(
+                               (BoolExpr)nctx.recv.apply(      new Expr[]{ n_0, node, p_0, t_0}),
+                       (BoolExpr)nctx.nodeHasAddr.apply(new Expr[]{node, nctx.pf.get("dest").apply(p_0)})),1,null,null,null,null));
+
+//       Just a try: here we state that an endhost is not able to issue a HTTP response traffic
+//       See PolitoCache.py model for constants definition (2 means HTTP_RESPONSE, 1 means HTTP_REQUEST)
+//         constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+//                 ctx.mkImplies((BoolExpr)nctx.send.apply(node, n_0, p_0, t_0),
+//                            ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(1))),1,null,null,null,null));
+    }
+}
\ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PacketModel.java b/verigraph/service/src/mcnet/netobjs/PacketModel.java
new file mode 100644 (file)
index 0000000..5761861
--- /dev/null
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import com.microsoft.z3.DatatypeExpr;
+
+/*
+ * Fields that can be configured -> "dest","body","seq","proto","emailFrom","url","options"
+ */
+public class PacketModel {
+
+       private DatatypeExpr ip_dest;
+       private Integer body;
+       private Integer seq;
+       private Integer proto;
+       private Integer emailFrom;
+       private Integer url;
+       private Integer options;
+
+       public DatatypeExpr getIp_dest() {
+               return ip_dest;
+       }
+       public void setIp_dest(DatatypeExpr ip_dest) {
+               this.ip_dest = ip_dest;
+       }
+       public Integer getBody() {
+               return body;
+       }
+       public void setBody(Integer body) {
+               this.body = body;
+       }
+       public Integer getSeq() {
+               return seq;
+       }
+       public void setSeq(Integer seq) {
+               this.seq = seq;
+       }
+       public Integer getProto() {
+               return proto;
+       }
+       public void setProto(Integer proto) {
+               this.proto = proto;
+       }
+       public Integer getEmailFrom() {
+               return emailFrom;
+       }
+       public void setEmailFrom(Integer emailFrom) {
+               this.emailFrom = emailFrom;
+       }
+       public Integer getUrl() {
+               return url;
+       }
+       public void setUrl(Integer url) {
+               this.url = url;
+       }
+       public Integer getOptions() {
+               return options;
+       }
+       public void setOptions(Integer options) {
+               this.options = options;
+       }
+
+}
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoAntispam.java b/verigraph/service/src/mcnet/netobjs/PolitoAntispam.java
new file mode 100644 (file)
index 0000000..abb4615
--- /dev/null
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+/**
+ * Model of an anti-spam node
+ *
+ */
+public class PolitoAntispam extends NetworkObject{
+
+               List<BoolExpr> constraints;
+               Context ctx;
+               DatatypeExpr politoAntispam;
+               Network net;
+               NetContext nctx;
+               FuncDecl isInBlacklist;
+
+               public PolitoAntispam(Context ctx, Object[]... args) {
+                       super(ctx, args);
+               }
+
+               @Override
+               protected void init(Context ctx, Object[]... args) {
+                       this.ctx = ctx;
+                       isEndHost=false;
+                       constraints = new ArrayList<BoolExpr>();
+               z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+               politoAntispam = z3Node;
+               net = (Network)args[0][1];
+               nctx = (NetContext)args[0][2];
+               //net.saneSend(this);
+           }
+
+               @Override
+               public DatatypeExpr getZ3Node() {
+                       return politoAntispam;
+               }
+
+               @Override
+               protected void addConstraints(Solver solver) {
+                               BoolExpr[] constr = new BoolExpr[constraints.size()];
+                           solver.add(constraints.toArray(constr));
+               }
+
+           public void installAntispam (int[] blackList){
+               Expr n_0 = ctx.mkConst(politoAntispam+"_n_0", nctx.node);
+               Expr n_1 = ctx.mkConst(politoAntispam+"_n_1", nctx.node);
+               Expr p_0 = ctx.mkConst(politoAntispam+"_p_0", nctx.packet);
+               IntExpr t_0 = ctx.mkIntConst(politoAntispam+"_t_0");
+               IntExpr t_1 = ctx.mkIntConst(politoAntispam+"_t_1");
+               IntExpr ef_0 = ctx.mkIntConst(politoAntispam+"_ef_0");
+
+            isInBlacklist = ctx.mkFuncDecl(politoAntispam+"_isInBlacklist", ctx.mkIntSort(), ctx.mkBoolSort());
+            BoolExpr[] blConstraint = new BoolExpr[blackList.length];
+            if(blackList.length != 0){
+                for (int i=0;i<blackList.length;i++)
+                    blConstraint[i]=(ctx.mkEq(ef_0,ctx.mkInt(blackList[i])));
+                //Constraint1a         if(isInBlackList(ef_0) == or(for bl in blacklist (ef_0==bl)) ? true : false
+                constraints.add(ctx.mkForall(new Expr[]{ef_0}, ctx.mkIff((BoolExpr)isInBlacklist.apply(ef_0),ctx.mkOr(blConstraint)),1,null,null,null,null));
+            }else{
+                //Constraint1b         isInblackList(ef_0) == false
+                constraints.add(ctx.mkForall(new Expr[]{ef_0}, ctx.mkEq((BoolExpr)isInBlacklist.apply(ef_0), ctx.mkBool(false)),1,null,null,null,null));
+            }
+
+            //Constraint2              send(politoAntispam, n_0, p, t_0) && p.proto(POP3_RESP) ->
+            //                                         (exist  n_1,t_1 : (recv(n_1, politoAntispam, p, t_1) && t_1 < t_0)) && !isInBlackList(p.emailFrom)
+            constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                                ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(politoAntispam, n_0, p_0, t_0), ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_RESPONSE))),
+                                    ctx.mkAnd( ctx.mkExists(new Expr[]{n_1, t_1},
+                                               ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1, politoAntispam, p_0, t_1), ctx.mkLt(t_1 , t_0)),1,null,null,null,null),
+                                                       ctx.mkNot((BoolExpr)isInBlacklist.apply(nctx.pf.get("emailFrom").apply(p_0))))),1,null,null,null,null));
+
+               //Constraint3           send(politoAntispam, n_0, p, t_0) && p.proto(POP3_REQ) ->
+            //                                         (exist n_1,t_1 : (recv(n_1, politoAntispam, p, t_1) && t_1 < t_0))
+            constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(politoAntispam, n_0, p_0, t_0), ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_REQUEST))),
+                        ctx.mkAnd(ctx.mkExists(new Expr[]{n_1, t_1},
+                                    ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1, politoAntispam, p_0, t_1),
+                                                       ctx.mkLt(t_1 , t_0)),1,null,null,null,null))),1,null,null,null,null));
+
+            //Constraint4              send(politoAntispam, politoErrFunction, p, t_0) ->
+            //                                 (exist n_1,t_1 : (recv(n_1, politoAntispam, p, t_1) && t_1 < t_0 && p.emailFrom ==1))
+            constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoAntispam, nctx.nm.get("politoErrFunction").getZ3Node(), p_0, t_0),
+                        ctx.mkAnd(ctx.mkExists(new Expr[]{n_1, t_1},
+                                    ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1, politoAntispam, p_0, t_1),
+                                                       ctx.mkLt(t_1 , t_0),
+                                                       ctx.mkEq(nctx.pf.get("emailFrom").apply(p_0),ctx.mkInt(1))),1,null,null,null,null))),1,null,null,null,null));
+
+               //Constraint5           send(politoAntispam, n_0, p, t_0) -> p.proto == POP_REQ || p.protpo == POP_RESP
+            constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoAntispam, n_0, p_0, t_0),
+                        ctx.mkOr(      ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_REQUEST)),
+                                               ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_RESPONSE)))),1,null,null,null,null));
+
+            //Constraint6              send(politoAntispam, n_0, p, t_0) -> nodeHasAddr(politoAntispam,p.src)
+            constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoAntispam, n_0, p_0, t_0),
+                        ctx.mkNot((BoolExpr)nctx.nodeHasAddr.apply(politoAntispam,nctx.pf.get("src").apply(p_0)))),1,null,null,null,null));
+           }
+       }
\ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoCache.java b/verigraph/service/src/mcnet/netobjs/PolitoCache.java
new file mode 100644 (file)
index 0000000..948915c
--- /dev/null
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+import com.microsoft.z3.Sort;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+/**Cache Model
+ *
+ */
+public class PolitoCache extends NetworkObject{
+
+               List<BoolExpr> constraints;
+               Context ctx;
+               DatatypeExpr politoCache;
+               Network net;
+               NetContext nctx;
+               FuncDecl isInBlacklist;
+
+               public PolitoCache(Context ctx, Object[]... args) {
+                       super(ctx, args);
+               }
+
+               @Override
+               protected void init(Context ctx, Object[]... args) {
+                       this.ctx = ctx;
+                       isEndHost=false;
+                       constraints = new ArrayList<BoolExpr>();
+               z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+               politoCache = z3Node;
+               net = (Network)args[0][1];
+               nctx = (NetContext)args[0][2];
+               //net.saneSend(this);
+           }
+
+               @Override
+               public DatatypeExpr getZ3Node() {
+                       return politoCache;
+               }
+
+               @Override
+               protected void addConstraints(Solver solver) {
+                               BoolExpr[] constr = new BoolExpr[constraints.size()];
+                           solver.add(constraints.toArray(constr));
+               }
+
+           public void installCache (NetworkObject[] internalNodes){
+               Expr n_0 = ctx.mkConst("politoCache_"+politoCache+"_n_0", nctx.node);
+               Expr n_1 = ctx.mkConst("politoCache_"+politoCache+"_n_1", nctx.node);
+               Expr n_2 = ctx.mkConst("politoCache_"+politoCache+"_n_2", nctx.node);
+               Expr p_0 = ctx.mkConst("politoCache_"+politoCache+"_p_0", nctx.packet);
+               Expr p_1 = ctx.mkConst("politoCache_"+politoCache+"_p_1", nctx.packet);
+               Expr p_2 = ctx.mkConst("politoCache_"+politoCache+"_p_2", nctx.packet);
+
+               IntExpr t_0 = ctx.mkIntConst("politoCache_"+politoCache+"_t_0");
+               IntExpr t_1 = ctx.mkIntConst("politoCache_"+politoCache+"_t_1");
+               IntExpr t_2 = ctx.mkIntConst("politoCache_"+politoCache+"_t_2");
+
+               Expr a_0 = ctx.mkConst(politoCache+"politoCache_a_0", nctx.node);
+               IntExpr u_0 = ctx.mkIntConst("politoCache_"+politoCache+"_u_0");
+
+               FuncDecl isInternalNode = ctx.mkFuncDecl(politoCache+"_isInternalNode", nctx.node, ctx.mkBoolSort());
+               FuncDecl isInCache = ctx.mkFuncDecl(politoCache+"_isInCache", new Sort[]{ctx.mkIntSort(),ctx.mkIntSort()}, ctx.mkBoolSort());
+
+               assert(internalNodes.length!=0); //No internal nodes => Should never happen
+
+               //Modeling the behavior of the isInternalNode() and isInCache() functions
+               BoolExpr[] internalNodesConstraint = new BoolExpr[internalNodes.length];
+               for(int w=0;w<internalNodesConstraint.length;w++)
+                       internalNodesConstraint[w]= (ctx.mkEq(a_0,internalNodes[w].getZ3Node()));
+
+               //Constraint1           if(isInternalNode(a_0) == or(listadeinodiinterni) ? True : false
+               constraints.add(
+                                ctx.mkForall(new Expr[]{a_0},
+                                                ctx.mkIff((BoolExpr)isInternalNode.apply(a_0), ctx.mkOr(internalNodesConstraint)),1,null,null,null,null));
+
+//             constraints.add(ctx.mkForall(new Expr[]{a_0}, ctx.mkEq(isInternalNode.apply(a_0),ctx.mkOr(internalNodesConstraint)),1,null,null,null,null));
+
+//             constraints.add(ctx.mkForall(new Expr[]{u_0, t_0},
+//                     ctx.mkITE(ctx.mkExists(new Expr[]{t_1, t_2, p_1, p_2, n_1, n_2},
+//                                     ctx.mkAnd(ctx.mkLt(t_1, t_2),
+//                                     ctx.mkLt(t_1, t_0),
+//                                     ctx.mkLt(t_2, t_0),
+//                                     (BoolExpr)nctx.recv.apply(n_1, politoCache, p_1, t_1),
+//                                     (BoolExpr)nctx.recv.apply(n_2, politoCache, p_2, t_2),
+//                                     ctx.mkEq(nctx.pf.get("proto").apply(p_1),ctx.mkInt(nctx.HTTP_REQUEST)),
+//                                     ctx.mkEq(nctx.pf.get("proto").apply(p_2),ctx.mkInt(nctx.HTTP_RESPONSE)),
+//                                     (BoolExpr)isInternalNode.apply(n_1),
+//                                     ctx.mkNot((BoolExpr)isInternalNode.apply(n_2)),
+//                                     ctx.mkEq(nctx.pf.get("url").apply(p_1),u_0),
+//                                     ctx.mkEq(nctx.pf.get("url").apply(p_2),u_0)),1,null,null,null,null),
+//                              ctx.mkEq(isInCache.apply(u_0,t_0),ctx.mkBool(true)),ctx.mkEq(isInCache.apply(u_0,t_0),ctx.mkBool(false))),1,null,null,null,null));
+//
+
+               //Constraint2   isInCache(u_0,t_0), exist t_1, t_2, p_1, p_2, n_1, n_2 :
+               //                                                      (   t_1< t_2 < t_0 && recv(n_1, politoCache, p_1, t_1) && recv(n_2, politoCache, p_2, t_2))) &&
+               //                                                              p_1.proto == HTTP_REQ &&  p_2.proto == HTTP_RESP &&
+               //                                                              isInternalNode(n_1) && !isInternalNode(n_2) &&
+               //                                                              p_1.url == u_0 &&  p_2.url == u_0 )
+               constraints.add(
+                               ctx.mkForall(new Expr[]{u_0, t_0},
+                                ctx.mkImplies((BoolExpr)isInCache.apply(u_0, t_0),
+                                                ctx.mkExists(new Expr[]{t_1,t_2,p_1,p_2,n_1, n_2},
+                                                                ctx.mkAnd(
+                                                                                ctx.mkLt(t_1, t_2),
+                                                                                ctx.mkLt(t_1, t_0),
+                                                                                ctx.mkLt(t_2, t_0),
+                                                                                (BoolExpr)nctx.recv.apply(n_1, politoCache, p_1, t_1),
+                                                                                (BoolExpr)nctx.recv.apply(n_2, politoCache, p_2, t_2),
+                                                                                ctx.mkEq(nctx.pf.get("proto").apply(p_1), ctx.mkInt(nctx.HTTP_REQUEST)),
+                                                                                ctx.mkEq(nctx.pf.get("proto").apply(p_2), ctx.mkInt(nctx.HTTP_RESPONSE)),
+                                                                                (BoolExpr)isInternalNode.apply(n_1),
+                                                                                ctx.mkNot((BoolExpr)isInternalNode.apply(n_2)),
+                                                                                ctx.mkEq(nctx.pf.get("url").apply(p_1), u_0),
+                                                                                ctx.mkEq(nctx.pf.get("url").apply(p_2), u_0)),1,null,null,null,null)),1,null,null,null,null));
+//             //Always in cache
+//             constraints.add(ctx.mkForall(new Expr[]{u_0, t_0},ctx.mkEq(isInCache.apply(u_0,t_0),ctx.mkBool(true)),1,null,null,null,null));
+
+               //Constraint3   Modeling the behavior of the cache
+               //                              send(politoCache, n_0, p, t_0) && !isInternalNode(n_0) ->
+                       //                              (exist t_1,n_1 :
+                       //                          (t_1 < t_0 && recv(n_1, politoCache, p, t_1) &&
+                       //                           p.proto == HTTP_REQ &&  !isInCache(p.url,t_0))
+               constraints.add(
+                               ctx.mkForall(new Expr[]{n_0,p_0, t_0},
+                                        ctx.mkImplies(
+                                                        ctx.mkAnd((BoolExpr)nctx.send.apply(politoCache,n_0,p_0,t_0),ctx.mkNot((BoolExpr)isInternalNode.apply(n_0))),
+                                                        ctx.mkAnd(ctx.mkExists(new Expr[]{t_1, n_1},
+                                                                        ctx.mkAnd(
+                                                                                        ctx.mkLt(t_1, t_0),
+                                                                                        (BoolExpr)isInternalNode.apply(n_1),
+                                                                                        (BoolExpr)nctx.recv.apply(n_1, politoCache, p_0, t_1)),1,null,null,null,null),
+                                                                                        ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_REQUEST)),
+                                                                                        ctx.mkNot((BoolExpr)isInCache.apply(nctx.pf.get("url").apply(p_0), t_0)))),1,null,null,null,null));
+
+               //Constraint4           send(politoCache, n_0, p, t_0) && isInternalNode(n_0) ->
+                       //                              (exist p_1,t_1 :
+                       //                              (t_1 < t_0 && recv(n_0, politoCache, p_1, t_1) &&
+                       //                              p_1.proto == HTTP_REQ && p.proto == HTTP_RESP &&
+                       //                              p_1.url == p.url &&  p.src == p_1.dest && p.dest==p_1.src
+                       //                              && isInCache(p.url,t_0))
+               constraints.add(
+                               ctx.mkForall(new Expr[]{n_0,p_0, t_0},
+                                        ctx.mkImplies(
+                                                        ctx.mkAnd((BoolExpr)nctx.send.apply(politoCache,n_0,p_0,t_0),(BoolExpr)isInternalNode.apply(n_0)),
+                                                        ctx.mkAnd(ctx.mkExists(new Expr[]{p_1, t_1},
+                                                                        ctx.mkAnd(
+                                                                                        ctx.mkLt(t_1, t_0),
+                                                                                       (BoolExpr)nctx.recv.apply(n_0, politoCache, p_1, t_1),
+                                                                                        ctx.mkEq(nctx.pf.get("proto").apply(p_1), ctx.mkInt(nctx.HTTP_REQUEST)),
+                                                                                        ctx.mkEq(nctx.pf.get("url").apply(p_1), nctx.pf.get("url").apply(p_0))),1,null,null,null,null),
+                                                                        ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_RESPONSE)),
+                                                                        ctx.mkEq(nctx.pf.get("src").apply(p_0), nctx.pf.get("dest").apply(p_1)),
+                                                                        ctx.mkEq(nctx.pf.get("dest").apply(p_0), nctx.pf.get("src").apply(p_1)),
+                                                                       (BoolExpr)isInCache.apply(nctx.pf.get("url").apply(p_0), t_0))),1,null,null,null,null));
+           }
+}
\ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoEndHost.java b/verigraph/service/src/mcnet/netobjs/PolitoEndHost.java
new file mode 100644 (file)
index 0000000..e12579f
--- /dev/null
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+public class PolitoEndHost extends NetworkObject {
+
+       List<BoolExpr> constraints = new ArrayList<BoolExpr>();
+       Context ctx;
+       DatatypeExpr politoEndHost;
+       Network net;
+       NetContext nctx;
+
+       public PolitoEndHost(Context ctx, Object[]... args) {
+               super(ctx, args);
+       }
+
+       @Override
+       public DatatypeExpr getZ3Node() {
+               return politoEndHost;
+       }
+
+       @Override
+       protected void init(Context ctx, Object[]... args) {
+               this.ctx = ctx;
+               this.isEndHost = true;
+               this.politoEndHost = this.z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+               this.net = (Network)args[0][1];
+        this.nctx = (NetContext)args[0][2];
+       }
+
+       @Override
+       protected void addConstraints(Solver solver) {
+               BoolExpr[] constr = new BoolExpr[constraints.size()];
+           solver.add(constraints.toArray(constr));
+       }
+
+       /*
+        * Fields that can be configured -> "dest","body","seq","proto","emailFrom","url","options"
+        */
+       public void installEndHost (PacketModel packet){
+               System.out.println("Installing PolitoEndHost...");
+               Expr n_0 = ctx.mkConst("PolitoEndHost_"+politoEndHost+"_n_0", nctx.node);
+       Expr p_0 = ctx.mkConst("PolitoEndHost_"+politoEndHost+"_p_0", nctx.packet);
+       IntExpr t_0 = ctx.mkIntConst("PolitoEndHost_"+politoEndHost+"_t_0");
+               BoolExpr predicatesOnPktFields = ctx.mkTrue();
+
+               if(packet.getIp_dest() != null)
+                       predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("dest").apply(p_0), packet.getIp_dest()));
+               if(packet.getBody() != null)
+                       predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("body").apply(p_0), ctx.mkInt(packet.getBody())));
+               if(packet.getEmailFrom() != null)
+                       predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("emailFrom").apply(p_0), ctx.mkInt(packet.getEmailFrom())));
+               if(packet.getOptions() != null)
+                       predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("options").apply(p_0), ctx.mkInt(packet.getOptions())));
+               if(packet.getProto() != null)
+                       predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(packet.getProto())));
+               if(packet.getSeq() != null)
+                       predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("seq").apply(p_0), ctx.mkInt(packet.getSeq())));
+               if(packet.getUrl() != null)
+                       predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("url").apply(p_0), ctx.mkInt(packet.getUrl())));
+
+               //Constraint1           send(politoWebClient, n_0, p, t_0) -> p.origin == politoWebClient && p.orig_body == p.body && nodeHasAddr(politoWebClient,p.src)
+               constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                ctx.mkImplies((BoolExpr)nctx.send.apply(politoEndHost, n_0, p_0, t_0),
+                               ctx.mkAnd(predicatesOnPktFields,
+                                                 ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0)),
+                                                 ctx.mkEq(nctx.pf.get("origin").apply(p_0),politoEndHost),
+                                                 (BoolExpr)nctx.nodeHasAddr.apply(politoEndHost,nctx.pf.get("src").apply(p_0)))),1,null,null,null,null));
+
+               //Constraint2           recv(n_0, politoWebClient, p, t_0) -> nodeHasAddr(politoWebClient,p.dest)
+               constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0,politoEndHost, p_0, t_0),
+                               (BoolExpr)nctx.nodeHasAddr.apply(politoEndHost,nctx.pf.get("dest").apply(p_0))),1,null,null,null,null));
+
+               System.out.println("Done.");
+               return;
+       }
+
+}
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoErrFunction.java b/verigraph/service/src/mcnet/netobjs/PolitoErrFunction.java
new file mode 100644 (file)
index 0000000..5f84b9f
--- /dev/null
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+/**Error Function objects
+ *
+ */
+public class PolitoErrFunction extends NetworkObject{
+
+               List<BoolExpr> constraints;
+               Context ctx;
+               DatatypeExpr politoErrFunction;
+               Network net;
+               NetContext nctx;
+               FuncDecl isInBlacklist;
+
+               public PolitoErrFunction(Context ctx, Object[]... args) {
+                       super(ctx, args);
+               }
+
+               @Override
+               protected void init(Context ctx, Object[]... args) {
+                       this.ctx = ctx;
+                       isEndHost=true;
+                       constraints = new ArrayList<BoolExpr>();
+               z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+               politoErrFunction = z3Node;
+               net = (Network)args[0][1];
+               nctx = (NetContext)args[0][2];
+               errFunctionRules();
+               //net.saneSend(this);
+           }
+
+               @Override
+               public DatatypeExpr getZ3Node() {
+                       return politoErrFunction;
+               }
+
+               @Override
+               protected void addConstraints(Solver solver) {
+//                     System.out.println("[ERR FUNC] Installing rules.");
+                       BoolExpr[] constr = new BoolExpr[constraints.size()];
+                       solver.add(constraints.toArray(constr));
+               }
+
+           private void errFunctionRules (){
+               Expr n_0 = ctx.mkConst("PolitoErrFunction_"+politoErrFunction+"_n_0", nctx.node);
+               Expr p_0 = ctx.mkConst("PolitoErrFunction_"+politoErrFunction+"_p_0", nctx.packet);
+               IntExpr t_0 = ctx.mkIntConst("PolitoErrFunction_"+politoErrFunction+"_t_0");
+
+//              constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+//                              ctx.mkImplies((BoolExpr)nctx.send.apply(politoErrFunction, n_0, p_0, t_0),
+//                      (BoolExpr)nctx.nodeHasAddr.apply(politoErrFunction, nctx.pf.get("src").apply(p_0))),1,null,null,null,null));
+//              constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+//                              ctx.mkImplies((BoolExpr)nctx.send.apply(politoErrFunction, n_0, p_0, t_0),
+//                      ctx.mkEq(nctx.pf.get("origin").apply(p_0), politoErrFunction)),1,null,null,null,null));
+//
+//              constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+//                              ctx.mkImplies((BoolExpr)nctx.send.apply(politoErrFunction, n_0, p_0, t_0),
+//                                     ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),1,null,null,null,null));
+
+
+//            Constraint1      We want the ErrFunction not to send out any packet
+//                                             send(politoErrFunction, n_0, p, t_0) -> 1 == 2
+            constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoErrFunction, n_0, p_0, t_0),
+                                               ctx.mkEq(ctx.mkInt(1),ctx.mkInt(2))),1,null,null,null,null));
+
+//            constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+//                     ctx.mkImplies(  (BoolExpr)nctx.send.apply(n_0, politoErrFunction, p_0, t_0),
+//                                     (BoolExpr)nctx.nodeHasAddr.apply(politoErrFunction, nctx.pf.get("dest").apply(p_0))),1,null,null,null,null));
+
+           }
+       }
\ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoFieldModifier.java b/verigraph/service/src/mcnet/netobjs/PolitoFieldModifier.java
new file mode 100644 (file)
index 0000000..6d8d8fe
--- /dev/null
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+public class PolitoFieldModifier extends NetworkObject {
+
+       List<BoolExpr> constraints;
+       Context ctx;
+       DatatypeExpr politoFieldModifier;
+       Network net;
+       NetContext nctx;
+
+       public PolitoFieldModifier(Context ctx, Object[]... args) {
+               super(ctx, args);
+       }
+
+       @Override
+       public DatatypeExpr getZ3Node() {
+               return politoFieldModifier;
+       }
+
+       @Override
+       protected void init(Context ctx, Object[]... args) {
+               this.ctx = ctx;
+               isEndHost=false;
+               constraints = new ArrayList<BoolExpr>();
+        z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+        politoFieldModifier = z3Node;
+        net = (Network)args[0][1];
+        nctx = (NetContext)args[0][2];
+       }
+
+       @Override
+       protected void addConstraints(Solver solver) {
+               BoolExpr[] constr = new BoolExpr[constraints.size()];
+           solver.add(constraints.toArray(constr));
+       }
+
+       public void installFieldModifier (){
+               Expr x = ctx.mkConst("politoFieldModifier_"+politoFieldModifier+"_x", nctx.node);
+       Expr y = ctx.mkConst("politoFieldModifier_"+politoFieldModifier+"_y", nctx.node);
+       Expr p_0 = ctx.mkConst("politoFieldModifier_"+politoFieldModifier+"_p_0", nctx.packet);
+       Expr p_1 = ctx.mkConst("politoFieldModifier_"+politoFieldModifier+"_p_1", nctx.packet);
+
+       IntExpr t_0 = ctx.mkIntConst("politoFieldModifier_"+politoFieldModifier+"_t_0");
+       IntExpr t_1 = ctx.mkIntConst("politoFieldModifier_"+politoFieldModifier+"_t_1");
+
+       constraints.add(
+                       ctx.mkForall(new Expr[]{t_0, p_0, x},
+                               ctx.mkImplies((BoolExpr)nctx.send.apply(politoFieldModifier,x,p_0,t_0),
+                                                         ctx.mkExists(new Expr[]{y, p_1, t_1},
+                                                                ctx.mkAnd(ctx.mkLt(t_1, t_0),
+                                                                                  (BoolExpr)nctx.recv.apply(y, politoFieldModifier, p_1, t_1),
+                                                                                  ctx.mkEq(nctx.pf.get("encrypted").apply(p_0), nctx.pf.get("encrypted").apply(p_1)),
+                                                                                  ctx.mkEq(nctx.pf.get("src").apply(p_0), nctx.pf.get("src").apply(p_1)),
+                                                                                  ctx.mkEq(nctx.pf.get("dest").apply(p_0), nctx.pf.get("dest").apply(p_1)),
+                                                                                  ctx.mkEq(nctx.pf.get("inner_src").apply(p_0), nctx.pf.get("inner_src").apply(p_1)),
+                                                                                  ctx.mkEq(nctx.pf.get("inner_dest").apply(p_0), nctx.pf.get("inner_dest").apply(p_1)),
+                                                                                  ctx.mkEq(nctx.pf.get("origin").apply(p_0), nctx.pf.get("origin").apply(p_1)),
+                                                                                  ctx.mkEq(nctx.pf.get("orig_body").apply(p_0), nctx.pf.get("orig_body").apply(p_1)),
+                                                                                  ctx.mkEq(nctx.pf.get("body").apply(p_0), nctx.pf.get("body").apply(p_1)),
+                                                                                  ctx.mkEq(nctx.pf.get("seq").apply(p_0), nctx.pf.get("seq").apply(p_1)),
+                                                                                  ctx.mkEq(nctx.pf.get("proto").apply(p_0), nctx.pf.get("proto").apply(p_1)),
+                                                                                  ctx.mkEq(nctx.pf.get("emailFrom").apply(p_0), nctx.pf.get("emailFrom").apply(p_1)),
+                                                                                  ctx.mkNot(ctx.mkEq(nctx.pf.get("url").apply(p_0), nctx.pf.get("url").apply(p_1))),
+                                                                                  ctx.mkEq(nctx.pf.get("options").apply(p_0), nctx.pf.get("options").apply(p_1))),1,null,null,null,null)),
+                       1,null,null,null,null));
+       }
+
+}
\ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoIDS.java b/verigraph/service/src/mcnet/netobjs/PolitoIDS.java
new file mode 100644 (file)
index 0000000..6f2cddf
--- /dev/null
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+public class PolitoIDS extends NetworkObject {
+
+       public static final int DROGA = 1; //no go
+       public static final int GATTINI = 2;  //go
+
+       Context ctx;
+       List<BoolExpr> constraints = new ArrayList<BoolExpr>();
+       DatatypeExpr politoIDS;
+       Network net;
+       NetContext nctx;
+       FuncDecl isInBlacklist;
+
+
+       public PolitoIDS(Context ctx, Object[]...args){
+               super(ctx, args);
+       }
+
+       @Override
+       public DatatypeExpr getZ3Node() {
+               return politoIDS;
+       }
+
+       @Override
+       protected void init(Context ctx, Object[]... args) {
+
+               this.ctx = ctx;
+               this.isEndHost = false;
+               this.politoIDS = this.z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+               this.net = (Network)args[0][1];
+        this.nctx = (NetContext)args[0][2];
+
+       }
+
+       @Override
+       protected void addConstraints(Solver solver) {
+               BoolExpr[] constr = new BoolExpr[constraints.size()];
+           solver.add(constraints.toArray(constr));
+
+       }
+
+       public void installIDS(int[] blackList){
+               Expr n_0 = ctx.mkConst(politoIDS + "_n_0", nctx.node);
+               Expr n_1 = ctx.mkConst(politoIDS + "_n_1", nctx.node);
+               Expr p_0 = ctx.mkConst(politoIDS + "_p_0", nctx.packet);
+               IntExpr t_0 = ctx.mkIntConst(politoIDS + "_t_0");
+               IntExpr t_1 = ctx.mkIntConst(politoIDS + "_t_1");
+               Expr b_0 = ctx.mkIntConst(politoIDS + "_b_0");
+
+               isInBlacklist = ctx.mkFuncDecl(politoIDS + "_isInBlacklist", ctx.mkIntSort(), ctx.mkBoolSort());
+
+
+               BoolExpr[] blConstraints = new BoolExpr[blackList.length];
+               if(blackList.length != 0){
+
+                       for(int i = 0; i<blackList.length; i++)
+                               blConstraints[i] = ctx.mkEq(b_0, ctx.mkInt(blackList[i]));
+
+                       this.constraints.add(ctx.mkForall(new Expr[]{b_0},
+                                                                                         ctx.mkIff((BoolExpr)isInBlacklist.apply(b_0), ctx.mkOr(blConstraints)),
+                                                                                         1,
+                                                                                         null, null, null, null));
+               }else{
+                       this.constraints.add(ctx.mkForall(new Expr[]{b_0},
+                                                                                         ctx.mkEq(isInBlacklist.apply(b_0), ctx.mkBool(false)),
+                                                                                         1,
+                                                                                         null, null, null, null));
+               }
+
+               //Constraint2                   send(politoIDS, n_0, p, t_0) && (p.proto(HTTP_RESPONSE) || p.proto(HTTP_REQUEST)) ->
+        //                                             (exist  n_1,t_1 : (recv(n_1, politoIDS, p, t_1) && t_1 < t_0)) && !isInBlackList(p.body)
+
+               this.constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                                                                                 ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(politoIDS, n_0, p_0, t_0), ctx.mkOr(ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_RESPONSE)), ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_REQUEST)))),
+                                                                                                               ctx.mkAnd(ctx.mkExists(new Expr[]{n_1,t_1},
+                                                                                                                                                          ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1,politoIDS,p_0,t_1),ctx.mkLt(t_1, t_0)),
+                                                                                                                                                          1,
+                                                                                                                                                          null, null, null, null),
+                                                                                                                                 ctx.mkNot((BoolExpr)isInBlacklist.apply(nctx.pf.get("body").apply(p_0))))),
+                                                                                 1,
+                                                                                 null, null, null, null));
+
+               //Constraint3           send(politoIDS, n_0, p, t_0) && p.proto(HTTP_REQUEST) ->
+        //                                             (exist n_1,t_1 : (recv(n_1, politoIDS, p, t_1) && t_1 < t_0)) Constraint not needed anymore (included in contr. 2)
+               /*
+               this.constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                                                                                 ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(politoIDS, n_0, p_0, t_0), ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_REQUEST))),
+                                                                                                               ctx.mkAnd(ctx.mkExists(new Expr[]{n_1,t_1},
+                                                                                                                                                          ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1,politoIDS,p_0,t_1),ctx.mkLt(t_1, t_0)),
+                                                                                                                                                          1,
+                                                                                                                                                          null, null, null, null))),
+                                                                                 1,
+                                                                                 null, null, null, null));
+               */
+
+               //Constraint5           send(politoIDS, n_0, p, t_0) -> p.proto == HTTP_REQ || p.protpo == HTTP_RESP
+
+        this.constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                                                                 ctx.mkImplies((BoolExpr)nctx.send.apply(politoIDS, n_0, p_0, t_0),
+                                                                                               ctx.mkOr(ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_REQUEST)),
+                                                                                                                ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_RESPONSE)))),
+                                                                 1,
+                                                                 null,null,null,null));
+
+        //Constraint6          send(politoIDS, n_0, p, t_0) -> nodeHasAddr(politoIDS,p.src)
+
+        this.constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                                                                 ctx.mkImplies((BoolExpr)nctx.send.apply(politoIDS, n_0, p_0, t_0),
+                                                                                               ctx.mkNot((BoolExpr)nctx.nodeHasAddr.apply(politoIDS,nctx.pf.get("src").apply(p_0)))),
+                                                                 1,
+                                                                 null,null,null,null));
+
+       }
+
+}
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoMailClient.java b/verigraph/service/src/mcnet/netobjs/PolitoMailClient.java
new file mode 100644 (file)
index 0000000..6925258
--- /dev/null
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+/**
+ *  MailClient objects
+ *
+ */
+public class PolitoMailClient extends NetworkObject{
+
+               List<BoolExpr> constraints;
+               Context ctx;
+               DatatypeExpr politoMailClient;
+               Network net;
+               NetContext nctx;
+               FuncDecl isInBlacklist;
+
+               public PolitoMailClient(Context ctx, Object[]... args) {
+                       super(ctx, args);
+               }
+
+               @Override
+               protected void init(Context ctx, Object[]... args) {
+                       this.ctx = ctx;
+               isEndHost=true;
+                       constraints = new ArrayList<BoolExpr>();
+               z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+               politoMailClient = z3Node;
+               net = (Network)args[0][1];
+               nctx = (NetContext)args[0][2];
+               DatatypeExpr ipServer = (DatatypeExpr) args[0][3];
+               mailClientRules(ipServer);
+               //net.saneSend(this);
+           }
+
+               @Override
+               public DatatypeExpr getZ3Node() {
+                       return politoMailClient;
+               }
+
+               @Override
+               protected void addConstraints(Solver solver) {
+//                     System.out.println("[MailClient] Installing rules.");
+                       BoolExpr[] constr = new BoolExpr[constraints.size()];
+                       solver.add(constraints.toArray(constr));
+               }
+
+           private void mailClientRules (DatatypeExpr ipServer){
+               Expr n_0 = ctx.mkConst("PolitoMailClient_"+politoMailClient+"_n_0", nctx.node);
+               Expr p_0 = ctx.mkConst("PolitoMailClient_"+politoMailClient+"_p_0", nctx.packet);
+               IntExpr t_0 = ctx.mkIntConst("PolitoMailClient_"+politoMailClient+"_t_0");
+
+//            Constraint1              send(politoMailClient, n_0, p, t_0) -> nodeHasAddr(politoMailClient,p.src)
+                       constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailClient, n_0, p_0, t_0),
+                               (BoolExpr)nctx.nodeHasAddr.apply(politoMailClient,nctx.pf.get("src").apply(p_0))),1,null,null,null,null));
+
+//            Constraint2              send(politoMailClient, n_0, p, t_0) -> p.origin == politoMailClient
+                       constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailClient, n_0, p_0, t_0),
+                               ctx.mkEq(nctx.pf.get("origin").apply(p_0),politoMailClient)),1,null,null,null,null));
+
+//            Constraint3              send(politoMailClient, n_0, p, t_0) -> p.orig_body == p.body
+                       constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailClient, n_0, p_0, t_0),
+                               ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),1,null,null,null,null));
+
+//            Constraint4              recv(n_0, politoMailClient, p, t_0) -> nodeHasAddr(politoMailClient,p.dest)
+                       constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0,politoMailClient, p_0, t_0),
+                               (BoolExpr)nctx.nodeHasAddr.apply(politoMailClient,nctx.pf.get("dest").apply(p_0))),1,null,null,null,null));
+
+//            Constraint5              This client is only able to produce POP3 requests
+//                                                             send(politoMailClient, n_0, p, t_0) -> p.proto == POP3_REQ
+            constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailClient, n_0, p_0, t_0),
+                        ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_REQUEST))),1,null,null,null,null));
+
+//            Constraint6              send(politoMailClient, n_0, p, t_0) -> p.dest == ip_mailServer
+            constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailClient, n_0, p_0, t_0),
+                            ctx.mkEq(nctx.pf.get("dest").apply(p_0), ipServer)),1,null,null,null,null));
+               }
+}
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoMailServer.java b/verigraph/service/src/mcnet/netobjs/PolitoMailServer.java
new file mode 100644 (file)
index 0000000..c464195
--- /dev/null
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+/** Mail server objects
+ *
+ */
+public class PolitoMailServer extends NetworkObject{
+
+               List<BoolExpr> constraints;
+               Context ctx;
+               DatatypeExpr politoMailServer;
+               Network net;
+               NetContext nctx;
+               FuncDecl isInBlacklist;
+
+               public PolitoMailServer(Context ctx, Object[]... args) {
+                       super(ctx, args);
+               }
+
+               @Override
+               protected void init(Context ctx, Object[]... args) {
+                       this.ctx = ctx;
+                       isEndHost=false;
+                       constraints = new ArrayList<BoolExpr>();
+               z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+               politoMailServer = z3Node;
+               net = (Network)args[0][1];
+               nctx = (NetContext)args[0][2];
+               mailServerRules();
+               net.saneSend(this);
+           }
+
+               @Override
+               public DatatypeExpr getZ3Node() {
+                       return politoMailServer;
+               }
+
+               @Override
+               protected void addConstraints(Solver solver) {
+                               BoolExpr[] constr = new BoolExpr[constraints.size()];
+                           solver.add(constraints.toArray(constr));
+               }
+
+           private void mailServerRules (){
+               Expr n_0 = ctx.mkConst(politoMailServer+"_n_0", nctx.node);
+               Expr p_0 = ctx.mkConst(politoMailServer+"_p_0", nctx.packet);
+               Expr p_1 = ctx.mkConst(politoMailServer+"_p_1", nctx.packet);
+               IntExpr t_0 = ctx.mkIntConst(politoMailServer+"_t_0");
+               IntExpr t_1 = ctx.mkIntConst(politoMailServer+"_t_1");
+
+//            Constraint1              send(politoMailServer, n_0, p, t_0) -> nodeHasAddr(politoMailServer,p.src)
+               constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0),
+                               (BoolExpr)nctx.nodeHasAddr.apply(politoMailServer,nctx.pf.get("src").apply(p_0))),1,null,null,null,null));
+
+//            Constraint2              send(politoMailServer, n_0, p, t_0) -> p.origin == politoMailServer
+               constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0),
+                               ctx.mkEq(nctx.pf.get("origin").apply(p_0),politoMailServer)),1,null,null,null,null));
+
+//            Constraint3              send(politoMailServer, n_0, p, t_0) -> p.orig_body == p.body
+               constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0),
+                               ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),1,null,null,null,null));
+
+//            Constraint4              recv(n_0, politoMailServer, p, t_0) -> nodeHasAddr(politoMailServer,p.dest)
+               constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0,politoMailServer, p_0, t_0),
+                               (BoolExpr)nctx.nodeHasAddr.apply(politoMailServer,nctx.pf.get("dest").apply(p_0))),1,null,null,null,null));
+
+//            Constraint5              send(politoMailServer, n_0, p, t_0) -> p.proto == POP3_RESP && p.emailFrom == 1
+               constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0),
+                       ctx.mkAnd(      ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_RESPONSE)),
+                                               ctx.mkEq(nctx.pf.get("emailFrom").apply(p_0), ctx.mkInt(1)))),1,null,null,null,null));
+
+//            Constraint6              send(politoMailServer, n_0, p, t_0)  ->
+//                                                     (exist p_1, t_1 : (t_1 < t_0 && recv(n_0, politoMailServer, p_1, t_1) &&
+//                                                     p_0.proto == POP3_RESP &&  p_1.proto == POP3_REQ && p_0.dest == p_1.src )
+
+               constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0),
+                        ctx.mkExists(new Expr[]{p_1, t_1},
+                            ctx.mkAnd(ctx.mkLt(t_1, t_0),
+                                       (BoolExpr)nctx.recv.apply(n_0, politoMailServer, p_1, t_1),
+                                       ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_RESPONSE)),
+                                       ctx.mkEq(nctx.pf.get("proto").apply(p_1), ctx.mkInt(nctx.POP3_REQUEST)),
+                                       ctx.mkEq(nctx.pf.get("dest").apply(p_0), nctx.pf.get("src").apply(p_1))),1,null,null,null,null)),1,null,null,null,null));
+
+//             constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+//                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0),
+//                             ctx.mkEq(nctx.pf.get("emailFrom").apply(p_0),ctx.mkInt(2))),1,null,null,null,null));
+           }
+}
\ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoNF.java b/verigraph/service/src/mcnet/netobjs/PolitoNF.java
new file mode 100644 (file)
index 0000000..53cae28
--- /dev/null
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+import com.microsoft.z3.Sort;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+/** First example of custom network function: a simple filter
+ *
+ */
+public class PolitoNF extends NetworkObject{
+
+               List<BoolExpr> constraints;
+               Context ctx;
+               DatatypeExpr politoNF;
+               Network net;
+               NetContext nctx;
+               FuncDecl isInBlacklist;
+
+
+               public PolitoNF(Context ctx, Object[]... args) {
+                       super(ctx, args);
+               }
+
+               @Override
+               protected void init(Context ctx, Object[]... args) {
+                       this.ctx = ctx;
+                       isEndHost=false;
+                       constraints = new ArrayList<BoolExpr>();
+               z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+               politoNF = z3Node;
+               net = (Network)args[0][1];
+               nctx = (NetContext)args[0][2];
+               //net.saneSend(this);
+           }
+
+           public void politoNFRules (DatatypeExpr ipA,DatatypeExpr ipB){
+//             System.out.println("[PolitoNf] Installing rules");
+               Expr n_0 = ctx.mkConst("politoNF_"+politoNF+"_n_0", nctx.node);
+               Expr n_1 = ctx.mkConst("politoNF_"+politoNF+"_n_1", nctx.node);
+               Expr p_0 = ctx.mkConst("politoNF_"+politoNF+"_p_0", nctx.packet);
+               IntExpr t_0 = ctx.mkIntConst("politoNF_"+politoNF+"_t_0");
+               IntExpr t_1 = ctx.mkIntConst("politoNF_"+politoNF+"_t_1");
+               Expr a_0 = ctx.mkConst(politoNF+"_politoNF_a_0", nctx.address);
+               Expr a_1 = ctx.mkConst(politoNF+"_politoNF_a_1", nctx.address);
+
+               FuncDecl myFunction = ctx.mkFuncDecl(politoNF+"_myFunction", new Sort[]{nctx.address,nctx.address}, ctx.mkBoolSort());
+
+               BoolExpr myConstraint = ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                                ctx.mkImplies((BoolExpr)nctx.send.apply(politoNF, n_0, p_0, t_0),
+                                                ctx.mkExists(new Expr[]{n_1, t_1},
+                                                                ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1, politoNF, p_0, t_1),
+                                                                                       ctx.mkLt(t_1 , t_0),
+                                                                                       (BoolExpr)myFunction.apply(nctx.pf.get("src").apply(p_0), nctx.pf.get("dest").apply(p_0))),1,null,null,null,null)),1,null,null,null,null);
+
+               BoolExpr funcConstraint = ctx.mkOr(ctx.mkAnd(ctx.mkEq(a_0, ipA), ctx.mkEq(a_1, ipB)), ctx.mkAnd(ctx.mkEq(a_0,ipB), ctx.mkEq(a_1,ipA)));
+
+               // Constraint1          myFunction(a_0,a_1) == ((a_0 == ipA && a_1 == ipB) || (a_0 == ipB && a_1 == ipA))
+                        constraints.add(
+                                        ctx.mkForall(new Expr[]{a_0,a_1},
+                                                        ctx.mkEq(myFunction.apply(a_0, a_1), funcConstraint),1,null,null,null,null));
+
+                       //Constraint2           send(politoNF, n_0, p, t_0)  ->
+                        //                                     (exist n_1,t_1 : (t_1 < t_0 && recv(n_1, politoNF, p, t_1) && myFunction(p.src,p.dest))
+                        constraints.add(myConstraint);
+
+           }
+
+           @Override
+               protected void addConstraints(Solver solver) {
+                               BoolExpr[] constr = new BoolExpr[constraints.size()];
+                           solver.add(constraints.toArray(constr));
+               }
+
+           @Override
+               public DatatypeExpr getZ3Node() {
+                       return politoNF;
+               }
+
+       }
\ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoNat.java b/verigraph/service/src/mcnet/netobjs/PolitoNat.java
new file mode 100644 (file)
index 0000000..6d8a36d
--- /dev/null
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+/**
+ * NAT Model object
+ *
+ */
+public class PolitoNat extends NetworkObject{
+       List<BoolExpr> constraints;
+       Context ctx;
+       DatatypeExpr nat;
+       List<DatatypeExpr> private_addresses;
+       List<NetworkObject> private_node;
+       Network net;
+       NetContext nctx;
+       FuncDecl private_addr_func ;
+
+       public PolitoNat(Context ctx, Object[]... args) {
+               super(ctx, args);
+       }
+
+       @Override
+       protected void init(Context ctx, Object[]... args) {
+               this.ctx = ctx;
+               isEndHost=false;
+               constraints = new ArrayList<BoolExpr>();
+        z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+        nat = z3Node;
+        net = (Network)args[0][1];
+        nctx = (NetContext)args[0][2];
+        private_addresses = new ArrayList<DatatypeExpr>();
+        private_node = new ArrayList<NetworkObject>();
+        net.saneSend(this);
+    }
+
+       @Override
+       public DatatypeExpr getZ3Node() {
+               return nat;
+       }
+
+       @Override
+       protected void addConstraints(Solver solver) {
+                       BoolExpr[] constr = new BoolExpr[constraints.size()];
+                   solver.add(constraints.toArray(constr));
+       }
+
+       /*
+       private void addPrivateAdd(List<DatatypeExpr> address){
+               private_addresses.addAll(address);
+       }
+       */
+
+       public List<DatatypeExpr> getPrivateAddress(){
+               return private_addresses;
+       }
+
+    public void natModel(DatatypeExpr natIp){
+       Expr x = ctx.mkConst("x", nctx.node);
+       Expr y = ctx.mkConst("y", nctx.node);
+       Expr z = ctx.mkConst("z", nctx.node);
+
+       Expr p_0 = ctx.mkConst("p_0", nctx.packet);
+       Expr p_1 = ctx.mkConst("p_1", nctx.packet);
+       Expr p_2 = ctx.mkConst("p_2", nctx.packet);
+
+       IntExpr t_0 = ctx.mkIntConst("t_0");
+       IntExpr t_1 = ctx.mkIntConst("t_1");
+       IntExpr t_2 = ctx.mkIntConst("t_2");
+
+//     private_addr_func = ctx.mkFuncDecl("private_addr_func", nctx.address, ctx.mkBoolSort());
+       private_addr_func = ctx.mkFuncDecl(nat + "_nat_func", nctx.address, ctx.mkBoolSort());
+
+       //Constraint1
+//     "send(nat, x, p_0, t_0) && !private_addr_func(p_0.dest) ->
+//     p_0.src == ip_politoNat &&
+//     (exist y, p_1,t_1 :
+//        (recv(y, nat, p_1, t_1) && t_1 < t_0 &&
+//         private_addr_func(p1.src) &&
+//         p_1.origin == p_0.origin &&
+//         same for p_1.<dest,orig_body,body,seq,proto,emailFrom,url,options> == p_0.<...>) "
+       constraints.add( ctx.mkForall(new Expr[]{t_0, p_0, x},
+               ctx.mkImplies(
+                               ctx.mkAnd((BoolExpr)nctx.send.apply(nat, x, p_0, t_0),
+                                               ctx.mkNot((BoolExpr)private_addr_func.apply(nctx.pf.get("dest").apply(p_0)))),
+                               ctx.mkAnd(
+                                               ctx.mkEq(nctx.pf.get("src").apply(p_0),natIp),
+                                               ctx.mkExists(new Expr[]{y, p_1, t_1},
+                                                               ctx.mkAnd(
+                                                                       (BoolExpr)nctx.recv.apply(y, nat, p_1, t_1),
+                                                                       ctx.mkLt(t_1 , t_0),
+                                                                       (BoolExpr)private_addr_func.apply(nctx.pf.get("src").apply(p_1)),
+                                                                       ctx.mkEq(nctx.pf.get("origin").apply(p_1),nctx.pf.get("origin").apply(p_0)),
+                                                                       ctx.mkEq(nctx.pf.get("dest").apply(p_1),nctx.pf.get("dest").apply(p_0)),
+                                                                       ctx.mkEq(nctx.pf.get("orig_body").apply(p_1),nctx.pf.get("orig_body").apply(p_0)),
+                                                                       ctx.mkEq(nctx.pf.get("body").apply(p_1),nctx.pf.get("body").apply(p_0)),
+                                                                       ctx.mkEq(nctx.pf.get("seq").apply(p_1),nctx.pf.get("seq").apply(p_0)),
+                                                                       ctx.mkEq(nctx.pf.get("proto").apply(p_1),nctx.pf.get("proto").apply(p_0)),
+                                                                       ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1),nctx.pf.get("emailFrom").apply(p_0)),
+                                                                       ctx.mkEq(nctx.pf.get("url").apply(p_1),nctx.pf.get("url").apply(p_0)),
+                                                                       ctx.mkEq(nctx.pf.get("options").apply(p_1),nctx.pf.get("options").apply(p_0))),1,null,null,null,null))),1,null,null,null,null));
+
+       //Constraint2
+//     send(nat, x, p_0, t_0) && private_addr_func(p_0.dest) ->
+//     !private_addr_func(p_0.src) &&
+//     (exist y, p_1,t_1 :
+//       (recv(y, nat, p_1, t_1) && t_1 < t_0 &&
+//        !private_addr_func(p1.src) &&
+//        p_1.dest == ip_politoNat &&
+//        p_1.origin == p_0.origin &&
+//        same for p_1.<src,orig_body,body,seq,proto,emailFrom,url,options> == p_0.<...>)
+       constraints.add( ctx.mkForall(new Expr[]{x, p_0, t_0},
+                       ctx.mkImplies(
+                               ctx.mkAnd((BoolExpr)nctx.send.apply(nat, x, p_0, t_0),
+                                       (BoolExpr)private_addr_func.apply(nctx.pf.get("dest").apply(p_0))),
+                                       ctx.mkAnd(
+                                               ctx.mkNot((BoolExpr)private_addr_func.apply(nctx.pf.get("src").apply(p_0))),
+                                               ctx.mkExists(new Expr[]{y, p_1, t_1},
+                                                       ctx.mkAnd(
+                                                                       ctx.mkLt(t_1 , t_0),
+                                                                       (BoolExpr)nctx.recv.apply(y, nat, p_1, t_1),
+                                                                       ctx.mkNot((BoolExpr)private_addr_func.apply(nctx.pf.get("src").apply(p_1))),
+                                                                       ctx.mkEq(nctx.pf.get("dest").apply(p_1),natIp),
+                                                                       ctx.mkEq(nctx.pf.get("src").apply(p_1),nctx.pf.get("src").apply(p_0)),
+                                                                       ctx.mkEq(nctx.pf.get("origin").apply(p_0),nctx.pf.get("origin").apply(p_1)),
+                                                                       ctx.mkEq(nctx.pf.get("orig_body").apply(p_1),nctx.pf.get("orig_body").apply(p_0)),
+                                                                       ctx.mkEq(nctx.pf.get("body").apply(p_1),nctx.pf.get("body").apply(p_0)),
+                                                                       ctx.mkEq(nctx.pf.get("seq").apply(p_1),nctx.pf.get("seq").apply(p_0)),
+                                                                       ctx.mkEq(nctx.pf.get("proto").apply(p_1),nctx.pf.get("proto").apply(p_0)),
+                                                                       ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1),nctx.pf.get("emailFrom").apply(p_0)),
+                                                                       ctx.mkEq(nctx.pf.get("url").apply(p_1),nctx.pf.get("url").apply(p_0)),
+                                                                       ctx.mkEq(nctx.pf.get("options").apply(p_1),nctx.pf.get("options").apply(p_0)),
+                                                                       ctx.mkExists(new Expr[]{z, p_2, t_2},
+                                                                               ctx.mkAnd(
+                                                                                               ctx.mkLt(t_2 , t_1),
+                                                                                               (BoolExpr)nctx.recv.apply(z, nat, p_2, t_2),
+                                                                                               (BoolExpr)private_addr_func.apply(nctx.pf.get("src").apply(p_2)),
+                                                                                               ctx.mkEq(nctx.pf.get("src").apply(p_1),nctx.pf.get("dest").apply(p_2)),
+                                                                                               ctx.mkEq(nctx.pf.get("src").apply(p_0),nctx.pf.get("dest").apply(p_2)),
+                                                                                               ctx.mkEq(nctx.pf.get("src").apply(p_2),nctx.pf.get("dest").apply(p_0))),1,null,null,null,null)),1,null,null,null,null))),1,null,null,null,null));
+    }
+
+    public void setInternalAddress(ArrayList<DatatypeExpr> internalAddress){
+       List<BoolExpr> constr = new ArrayList<BoolExpr>();
+       Expr n_0 = ctx.mkConst("nat_node", nctx.address);
+
+       for(DatatypeExpr n : internalAddress){
+               constr.add(ctx.mkEq(n_0,n));
+       }
+       BoolExpr[] constrs = new BoolExpr[constr.size()];
+       //Constraint            private_addr_func(n_0) == or(n_0==n foreach internal address)
+       constraints.add(ctx.mkForall(new Expr[]{n_0}, ctx.mkEq(private_addr_func.apply(n_0),ctx.mkOr(constr.toArray(constrs))),1,null,null,null,null));
+    }
+}
\ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoVpnAccess.java b/verigraph/service/src/mcnet/netobjs/PolitoVpnAccess.java
new file mode 100644 (file)
index 0000000..e6fc5fe
--- /dev/null
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+public class PolitoVpnAccess extends NetworkObject {
+
+       List<BoolExpr> constraints = new ArrayList<BoolExpr>();
+       DatatypeExpr politoVpnAccess;
+       FuncDecl private_addr_func;
+       NetContext nctx;
+       Context ctx;
+       Network net;
+
+       public PolitoVpnAccess(Context ctx, Object[]... args) {
+               super(ctx, args);
+       }
+
+       @Override
+       public DatatypeExpr getZ3Node() {
+               return politoVpnAccess;
+       }
+
+       @Override
+       protected void init(Context ctx, Object[]... args) {
+               this.ctx = ctx;
+               this.isEndHost = false;
+               this.politoVpnAccess = this.z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+               this.net = (Network)args[0][1];
+        this.nctx = (NetContext)args[0][2];
+       }
+
+       @Override
+       protected void addConstraints(Solver solver) {
+               BoolExpr[] constr = new BoolExpr[constraints.size()];
+           solver.add(constraints.toArray(constr));
+       }
+
+       public void vpnAccessModel(DatatypeExpr vpnAccessIp, DatatypeExpr vpnExitIp) {
+               Expr x = ctx.mkConst("vpn_x", nctx.node);
+               Expr y = ctx.mkConst("vpn_y", nctx.node);
+
+               Expr p_0 = ctx.mkConst("vpn_p_0", nctx.packet);
+               Expr p_1 = ctx.mkConst("vpn_p_1", nctx.packet);
+
+               IntExpr t_0 = ctx.mkIntConst("vpn_t_0");
+               IntExpr t_1 = ctx.mkIntConst("vpn_t_1");
+
+               private_addr_func = ctx.mkFuncDecl("vpn_private_addr_func", nctx.address, ctx.mkBoolSort());
+
+               BoolExpr constraint1 = ctx.mkForall(new Expr[]{t_0, p_0, x},
+                               ctx.mkImplies(ctx.mkAnd(
+                                                                         (BoolExpr)nctx.send.apply(politoVpnAccess, x, p_0, t_0),
+                                                                         ctx.mkEq(nctx.pf.get("inner_src").apply(p_0), nctx.am.get("null"))),
+                                                         ctx.mkAnd(
+                                                                         (BoolExpr)private_addr_func.apply(nctx.pf.get("dest").apply(p_0)),
+                                                                         ctx.mkNot((BoolExpr)nctx.pf.get("encrypted").apply(p_0)),
+                                                                         ctx.mkExists(new Expr[]{y, p_1, t_1},
+                                                                                         ctx.mkAnd((BoolExpr)nctx.recv.apply(y, politoVpnAccess, p_1, t_1),
+                                                                                                           ctx.mkLt(t_1, t_0),
+                                                                                                           (BoolExpr)nctx.pf.get("encrypted").apply(p_1),
+                                                                                                           ctx.mkEq(nctx.pf.get("src").apply(p_1), vpnExitIp),
+                                                                                                           ctx.mkEq(nctx.pf.get("dest").apply(p_1), vpnAccessIp),
+                                                                                                           ctx.mkEq(nctx.pf.get("inner_src").apply(p_1), nctx.pf.get("src").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("inner_dest").apply(p_1), nctx.pf.get("dest").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("origin").apply(p_1), nctx.pf.get("origin").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("orig_body").apply(p_1), nctx.pf.get("orig_body").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("body").apply(p_1), nctx.pf.get("body").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("seq").apply(p_1), nctx.pf.get("seq").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("proto").apply(p_1), nctx.pf.get("proto").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1), nctx.pf.get("emailFrom").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("url").apply(p_1), nctx.pf.get("url").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("options").apply(p_1), nctx.pf.get("options").apply(p_0))), 1, null, null, null, null))),
+                       1,null,null,null,null);
+
+               constraints.add(constraint1);
+
+               BoolExpr constraint2 = ctx.mkForall(new Expr[]{t_0, p_0, x},
+                               ctx.mkImplies(ctx.mkAnd(
+                                                                         (BoolExpr)nctx.send.apply(politoVpnAccess, x, p_0, t_0),
+                                                                         ctx.mkNot(ctx.mkEq(nctx.pf.get("inner_src").apply(p_0), nctx.am.get("null")))),
+                                                         ctx.mkAnd(
+                                                                         ctx.mkEq(nctx.pf.get("src").apply(p_0), vpnAccessIp),
+                                                                         ctx.mkEq(nctx.pf.get("dest").apply(p_0), vpnExitIp),
+                                                                         (BoolExpr)private_addr_func.apply(nctx.pf.get("inner_src").apply(p_0)),
+                                                                         ctx.mkNot(ctx.mkEq(nctx.pf.get("inner_dest").apply(p_0), vpnAccessIp)),
+                                                                         (BoolExpr)nctx.pf.get("encrypted").apply(p_0),
+                                                                         ctx.mkExists(new Expr[]{y, p_1, t_1},
+                                                                                         ctx.mkAnd((BoolExpr)nctx.recv.apply(y, politoVpnAccess, p_1, t_1),
+                                                                                                           ctx.mkLt(t_1, t_0),
+                                                                                                           ctx.mkNot((BoolExpr)nctx.pf.get("encrypted").apply(p_1)),
+                                                                                                           ctx.mkEq(nctx.pf.get("src").apply(p_1), nctx.pf.get("inner_src").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("dest").apply(p_1), nctx.pf.get("inner_dest").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("inner_src").apply(p_1), nctx.am.get("null")),
+                                                                                                           ctx.mkEq(nctx.pf.get("inner_dest").apply(p_1), nctx.am.get("null")),
+                                                                                                           ctx.mkEq(nctx.pf.get("origin").apply(p_1), nctx.pf.get("origin").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("orig_body").apply(p_1), nctx.pf.get("orig_body").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("body").apply(p_1), nctx.pf.get("body").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("seq").apply(p_1), nctx.pf.get("seq").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("proto").apply(p_1), nctx.pf.get("proto").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1), nctx.pf.get("emailFrom").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("url").apply(p_1), nctx.pf.get("url").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("options").apply(p_1), nctx.pf.get("options").apply(p_0))), 1, null, null, null, null))),
+                               1,null,null,null,null);
+
+               constraints.add(constraint2);
+       }
+
+       public void setInternalAddress(ArrayList<DatatypeExpr> internalAddress){
+       List<BoolExpr> constr = new ArrayList<BoolExpr>();
+       Expr n_0 = ctx.mkConst("vpn_node", nctx.address);
+
+       for(DatatypeExpr n : internalAddress){
+               constr.add(ctx.mkEq(n_0,n));
+       }
+       BoolExpr[] constrs = new BoolExpr[constr.size()];
+       //Constraint            private_addr_func(n_0) == or(n_0==n foreach internal address)
+       constraints.add(ctx.mkForall(new Expr[]{n_0}, ctx.mkEq(private_addr_func.apply(n_0),ctx.mkOr(constr.toArray(constrs))),1,null,null,null,null));
+    }
+
+}
\ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoVpnExit.java b/verigraph/service/src/mcnet/netobjs/PolitoVpnExit.java
new file mode 100644 (file)
index 0000000..fb2341f
--- /dev/null
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+public class PolitoVpnExit extends NetworkObject {
+
+       List<BoolExpr> constraints = new ArrayList<BoolExpr>();
+       DatatypeExpr politoVpnExit;
+       FuncDecl private_addr_func;
+       NetContext nctx;
+       Context ctx;
+       Network net;
+
+       public PolitoVpnExit(Context ctx, Object[]... args) {
+               super(ctx, args);
+       }
+
+       @Override
+       public DatatypeExpr getZ3Node() {
+               return politoVpnExit;
+       }
+
+       @Override
+       protected void init(Context ctx, Object[]... args) {
+               this.ctx = ctx;
+               this.isEndHost = false;
+               this.politoVpnExit = this.z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+               this.net = (Network)args[0][1];
+        this.nctx = (NetContext)args[0][2];
+       }
+
+       @Override
+       protected void addConstraints(Solver solver) {
+               BoolExpr[] constr = new BoolExpr[constraints.size()];
+           solver.add(constraints.toArray(constr));
+       }
+
+       public void vpnAccessModel(DatatypeExpr vpnAccessIp, DatatypeExpr vpnExitIp) {
+               Expr x = ctx.mkConst("vpn_x", nctx.node);
+               Expr y = ctx.mkConst("vpn_y", nctx.node);
+
+               Expr p_0 = ctx.mkConst("vpn_p_0", nctx.packet);
+               Expr p_1 = ctx.mkConst("vpn_p_1", nctx.packet);
+
+               IntExpr t_0 = ctx.mkIntConst("vpn_t_0");
+               IntExpr t_1 = ctx.mkIntConst("vpn_t_1");
+
+               private_addr_func = ctx.mkFuncDecl("vpn_private_addr_func", nctx.address, ctx.mkBoolSort());
+
+               BoolExpr constraint1 = ctx.mkForall(new Expr[]{t_0, p_0, x},
+                               ctx.mkImplies(ctx.mkAnd(
+                                                                         (BoolExpr)nctx.send.apply(politoVpnExit, x, p_0, t_0),
+                                                                         ctx.mkEq(nctx.pf.get("inner_src").apply(p_0), nctx.am.get("null"))),
+                                                         ctx.mkAnd(
+                                                                         (BoolExpr)private_addr_func.apply(nctx.pf.get("src").apply(p_0)),
+                                                                         ctx.mkNot((BoolExpr)nctx.pf.get("encrypted").apply(p_0)),
+                                                                         ctx.mkExists(new Expr[]{y, p_1, t_1},
+                                                                                         ctx.mkAnd((BoolExpr)nctx.recv.apply(y, politoVpnExit, p_1, t_1),
+                                                                                                           ctx.mkLt(t_1, t_0),
+                                                                                                           (BoolExpr)nctx.pf.get("encrypted").apply(p_1),
+                                                                                                           ctx.mkEq(nctx.pf.get("src").apply(p_1), vpnAccessIp),
+                                                                                                           ctx.mkEq(nctx.pf.get("dest").apply(p_1), vpnExitIp),
+                                                                                                           ctx.mkEq(nctx.pf.get("inner_src").apply(p_1), nctx.pf.get("src").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("inner_dest").apply(p_1), nctx.pf.get("dest").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("origin").apply(p_1), nctx.pf.get("origin").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("orig_body").apply(p_1), nctx.pf.get("orig_body").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("body").apply(p_1), nctx.pf.get("body").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("seq").apply(p_1), nctx.pf.get("seq").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("proto").apply(p_1), nctx.pf.get("proto").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1), nctx.pf.get("emailFrom").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("url").apply(p_1), nctx.pf.get("url").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("options").apply(p_1), nctx.pf.get("options").apply(p_0))), 1, null, null, null, null))),
+                       1,null,null,null,null);
+
+               constraints.add(constraint1);
+
+               BoolExpr constraint2 = ctx.mkForall(new Expr[]{t_0, p_0, x},
+                               ctx.mkImplies(ctx.mkAnd(
+                                                                         (BoolExpr)nctx.send.apply(politoVpnExit, x, p_0, t_0),
+                                                                         ctx.mkNot(ctx.mkEq(nctx.pf.get("inner_src").apply(p_0), nctx.am.get("null")))),
+                                                         ctx.mkAnd(
+                                                                         ctx.mkEq(nctx.pf.get("src").apply(p_0), vpnExitIp),
+                                                                         ctx.mkEq(nctx.pf.get("dest").apply(p_0), vpnAccessIp),
+                                                                         (BoolExpr)private_addr_func.apply(nctx.pf.get("dest").apply(p_0)),
+                                                                         ctx.mkNot(ctx.mkEq(nctx.pf.get("inner_dest").apply(p_1), vpnExitIp)),
+                                                                         (BoolExpr)nctx.pf.get("encrypted").apply(p_0),
+                                                                         ctx.mkExists(new Expr[]{y, p_1, t_1},
+                                                                                         ctx.mkAnd((BoolExpr)nctx.recv.apply(y, politoVpnExit, p_1, t_1),
+                                                                                                           ctx.mkLt(t_1, t_0),
+                                                                                                           ctx.mkNot((BoolExpr)nctx.pf.get("encrypted").apply(p_1)),
+                                                                                                           ctx.mkEq(nctx.pf.get("src").apply(p_1), nctx.pf.get("inner_src").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("dest").apply(p_1), nctx.pf.get("inner_dest").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("inner_src").apply(p_1), nctx.am.get("null")),
+                                                                                                           ctx.mkEq(nctx.pf.get("inner_dest").apply(p_1), nctx.am.get("null")),
+                                                                                                           ctx.mkEq(nctx.pf.get("origin").apply(p_1), nctx.pf.get("origin").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("orig_body").apply(p_1), nctx.pf.get("orig_body").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("body").apply(p_1), nctx.pf.get("body").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("seq").apply(p_1), nctx.pf.get("seq").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("proto").apply(p_1), nctx.pf.get("proto").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1), nctx.pf.get("emailFrom").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("url").apply(p_1), nctx.pf.get("url").apply(p_0)),
+                                                                                                           ctx.mkEq(nctx.pf.get("options").apply(p_1), nctx.pf.get("options").apply(p_0))), 1, null, null, null, null))),
+                               1,null,null,null,null);
+
+               constraints.add(constraint2);
+       }
+
+       public void setInternalAddress(ArrayList<DatatypeExpr> internalAddress){
+       List<BoolExpr> constr = new ArrayList<BoolExpr>();
+       Expr n_0 = ctx.mkConst("vpn_node", nctx.address);
+
+       for(DatatypeExpr n : internalAddress){
+               constr.add(ctx.mkEq(n_0,n));
+       }
+       BoolExpr[] constrs = new BoolExpr[constr.size()];
+       //Constraint            private_addr_func(n_0) == or(n_0==n foreach internal address)
+       constraints.add(ctx.mkForall(new Expr[]{n_0}, ctx.mkEq(private_addr_func.apply(n_0),ctx.mkOr(constr.toArray(constrs))),1,null,null,null,null));
+    }
+
+}
\ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoWebClient.java b/verigraph/service/src/mcnet/netobjs/PolitoWebClient.java
new file mode 100644 (file)
index 0000000..28e2cf2
--- /dev/null
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+/**
+ * WebClient
+ */
+public class PolitoWebClient extends NetworkObject{
+
+               List<BoolExpr> constraints;
+               Context ctx;
+               DatatypeExpr politoWebClient;
+               Network net;
+               NetContext nctx;
+               FuncDecl isInBlacklist;
+
+               public PolitoWebClient(Context ctx, Object[]... args) {
+                       super(ctx, args);
+               }
+
+               @Override
+               protected void init(Context ctx, Object[]... args) {
+                       this.ctx = ctx;
+                   isEndHost=true;
+                       constraints = new ArrayList<BoolExpr>();
+                       z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+                       politoWebClient = z3Node;
+                       net = (Network)args[0][1];
+                       nctx = (NetContext)args[0][2];
+                       DatatypeExpr ipServer = (DatatypeExpr) args[0][3];
+                       webClientRules(ipServer);
+                       //net.saneSend(this);
+           }
+
+               @Override
+               public DatatypeExpr getZ3Node() {
+                       return politoWebClient;
+               }
+
+               @Override
+               protected void addConstraints(Solver solver) {
+//                     System.out.println("[MailClient] Installing rules.");
+                       BoolExpr[] constr = new BoolExpr[constraints.size()];
+                       solver.add(constraints.toArray(constr));
+               }
+
+           private void webClientRules (DatatypeExpr ipServer){
+               Expr n_0 = ctx.mkConst("PolitoWebClient_"+politoWebClient+"_n_0", nctx.node);
+               Expr p_0 = ctx.mkConst("PolitoWebClient_"+politoWebClient+"_p_0", nctx.packet);
+               IntExpr t_0 = ctx.mkIntConst("PolitoWebClient_"+politoWebClient+"_t_0");
+
+               //Constraint1           send(politoWebClient, n_0, p, t_0) -> nodeHasAddr(politoWebClient,p.src)
+                       constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoWebClient, n_0, p_0, t_0),
+                               (BoolExpr)nctx.nodeHasAddr.apply(politoWebClient,nctx.pf.get("src").apply(p_0))),1,null,null,null,null));
+
+                       //Constraint2           send(politoWebClient, n_0, p, t_0) -> p.origin == politoWebClient
+                       constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoWebClient, n_0, p_0, t_0),
+                               ctx.mkEq(nctx.pf.get("origin").apply(p_0),politoWebClient)),1,null,null,null,null));
+
+                       //Constraint3           send(politoWebClient, n_0, p, t_0) -> p.orig_body == p.body
+                       constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoWebClient, n_0, p_0, t_0),
+                               ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),1,null,null,null,null));
+
+                       //Constraint4           recv(n_0, politoWebClient, p, t_0) -> nodeHasAddr(politoWebClient,p.dest)
+                       constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0,politoWebClient, p_0, t_0),
+                               (BoolExpr)nctx.nodeHasAddr.apply(politoWebClient,nctx.pf.get("dest").apply(p_0))),1,null,null,null,null));
+
+
+                       //Constraint5           This client is only able to produce HTTP requests
+                       //                                      send(politoWebClient, n_0, p, t_0) -> p.proto == HTTP_REQ
+            constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoWebClient, n_0, p_0, t_0),
+                        ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_REQUEST))),1,null,null,null,null));
+
+            //Constraint6              send(politoWebClient, n_0, p, t_0) -> p.dest == ipServer
+            constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(politoWebClient, n_0, p_0, t_0),
+                            ctx.mkEq(nctx.pf.get("dest").apply(p_0), ipServer)),1,null,null,null,null));
+           }
+       }
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoWebServer.java b/verigraph/service/src/mcnet/netobjs/PolitoWebServer.java
new file mode 100644 (file)
index 0000000..54710d9
--- /dev/null
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+/**
+ * WebServer object
+ *
+ */
+public class PolitoWebServer extends NetworkObject{
+
+               List<BoolExpr> constraints;
+               Context ctx;
+               DatatypeExpr node;
+               Network net;
+               NetContext nctx;
+               FuncDecl isInBlacklist;
+
+               public PolitoWebServer(Context ctx, Object[]... args) {
+                       super(ctx, args);
+               }
+
+               @Override
+               protected void init(Context ctx, Object[]... args) {
+                       this.ctx = ctx;
+                   isEndHost=true;
+                       constraints = new ArrayList<BoolExpr>();
+               z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+               node = z3Node;
+               net = (Network)args[0][1];
+               nctx = (NetContext)args[0][2];
+               webServerRules();
+           }
+
+               @Override
+               public DatatypeExpr getZ3Node() {
+                       return node;
+               }
+
+               @Override
+               protected void addConstraints(Solver solver) {
+                               BoolExpr[] constr = new BoolExpr[constraints.size()];
+                           solver.add(constraints.toArray(constr));
+               }
+
+           private void webServerRules (){
+               Expr n_0 = ctx.mkConst("webserver_"+node+"_n_0", nctx.node);
+               Expr p_0 = ctx.mkConst("webserver_"+node+"_p_0", nctx.packet);
+               Expr p_1 = ctx.mkConst("webserver_"+node+"_p_1", nctx.packet);
+               IntExpr t_0 = ctx.mkIntConst("webserver_"+node+"_t_0");
+               IntExpr t_1 = ctx.mkIntConst("webserver_"+node+"_t_1");
+
+               //Constraint1           send(politoWebServer, n_0, p, t_0) -> nodeHasAddr(politoWebServer,p.src)
+               constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(node, n_0, p_0, t_0),
+                               (BoolExpr)nctx.nodeHasAddr.apply(node,nctx.pf.get("src").apply(p_0))),1,null,null,null,null));
+
+               //Constraint2           send(politoWebServer, n_0, p, t_0) -> p.origin == politoWebServer
+               constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(node, n_0, p_0, t_0),
+                               ctx.mkEq(nctx.pf.get("origin").apply(p_0),node)),1,null,null,null,null));
+
+               //Constraint3           send(politoWebServer, n_0, p, t_0) -> p.orig_body == p.body
+               constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(node, n_0, p_0, t_0),
+                               ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),
+                    1,null,null,null,null));
+
+               //Constraint4           recv(n_0, politoWebServer, p, t_0) -> nodeHasAddr(politoWebServer,p.dest)
+               constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0,node, p_0, t_0),
+                               (BoolExpr)nctx.nodeHasAddr.apply(node,nctx.pf.get("dest").apply(p_0))),1,null,null,null,null));
+
+               //Constraint5
+                       //                              send(politoWebServer, n_0, p, t_0)  ->
+                       //                              (exist p_1,t_1 :
+                       //                              (t_1 < t_0 && recv(n_0, politoWebServer, p_1, t_1) &&
+                       //                              p_0.proto == HTTP_RESP &&  p_1.proto == HTTP_REQ &&
+                       //                              p_0.dest == p_1.src && p_0.src == p_1.dest &&  p_0.url == p_1.url)
+               constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+                    ctx.mkImplies((BoolExpr)nctx.send.apply(node, n_0, p_0, t_0),
+                        ctx.mkExists(new Expr[]{p_1, t_1},
+                            ctx.mkAnd(
+                                       ctx.mkLt(t_1, t_0),
+                                       ctx.mkEq(nctx.pf.get("url").apply(p_0), nctx.pf.get("url").apply(p_1)),
+                                       (BoolExpr)nctx.recv.apply(n_0, node, p_1, t_1),
+                                       ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_RESPONSE)),
+                                       ctx.mkEq(nctx.pf.get("proto").apply(p_1), ctx.mkInt(nctx.HTTP_REQUEST)),
+                                       ctx.mkEq(nctx.pf.get("dest").apply(p_0), nctx.pf.get("src").apply(p_1)),
+                                       ctx.mkEq(nctx.pf.get("src").apply(p_0), nctx.pf.get("dest").apply(p_1))),
+                            1,null,null,null,null)),1,null,null,null,null));
+           }
+}
diff --git a/verigraph/service/src/tests/j-verigraph-generator/README.rst b/verigraph/service/src/tests/j-verigraph-generator/README.rst
new file mode 100644 (file)
index 0000000..c796af7
--- /dev/null
@@ -0,0 +1,54 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+
+CODE\_GENERATOR Java serializer and formatter
+
+UTILITY Contains utility methods used by other modules
+
+JSON\_GENERATOR Interactive module to generate the configuration files
+(default names are "chains.json" and "config.json") "chains.json"
+describes all the chains of nodes belonging to a certain scenario
+
+TEST\_CLASS\_GENERATOR Generates one or multiple test scenarios given
+the two configuration files above (default names are "chains.json" and
+"config.json") All the test scenarios have to be placed in the examples
+folder (i. e. under "j-verigraph/service/src/tests/examples"). Here is
+the script help:
+
+test\_class\_generator.py -c -f -o
+
+Supposing the module gets executed from the project root directory (i.e.
+"j-verigraph"), a sample command is the following:
+
+service/src/tests/j-verigraph-generator/test\_class\_generator.py -c
+"service/src/tests/j-verigraph-generator/examples/budapest/chains.json"
+-f
+"service/src/tests/j-verigraph-generator/examples/budapest/config.json"
+-o "service/src/tests/examples/Scenario"
+
+Keep in mind that in the previous command "Scenario" represents a prefix
+which will be followed by an underscore and an incremental number
+starting from 1, which represents the n-th scenario starting from the
+previously mentioned "chains.json" file (this file can indeed contain
+multiple chains).
+
+TEST\_GENERATOR Generates a file which performs the verification test
+through Z3 (theorem prover from Microsoft Research) given a certain
+scenario generated with the above snippet. All the test modules have to
+be placed under the "tests" directory (i.e. under
+"j-verigraph/service/src/tests"). Here is the module help:
+
+test\_generator.py -i -o -s -d
+
+Supposing the module gets executed from the project root directory (i.e.
+"j-verigraph") a sample command given the previously generated scenario
+is the following:
+
+service/src/tests/j-verigraph-generator/test\_generator.py -i
+service/src/tests/examples/Scenario\_1.java -o
+service/src/tests/Test.java -s user1 -d webserver
+
+The aforementioned "Test.java" file can be compiled and executed
+normally. Its output will be either "SAT" or "UNSAT". For possible
+statistics the test is repeated 10 times and the average execution time
+in seconds is printed to the console.
diff --git a/verigraph/service/src/tests/j-verigraph-generator/__init__.py b/verigraph/service/src/tests/j-verigraph-generator/__init__.py
new file mode 100644 (file)
index 0000000..d8a620f
--- /dev/null
@@ -0,0 +1,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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
diff --git a/verigraph/service/src/tests/j-verigraph-generator/batch_generator.py b/verigraph/service/src/tests/j-verigraph-generator/batch_generator.py
new file mode 100644 (file)
index 0000000..517bdf7
--- /dev/null
@@ -0,0 +1,186 @@
+#!/usr/bin/python
+
+##############################################################################
+# 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import json
+from pprint import pprint
+import sys, getopt
+import commands
+import os
+from config import *
+from utility import *
+import subprocess
+
+#global variables
+chains = {}
+chains["chains"] = []
+routing = {}
+routing["routing_table"] = []
+configuration = {}
+configuration["nodes"] = []
+#end of global variables
+
+
+#generates json file describing the chains (default chains.json)
+def generate_chains(curr_dir, multiplier, flowspace):
+    filename = "chains.json"
+
+    multiplier = int(multiplier)
+    number_of_chains = multiplier*multiplier
+    for i in range(0, int(number_of_chains)):
+        chains["chains"].insert(i, {})
+        chains["chains"][i]["id"] = i+1
+        chains["chains"][i]["flowspace"] = flowspace
+        chain_nodes = multiplier
+        chains["chains"][i]["nodes"] = []
+        #set attributes for nth client
+        chains["chains"][i]["nodes"].insert(0, {})
+        node_name = "client_" + str((i%multiplier)+1)
+        chains["chains"][i]["nodes"][0]["name"] = node_name
+        node_type = "web_client"
+        chains["chains"][i]["nodes"][0]["functional_type"] = node_type
+        node_address = "ip_web_client_" + str((i%multiplier)+1)
+        chains["chains"][i]["nodes"][0]["address"] = node_address
+        #set attributes for chain of firewalls
+        for j in range(1, chain_nodes+1):
+            chains["chains"][i]["nodes"].insert(j, {})
+            node_name = "firewall_" + str(j)
+            chains["chains"][i]["nodes"][j]["name"] = node_name
+            node_type = "firewall"
+            chains["chains"][i]["nodes"][j]["functional_type"] = node_type
+            node_address = "ip_firewall_" + str(j)
+            chains["chains"][i]["nodes"][j]["address"] = node_address
+        #set attributes for nth web server
+        chains["chains"][i]["nodes"].insert(chain_nodes+1, {})
+        node_name = "server_" + str((i%multiplier)+1)
+        chains["chains"][i]["nodes"][chain_nodes+1]["name"] = node_name
+        node_type = "web_server"
+        chains["chains"][i]["nodes"][chain_nodes+1]["functional_type"] = node_type
+        node_address = "ip_web_server_" + str((i%multiplier)+1)
+        chains["chains"][i]["nodes"][chain_nodes+1]["address"] = node_address
+    #pprint(chains)
+    with smart_open(curr_dir + "/" + filename) as f:
+        print >>f, json.dumps(chains)
+    return filename
+
+#generates json file describing the node configurations (default config.json)
+def generate_config(curr_dir):
+    chains_file = "chains.json"
+
+    chains = parse_chains(curr_dir + "/" + chains_file)
+
+    print "Chains read from file:"
+    pprint(chains)
+    chains_id = []
+
+    for chain_id, chain in chains.items():
+        chains_id.append(chain_id)
+        print "Chain #" +  str(chain_id) + " has " + str(len(chain)) + " elements"
+        for node_name in chain.keys():
+            print node_name + " ",
+        print ""
+
+
+    filename = "config.json"
+
+    config_names = []
+
+    i = -1
+
+    for number_of_chain in chains_id:
+        number_of_nodes = len(chains[number_of_chain].keys())
+
+    #     for i in range(0, number_of_nodes):
+
+        for node_name, node_map in chains[number_of_chain].items():
+            if node_name in config_names:
+                continue
+            config_names.append(node_name)
+            i += 1
+            configuration["nodes"].insert(i, {})
+    #         node_id = raw_input("Node #" + str(i+1) + " id? -->")
+    #         configuration["nodes"][i]["id"] = node_id
+            configuration["nodes"][i]["id"] = node_name
+
+            name_split = node_name.split("_")
+
+            #init = raw_input("Any parameter for inizialization of node " + node_name + "? (N/Y)-->")
+            init_list = devices_initialization[node_map["functional_type"]]
+            if init_list != []:
+                for init_item in init_list:
+                    init_param = "ip_" + init_item + "_" + name_split[1]
+                    configuration["nodes"][i][init_item] = init_param
+
+            node_description = name_split[0] + " denies any traffic from web_client #" + name_split[1] + " to web_server #" + name_split[1]
+            configuration["nodes"][i]["description"] = node_description
+            while(True):
+                #node_configuration_type = raw_input("Node " + node_id +"'s configuration type (list, maps)? (L/M) -->")
+                #n = search_node_in_chains(node_id)
+
+                node_configuration_type = devices_configuration_methods[node_map["functional_type"]]
+                if node_configuration_type == "list":
+                    #list
+                    configuration["nodes"][i]["configuration"] = []
+
+                    break
+                if node_configuration_type == "maps":
+                    #maps
+                    configuration["nodes"][i]["configuration"] = []
+                    n_entries = 1
+
+                    for m in range(0, n_entries):
+                        configuration["nodes"][i]["configuration"].insert(m, {})
+
+                        map_elements = 1
+
+                        for n in range(0, map_elements):
+                            key = "ip_web_server_" + name_split[1]
+                            value = "ip_web_client_" + name_split[1]
+                            configuration["nodes"][i]["configuration"][m][key] = value
+                    break
+                else:
+                    print "Invalid config, please edit the config file"
+        #pprint(configuration)
+        with smart_open(curr_dir + "/" + filename) as f:
+            print >>f, json.dumps(configuration)
+    return filename
+
+def main(argv):
+    #exit if any command line argument is missing
+    if len(argv) < 4:
+        print 'batch_generator.py -m <multiplier> -o <output_directory>'
+        sys.exit(2)
+     #initialize json file names
+    chains_file = ''
+    configuration_file = ''
+    output_dir = ''
+    multiplier = ''
+    #parse command line arguments and exit if there is an error
+    try:
+        opts, args = getopt.getopt(argv,"hm:o:",["mutliplier=","help","odir="])
+    except getopt.GetoptError as err:
+        print str(err)
+        print 'batch_generator.py -m <multiplier> -o <output_directory>'
+        sys.exit(2)
+    for opt, arg in opts:
+        if opt in ("-h", "--help"):
+            print 'batch_generator.py -m <multiplier> -o <output_directory>'
+            sys.exit()
+        elif opt in ("-o", "--output"):
+            output_dir = arg
+        elif opt in ("-m", "--multiplier"):
+            multiplier = arg
+
+    generate_chains(output_dir, multiplier, "tcp=80")
+    generate_config(output_dir)
+
+
+if __name__ == "__main__":
+    main(sys.argv[1:])
diff --git a/verigraph/service/src/tests/j-verigraph-generator/code_generator.py b/verigraph/service/src/tests/j-verigraph-generator/code_generator.py
new file mode 100644 (file)
index 0000000..5b9834f
--- /dev/null
@@ -0,0 +1,59 @@
+#!/usr/bin/python
+
+##############################################################################
+# 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import sys, string
+
+class CodeGeneratorBackend:
+
+    def begin(self, tab="\t"):
+        self.code = []
+        self.tab = tab
+        self.level = 0
+
+    def end(self):
+        return string.join(self.code, "")
+
+    def write(self, string):
+        self.code.append(self.tab * self.level + string)
+
+    def writeln(self, string):
+        self.code.append(self.tab * self.level + string + "\n")
+
+    def append(self, string):
+        self.code.append(string)
+
+    def indent(self):
+        self.level = self.level + 1
+
+    def dedent(self):
+        if self.level == 0:
+            raise SyntaxError, "internal error in code generator"
+        self.level = self.level - 1
+
+    def write_list(self, data, delimiter=True, wrapper="'"):
+        if delimiter == True:
+            self.code.append("{")
+        first = True
+        for element in data:
+            if (first == False):
+                self.code.append(", ")
+            else:
+                first = False
+            if wrapper == "'":
+                self.code.append("'" + str(element) + "'")
+            elif wrapper == "\"":
+                self.code.append("\"" + str(element) + "\"")
+            elif wrapper == "b":
+                self.code.append("(" + str(element) + ")")
+            else:
+                self.code.append(str(element))
+        if delimiter == True:
+            self.code.append("}")
diff --git a/verigraph/service/src/tests/j-verigraph-generator/config.py b/verigraph/service/src/tests/j-verigraph-generator/config.py
new file mode 100644 (file)
index 0000000..3fe5d6c
--- /dev/null
@@ -0,0 +1,88 @@
+#!/usr/bin/python
+
+##############################################################################
+# 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+devices_to_classes = {  "webclient" : "PolitoWebClient",
+                        "webserver" : "PolitoWebServer",
+                        "cache" : "PolitoCache",
+                        "nat" : "PolitoNat",
+                        "firewall" : "AclFirewall",
+                        "mailclient" : "PolitoMailClient",
+                        "mailserver" : "PolitoMailServer",
+                        "antispam" : "PolitoAntispam",
+                        "endpoint": "EndHost",
+                        "dpi": "PolitoIDS",
+                        "endhost": "PolitoEndHost",
+                        "vpnaccess":"PolitoVpnAccess",
+                        "vpnexit":"PolitoVpnExit",
+                        "fieldmodifier":"PolitoFieldModifier"
+                     }
+devices_to_configuration_methods = {"webclient" : "",
+                                    "webserver" : "",
+                                    "cache" : "installCache",
+                                    "nat" : "setInternalAddress",
+                                    "firewall" : "addAcls",
+                                    "mailclient" : "",
+                                    "mailserver" : "",
+                                    "antispam" : "",
+                                    "endpoint": "",
+                                    "dpi": "installIDS",
+                                    "endhost": "installEndHost",
+                                    "vpnaccess":"vpnAccessModel",
+                                    "vpnexit":"vpnAccessModel",
+                                    "fieldmodifier":"installFieldModifier"
+                                    }
+devices_initialization = {  "webclient" : ["webserver"],
+                            "webserver" : [],
+                            "cache" : [],
+                            "nat" : [],
+                            "firewall" : [],
+                            "mailclient" : ["mailserver"],
+                            "mailserver" : [],
+                            "antispam" : [],
+                            "endpoint": [],
+                            "dpi":[] ,
+                            "endhost":[],
+                            "vpnaccess":[],
+                            "vpnexit":[],
+                            "fieldmodifier":[]
+                          }
+
+convert_configuration_property_to_ip = {    "webclient" : ["value"],
+                                            "webserver" : [],
+                                            "cache" : ["value"],
+                                            "nat" : ["value"],
+                                            "firewall" : ["key", "value"],
+                                            "mailclient" : ["value"],
+                                            "mailserver" : [],
+                                            "antispam" : [],
+                                            "endpoint": [],
+                                            "dpi": [],
+                                            "endhost": [],
+                                            "vpnaccess": ["value"],
+                                            "vpnexit": ["value"],
+                                            "fieldmodifier": []
+                                        }
+
+devices_configuration_fields = {    "webclient" : "",
+                                    "webserver" : "",
+                                    "cache" : "cached address",
+                                    "nat" : "natted address",
+                                    "firewall" : "acl entry",
+                                    "mailclient" : "",
+                                    "mailserver" : "",
+                                    "antispam" : "",
+                                    "endpoint": "",
+                                    "dpi":"words blacklist",
+                                    "endhost":"",
+                                    "vpnaccess":"vpn access",
+                                    "vpnexit":"vpn exit",
+                                    "fieldmodifier":"field modifier"
+                                 }
diff --git a/verigraph/service/src/tests/j-verigraph-generator/json_generator.py b/verigraph/service/src/tests/j-verigraph-generator/json_generator.py
new file mode 100644 (file)
index 0000000..d65ea43
--- /dev/null
@@ -0,0 +1,261 @@
+#!/usr/bin/python
+
+##############################################################################
+# 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import json
+from pprint import pprint
+import sys
+import commands
+import os
+from config import *
+from utility import *
+import batch_generator
+import subprocess
+
+#global variables
+chains = {}
+chains["chains"] = []
+routing = {}
+routing["routing_table"] = []
+configuration = {}
+configuration["nodes"] = []
+#end of global variables
+
+
+
+#generates json file describing the chains (default chains.json)
+def generate_chains(curr_dir):
+    filename = "chains.json"
+    fn = raw_input("Please enter a file name for the json file describing the nodes chains (default \"chains.json\") -->")
+    if fn != "":
+        filename = fn
+
+    number_of_chains = check_input_is_int("Please enter the number of chains you wish to simulate: -->")
+    for i in range(0, int(number_of_chains)):
+        chains["chains"].insert(i, {})
+        #decomment the following 2 lines to make chain id an arbitrary integer
+        #chain_id = check_input_is_int("Chain #" + str(i+1) + " id? -->")
+        #chains["chains"][i]["id"] = chain_id
+        chains["chains"][i]["id"] = i+1
+        flowspace = raw_input("Chain #" + str(i+1) + " flowspace? -->")
+        chains["chains"][i]["flowspace"] = flowspace
+        chain_nodes = check_input_is_int("How many nodes does the chain #" + str(i+1) + " have? -->")
+        chains["chains"][i]["nodes"] = []
+        for j in range(0, chain_nodes):
+            chains["chains"][i]["nodes"].insert(j, {})
+            node_name = raw_input("Node #" + str(j+1) + " name? -->")
+            chains["chains"][i]["nodes"][j]["name"] = node_name
+            print "Available functional types are:"
+            for device in devices_to_classes.keys():
+                print device + " ",
+            while True:
+                node_type = raw_input("Node #" + str(j+1) + " functional_type (see valid options above)? -->")
+                if node_type in devices_to_classes.keys():
+                    break
+            chains["chains"][i]["nodes"][j]["functional_type"] = node_type
+            node_address = raw_input("Node #" + str(j+1) + " address? -->")
+            chains["chains"][i]["nodes"][j]["address"] = node_address
+    #pprint(chains)
+    with smart_open(curr_dir + "/" + filename) as f:
+        print >>f, json.dumps(chains)
+    return filename
+
+#generates json file describing the node configurations (default config.json)
+def generate_config(curr_dir):
+    chains_file = "chains.json"
+    while True:
+        list_files(curr_dir)
+        fn = raw_input("Please enter the file name of the json file containing the chains (default \"chains.json\") -->")
+        if fn != "":
+            chains_file = fn
+        try:
+            chains = parse_chains(curr_dir + "/" + chains_file)
+        except:
+            print "Chains file is not valid"
+            continue
+        break
+    print "Chains read from file:"
+    pprint(chains)
+    chains_id = []
+
+    for chain_id, chain in chains.items():
+        chains_id.append(chain_id)
+        print "Chain #" +  str(chain_id) + " has " + str(len(chain)) + " elements"
+        for node_name in chain.keys():
+            print node_name + " ",
+        print ""
+
+    while True:
+        number_of_chain = check_input_is_int("Please enter the number of the chain you wish to configure: -->")
+        if number_of_chain in chains_id:
+            break
+        else:
+            print "Please enter a valid chain id (see options above)"
+
+    filename = "config.json"
+    fn = raw_input("Please enter a file name for the json file describing the nodes configuration (default \"config.json\") -->")
+    if fn != "":
+        filename = fn
+
+    number_of_nodes = len(chains[number_of_chain].keys())
+
+#     for i in range(0, number_of_nodes):
+    i = -1
+    for node_name, node_map in chains[number_of_chain].items():
+        i += 1
+        configuration["nodes"].insert(i, {})
+#         node_id = raw_input("Node #" + str(i+1) + " id? -->")
+#         configuration["nodes"][i]["id"] = node_id
+        configuration["nodes"][i]["id"] = node_name
+        #init = raw_input("Any parameter for inizialization of node " + node_name + "? (N/Y)-->")
+        init_list = devices_initialization[node_map["functional_type"]]
+        if init_list != []:
+            for init_item in init_list:
+                init_param = raw_input("Please enter the IP address of parameter \"" + init_item + "\" for node " + node_name + ": -->")
+                configuration["nodes"][i][init_item] = init_param
+
+        node_description = raw_input("Node " + node_name +"'s configuration description? -->")
+        configuration["nodes"][i]["description"] = node_description
+        while(True):
+            #node_configuration_type = raw_input("Node " + node_id +"'s configuration type (list, maps)? (L/M) -->")
+            #n = search_node_in_chains(node_id)
+
+            node_configuration_type = devices_configuration_methods[node_map["functional_type"]]
+            if node_configuration_type == "list":
+                #list
+                configuration["nodes"][i]["configuration"] = []
+                config_elements = check_input_is_int("How many configuration elements for node " + node_name + "? (type 0 to skip configuration) -->")
+                for e in range(0, config_elements):
+                    element = raw_input("\tPlease enter " + devices_configuration_fields[node_map["functional_type"]] + "#" + str(e+1) + " -->")
+                    configuration["nodes"][i]["configuration"].append(element)
+                break
+            elif node_configuration_type == "maps":
+                #maps
+                configuration["nodes"][i]["configuration"] = []
+                n_entries = check_input_is_int("How many maps for the configuration of node " + node_name + "? (type 0 to skip configuration) -->")
+
+                for m in range(0, n_entries):
+                    configuration["nodes"][i]["configuration"].insert(m, {})
+
+                    map_elements = check_input_is_int("How many elements for map #" + str(m+1) + "? -->")
+
+                    for n in range(0, map_elements):
+                        key = raw_input("\tKey for " + devices_configuration_fields[node_map["functional_type"]] + "#" + str(n+1) + ": -->")
+                        value = raw_input("\tValue for " + devices_configuration_fields[node_map["functional_type"]] + "#" + str(n+1) + ": -->")
+                        configuration["nodes"][i]["configuration"][m][key] = value
+                break
+            else:
+                print "Invalid config, please edit the config file"
+    #pprint(configuration)
+    with smart_open(curr_dir + "/" + filename) as f:
+        print >>f, json.dumps(configuration)
+    return filename
+
+
+def main():
+
+    chains_file = ""
+    configuration_file = ""
+    routing_file = ""
+    curr_dir = os.getcwd()
+    current_path = curr_dir
+
+    set_dir = raw_input("Change working directory? (" + curr_dir + ") (N/Y) -->")
+    if set_dir == "Y" or set_dir == "y":
+        print "List of subdirectories:"
+        print list_directories(curr_dir)
+        while True:
+            curr_dir = os.path.abspath(raw_input("Enter working path (relative or absolute path are supported) -->"))
+            if os.path.exists(curr_dir):
+                current_path = curr_dir
+                break
+            else:
+                print "Please enter a valid path!"
+
+    directory = raw_input("Do you want to create a new test directory? (N/Y) -->")
+    if directory == "Y" or directory =="y":
+        directory_name = raw_input("Directory name? -->")
+        print commands.getoutput("mkdir -v " + curr_dir + "/" + directory_name)
+        current_path = curr_dir + "/" + directory_name
+
+    print "Files will be created at " + current_path
+
+    firewall_chain = False
+
+    while True:
+        choice = raw_input("""CHAINS?\n
+        Choose one of the following options:\n
+        1) Automatic generation of chains.json and config.json for an N-firewall chain
+        2) Generate step-by-step
+        3) Verify the integrity of an existing json file
+        4) Skip step\n-->""")
+        try:
+            if int(choice) == 1:
+                multiplier = check_input_is_int("Please enter N -->")
+                arguments = ["-m", str(multiplier), "-o", current_path]
+                batch_generator.main(arguments)
+                firewall_chain = True
+                break
+            elif int(choice) == 2:
+                chains_file = generate_chains(current_path)
+                break
+            elif int(choice) == 3:
+                chains_file = raw_input("Input file for CHAINS? -->")
+                if(check_chains_integrity(current_path + "/" + chains_file)) == True:
+                    break
+                else:
+                    print "Input json file for CHAINS not well formed, please try again!"
+            elif int(choice) == 4:
+                break
+            else:
+                print "Invalid choice, please try again!"
+        except ValueError, e:
+            print "Invalid choice, please try again!"
+            continue
+
+    while True:
+
+        if firewall_chain == True:
+            chains_file = "chains.json"
+            configuration_file = "config.json"
+            routing_file = ""
+            break
+
+        choice = raw_input("""CONFIGURATION?\n
+        Choose one of the following options:\n
+        1) Generate step-by-step
+        2) Verify the integrity of an existing json file
+        3) Skip step\n-->""")
+        try:
+            if int(choice) == 1:
+                configuration_file = generate_config(current_path)
+                break
+            elif int(choice) == 2:
+                configuration_file = raw_input("Input file for CONFIGURATION? -->")
+                if(check_config_integrity(current_path + "/" + configuration_file)) == True:
+                    break
+                else:
+                    print "Input json file for CONFIGURATION not well formed, please try again!"
+            elif int(choice) == 3:
+                break
+            else:
+                print "Invalid choice, please try again!"
+        except ValueError, e:
+            print "Invalid choice, please try again!"
+            continue
+
+    print "All done, you are ready to launch the test generator like so:"
+    print "test_class_generator.py -c " + chains_file + " -f " + configuration_file + " -o <output_file>"
+
+    return chains_file, configuration_file, routing_file, current_path
+
+
+if __name__ == "__main__":
+    main()
diff --git a/verigraph/service/src/tests/j-verigraph-generator/routing_generator.py b/verigraph/service/src/tests/j-verigraph-generator/routing_generator.py
new file mode 100644 (file)
index 0000000..c8956f2
--- /dev/null
@@ -0,0 +1,80 @@
+#!/usr/bin/python
+
+##############################################################################
+# 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from pprint import pprint
+import sys, getopt
+import os
+from utility import *
+
+# used by test_class_generator
+def generate_routing_from_chain(chain):
+    routing = {}
+    routing["routing_table"] = {}
+
+    chain = chain["nodes"]
+    for i in range(0, len(chain)):
+        routing["routing_table"][chain[i]["name"]] = {}
+        for j in range(i-1, -1, -1):
+            routing["routing_table"][chain[i]["name"]][chain[j]["address"]] = chain[i-1]["name"]
+        for k in range (i+1, len(chain)):
+            routing["routing_table"][chain[i]["name"]][chain[k]["address"]] = chain[i+1]["name"]
+    pprint(routing)
+    return routing
+
+def generate_routing_from_chains_file(chains_file, chain_number):
+    routing = {}
+    routing["routing_table"] = {}
+
+    chains = convert_unicode_to_ascii(parse_json_file(chains_file))
+    chain = None
+    for chn in chains["chains"]:
+         if chn["id"] == chain_number:
+             chain = chn["nodes"]
+             break
+    if chain == None:
+         return routing
+
+    for i in range(0, len(chain)):
+        routing["routing_table"][chain[i]["name"]] = {}
+        for j in range(i-1, -1, -1):
+            routing["routing_table"][chain[i]["name"]][chain[j]["address"]] = chain[i-1]["name"]
+        for k in range (i+1, len(chain)):
+            routing["routing_table"][chain[i]["name"]][chain[k]["address"]] = chain[i+1]["name"]
+    pprint(routing)
+    return routing
+
+def main(argv):
+    if len(argv) < 4:
+        print 'routing_generator.py -c <chains_file> -n <chain_number>'
+        sys.exit(2)
+    chains_file = ""
+    chain_number = ""
+    try:
+        opts, args = getopt.getopt(argv,"hc:n:",["chains=","id="])
+    except getopt.GetoptError:
+        print 'routing_generator.py -c <chains_file> -n <chain_number>'
+        sys.exit(2)
+    for opt, arg in opts:
+        if opt == '-h':
+            print 'routing_generator.py -c <chains_file> -n <chain_number>'
+            sys.exit()
+        elif opt in ("-c", "--chains"):
+            chains_file = arg
+        elif opt in ("-n", "--id"):
+            chain_number = arg
+
+    print "Chains file is " + chains_file
+    print "Chain id is " + chain_number
+
+    return generate_routing_from_chains_file(chains_file, chain_number)
+
+if __name__ == '__main__':
+    main(sys.argv[1:])
\ No newline at end of file
diff --git a/verigraph/service/src/tests/j-verigraph-generator/test_class_generator.py b/verigraph/service/src/tests/j-verigraph-generator/test_class_generator.py
new file mode 100644 (file)
index 0000000..7bf446c
--- /dev/null
@@ -0,0 +1,399 @@
+#!/usr/bin/python
+
+##############################################################################
+# 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from pprint import pprint
+from pprint import pformat
+import sys, getopt
+from code_generator import CodeGeneratorBackend
+import os, errno
+from config import *
+from utility import *
+from routing_generator import *
+import logging
+from pip._vendor.pkg_resources import null_ns_handler
+
+#generates a custom test file
+def generate_test_file(chain, number, configuration, output_file="test_class"):
+
+    route = {}
+    config = {}
+    chn = {}
+
+    #initiatlize the config dictionary for each node
+    for node in chain["nodes"]:
+        config[node["name"]] = {}
+
+    #initiatlize the route dictionary for each node
+    for node in chain["nodes"]:
+        route[node["name"]] = {}
+
+    #initiatlize the chn dictionary for each node
+    for node in chain["nodes"]:
+        chn[node["name"]] = {}
+
+    #set chn values: chn[name][key] = value
+    for node in chain["nodes"]:
+        for key, value in node.items():
+            try:
+                #name key is redundant in map
+                if key != "name":
+                    chn[node["name"]][key] = value
+            except KeyError, e:
+                logging.debug("Field " + str(key) + " not found for node " + str(node["name"]))
+                logging.debug("Cotinuing...")
+                continue
+
+    #debug print of chn
+    logging.debug(pformat((chn)))
+
+    routing = generate_routing_from_chain(chain)
+
+    for node_name, node_rt in routing["routing_table"].items():
+        route[node_name] = node_rt
+
+    #debug print of route
+    logging.debug(pformat((route)))
+
+    #set config: config[node_name][key] = value
+    for node in configuration["nodes"]:
+        for key, value in node.items():
+            #id field is redundant
+            if key != "id":
+                try:
+                    if key == "configuration":
+                        #init config[node_name][key] with an empty array
+                        config[node["id"]][key] = []
+
+                        for value_item in value:
+                            change_key = "key" in convert_configuration_property_to_ip[chn[node["id"]]["functional_type"]]
+                            change_value = "value" in convert_configuration_property_to_ip[chn[node["id"]]["functional_type"]]
+                            if (change_key==False and change_value==False):
+                                config[node["id"]][key].append(value_item)
+                                continue
+                            # config[node_name][configuration] is a dictionary
+                            if isinstance(value_item, dict):
+                                for config_item_key, config_item_value in value_item.items():
+                                    new_key = config_item_key
+                                    changed_key = False
+                                    changed_value = False
+                                    if change_key and config_item_key in chn.keys():
+                                        changed_key = True
+                                        new_key = "ip_" + str(config_item_key)
+                                        value_item[new_key] = str(config_item_value)
+                                        del value_item[config_item_key]
+                                    if change_value and config_item_value in chn.keys():
+                                        changed_value = True
+                                        new_value = "ip_" + str(config_item_value)
+                                        value_item[new_key] = new_value
+                                    if(change_key==changed_key) and (change_value==changed_value):
+                                        config[node["id"]][key].append(value_item)
+                            else:
+                                if change_value:
+                                    if value_item in chn.keys():
+                                        new_value = "ip_" + str(value_item)
+                                        config[node["id"]][key].append(new_value)
+                                else:
+                                    config[node["id"]][key].append(str(value_item))
+                    else:
+                        config[node["id"]][key] = value
+                except KeyError, e:
+                    #node not found in current chain
+                    logging.debug("Field '" + key + "' not found for node '" + str(node["id"]) + "'")
+                    logging.debug(key + " probably doesn't belong to the current chain, thus it will be skipped")
+                    #sys.exit(1)
+                    continue
+
+    # debug print of config
+    logging.debug(pformat((config)))
+
+    #prepare a few more helpful data structures
+    nodes_names = []
+    nodes_types = []
+    nodes_addresses = []
+    nodes_ip_mappings = []
+    nodes_rt = {}
+
+    #initialize vectors for node names and routing tables
+    for name in chn.keys():
+        nodes_names.append(name)
+        nodes_rt[name] = []
+
+    #add functional types, addresses and ip mapping to vectors
+    for node, field in chn.items():
+        nodes_types.append(field["functional_type"])
+        nodes_addresses.append(field["address"])
+        nodes_ip_mappings.append(field["address"])
+
+    for node, rt in route.items():
+        for dest, next_hop in rt.items():
+            row = "nctx.am.get(\"" + dest + "\"), " + next_hop
+            try:
+                nodes_rt[node].append(row)
+            except KeyError, e:
+                #node not found, notify and exit
+                logging.debug("Node " + node + " not found!")
+                sys.exit(1)
+
+    #begin file generation
+    logging.debug("* instantiating chain #" + str(number))
+    dirname = os.path.dirname(output_file)
+    basename = os.path.basename(output_file)
+    basename = os.path.splitext(basename)[0]
+    basename = basename[0].upper() + basename[1:]
+    with smart_open(dirname + "/" + basename + "_" + str(number) + ".java") as f:
+        c = CodeGeneratorBackend()
+        c.begin(tab="    ")
+
+        c.writeln("package tests.scenarios;")
+
+        #imports here
+        c.writeln("import java.util.ArrayList;")
+        c.writeln("import com.microsoft.z3.Context;")
+        c.writeln("import com.microsoft.z3.DatatypeExpr;")
+
+        c.writeln("import mcnet.components.Checker;")
+        c.writeln("import mcnet.components.NetContext;")
+        c.writeln("import mcnet.components.Network;")
+        c.writeln("import mcnet.components.NetworkObject;")
+        c.writeln("import mcnet.components.Tuple;")
+        c.writeln("import mcnet.netobjs.PacketModel;")
+
+        #import components
+        #for i in range(0, len(nodes_names)):
+        #    c.writeln("import mcnet.netobjs." + devices_to_classes[str(nodes_types[i])] + ";")
+
+        for key, value in devices_to_classes.items():
+            c.writeln("import mcnet.netobjs." + value + ";")
+
+        c.writeln("public class " + basename + "_" + str(number) + "{")
+
+        c.indent()
+        c.writeln("public Checker check;")
+        # declare components
+        for i in range(0, len(nodes_names)):
+            c.writeln("public " + devices_to_classes[str(nodes_types[i])] + " " + str(nodes_names[i]) + ";")
+
+        # method setDevices
+        c.writeln("private void setDevices(Context ctx, NetContext nctx, Network net){")
+        c.indent()
+        for i in range(0, len(nodes_names)):
+            c.write(str(nodes_names[i]) + " = new " + devices_to_classes[str(nodes_types[i])] + "(ctx, new Object[]{nctx.nm.get(\"" + nodes_names[i] + "\"), net, nctx")
+            if devices_initialization[nodes_types[i]] != [] :
+                for param in devices_initialization[nodes_types[i]]:
+                    print "configuring node " + nodes_names[i]
+                    for config_param in config[nodes_names[i]]["configuration"]:
+                        if param in config_param:
+                            c.append(", nctx.am.get(\"" + config_param[param] + "\")")
+            c.append("});\n")
+        c.dedent()
+        c.writeln("}")
+        # end method setDevices
+
+        # method doMappings
+        c.writeln("private void doMappings(NetContext nctx, ArrayList<Tuple<NetworkObject,ArrayList<DatatypeExpr>>> adm){")
+        c.indent()
+        for i in range(0, len(nodes_names)):
+            c.writeln("ArrayList<DatatypeExpr> al" + str(i) + " = new ArrayList<DatatypeExpr>();")
+            c.writeln("al" + str(i) + ".add(nctx.am.get(\"" + nodes_ip_mappings[i] + "\"));")
+            c.writeln("adm.add(new Tuple<>((NetworkObject)" + nodes_names[i] + ", al" + str(i) + "));")
+        c.dedent()
+        c.writeln("}")
+        # end method doMappings
+
+        # for each node methods setRouting and configureDevice
+        for i in range(0, len(nodes_names)):
+            # method setRouting
+            c.writeln("private void setRouting" + nodes_names[i] + "(NetContext nctx, Network net, ArrayList<Tuple<DatatypeExpr,NetworkObject>> rt_" + nodes_names[i] + "){")
+            c.indent()
+            for row in nodes_rt[nodes_names[i]]:
+                c.writeln("rt_" + nodes_names[i] + ".add(new Tuple<DatatypeExpr,NetworkObject>(" + row + "));")
+            c.writeln("net.routingTable(" + nodes_names[i] + ", rt_" + nodes_names[i] + ");")
+            c.dedent()
+            c.writeln("}")
+            # end method setRouting
+            # method configureDevice
+            c.writeln("private void configureDevice" + nodes_names[i] + "(NetContext nctx) {")
+            c.indent()
+            #configure middle-box only if its configuration is not empty
+            if config[nodes_names[i]]["configuration"] != [] :
+                if nodes_types[i] == "cache":
+                    c.write(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(new NetworkObject[]")
+                    cache_ips = config[nodes_names[i]]["configuration"]
+                    cache_hosts = []
+                    for cache_ip in cache_ips:
+                        i = -1
+                        for host in nodes_addresses:
+                            i += 1
+                            if host == cache_ip:
+                                cache_hosts.append(nodes_names[i])
+                    c.write_list(formatted_list_from_list_of_maps(cache_hosts), wrapper="")
+                    c.append(");\n")
+                elif nodes_types[i] == "nat":
+                    c.writeln("ArrayList<DatatypeExpr> ia" + str(i) +" = new ArrayList<DatatypeExpr>();")
+                    config_elements = []
+                    config_elements = formatted_list_from_list_of_maps(config[nodes_names[i]]["configuration"])
+                    for address in config_elements:
+                        c.writeln("ia" + str(i) + ".add(nctx.am.get(\"" + address + "\"));")
+                    c.writeln(nodes_names[i] + ".natModel(nctx.am.get(\"ip_" + nodes_names[i] + "\"));")
+                    c.writeln(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(ia" + str(i) +");")
+                elif nodes_types[i] == "firewall":
+                    c.writeln("ArrayList<Tuple<DatatypeExpr,DatatypeExpr>> acl" + str(i) + " = new ArrayList<Tuple<DatatypeExpr,DatatypeExpr>>();")
+                    for config_element in config[nodes_names[i]]["configuration"]:
+                        if isinstance(config_element,dict):
+                            for key, value in config_element.items():
+                                if key in nodes_addresses and value in nodes_addresses:
+                                    c.writeln("acl" + str(i) + ".add(new Tuple<DatatypeExpr,DatatypeExpr>(nctx.am.get(\"" + key + "\"),nctx.am.get(\"" + value + "\")));")
+                    c.writeln(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(acl" + str(i) + ");")
+                elif nodes_types[i] == "antispam":
+                    c.write(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(new int[]")
+                    c.write_list(formatted_list_from_list_of_maps(config[nodes_names[i]]["configuration"]))
+                    c.append(");\n")
+                elif nodes_types[i] == "dpi":
+                    for index in range(0, len(config[nodes_names[i]]["configuration"])):
+                        config[nodes_names[i]]["configuration"][index] = "String.valueOf(\"" + str(config[nodes_names[i]]["configuration"][index]) + "\").hashCode()"
+                    c.write(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(new int[]")
+                    c.write_list(formatted_list_from_list_of_maps(config[nodes_names[i]]["configuration"]), wrapper="")
+                    c.append(");\n")
+                elif nodes_types[i] == "endhost":
+                    c.writeln("PacketModel pModel" + str(i) + " = new PacketModel();")
+                    if "body" in config[nodes_names[i]]["configuration"][0]:
+                        c.writeln("pModel" + str(i) + ".setBody(String.valueOf(\"" + config[nodes_names[i]]["configuration"][0]["body"] + "\").hashCode());")
+                    if "sequence" in config[nodes_names[i]]["configuration"][0]:
+                        c.writeln("pModel" + str(i) + ".setSeq(" + config[nodes_names[i]]["configuration"][0]["sequence"] + ");")
+                    if "protocol" in config[nodes_names[i]]["configuration"][0]:
+                        c.writeln("pModel" + str(i) + ".setProto(nctx." + config[nodes_names[i]]["configuration"][0]["protocol"] + ");")
+                    if "email_from" in config[nodes_names[i]]["configuration"][0]:
+                        c.writeln("pModel" + str(i) + ".setEmailFrom(String.valueOf(\"" + config[nodes_names[i]]["configuration"][0]["email_from"] + "\").hashCode());")
+                    if "url" in config[nodes_names[i]]["configuration"][0]:
+                        c.writeln("pModel" + str(i) + ".setUrl(String.valueOf(\"" + config[nodes_names[i]]["configuration"][0]["url"] + "\").hashCode());")
+                    if "options" in config[nodes_names[i]]["configuration"][0]:
+                        c.writeln("pModel" + str(i) + ".setOptions(String.valueOf(\"" + config[nodes_names[i]]["configuration"][0]["options"] + "\").hashCode());")
+                    if "destination" in config[nodes_names[i]]["configuration"][0]:
+                        c.writeln("pModel" + str(i) + ".setIp_dest(nctx.am.get(\"" + config[nodes_names[i]]["configuration"][0]["destination"] + "\"));")
+
+                    c.writeln(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(pModel" + str(i) + ");")
+                elif nodes_types[i] == "vpnaccess":
+                    c.writeln(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(nctx.am.get(\"" + nodes_addresses[i] + "\"), nctx.am.get(\"" + config[nodes_names[i]]["configuration"][0]["vpnexit"] + "\"));")
+                elif nodes_types[i] == "vpnexit":
+                    c.writeln(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(nctx.am.get(\"" + config[nodes_names[i]]["configuration"][0]["vpnaccess"] + "\"), nctx.am.get(\"" + nodes_addresses[i] + "\"));")
+
+            # config is empty but configure device anyway
+            elif nodes_types[i] == "fieldmodifier":
+                c.writeln(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "();")
+            c.dedent()
+            c.writeln("}")
+            # end method configureDevice
+
+
+        c.writeln("public " + basename + "_" + str(number) + "(Context ctx){")
+        c.indent()
+        c.write("NetContext nctx = new NetContext (ctx,new String[]")
+        c.write_list(nodes_names, wrapper="\"")
+        c.append(", new String[]")
+        c.write_list(nodes_addresses, wrapper="\"")
+        c.append(");\n")
+        c.writeln("Network net = new Network (ctx,new Object[]{nctx});")
+        # call method setDevices
+        c.writeln("setDevices(ctx, nctx, net);")
+
+        #SET ADDRESS MAPPINGS
+        c.writeln("ArrayList<Tuple<NetworkObject,ArrayList<DatatypeExpr>>> adm = new ArrayList<Tuple<NetworkObject,ArrayList<DatatypeExpr>>>();")
+        # call doMappings
+        c.writeln("doMappings(nctx, adm);")
+        c.writeln("net.setAddressMappings(adm);")
+
+        #CONFIGURE ROUTING TABLE
+        for i in range(0, len(nodes_names)):
+            c.writeln("ArrayList<Tuple<DatatypeExpr,NetworkObject>> rt_" + nodes_names[i] + " = new ArrayList<Tuple<DatatypeExpr,NetworkObject>>(); ")
+            c.writeln("setRouting" + nodes_names[i] + "(nctx, net, rt_" + nodes_names[i] + ");")
+
+        #ATTACH DEVICES
+        c.write("net.attach(")
+        c.write_list(nodes_names, delimiter = False, wrapper="")
+        c.append(");\n")
+
+        #CONFIGURE MIDDLE-BOXES
+        for i in range(0, len(nodes_names)):
+            c.writeln("configureDevice" + nodes_names[i] + "(nctx);")
+
+        c.writeln("check = new Checker(ctx,nctx,net);")
+
+        c.dedent()
+        c.writeln("}")
+
+        c.dedent()
+        c.writeln("}")
+
+        #write c object to file
+        print >>f, c.end()
+
+        logging.debug("wrote test file " + os.path.abspath(dirname + "/" + basename + "_" + str(number)) + ".java" + " successfully!")
+
+
+def main(argv):
+    #exit if any command line argument is missing
+    if len(argv) < 6:
+        print 'test_class_generator.py -c <chain_file> -f <conf_file> -o <output_name>'
+        sys.exit(1)
+
+    #initialize json file names
+    chains_file = ''
+    configuration_file = ''
+    output_file = ''
+
+    #parse command line arguments and exit in case of any error
+    try:
+        opts, args = getopt.getopt(argv,"hc:f:r:o:",["help","chain=","config=","route=","ofile="])
+    except getopt.GetoptError as err:
+        print str(err)
+        print 'test_class_generator.py -c <chain_file> -f <conf_file> -o <output_name>'
+        sys.exit(2)
+    for opt, arg in opts:
+        if opt in ("-h", "--help"):
+            print 'test_class_generator.py -c <chain_file> -f <conf_file> -o <output_name'
+            sys.exit()
+        elif opt in ("-c", "--chain"):
+            chains_file = arg
+        elif opt in ("-f", "--config"):
+            configuration_file = arg
+        elif opt in ("-o", "--ofile"):
+            output_file = arg
+
+    #set logging
+    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
+
+    #parse chains file
+    chains = convert_unicode_to_ascii(parse_json_file(chains_file))
+
+    #parse configuration file
+    configuration = convert_unicode_to_ascii(parse_json_file(configuration_file))
+
+    logging.debug(pformat((chains)))
+    logging.debug(pformat((configuration)))
+
+    #custom formatted prints
+    print_chains(chains)
+    print_configuration(configuration)
+
+    #counter for the number of chains
+    number_of_chains = 0
+
+    #generate test classes
+    for chain in chains["chains"]:
+        #increment the number of chains
+        number_of_chains += 1;
+        #generate test files
+        generate_test_file(chain, number_of_chains, configuration, output_file)
+
+
+if __name__ == "__main__":
+    main(sys.argv[1:])
+
diff --git a/verigraph/service/src/tests/j-verigraph-generator/test_generator.py b/verigraph/service/src/tests/j-verigraph-generator/test_generator.py
new file mode 100644 (file)
index 0000000..f4629bb
--- /dev/null
@@ -0,0 +1,160 @@
+#!/usr/bin/python
+
+##############################################################################
+# 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from pprint import pprint
+from code_generator import CodeGeneratorBackend
+import sys, getopt
+import contextlib
+import os
+from utility import *
+import logging
+
+def main(argv):
+    if len(argv) < 8:
+        print 'test_generator.py -i <inputfile> -o <outputfile> -s <source> -d <destination>'
+        sys.exit(2)
+    #initialize command line arguments values
+    inputfile = ''
+    outputfile = ''
+    source = ''
+    destination = ''
+    #parse command line arguments and exit if there is an error
+    try:
+        opts, args = getopt.getopt(argv,"hi:o:s:d:",["ifile=","ofile=","source=","destination="])
+    except getopt.GetoptError:
+        print 'test_generator.py -i <inputfile> -o <outputfile> -s <source> -d <destination>'
+        sys.exit(2)
+    for opt, arg in opts:
+        if opt == '-h':
+            print 'test_generator.py -i <inputfile> -o <outputfile> -s <source> -d <destination>'
+            sys.exit()
+        elif opt in ("-i", "--ifile"):
+            inputfile = arg
+        elif opt in ("-o", "--ofile"):
+            outputfile = arg
+        elif opt in ("-s", "--source"):
+            source = arg
+        elif opt in ("-d", "--destination"):
+            destination = arg
+    #set logging
+    logging.basicConfig(stream=sys.stderr, level=logging.INFO)
+    #capitalize ouput filename
+    dirname = os.path.dirname(outputfile)
+    basename = os.path.basename(outputfile)
+    basename = os.path.splitext(basename)[0]
+    basename = basename[0].upper() + basename[1:]
+
+    #print arguments
+    logging.debug('Input file is', inputfile)
+    logging.debug('Output file is', dirname + "/" + basename)
+    logging.debug('Source node is', source)
+    logging.debug('Destination node is', destination)
+
+    #begin file generation
+    with smart_open(dirname + "/" + basename + ".java") as f:
+        c = CodeGeneratorBackend()
+        c.begin(tab="    ")
+        c.writeln("package tests;")
+        c.writeln("import java.util.Calendar;")
+        c.writeln("import java.util.Date;")
+        c.writeln("import java.util.HashMap;")
+
+        c.writeln("import com.microsoft.z3.Context;")
+        c.writeln("import com.microsoft.z3.FuncDecl;")
+        c.writeln("import com.microsoft.z3.Model;")
+        c.writeln("import com.microsoft.z3.Status;")
+        c.writeln("import com.microsoft.z3.Z3Exception;")
+        c.writeln("import mcnet.components.IsolationResult;")
+
+
+        inputfile = os.path.basename(inputfile)
+        c.writeln("import tests.scenarios." + os.path.splitext(inputfile)[0] + ";")
+        c.writeln("public class " + basename + "{")
+
+        c.indent()
+        c.writeln("Context ctx;")
+
+        c.write("public void resetZ3() throws Z3Exception{\n\
+        HashMap<String, String> cfg = new HashMap<String, String>();\n\
+        cfg.put(\"model\", \"true\");\n\
+        ctx = new Context(cfg);\n\
+        \r\t}\n")
+
+        c.write("public void printVector (Object[] array){\n\
+        int i=0;\n\
+        System.out.println( \"*** Printing vector ***\");\n\
+        for (Object a : array){\n\
+            i+=1;\n\
+            System.out.println( \"#\"+i);\n\
+            System.out.println(a);\n\
+            System.out.println(  \"*** \"+ i+ \" elements printed! ***\");\n\
+        }\n\
+        \r\t}\n")
+
+        c.write("public void printModel (Model model) throws Z3Exception{\n\
+        for (FuncDecl d : model.getFuncDecls()){\n\
+            System.out.println(d.getName() +\" = \"+ d.toString());\n\
+              System.out.println(\"\");\n\
+        }\n\
+        \r\t}\n")
+
+        c.writeln("public int run() throws Z3Exception{")
+        c.indent()
+
+        c.writeln(basename + " p = new " + basename + "();")
+
+        #adding time estimation
+        #c.writeln("int k = 0;")
+        #c.writeln("long t = 0;")
+
+        #c.writeln("for(;k<1;k++){")
+        #c.indent()
+
+        c.writeln("p.resetZ3();")
+
+        c.write(os.path.splitext(inputfile)[0] + " model = new " + os.path.splitext(inputfile)[0] + "(p.ctx);\n")
+
+        #c.writeln("Calendar cal = Calendar.getInstance();")
+        #c.writeln("Date start_time = cal.getTime();")
+
+        c.write("IsolationResult ret =model.check.checkIsolationProperty(model.")
+        c.append(source + ", model." + destination + ");\n")
+        #c.writeln("Calendar cal2 = Calendar.getInstance();")
+        #c.writeln("t = t+(cal2.getTime().getTime() - start_time.getTime());")
+
+        c.writeln("if (ret.result == Status.UNSATISFIABLE){\n\
+            System.out.println(\"UNSAT\");\n\
+            return -1;\n\
+        }else if (ret.result == Status.SATISFIABLE){\n\
+            System.out.println(\"SAT\");\n\
+            return 0;\n\
+        }else{\n\
+            System.out.println(\"UNKNOWN\");\n\
+            return -2;\n\
+        \r\t\t}")
+
+        #c.dedent()
+        #c.writeln("}")
+
+        #c.writeln("")
+        #c.writeln("System.out.printf(\"Mean execution time " + source + " -> " + destination + ": %.16f\", ((float) t/(float)1000)/k);")
+
+        c.dedent()
+        c.writeln("}")
+
+        c.dedent()
+        c.writeln("}")
+
+        print >>f, c.end()
+    logging.debug("File " + os.path.abspath(dirname + "/" + basename + ".java") + " has been successfully generated!!")
+
+if __name__ == "__main__":
+    main(sys.argv[1:])
diff --git a/verigraph/service/src/tests/j-verigraph-generator/utility.py b/verigraph/service/src/tests/j-verigraph-generator/utility.py
new file mode 100644 (file)
index 0000000..47d0180
--- /dev/null
@@ -0,0 +1,257 @@
+#!/usr/bin/python
+
+##############################################################################
+# 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import json
+import contextlib
+import sys
+import os
+import subprocess
+from pprint import pprint
+
+#manages output easily (can either write to file or to stdout)
+@contextlib.contextmanager
+def smart_open(filename=None):
+    if filename and filename != '-':
+        fh = open(filename, 'w')
+    else:
+        fh = sys.stdout
+    try:
+        yield fh
+    finally:
+        if fh is not sys.stdout:
+            fh.close()
+
+def check_input_is_int(text):
+    while True:
+        data = raw_input(text)
+        try:
+            int_value = int(data)
+        except ValueError:
+            print "Please enter a valid number!"
+            continue
+        return int_value
+
+#parses a json file into a unicode dictionary
+def parse_json_file(filename):
+    with open(filename) as json_file:
+        return json.load(json_file)
+
+#returns an ascii dictionary from a unicode one
+def convert_unicode_to_ascii(input):
+    if isinstance(input, dict):
+        return {convert_unicode_to_ascii(key): convert_unicode_to_ascii(value) for key, value in input.iteritems()}
+    elif isinstance(input, list):
+        return [convert_unicode_to_ascii(element) for element in input]
+    elif isinstance(input, unicode):
+        return input.encode('utf-8')
+    else:
+        return input
+
+#parses a chains file
+def parse_chains(chains_file):
+    chains_json = convert_unicode_to_ascii(parse_json_file(chains_file))
+
+    chains = {}
+
+    for chn in chains_json["chains"]:
+        try:
+            chains[chn["id"]] = {}
+            #initiatlize the config dictionary for each node
+            for node in chn["nodes"]:
+                chains[chn["id"]][node["name"]] = {}
+        except:
+            raise KeyError("Chains file is not valid!")
+
+    for chn in chains_json["chains"]:
+        try:
+            #set chn values ---> chn(name, (field, value))
+            for node in chn["nodes"]:
+                for key, value in node.items():
+                    #name key is redundant in map
+                    if key != "name":
+                        chains[chn["id"]][node["name"]][key] = value
+        except:
+            raise KeyError("Chains file is not valid!")
+    return chains
+
+def check_chains_integrity(filename):
+    print "Checking input file..."
+    try:
+        chains = convert_unicode_to_ascii(parse_json_file(filename))
+        print "File correctly parsed"
+        if isinstance(chains["chains"], list) == False:
+            print "Child of chains is not a list!"
+            return False
+        for chain in chains["chains"]:
+            print "Chain found, checking its fields..."
+            print "Checking chain id field... "
+            chain["id"]
+            print "OK!"
+            print "Checking chain flowspace field... "
+            chain["flowspace"]
+            print "OK!"
+            if isinstance(chain["nodes"], list) == False:
+                print "Chain #" + chain["id"] + " does not have a list of nodes!"
+                return False
+            for node in chain["nodes"]:
+                print "Node found, checking its fields..."
+                print "Checking node name... "
+                node["name"]
+                print "OK!"
+                print "Checking node functional_type field... "
+                node["functional_type"]
+                print "OK!"
+                print "Checking node address field... "
+                node["address"]
+                print "OK!"
+    except (KeyboardInterrupt, SystemExit):
+        raise
+    except:
+        print "One or more required fields are missing!"
+        return False
+    print filename + " validated successfully!"
+    return True
+
+def check_config_integrity(filename):
+    print "Checking input file..."
+    try:
+        config = convert_unicode_to_ascii(parse_json_file(filename))
+        pprint(config)
+        print "File correctly parsed"
+        if isinstance(config["nodes"], list) == False:
+            print "Child of nodes is not a list!"
+            return False
+        for node in config["nodes"]:
+            print "Node found, checking its fields..."
+            print "Checking id field... "
+            node["id"]
+            print "OK!"
+            print "Checking description field... "
+            node["description"]
+            print "OK!"
+            print "Checking configuration field... "
+            node["configuration"]
+            print "OK!"
+            if isinstance(node["configuration"], list) == False:
+                print "Checking if node configuration is a list..."
+                print "Node with id " + node["id"] + " does not have a configuration list!"
+                return False
+            for c in node["configuration"]:
+                print "Checking if node configuration element is a string or a dictionary..."
+                if (isinstance(c, str) == False and isinstance(c, dict) == False):
+                    print "At least one element of node with id " + node["id"] + " has an invalid configuration (it is neither a string or a map)"
+                    return False
+    except (KeyboardInterrupt, SystemExit):
+        raise
+    except:
+        print "One or more required fields are missing!"
+        return False
+    print filename + " validated successfully!"
+    return True
+
+def check_routing_integrity(filename):
+    print "Checking input file..."
+    try:
+        routing = convert_unicode_to_ascii(parse_json_file(filename))
+        print "File correctly parsed"
+        if isinstance(routing["routing_table"], list) == False:
+            print "Child of routing_table is not a list!"
+            return False
+        for node in routing["routing_table"]:
+            if isinstance(node, dict) == False:
+                print "Child of routing_table is not a map!"
+                return False
+            for n, rt in node.items():
+                if isinstance(rt, list) == False:
+                    print "Routing table of element " + n + " is not a list!"
+                    return False
+                for entry in rt:
+                    if isinstance(entry, dict) == False:
+                        print "Invalid entry for node " + n + " (not a map)!"
+                        return False
+    except (KeyboardInterrupt, SystemExit):
+        raise
+    except:
+        print "One or more required fields are missing!"
+        return False
+    return True
+
+#prints every node for each input chain
+def print_chains(chains):
+    for chain in chains["chains"]:
+        print "CHAIN #" + str(chain["id"])
+        for node in chain["nodes"]:
+            print "Name: " + str(node["name"])
+            print "Functional type: " + str(node["functional_type"])
+            print "Address: " + str(node["address"])
+            print "-----------------------------------"
+        print ""
+
+#prints every node's configuration
+def print_configuration(configuration):
+    print "NODES CONFIGURATION"
+    for node in configuration["nodes"]:
+        print "Name: " + str(node["id"])
+        print "Description: " + str(node["description"])
+        print "Configuration: "
+        pprint(node["configuration"])
+        print "-----------------------------------"
+    print ""
+
+#print every node's routing table
+def print_routing_table(routing):
+    print "ROUTING"
+    for table in routing["routing_table"]:
+        for node,rt in table.items():
+            print "Name: " + str(node)
+            pprint(rt)
+            print "-----------------------------------"
+        print ""
+
+#returns a list of tuple [(k1, v1), (k2, v2)] from a list of maps like [{k1 : v1},{k2 : v2}]
+def formatted_list_from_list_of_maps(maps):
+    l = []
+    for map in maps:
+        if isinstance(map, dict):
+            for k, v in map.items():
+                #l.append("(ctx." + str(k) + ", ctx." + str(v) + ")")
+                l.append(str(k))
+                l.append(str(v))
+        else:
+            #l.append("ctx." + map)
+            l.append(map)
+    return l
+
+def list_directories(dir):
+    #output = subprocess.call(["ls", "-d", "*/"])
+    output = subprocess.call(["find", dir, "-type", "d"])
+
+    #TREE VERSION
+    #find = subprocess.Popen(["find", ".", "-type", "d"], stdout=subprocess.PIPE)
+    #output = subprocess.check_output(["sed", "-e", "s/[^-][^\/]*\//  |/g", "-e", "s/|\([^ ]\)/|-\1/"], stdin=find.stdout)
+    #find.wait()
+
+#     ps = subprocess.Popen(('ps', '-A'), stdout=subprocess.PIPE)
+#     output = subprocess.check_output(('grep', 'process_name'), stdin=ps.stdout)
+#     ps.wait()
+    return output
+
+def list_files(dir):
+    output = subprocess.call(["find", dir, "-type", "f"])
+    return output
+
+def search_node_in_chains(n):
+    found = []
+    for chain in chains["chains"]:
+        for node in chain["nodes"]:
+            if node["name"] == n:
+                found.append(node)
+    return found
\ No newline at end of file
diff --git a/verigraph/src/main/java/it/polito/escape/verify/client/Neo4jManagerClient.java b/verigraph/src/main/java/it/polito/escape/verify/client/Neo4jManagerClient.java
new file mode 100644 (file)
index 0000000..044c136
--- /dev/null
@@ -0,0 +1,339 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.client;
+
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.ProcessingException;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.stream.FactoryConfigurationError;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import it.polito.escape.verify.deserializer.PathsMessageBodyReader;
+import it.polito.escape.verify.model.Entry;
+import it.polito.nffg.neo4j.jaxb.ActionEnumType;
+import it.polito.nffg.neo4j.jaxb.ActionType;
+import it.polito.nffg.neo4j.jaxb.ActionsType;
+import it.polito.nffg.neo4j.jaxb.CiType;
+import it.polito.nffg.neo4j.jaxb.CiType.Attributes;
+import it.polito.nffg.neo4j.jaxb.CiType.Attributes.Attribute;
+import it.polito.nffg.neo4j.jaxb.CpType;
+import it.polito.nffg.neo4j.jaxb.CpointsType;
+import it.polito.nffg.neo4j.jaxb.CtrlInterfacesType;
+import it.polito.nffg.neo4j.jaxb.EpCpType;
+import it.polito.nffg.neo4j.jaxb.EpType;
+import it.polito.nffg.neo4j.jaxb.EpType.Flowspace;
+import it.polito.nffg.neo4j.jaxb.EpointsType;
+import it.polito.nffg.neo4j.jaxb.EpsCpsType;
+import it.polito.nffg.neo4j.jaxb.FlowrulesType;
+import it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Tcp;
+import it.polito.nffg.neo4j.jaxb.MonParamsType;
+import it.polito.nffg.neo4j.jaxb.MonParamsType.Parameter;
+import it.polito.nffg.neo4j.jaxb.NeType;
+import it.polito.nffg.neo4j.jaxb.NelementsType;
+import it.polito.nffg.neo4j.jaxb.NfType;
+import it.polito.nffg.neo4j.jaxb.Nffg;
+import it.polito.nffg.neo4j.jaxb.NfunctionsType;
+import it.polito.nffg.neo4j.jaxb.ObjectFactory;
+import it.polito.nffg.neo4j.jaxb.Paths;
+import it.polito.nffg.neo4j.jaxb.PortDirEnumType;
+import it.polito.nffg.neo4j.jaxb.PortType;
+import it.polito.nffg.neo4j.jaxb.SpecType;
+import it.polito.nffg.neo4j.jaxb.SpecType.Cpu;
+import it.polito.nffg.neo4j.jaxb.SpecType.Deployment;
+import it.polito.nffg.neo4j.jaxb.SpecType.Image;
+import it.polito.nffg.neo4j.jaxb.SpecType.Memory;
+import it.polito.nffg.neo4j.jaxb.SpecType.Storage;
+
+public class Neo4jManagerClient {
+
+       private JAXBContext                                     jc;
+
+       private String                                          address;
+
+       private Nffg                                            nffg;
+
+       private List<String>                            endpoints               = new LinkedList<String>();
+
+       private List<String>                            firewalls               = new LinkedList<String>();
+
+       private Map<String, List<Entry>>        routingTable    = new HashMap<String, List<Entry>>();
+
+       private String                                          source;
+
+       private String                                          destination;
+
+       private String                                          xmlString;
+
+       private WebTarget                                       baseTarget;
+
+       public Neo4jManagerClient() {
+
+       }
+
+       public Neo4jManagerClient(      String address, String source, String destination, List<String> endpoints,
+                                                               List<String> firewalls, Map<String, List<Entry>> routingTable) {
+               this.address = address;
+               this.source = source;
+               this.destination = destination;
+               this.endpoints = endpoints;
+               this.firewalls = firewalls;
+               this.routingTable = routingTable;
+
+               Client client = ClientBuilder.newBuilder().register(PathsMessageBodyReader.class).build();
+
+               this.baseTarget = client.target(this.address);
+       }
+
+       public Paths getPaths() throws Exception {
+               try {
+                       this.generateCustomXml();
+               }
+               catch (JAXBException e) {
+                       throw (e);
+               }
+
+               WebTarget graphsTarget = baseTarget.path("graphs");
+               WebTarget pathSourceDestination = graphsTarget.path("{graphId}/paths");
+               WebTarget deleteNffg = graphsTarget.path("{graphId}");
+
+               Response deleteNffgResponse = deleteNffg.resolveTemplate("graphId", "1").request().delete();
+               if (deleteNffgResponse.getStatus() != javax.ws.rs.core.Response.Status.NO_CONTENT.getStatusCode()
+                       && deleteNffgResponse.getStatus() != javax.ws.rs.core.Response.Status.NOT_FOUND.getStatusCode()) {
+                       throw new Exception("graph deletion failed");
+               }
+
+               Response createNffgResponse = graphsTarget      .request("application/xml")
+                                                                                                       .post(Entity.entity(this.xmlString, "application/xml"));
+               if (createNffgResponse.getStatus() != javax.ws.rs.core.Response.Status.CREATED.getStatusCode()) {
+                       throw new Exception("graph creation failed");
+               }
+
+               System.out.println("Getting paths from node \"" + this.source + "\" to node \"" + this.destination + "\"...");
+               Response getPath = pathSourceDestination.resolveTemplate("graphId", "1")
+                                                                                               .queryParam("src", this.source)
+                                                                                               .queryParam("dst", this.destination)
+                                                                                               .queryParam("dir", "outgoing")
+                                                                                               .request(MediaType.APPLICATION_XML)
+                                                                                               .get();
+
+               System.out.println("Paths from node \"" + this.source + "\" to node \"" + this.destination + "\":");
+
+               Paths paths = null;
+               try {
+                       paths = getPath.readEntity(Paths.class);
+               }
+               catch (ProcessingException e) {
+                       throw (e);
+               }
+               catch (IllegalStateException e) {
+                       throw (e);
+               }
+
+               return paths;
+       }
+
+       private void generateCustomXml() throws JAXBException {
+
+               jc = JAXBContext.newInstance("it.polito.nffg.neo4j.jaxb");
+
+               nffg = new Nffg();
+               nffg.setId("nffg_1");
+
+               generateEndpoints();
+               generateFirewalls();
+               generateConnections();
+
+               MonParamsType monitoring_parameters = new MonParamsType();
+               nffg.setMonitoringParameters(monitoring_parameters);
+
+               JAXBElement<Nffg> root = (new ObjectFactory()).createNffg(nffg);
+
+               Marshaller m;
+               try {
+                       m = jc.createMarshaller();
+                       m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+
+                       StringWriter stringWriter = new StringWriter();
+                       try {
+                               XMLStreamWriter xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(stringWriter);
+                               m.marshal(root, xmlStreamWriter);
+                               xmlString = stringWriter.getBuffer().toString();
+                       }
+                       catch (XMLStreamException e) {
+                               e.printStackTrace();
+                       }
+                       catch (FactoryConfigurationError e) {
+
+                               e.printStackTrace();
+                       }
+                       // m.marshal( root, new File("nffg.xml") );
+                       System.out.println(xmlString);
+
+               }
+               catch (JAXBException e) {
+                       throw (e);
+               }
+       }
+
+       private void generateConnections() {
+               NelementsType network_elements = new NelementsType();
+               NeType network_element = new NeType();
+               network_element.setId("ne_1");
+               network_element.setType("BiSBiS");
+               EpsCpsType ep_cps = new EpsCpsType();
+
+               for (String node : routingTable.keySet()) {
+                       EpCpType ep_cp = new EpCpType();
+                       ep_cp.setIdRef(node);
+                       FlowrulesType flowrules = new FlowrulesType();
+                       it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace flowspace =
+                                                                                                                                               new it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace();
+                       flowrules.setFlowspace(flowspace);
+                       ActionsType actions = new ActionsType();
+                       for (Entry e : routingTable.get(node)) {
+                               ActionType action = new ActionType();
+                               action.setType(ActionEnumType.fromValue(e.getDirection()));
+                               action.setPort(e.getDestination());
+                               actions.getAction().add(action);
+                       }
+                       flowrules.setActions(actions);
+
+                       ep_cp.getFlowrules().add(flowrules);
+                       ep_cps.getEpCp().add(ep_cp);
+               }
+               network_element.setEpsCps(ep_cps);
+
+               MonParamsType monitoring_parameters = new MonParamsType();
+               Parameter parameter = new Parameter();
+               parameter.getValue().add("Bandwith ep_1 cp_1 100mbit");
+               monitoring_parameters.getParameter().add(parameter);
+               Parameter parameter2 = new Parameter();
+               parameter2.getValue().add("Delay ep_1 cp_1 50ms");
+               monitoring_parameters.getParameter().add(parameter2);
+
+               network_element.setMonitoringParameters(monitoring_parameters);
+
+               network_elements.getNetworkElement().add(network_element);
+
+               nffg.setNetworkElements(network_elements);
+
+       }
+
+       private void generateFirewalls() {
+               NfunctionsType network_functions = new NfunctionsType();
+
+               for (String firewall : firewalls) {
+                       NfType nf = new NfType();
+                       nf.setId(firewall);
+                       nf.setFunctionalType("firewall");
+
+                       SpecType specification = new SpecType();
+                       Deployment deployment = new Deployment();
+                       deployment.setType("PolitoFirewall");
+                       Image image = new Image();
+                       image.setUri("http://www.polito.it");
+                       Cpu cpu = new Cpu();
+                       cpu.setNumCores((short) (7));
+                       Memory memory = new Memory();
+                       memory.setSize("10MiB");
+                       Storage storage = new Storage();
+                       storage.setSize("100MiB");
+                       specification.setDeployment(deployment);
+                       specification.setImage(image);
+                       specification.setCpu(cpu);
+                       specification.setMemory(memory);
+                       specification.setStorage(storage);
+
+                       CpointsType connection_points = new CpointsType();
+                       CpType connection_point = new CpType();
+                       connection_point.setId(firewall + "_in");
+                       PortType port = new PortType();
+                       port.setId(79);
+                       port.setDirection(PortDirEnumType.IN);
+                       port.setType("GbE");
+                       connection_point.setPort(port);
+                       connection_points.getConnectionPoint().add(connection_point);
+
+                       CpType connection_point2 = new CpType();
+                       connection_point2.setId(firewall + "_out");
+                       PortType port2 = new PortType();
+                       port2.setId(77);
+                       port2.setDirection(PortDirEnumType.OUT);
+                       port2.setType("10GbE");
+                       connection_point2.setPort(port2);
+
+                       connection_points.getConnectionPoint().add(connection_point2);
+
+                       CtrlInterfacesType control_interfaces = new CtrlInterfacesType();
+                       CiType control_interface = new CiType();
+                       control_interface.setId(firewall + "_ci");
+
+                       Attributes attributes = new Attributes();
+                       Attribute attribute = new Attribute();
+                       attribute.setValue("tcp://127.0.0.1:5555");
+                       attributes.getAttribute().add(attribute);
+                       Attribute attribute2 = new Attribute();
+                       attribute2.setValue("Netconf");
+                       attributes.getAttribute().add(attribute2);
+                       control_interface.setAttributes(attributes);
+
+                       control_interfaces.getControlInterface().add(control_interface);
+
+                       MonParamsType monitoring_parameters = new MonParamsType();
+                       Parameter parameter = new Parameter();
+                       parameter.getValue().add("Measure script");
+                       monitoring_parameters.getParameter().add(parameter);
+
+                       nf.setSpecification(specification);
+                       nf.setConnectionPoints(connection_points);
+                       nf.setControlInterfaces(control_interfaces);
+                       nf.setMonitoringParameters(monitoring_parameters);
+
+                       network_functions.getNetworkFunction().add(nf);
+
+               }
+               nffg.setNetworkFunctions(network_functions);
+
+       }
+
+       private void generateEndpoints() {
+               EpointsType eps = new EpointsType();
+
+               for (String e : endpoints) {
+                       EpType endpoint = new EpType();
+                       endpoint.setId(e);
+                       Flowspace flowspace = new Flowspace();
+                       flowspace.setIngPhysPort("10");
+                       Tcp tcp = new Tcp();
+                       tcp.setSrc(80);
+                       flowspace.setTcp(tcp);
+                       endpoint.setFlowspace(flowspace);
+                       eps.getEndpoint().add(endpoint);
+               }
+               nffg.setEndpoints(eps);
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/client/VerifyClient.java b/verigraph/src/main/java/it/polito/escape/verify/client/VerifyClient.java
new file mode 100644 (file)
index 0000000..1997553
--- /dev/null
@@ -0,0 +1,444 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.client;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.ProcessingException;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.ResponseProcessingException;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import it.polito.escape.verify.model.ErrorMessage;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Neighbour;
+import it.polito.escape.verify.model.Node;
+import it.polito.escape.verify.model.Verification;
+
+public class VerifyClient {
+
+       private WebTarget       baseTarget;
+
+       private WebTarget       graphsTarget;
+
+       private WebTarget       graphTarget;
+
+       private WebTarget       nodesTarget;
+
+       private WebTarget       nodeTarget;
+
+       private WebTarget       neighboursTarget;
+
+       private WebTarget       neighbourTarget;
+
+       private WebTarget       reachabilityTarget;
+
+       private WebTarget       isolationTarget;
+
+       private WebTarget       traversalTarget;
+
+       public VerifyClient(String address) {
+               Client client = ClientBuilder.newClient();
+
+               this.baseTarget = client.target(address);
+               this.graphsTarget = baseTarget.path("graphs");
+               this.graphTarget = graphsTarget.path("/{graphId}");
+               this.nodesTarget = graphTarget.path("/nodes");
+               this.nodeTarget = nodesTarget.path("//{nodeId}");
+               this.neighboursTarget = nodeTarget.path("/neighbours");
+               this.neighbourTarget = neighboursTarget.path("/{neighbourId}");
+               this.reachabilityTarget = graphTarget.path("/policy");
+               this.isolationTarget = graphTarget.path("/policy");
+               this.traversalTarget = graphTarget.path("/policy");
+       }
+
+       public void checkResponse(Response response) throws VerifyClientException {
+               int status = response.getStatus();
+
+               // 400
+               if (status == Response.Status.BAD_REQUEST.getStatusCode()) {
+                       try {
+                               // String responseString = response.readEntity(String.class);
+                               // System.out.println(responseString);
+                               ErrorMessage errorMessage = response.readEntity(ErrorMessage.class);
+                               String message = errorMessage.getErrorMessage();
+                               throw new VerifyClientException("Bad request: " + message);
+                       }
+                       catch (ProcessingException e) {
+                               throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'ErrorMessage': "
+                                                                                               + e.getMessage());
+                       }
+                       catch (IllegalStateException e) {
+                               throw new VerifyClientException("the entity is not backed by an input stream or the original entity input stream has already been consumed without buffering the entity data prior consuming: "
+                                                                                               + e.getMessage());
+                       }
+               }
+               // 403
+               if (status == Response.Status.FORBIDDEN.getStatusCode()) {
+                       try {
+                               ErrorMessage errorMessage = response.readEntity(ErrorMessage.class);
+                               String message = errorMessage.getErrorMessage();
+                               throw new VerifyClientException("Forbidden: " + message);
+                       }
+                       catch (ProcessingException e) {
+                               throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'ErrorMessage': "
+                                                                                               + e.getMessage());
+                       }
+                       catch (IllegalStateException e) {
+                               throw new VerifyClientException("the entity is not backed by an input stream or the original entity input stream has already been consumed without buffering the entity data prior consuming: "
+                                                                                               + e.getMessage());
+                       }
+               }
+               // 404
+               if (status == Response.Status.NOT_FOUND.getStatusCode()) {
+                       try {
+                               ErrorMessage errorMessage = response.readEntity(ErrorMessage.class);
+                               String message = errorMessage.getErrorMessage();
+                               throw new VerifyClientException("Not found: " + message);
+                       }
+                       catch (ProcessingException e) {
+                               throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'ErrorMessage': "
+                                                                                               + e.getMessage());
+                       }
+                       catch (IllegalStateException e) {
+                               throw new VerifyClientException("the 'Response' entity is not backed by an input stream or the original entity input stream has already been consumed without buffering the entity data prior consuming: "
+                                                                                               + e.getMessage());
+                       }
+               }
+               // 500
+               if (status == Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()) {
+                       try {
+                               ErrorMessage errorMessage = response.readEntity(ErrorMessage.class);
+                               String message = errorMessage.getErrorMessage();
+                               throw new VerifyClientException("Internal server error: " + message);
+                       }
+                       catch (ProcessingException e) {
+                               throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'ErrorMessage': "
+                                                                                               + e.getMessage());
+                       }
+                       catch (IllegalStateException e) {
+                               throw new VerifyClientException("the entity is not backed by an input stream or the original entity input stream has already been consumed without buffering the entity data prior consuming: "
+                                                                                               + e.getMessage());
+                       }
+               }
+               if (status != Response.Status.ACCEPTED.getStatusCode()  && status != Response.Status.CREATED.getStatusCode()
+                       && status != Response.Status.NO_CONTENT.getStatusCode() && status != Response.Status.OK.getStatusCode())
+                       throw new VerifyClientException("Unknown error");
+       }
+
+       public Response createGraph(Graph graph) throws VerifyClientException, ResponseProcessingException, ProcessingException {
+               Response response = graphsTarget.request().post(Entity.json(graph));
+               checkResponse(response);
+               return response;
+       }
+
+       public Response createGraph(String graph) throws VerifyClientException, ResponseProcessingException, ProcessingException {
+               Response response = graphsTarget.request().post(Entity.entity(graph, "application/json"));
+               checkResponse(response);
+               return response;
+       }
+
+       public Response retrieveGraph(long graphId) throws VerifyClientException, ProcessingException {
+               Response response = graphTarget.resolveTemplate("graphId", graphId).request().get();
+               checkResponse(response);
+               return response;
+       }
+
+       public Response updateGraph(long graphId, Graph graph) throws VerifyClientException, ResponseProcessingException, ProcessingException {
+               Response response = graphTarget.resolveTemplate("graphId", graphId).request().put(Entity.json(graph));
+               checkResponse(response);
+               return response;
+       }
+
+       public Response deleteGraph(long graphId) throws VerifyClientException, ResponseProcessingException, ProcessingException {
+               Response response = graphTarget.resolveTemplate("graphId", graphId).request().delete();
+               checkResponse(response);
+               return response;
+       }
+
+       public Response createNode(long graphId, Node node) throws VerifyClientException, ResponseProcessingException, ProcessingException {
+               Response response = nodesTarget.resolveTemplate("graphId", graphId).request().post(Entity.json(node));
+               checkResponse(response);
+               return response;
+       }
+
+       public Response retrieveNode(long graphId, long nodeId) throws VerifyClientException, ProcessingException {
+               Response response = nodeTarget  .resolveTemplate("graphId", graphId)
+                                                                               .resolveTemplate("nodeId", nodeId)
+                                                                               .request()
+                                                                               .get();
+               checkResponse(response);
+               return response;
+       }
+
+       public Response updateNode(long graphId, long nodeId, Node node) throws VerifyClientException, ResponseProcessingException, ProcessingException {
+               Response response = nodeTarget  .resolveTemplate("graphId", graphId)
+                                                                               .resolveTemplate("nodeId", nodeId)
+                                                                               .request()
+                                                                               .put(Entity.json(node));
+               checkResponse(response);
+               return response;
+       }
+
+       public Response deleteNode(long graphId, long nodeId) throws VerifyClientException, ResponseProcessingException, ProcessingException {
+               Response response = nodeTarget  .resolveTemplate("graphId", graphId)
+                                                                               .resolveTemplate("nodeId", nodeId)
+                                                                               .request()
+                                                                               .delete();
+               checkResponse(response);
+               return response;
+       }
+
+       public Response createNeighbour(long graphId, long nodeId, Neighbour neighbour) throws VerifyClientException, ResponseProcessingException, ProcessingException {
+               Response response = neighboursTarget.resolveTemplate("graphId", graphId)
+                                                                                       .resolveTemplate("nodeId", nodeId)
+                                                                                       .request()
+                                                                                       .post(Entity.json(neighbour));
+               checkResponse(response);
+               return response;
+       }
+
+       public Response retrieveNeighbour(long graphId, long nodeId, long neighbourId) throws VerifyClientException, ProcessingException {
+               Response response = neighbourTarget     .resolveTemplate("graphId", graphId)
+                                                                                       .resolveTemplate("nodeId", nodeId)
+                                                                                       .resolveTemplate("neighbourId", neighbourId)
+                                                                                       .request()
+                                                                                       .get();
+               checkResponse(response);
+               return response;
+       }
+
+       public Response updateNeighbour(long graphId, long nodeId, long neighbourId,
+                                                                       Neighbour neighbour) throws VerifyClientException, ResponseProcessingException, ProcessingException {
+               Response response = neighbourTarget     .resolveTemplate("graphId", graphId)
+                                                                                       .resolveTemplate("nodeId", nodeId)
+                                                                                       .resolveTemplate("neighbourId", neighbourId)
+                                                                                       .request()
+                                                                                       .put(Entity.json(neighbour));
+               checkResponse(response);
+               return response;
+       }
+
+       public Response deleteNeighbour(long graphId, long nodeId, long neighbourId) throws VerifyClientException, ResponseProcessingException, ProcessingException {
+               Response response = neighbourTarget     .resolveTemplate("graphId", graphId)
+                                                                                       .resolveTemplate("nodeId", nodeId)
+                                                                                       .resolveTemplate("neighbourId", neighbourId)
+                                                                                       .request()
+                                                                                       .delete();
+               checkResponse(response);
+               return response;
+       }
+
+       public Verification getReachability(long graphId, String source, String destination) throws VerifyClientException, ProcessingException{
+               Response response = reachabilityTarget.resolveTemplate("graphId", graphId)
+                               .queryParam("source", source)
+                               .queryParam("destination", destination)
+                               .queryParam("type", "reachability")
+                               .request()
+                               .get();
+               checkResponse(response);
+               try{
+                       Verification verification = response.readEntity(Verification.class);
+                       return verification;
+               }
+               catch (ProcessingException e) {
+                       throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'Verification': "
+                                                                                       + e.getMessage());
+               }
+               catch (IllegalStateException e) {
+                       throw new VerifyClientException("the 'Verification' entity is not backed by an input stream or the original entity input stream has already been consumed without buffering the entity data prior consuming: "
+                                                                                       + e.getMessage());
+               }
+       }
+
+       public Verification getIsolation(long graphId, String source, String destination, String middlebox) throws VerifyClientException, ProcessingException{
+               Response response = isolationTarget.resolveTemplate("graphId", graphId)
+                               .queryParam("source", source)
+                               .queryParam("destination", destination)
+                               .queryParam("middlebox", middlebox)
+                               .queryParam("type", "isolation")
+                               .request()
+                               .get();
+               checkResponse(response);
+               try{
+                       Verification verification = response.readEntity(Verification.class);
+                       return verification;
+               }
+               catch (ProcessingException e) {
+                       throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'Verification': "
+                                                                                       + e.getMessage());
+               }
+               catch (IllegalStateException e) {
+                       throw new VerifyClientException("the 'Verification' entity is not backed by an input stream or the original entity input stream has already been consumed without buffering the entity data prior consuming: "
+                                                                                       + e.getMessage());
+               }
+       }
+
+       public Verification getTraversal(long graphId, String source, String destination, String middlebox) throws VerifyClientException, ProcessingException{
+               Response response = traversalTarget.resolveTemplate("graphId", graphId)
+                               .queryParam("source", source)
+                               .queryParam("destination", destination)
+                               .queryParam("middlebox", middlebox)
+                               .queryParam("type", "traversal")
+                               .request()
+                               .get();
+               checkResponse(response);
+               try{
+                       Verification verification = response.readEntity(Verification.class);
+                       return verification;
+               }
+               catch (ProcessingException e) {
+                       throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'Verification': "
+                                                                                       + e.getMessage());
+               }
+               catch (IllegalStateException e) {
+                       throw new VerifyClientException("the 'Verification' entity is not backed by an input stream or the original entity input stream has already been consumed without buffering the entity data prior consuming: "
+                                                                                       + e.getMessage());
+               }
+       }
+
+       @SuppressWarnings("unused")
+       private static String deserializeString(File file) throws IOException {
+               int len;
+               char[] chr = new char[4096];
+               final StringBuffer buffer = new StringBuffer();
+               final FileReader reader = new FileReader(file);
+               try {
+                       while ((len = reader.read(chr)) > 0) {
+                               buffer.append(chr, 0, len);
+                       }
+               }
+               finally {
+                       reader.close();
+               }
+               return buffer.toString();
+       }
+
+       public List<File> getFiles() {
+               List<File> filesList = new ArrayList<File>();
+
+               String folderString = System.getProperty("folder");
+               File folder;
+               if (folderString == null)
+                       folder = new File(System.getProperty("user.dir") + "/examples");
+               else
+                       folder = new File(folderString);
+
+               System.out.println("Folder set to " + folder.getAbsolutePath());
+
+               File[] files = folder.listFiles(new FilenameFilter() {
+
+                       @Override
+                       public boolean accept(File dir, String name) {
+                               return name.endsWith(".json");
+                       }
+               });
+
+               for (File f : files) {
+                       filesList.add(f);
+               }
+
+               return filesList;
+       }
+
+       public Graph addGraphFromFile(File file) throws JsonParseException, JsonMappingException, IOException, Exception {
+               System.out.println("Parsing graph of file '" + file.getAbsolutePath() + "'...");
+               Graph graph = new ObjectMapper().readValue(file, Graph.class);
+               Response createGraphResponse = createGraph(graph);
+               if (createGraphResponse.getStatus() != Status.CREATED.getStatusCode()) {
+                       throw new Exception("Creation of graph contained in file '"     + file.getAbsolutePath() + "' returned status "
+                                                               + createGraphResponse.getStatus());
+               }
+               String responseString = createGraphResponse.readEntity(String.class);
+               System.out.println("Response:");
+               System.out.println(responseString);
+               Graph response = new ObjectMapper().readValue(responseString, Graph.class);
+               printGraph(response);
+               return response;
+       }
+
+       public void printGraph(Graph graph) {
+               System.out.println("Graph " + graph.getId());
+               for (Node n : graph.getNodes().values()) {
+                       System.out.println("\tNode " + n.getId());
+                       System.out.println("\tName " + n.getName());
+                       System.out.println("\tFunctional type: " + n.getFunctional_type());
+                       for (Neighbour neighbour : n.getNeighbours().values()) {
+                               System.out.println("\t\tNeighbour " + neighbour.getId());
+                               System.out.println("\t\tName: " + neighbour.getName());
+                       }
+               }
+       }
+
+       public Map<String, Graph> addGraphsFromFiles(List<File> files)  throws JsonParseException, JsonMappingException, IOException,
+                                                                                                                       Exception {
+               Map<String, Graph> graphs = new HashMap<String, Graph>();
+
+               for (File f : files) {
+                       Graph graph = addGraphFromFile(f);
+                       graphs.put(f.getName(), graph);
+               }
+
+               for (Map.Entry<String, Graph> graph : graphs.entrySet()) {
+                       System.out.println(graph.getKey() + " -> graph " + graph.getValue().getId());
+               }
+               System.out.println("Graphs added");
+
+               return graphs;
+       }
+
+       public static void main(String[] args) throws IOException, Exception {
+               System.out.println("Adding graphs");
+
+               VerifyClient verifyClient = new VerifyClient("http://localhost:8080/verify/api");
+
+               List<File> files = verifyClient.getFiles();
+               Map<String, Graph> graphs = verifyClient.addGraphsFromFiles(files);
+
+               for (Graph g : graphs.values()) {
+                       Response response = verifyClient.retrieveGraph(g.getId());
+                       String responseString = response.readEntity(String.class);
+
+                       System.out.println("Response");
+                       System.out.println(responseString);
+                       Graph graph = new ObjectMapper().readValue(responseString, Graph.class);
+                       System.out.println("Read graph " + graph.getId());
+                       System.out.println(response.getStatus());
+               }
+
+               Graph graph = graphs.get("budapest_sat.json");
+               System.out.println("graphId set to " + graph.getId());
+               System.out.println("Getting reachability from 'user1' to 'websever' in 'budapest' graph (expecting SAT)...");
+               Verification verification = verifyClient.getReachability(graph.getId(), "user1", "webserver");
+               System.out.println(verification.getResult());
+               graph = graphs.get("budapest_unsat.json");
+               System.out.println("graphId set to " + graph.getId());
+               System.out.println("Getting reachability from 'user1' to 'websever' in 'budapest' graph (expecting UNSAT)...");
+               verification = verifyClient.getReachability(graph.getId(), "user1", "webserver");
+               System.out.println(verification.getResult());
+
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/client/VerifyClientException.java b/verigraph/src/main/java/it/polito/escape/verify/client/VerifyClientException.java
new file mode 100644 (file)
index 0000000..d91d31e
--- /dev/null
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.client;
+
+
+public class VerifyClientException extends Exception{
+
+       /**
+        *
+        */
+       private static final long serialVersionUID = 4794956747093682854L;
+
+       public VerifyClientException(String message){
+               super(message);
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/database/DatabaseClass.java b/verigraph/src/main/java/it/polito/escape/verify/database/DatabaseClass.java
new file mode 100644 (file)
index 0000000..7837e51
--- /dev/null
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.database;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+
+import it.polito.escape.verify.exception.InternalServerErrorException;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Neighbour;
+import it.polito.escape.verify.model.Node;
+import it.polito.escape.verify.service.GraphService;
+
+public class DatabaseClass {
+
+       private static final DatabaseClass                              instance        = new DatabaseClass();
+
+       private static ConcurrentHashMap<Long, Graph>   graphs;
+
+       private static String                                                   persistenceFile;
+
+       private static boolean                                                  enablePersistence;
+
+       protected DatabaseClass() {
+               initialize();
+               if (enablePersistence)
+                       loadDatabase();
+       }
+
+       private void initialize() {
+               graphs = new ConcurrentHashMap<>();
+               enablePersistence = false;
+               persistenceFile = System.getProperty("catalina.base") + "/webapps/verify/json/" + "database.json";
+       }
+
+       private void loadDatabase() {
+               ObjectMapper mapper = new ObjectMapper();
+
+               List<Graph> parsedGraphs = null;
+               try {
+                       File databaseFile = new File(persistenceFile);
+                       parsedGraphs = mapper.readValue(databaseFile,
+                                                                                       TypeFactory.defaultInstance().constructCollectionType(  List.class,
+                                                                                                                                                                                                       Graph.class));
+               }
+               catch (JsonParseException e) {
+                       System.out.println("Database not loaded due to a JsonParseException: " + e.getMessage());
+                       return;
+               }
+               catch (JsonMappingException e) {
+                       System.out.println("Database not loaded due to a JsonMappingException: " + e.getMessage());
+                       return;
+               }
+               catch (IOException e) {
+                       //retry changing path
+                       persistenceFile = "src/main/webapp/json/" + "database.json";
+
+                       try {
+                               File databaseFile = new File(persistenceFile);
+                               parsedGraphs = mapper.readValue(databaseFile,
+                                               TypeFactory.defaultInstance().constructCollectionType(  List.class,
+                                                               Graph.class));
+                       } catch (JsonParseException e1) {
+                               System.out.println("Database not loaded due to a JsonParseException: " + e.getMessage());
+                               return;
+                       } catch (JsonMappingException e1) {
+                               System.out.println("Database not loaded due to a JsonMappingException: " + e.getMessage());
+                               return;
+                       } catch (IOException e1) {
+                               System.out.println("Database not loaded due to an IOException: " + e.getMessage());
+                               return;
+                       }
+               }
+
+               System.out.println("Loading database...");
+
+               for (Graph graph : parsedGraphs) {
+
+                       try {
+                               GraphService.validateGraph(graph);
+                       }
+                       catch (Exception e) {
+                               System.out.println("Invalid database file: at least one graph is invalid!");
+                               return;
+                       }
+
+                       graph.setId(getNumberOfGraphs() + 1);
+
+                       for (Map.Entry<Long, Node> nodeEntry : graph.getNodes().entrySet()) {
+                               nodeEntry.getValue().setId(nodeEntry.getKey());
+
+                               for (Map.Entry<Long, Neighbour> neighbourEntry : nodeEntry.getValue().getNeighbours().entrySet()) {
+                                       neighbourEntry.getValue().setId(neighbourEntry.getKey());
+                               }
+                       }
+
+                       graphs.put(graph.getId(), graph);
+               }
+
+               System.out.println("Database loaded!");
+               System.out.println(graphs.size() + " graphs added");
+       }
+
+       public static DatabaseClass getInstance() {
+               return instance;
+       }
+
+       public ConcurrentHashMap<Long, Graph> getGraphs() {
+               return graphs;
+       }
+
+       public synchronized int getNumberOfGraphs() {
+               return graphs.size();
+       }
+
+       public synchronized int getGraphNumberOfNodes(long graphId) {
+               Graph graph = graphs.get(graphId);
+               if (graph == null)
+                       return 0;
+               Map<Long, Node> nodes = graph.getNodes();
+               if (nodes == null)
+                       return 0;
+               return nodes.size();
+       }
+
+       public static void persistDatabase() {
+               if (!enablePersistence)
+                       return;
+               ObjectMapper mapper = new ObjectMapper();
+
+               try {
+                       mapper.writeValue(new File(persistenceFile), graphs);
+               }
+               catch (JsonGenerationException e) {
+                       throw new InternalServerErrorException("Unable to persist database due to a JsonGenerationException: "
+                                                                                                       + e.getMessage());
+               }
+               catch (JsonMappingException e) {
+                       throw new InternalServerErrorException("Unable to persist database due to a JsonMappingException: "
+                                                                                                       + e.getMessage());
+               }
+               catch (IOException e) {
+                       //retry changing path
+                       persistenceFile = "src/main/webapp/json/" + "database.json";
+                       try {
+                               mapper.writeValue(new File(persistenceFile), graphs);
+                       } catch (JsonGenerationException e1) {
+                               throw new InternalServerErrorException("Unable to persist database due to a JsonGenerationException: "
+                                               + e.getMessage());
+                       } catch (JsonMappingException e1) {
+                               throw new InternalServerErrorException("Unable to persist database due to a JsonGenerationException: "
+                                               + e.getMessage());
+                       } catch (IOException e1) {
+                               throw new InternalServerErrorException("Unable to persist database due to an IOException: "
+                                               + e.getMessage());
+                       }
+               }
+       }
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/deserializer/ConfigurationCustomDeserializer.java b/verigraph/src/main/java/it/polito/escape/verify/deserializer/ConfigurationCustomDeserializer.java
new file mode 100644 (file)
index 0000000..5cdd084
--- /dev/null
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.deserializer;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonNode;
+
+import it.polito.escape.verify.exception.InternalServerErrorException;
+import it.polito.escape.verify.model.Configuration;
+
+public class ConfigurationCustomDeserializer extends JsonDeserializer<Configuration> {
+
+       @Override
+       public Configuration deserialize(JsonParser jp, DeserializationContext ctxt)    throws IOException,
+                                                                                                                                                                       JsonProcessingException {
+               try {
+                       JsonNode root = jp.getCodec().readTree(jp);
+
+                       return new Configuration("", "", root);
+               }
+               catch (JsonProcessingException e) {
+                       throw new InternalServerErrorException("Error parsing configuration: " + e.getMessage());
+               }
+               catch (IOException e) {
+                       throw new InternalServerErrorException("I/O error parsing configuration: " + e.getMessage());
+               }
+
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/deserializer/GraphCustomDeserializer.java b/verigraph/src/main/java/it/polito/escape/verify/deserializer/GraphCustomDeserializer.java
new file mode 100644 (file)
index 0000000..f71c996
--- /dev/null
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.deserializer;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+
+import it.polito.escape.verify.exception.BadRequestException;
+import it.polito.escape.verify.exception.InternalServerErrorException;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Node;
+
+
+/**
+ * The Class GraphCustomDeserializer is a custom deserializer for a Graph object
+ */
+public class GraphCustomDeserializer extends JsonDeserializer<Graph>{
+
+       /* (non-Javadoc)
+        * @see com.fasterxml.jackson.databind.JsonDeserializer#deserialize(com.fasterxml.jackson.core.JsonParser, com.fasterxml.jackson.databind.DeserializationContext)
+        */
+       @Override
+       public Graph deserialize(JsonParser jp, DeserializationContext context){
+               JsonNode root = null;
+               try {
+                       root = jp.getCodec().readTree(jp);
+               }
+               catch (JsonProcessingException e) {
+                       throw new InternalServerErrorException("Error parsing a graph: " + e.getMessage());
+               }
+               catch (IOException e) {
+                       throw new InternalServerErrorException("I/O error parsing a graph: " + e.getMessage());
+               }
+
+               JsonNode nodesJson = root.get("nodes");
+
+               if(nodesJson == null)
+                       throw new BadRequestException("Invalid graph");
+
+               List<Node> nodeList = null;
+               try {
+                       nodeList = new ObjectMapper().readValue(nodesJson.toString(), TypeFactory.defaultInstance().constructCollectionType(List.class, Node.class));
+               }
+               catch (JsonParseException e) {
+                       throw new BadRequestException("Invalid content for a graph: " + e.getMessage());
+               }
+               catch (JsonMappingException e) {
+                       throw new BadRequestException("Invalid input json structure for a graph: " + e.getMessage());
+               }
+               catch (IOException e) {
+                       throw new InternalServerErrorException("I/O error parsing a graph: " + e.getMessage());
+               }
+
+               Graph graph = new Graph();
+               if(root.get("id") != null){
+                       long graphId = root.get("id").asLong();
+                       graph.setId(graphId);
+               }
+               Map<Long, Node> nodes = graph.getNodes();
+
+               long numberOfNodes = 0;
+               for (Node node : nodeList){
+                       nodes.put(++numberOfNodes, node);
+               }
+               return graph;
+
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/deserializer/NodeCustomDeserializer.java b/verigraph/src/main/java/it/polito/escape/verify/deserializer/NodeCustomDeserializer.java
new file mode 100644 (file)
index 0000000..fb451db
--- /dev/null
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.deserializer;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+
+import it.polito.escape.verify.exception.BadRequestException;
+import it.polito.escape.verify.exception.InternalServerErrorException;
+import it.polito.escape.verify.model.Configuration;
+import it.polito.escape.verify.model.Neighbour;
+import it.polito.escape.verify.model.Node;
+
+public class NodeCustomDeserializer extends JsonDeserializer<Node> {
+
+       @Override
+       public Node deserialize(JsonParser jp, DeserializationContext context) {
+
+               try {
+                       JsonNode root = jp.getCodec().readTree(jp);
+                       JsonNode neighboursJson = root.get("neighbours");
+                       JsonNode configurationJson = root.get("configuration");
+
+                       String nodeName = root.get("name").asText();
+                       String functionalType = root.get("functional_type").asText();
+
+                       Node node = new Node();
+                       if(root.get("id") != null){
+                               long nodeId = root.get("id").asLong();
+                               node.setId(nodeId);
+                       }
+                       node.setName(nodeName);
+                       node.setFunctional_type(functionalType);
+
+                       if (configurationJson == null)
+                               node.setConfiguration(new Configuration(node.getName(), "", new ObjectMapper().createArrayNode()));
+                       else {
+                               Configuration conf = node.getConfiguration();
+                               conf.setId(node.getName());
+                               conf.setDescription("");
+                               conf.setConfiguration(configurationJson);
+                       }
+
+                       try {
+                               List<Neighbour> neighbourList = new ObjectMapper().readValue(   neighboursJson.toString(),
+                                                                                                                                                               TypeFactory     .defaultInstance()
+                                                                                                                                                                                       .constructCollectionType(       List.class,
+                                                                                                                                                                                                                                               Neighbour.class));
+                               Map<Long, Neighbour> neighbours = node.getNeighbours();
+
+                               long numberOfNeighbours = 0;
+                               for (Neighbour neighbour : neighbourList) {
+                                       neighbours.put(++numberOfNeighbours, neighbour);
+                               }
+
+                               return node;
+                       }
+                       catch (JsonParseException e) {
+                               throw new BadRequestException("Invalid content for a node: " + e.getMessage());
+                       }
+                       catch (JsonMappingException e) {
+                               throw new BadRequestException("Invalid input json structure for a node: " + e.getMessage());
+                       }
+               }
+               catch (JsonProcessingException e) {
+                       throw new InternalServerErrorException("Error parsing a node: " + e.getMessage());
+               }
+               catch (IOException e) {
+                       throw new InternalServerErrorException("I/O error parsing a node: " + e.getMessage());
+               }
+
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/deserializer/PathsMessageBodyReader.java b/verigraph/src/main/java/it/polito/escape/verify/deserializer/PathsMessageBodyReader.java
new file mode 100644 (file)
index 0000000..3b54503
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.deserializer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.ProcessingException;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.Provider;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+
+import it.polito.nffg.neo4j.jaxb.Paths;
+
+@Provider
+@Consumes(MediaType.APPLICATION_XML)
+public class PathsMessageBodyReader implements MessageBodyReader<Paths>{
+
+       @Override
+       public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+               return type == Paths.class;
+       }
+
+       @Override
+       public Paths readFrom(Class<Paths> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+                       MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+                                       throws IOException, WebApplicationException {
+               try {
+               JAXBContext jaxbContext = JAXBContext.newInstance(Paths.class);
+               Paths paths = (Paths) jaxbContext.createUnmarshaller()
+                   .unmarshal(entityStream);
+               return paths;
+           } catch (JAXBException jaxbException) {
+               throw new ProcessingException("Error deserializing a Paths object.",
+                   jaxbException);
+           }
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/exception/BadRequestException.java b/verigraph/src/main/java/it/polito/escape/verify/exception/BadRequestException.java
new file mode 100644 (file)
index 0000000..abbdbf0
--- /dev/null
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.exception;
+
+public class BadRequestException extends RuntimeException {
+
+       /**
+        *
+        */
+       private static final long serialVersionUID = -548472179073745084L;
+
+       public BadRequestException(String message) {
+               super(message);
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/exception/BadRequestExceptionMapper.java b/verigraph/src/main/java/it/polito/escape/verify/exception/BadRequestExceptionMapper.java
new file mode 100644 (file)
index 0000000..8f1ba9c
--- /dev/null
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.exception;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import it.polito.escape.verify.model.ErrorMessage;
+
+@Provider
+public class BadRequestExceptionMapper implements ExceptionMapper<BadRequestException> {
+
+       @Override
+       public Response toResponse(BadRequestException exception) {
+               ErrorMessage errorMessage = new ErrorMessage(   exception.getMessage(),
+                                                                                                               400,
+                                                                                                               "http://localhost:8080/verify/api-docs/");
+               return Response.status(Status.BAD_REQUEST).entity(errorMessage).build();
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/exception/DataNotFoundException.java b/verigraph/src/main/java/it/polito/escape/verify/exception/DataNotFoundException.java
new file mode 100644 (file)
index 0000000..5cd1806
--- /dev/null
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.exception;
+
+public class DataNotFoundException extends RuntimeException {
+
+       /**
+        *
+        */
+       private static final long serialVersionUID = -6012364193903183208L;
+
+       public DataNotFoundException(String message) {
+               super(message);
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/exception/DataNotFoundExceptionMapper.java b/verigraph/src/main/java/it/polito/escape/verify/exception/DataNotFoundExceptionMapper.java
new file mode 100644 (file)
index 0000000..62e3556
--- /dev/null
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.exception;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import it.polito.escape.verify.model.ErrorMessage;
+
+@Provider
+public class DataNotFoundExceptionMapper implements ExceptionMapper<DataNotFoundException> {
+
+       @Override
+       public Response toResponse(DataNotFoundException exception) {
+               ErrorMessage errorMessage = new ErrorMessage(   exception.getMessage(),
+                                                                                                               404,
+                                                                                                               "http://localhost:8080/verify/api-docs/");
+               return Response.status(Status.NOT_FOUND).entity(errorMessage).build();
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/exception/ForbiddenException.java b/verigraph/src/main/java/it/polito/escape/verify/exception/ForbiddenException.java
new file mode 100644 (file)
index 0000000..dc79e97
--- /dev/null
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.exception;
+
+public class ForbiddenException extends RuntimeException {
+
+       /**
+        *
+        */
+       private static final long serialVersionUID = -4658914972167044321L;
+
+       public ForbiddenException(String message) {
+               super(message);
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/exception/ForbiddenExceptionMapper.java b/verigraph/src/main/java/it/polito/escape/verify/exception/ForbiddenExceptionMapper.java
new file mode 100644 (file)
index 0000000..d060b8b
--- /dev/null
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.exception;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import it.polito.escape.verify.model.ErrorMessage;
+
+@Provider
+public class ForbiddenExceptionMapper implements ExceptionMapper<ForbiddenException> {
+
+       @Override
+       public Response toResponse(ForbiddenException exception) {
+               ErrorMessage errorMessage = new ErrorMessage(   exception.getMessage(),
+                                                                                                               403,
+                                                                                                               "http://localhost:8080/verify/api-docs/");
+               return Response.status(Status.FORBIDDEN).entity(errorMessage).build();
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/exception/GenericExceptionMapper.java b/verigraph/src/main/java/it/polito/escape/verify/exception/GenericExceptionMapper.java
new file mode 100644 (file)
index 0000000..96f7caa
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.exception;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.ext.ExceptionMapper;
+
+import it.polito.escape.verify.model.ErrorMessage;
+
+// @Provider
+public class GenericExceptionMapper implements ExceptionMapper<Throwable> {
+
+       @Override
+       public Response toResponse(Throwable exception) {
+               ErrorMessage errorMessage = new ErrorMessage("Generic exception: "      + exception.getMessage(),
+                                                                                                               500,
+                                                                                                               "http://localhost:8080/verify/api-docs/");
+               return Response.status(Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build();
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/exception/InternalServerErrorException.java b/verigraph/src/main/java/it/polito/escape/verify/exception/InternalServerErrorException.java
new file mode 100644 (file)
index 0000000..877edb5
--- /dev/null
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.exception;
+
+public class InternalServerErrorException extends RuntimeException {
+
+       /**
+        *
+        */
+       private static final long serialVersionUID = 156815197709461502L;
+
+       public InternalServerErrorException(String message) {
+               super(message);
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/exception/InternalServerErrorExceptionMapper.java b/verigraph/src/main/java/it/polito/escape/verify/exception/InternalServerErrorExceptionMapper.java
new file mode 100644 (file)
index 0000000..02b6765
--- /dev/null
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.exception;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import it.polito.escape.verify.model.ErrorMessage;
+
+@Provider
+public class InternalServerErrorExceptionMapper implements ExceptionMapper<InternalServerErrorException> {
+
+       @Override
+       public Response toResponse(InternalServerErrorException exception) {
+               ErrorMessage errorMessage = new ErrorMessage(   exception.getMessage(),
+                                                                                                               500,
+                                                                                                               "http://localhost:8080/verify/api-docs/");
+               return Response.status(Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build();
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/model/Configuration.java b/verigraph/src/main/java/it/polito/escape/verify/model/Configuration.java
new file mode 100644 (file)
index 0000000..3498a10
--- /dev/null
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.model;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import it.polito.escape.verify.deserializer.ConfigurationCustomDeserializer;
+import it.polito.escape.verify.serializer.CustomConfigurationSerializer;
+
+@XmlRootElement
+@ApiModel("Configuration")
+@JsonSerialize(using = CustomConfigurationSerializer.class)
+@JsonDeserialize(using = ConfigurationCustomDeserializer.class)
+public class Configuration {
+
+       @ApiModelProperty(required = false, hidden = true)
+       @XmlTransient
+       private String          id;
+
+       @ApiModelProperty(required = false)
+       @XmlTransient
+       private String          description     = "";
+
+       @ApiModelProperty(required = true)
+       private JsonNode        configuration;
+
+       public Configuration() {
+
+       }
+
+       public Configuration(String id, String description, JsonNode configuration) {
+               this.id = id;
+               this.description = description;
+               this.configuration = configuration;
+       }
+
+       public String getId() {
+               return id;
+       }
+
+       public void setId(String id) {
+               this.id = id;
+       }
+
+       public String getDescription() {
+               return description;
+       }
+
+       public void setDescription(String description) {
+               this.description = description;
+       }
+
+       public JsonNode getConfiguration() {
+               return configuration;
+       }
+
+       public void setConfiguration(JsonNode configuration) {
+               this.configuration = configuration;
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/model/Entry.java b/verigraph/src/main/java/it/polito/escape/verify/model/Entry.java
new file mode 100644 (file)
index 0000000..f2fdf14
--- /dev/null
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.model;
+
+public class Entry {
+       private String  direction;
+       private String  destination;
+
+       public Entry(String direction, String destination) {
+               this.direction = direction;
+               this.destination = destination;
+       }
+
+       public String getDirection() {
+               return direction;
+       }
+
+       public void setDirection(String direction) {
+               this.direction = direction;
+       }
+
+       public String getDestination() {
+               return destination;
+       }
+
+       public void setDestination(String destination) {
+               this.destination = destination;
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/model/ErrorMessage.java b/verigraph/src/main/java/it/polito/escape/verify/model/ErrorMessage.java
new file mode 100644 (file)
index 0000000..e0e79d3
--- /dev/null
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.model;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "Error")
+@XmlRootElement
+public class ErrorMessage {
+
+       @ApiModelProperty(example = "Error message")
+       private String  errorMessage;
+       @ApiModelProperty(allowableValues = "400,403,404,500", value = "HTTP error code", example = "[400,403,404,500]")
+       private int             errorCode;
+       @ApiModelProperty(example = "http://localhost:8080/verify/api-docs/")
+       private String  documentation;
+
+       public ErrorMessage() {
+
+       }
+
+       public ErrorMessage(String errorMessage, int errorCode, String documentation) {
+               this.errorMessage = errorMessage;
+               this.errorCode = errorCode;
+               this.documentation = documentation;
+       }
+
+       public String getErrorMessage() {
+               return errorMessage;
+       }
+
+       public void setErrorMessage(String errorMessage) {
+               this.errorMessage = errorMessage;
+       }
+
+       public int getErrorCode() {
+               return errorCode;
+       }
+
+       public void setErrorCode(int errorCode) {
+               this.errorCode = errorCode;
+       }
+
+       public String getDocumentation() {
+               return documentation;
+       }
+
+       public void setDocumentation(String documentation) {
+               this.documentation = documentation;
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/model/Graph.java b/verigraph/src/main/java/it/polito/escape/verify/model/Graph.java
new file mode 100644 (file)
index 0000000..44a2273
--- /dev/null
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.model;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import it.polito.escape.verify.deserializer.GraphCustomDeserializer;
+import it.polito.escape.verify.serializer.CustomMapSerializer;
+
+@ApiModel(value = "Graph")
+@XmlRootElement
+@JsonDeserialize(using = GraphCustomDeserializer.class)
+@JsonInclude(JsonInclude.Include.NON_EMPTY)
+public class Graph {
+
+       @ApiModelProperty(required = false, hidden = true)
+       @XmlTransient
+       private long                    id;
+
+       @ApiModelProperty(name = "nodes", notes = "Nodes", dataType = "List[it.polito.escape.verify.model.Node]")
+       private Map<Long, Node> nodes   = new HashMap<Long, Node>();
+
+       @ApiModelProperty(required = false, hidden = true)
+       @XmlTransient
+       private Set<Link>               links   = new HashSet<Link>();
+
+       public Graph() {
+
+       }
+
+       public Graph(long id) {
+               this.id = id;
+       }
+
+       public long getId() {
+               return id;
+       }
+
+       public void setId(long id) {
+               this.id = id;
+       }
+
+       @JsonSerialize(using = CustomMapSerializer.class)
+       public Map<Long, Node> getNodes() {
+               return nodes;
+       }
+
+       public void setNodes(Map<Long, Node> nodes) {
+               this.nodes = nodes;
+       }
+
+       @XmlTransient
+       public Set<Link> getLinks() {
+               return links;
+       }
+
+       public void setLinks(Set<Link> links) {
+               this.links = links;
+       }
+
+       public void addLink(String url, String rel) {
+               Link link = new Link();
+               link.setLink(url);
+               link.setRel(rel);
+               links.add(link);
+       }
+
+       public Node searchNodeByName(String name) {
+               for (Node node : this.nodes.values()) {
+                       if (node.getName().equals(name))
+                               return node;
+               }
+               return null;
+       }
+
+       public int nodesWithName(String name) {
+               int occurrences = 0;
+               for (Node node : this.nodes.values()) {
+                       if (node.getName().equals(name))
+                               occurrences++;
+
+               }
+               return occurrences;
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/model/Link.java b/verigraph/src/main/java/it/polito/escape/verify/model/Link.java
new file mode 100644 (file)
index 0000000..dc2b4c5
--- /dev/null
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.model;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "Link")
+public class Link {
+       @ApiModelProperty(required = false, hidden = true)
+       private String  link;
+       @ApiModelProperty(required = false, hidden = true)
+       private String  rel;
+
+       public String getLink() {
+               return link;
+       }
+
+       public void setLink(String link) {
+               this.link = link;
+       }
+
+       public String getRel() {
+               return rel;
+       }
+
+       public void setRel(String rel) {
+               this.rel = rel;
+       }
+
+       @Override
+       public int hashCode() {
+               final int prime = 31;
+               int result = 1;
+               result = prime * result + ((link == null) ? 0 : link.hashCode());
+               result = prime * result + ((rel == null) ? 0 : rel.hashCode());
+               return result;
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (obj == null)
+                       return false;
+               if (getClass() != obj.getClass())
+                       return false;
+               Link other = (Link) obj;
+               if (link == null) {
+                       if (other.link != null)
+                               return false;
+               }
+               else if (!link.equals(other.link))
+                       return false;
+               if (rel == null) {
+                       if (other.rel != null)
+                               return false;
+               }
+               else if (!rel.equals(other.rel))
+                       return false;
+               return true;
+       }
+
+}
\ No newline at end of file
diff --git a/verigraph/src/main/java/it/polito/escape/verify/model/Neighbour.java b/verigraph/src/main/java/it/polito/escape/verify/model/Neighbour.java
new file mode 100644 (file)
index 0000000..4b1206c
--- /dev/null
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.model;
+
+import javax.xml.bind.annotation.XmlTransient;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "Neighbour")
+public class Neighbour {
+
+       @ApiModelProperty(required = false, hidden = true)
+       @XmlTransient
+       private long    id;
+
+       @ApiModelProperty(      required = true,
+                                               example = "nat",
+                                               value = "The neighbour name must refer to an existing node of the same graph")
+       private String  name;
+
+       public Neighbour() {
+
+       }
+
+       public Neighbour(long id, String name) {
+               this.id = id;
+               this.name = name;
+       }
+
+       public long getId() {
+               return id;
+       }
+
+       public void setId(long id) {
+               this.id = id;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       @Override
+       public int hashCode() {
+               final int prime = 31;
+               int result = 1;
+               result = prime * result + ((name == null) ? 0 : name.hashCode());
+               return result;
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               else
+                       return false;
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/model/Node.java b/verigraph/src/main/java/it/polito/escape/verify/model/Node.java
new file mode 100644 (file)
index 0000000..9f667ce
--- /dev/null
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.model;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import it.polito.escape.verify.deserializer.NodeCustomDeserializer;
+import it.polito.escape.verify.serializer.CustomMapSerializer;
+
+@ApiModel(value = "Node")
+@XmlRootElement
+@JsonDeserialize(using = NodeCustomDeserializer.class)
+@JsonInclude(JsonInclude.Include.NON_EMPTY)
+public class Node {
+
+       @ApiModelProperty(required = false, hidden = true)
+       @XmlTransient
+       private long                                    id;
+
+       @ApiModelProperty(required = true, example = "ep", value = "The name of the node can be any string")
+       private String                                  name;
+
+       @ApiModelProperty(      required = true,
+                                               example = "endpoint",
+                                               value = "The functional types that are currently supported are: endpoint, firewall, nat, antispam, webclient, webserver, mailclient, mailserver")
+       private String                                  functional_type;
+
+       @ApiModelProperty(required = false, hidden = true)
+       @XmlTransient
+       private Configuration                   configuration   = new Configuration();
+
+       @ApiModelProperty(      name = "neighbours",
+                                               notes = "Neighbours",
+                                               dataType = "List[it.polito.escape.verify.model.Neighbour]")
+       private Map<Long, Neighbour>    neighbours              = new HashMap<Long, Neighbour>();
+
+       @ApiModelProperty(required = false, hidden = true)
+       @XmlTransient
+       private Set<Link>                               links                   = new HashSet<>();
+
+       public Node() {
+
+       }
+
+       public Node(long id, String name, String functional_type, Configuration configuration) {
+               this.id = id;
+               this.name = name;
+               this.functional_type = functional_type;
+               this.configuration = configuration;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public String getFunctional_type() {
+               return functional_type;
+       }
+
+       public void setFunctional_type(String functional_type) {
+               this.functional_type = functional_type;
+       }
+
+       // @XmlTransient
+       public Configuration getConfiguration() {
+               return configuration;
+       }
+
+       public void setConfiguration(Configuration configuration) {
+               this.configuration = configuration;
+       }
+
+       @JsonSerialize(using = CustomMapSerializer.class)
+       public Map<Long, Neighbour> getNeighbours() {
+               return neighbours;
+       }
+
+       public void setNeighbours(Map<Long, Neighbour> neighbours) {
+               this.neighbours = neighbours;
+       }
+
+       public long getId() {
+               return this.id;
+       }
+
+       public void setId(long id) {
+               this.id = id;
+       }
+
+       public Set<Link> getLinks() {
+               return links;
+       }
+
+       public void setLinks(Set<Link> links) {
+               this.links = links;
+       }
+
+       public void addLink(String url, String rel) {
+               Link link = new Link();
+               link.setLink(url);
+               link.setRel(rel);
+               links.add(link);
+       }
+
+       @Override
+       public int hashCode() {
+               final int prime = 31;
+               int result = 1;
+               result = prime * result + ((name == null) ? 0 : name.hashCode());
+               return result;
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               else
+                       return false;
+       }
+
+       public Neighbour searchNeighbourByName(String name) {
+               for (Neighbour neighbour : this.neighbours.values()) {
+                       if (neighbour.getName().equals(name))
+                               return neighbour;
+               }
+               return null;
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/model/Test.java b/verigraph/src/main/java/it/polito/escape/verify/model/Test.java
new file mode 100644 (file)
index 0000000..1127abc
--- /dev/null
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Test {
+       private List<Node>      nodes   = new ArrayList<Node>();
+       private String          result;
+
+       public Test() {
+
+       }
+
+       public Test(List<Node> paths, int result) {
+               switch (result) {
+                       case 0:
+                               this.result = "SAT";
+                               break;
+                       case -1:
+                               this.result = "UNSAT";
+                               break;
+                       case -2:
+                               this.result = "UNKNOWN";
+                               break;
+                       default:
+                               this.result = "UNKNWON";
+                               break;
+               }
+               this.nodes = paths;
+       }
+
+       public Test(List<Node> paths, String result) {
+               this.nodes = paths;
+               this.result = result;
+       }
+
+       public List<Node> getPath() {
+               return nodes;
+       }
+
+       public void setPath(List<Node> paths) {
+               this.nodes = paths;
+       }
+
+       public String getResult() {
+               return result;
+       }
+
+       public void setResult(String result) {
+               this.result = result;
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/model/Verification.java b/verigraph/src/main/java/it/polito/escape/verify/model/Verification.java
new file mode 100644 (file)
index 0000000..60b4ddb
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "Policy verification")
+public class Verification {
+
+       @ApiModelProperty(example = "SAT | UNSAT | UNKNOWN")
+       private String          result;
+       private String comment;
+       private List<Test>      tests   = new ArrayList<Test>();
+
+       public Verification() {
+
+       }
+
+       public Verification(String result) {
+               this.result = result;
+       }
+
+       public Verification(String result, List<Test> tests, String comment){
+               this.result = result;
+               this.tests = tests;
+               this.comment = comment;
+       }
+
+       public Verification(String result, String comment){
+               this.result = result;
+               this.comment = comment;
+       }
+
+       public String getResult() {
+               return result;
+       }
+
+       public void setResult(String result) {
+               this.result = result;
+       }
+
+       public List<Test> getTests() {
+               return tests;
+       }
+
+       public void setTests(List<Test> tests) {
+               this.tests = tests;
+       }
+
+       public String getComment() {
+               return comment;
+       }
+
+       public void setComment(String comment) {
+               this.comment = comment;
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/model/jaxb.properties b/verigraph/src/main/java/it/polito/escape/verify/model/jaxb.properties
new file mode 100644 (file)
index 0000000..5837a4c
--- /dev/null
@@ -0,0 +1 @@
+javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
\ No newline at end of file
diff --git a/verigraph/src/main/java/it/polito/escape/verify/resources/GraphResource.java b/verigraph/src/main/java/it/polito/escape/verify/resources/GraphResource.java
new file mode 100644 (file)
index 0000000..e610f1d
--- /dev/null
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.resources;
+
+import java.net.URI;
+import java.util.List;
+
+import javax.ws.rs.BeanParam;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import it.polito.escape.verify.model.ErrorMessage;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Verification;
+import it.polito.escape.verify.resources.beans.VerificationBean;
+import it.polito.escape.verify.service.GraphService;
+import it.polito.escape.verify.service.VerificationService;
+
+@Path("/graphs")
+@Api(value = "/graphs", description = "Manage graphs")
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+public class GraphResource {
+       GraphService            graphService            = new GraphService();
+       VerificationService     verificationService     = new VerificationService();
+
+       @GET
+       @ApiOperation(  httpMethod = "GET",
+                                       value = "Returns all graphs",
+                                       notes = "Returns an array of graphs",
+                                       response = Graph.class,
+                                       responseContainer = "List")
+       @ApiResponses(value = { @ApiResponse(   code = 200,
+                                                                                       message = "All the graphs have been returned in the message body",
+                                                                                       response = Graph.class,
+                                                                                       responseContainer = "List"),
+                               @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class)})
+       public List<Graph> getGraphs() {
+               return graphService.getAllGraphs();
+       }
+
+       @POST
+       @ApiOperation(  httpMethod = "POST",
+                                       value = "Creates a graph",
+                                       notes = "Creates a signle graph",
+                                       response = Response.class)
+       @ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid graph supplied", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 201, message = "Graph successfully created", response = Graph.class) })
+       public Response addGraph(       @ApiParam(value = "New graph object", required = true) Graph graph,
+                                                               @Context UriInfo uriInfo) {
+               Graph newGraph = graphService.addGraph(graph);
+               String newId = String.valueOf(newGraph.getId());
+               URI uri = uriInfo.getAbsolutePathBuilder().path(newId).build();
+               return Response.created(uri).entity(newGraph).build();
+       }
+
+       @GET
+       @Path("/{graphId}")
+       @ApiOperation(  httpMethod = "GET",
+                                       value = "Returns a graph",
+                                       notes = "Returns a signle graph",
+                                       response = Graph.class)
+       @ApiResponses(value = { @ApiResponse(code = 403, message = "Invalid graph id", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 404, message = "Graph not found", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
+                                                       @ApiResponse(   code = 200,
+                                                                                       message = "The requested graph has been returned in the message body",
+                                                                                       response = Graph.class) })
+       public Graph getGraph(  @ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId,
+                                                       @Context UriInfo uriInfo) {
+               Graph graph = graphService.getGraph(graphId);
+               graph.addLink(getUriForSelf(uriInfo, graph), "self");
+               graph.addLink(getUriForNodes(uriInfo, graph), "nodes");
+               return graph;
+       }
+
+       @PUT
+       @Path("/{graphId}")
+       @ApiOperation(httpMethod = "PUT", value = "Edits a graph", notes = "Edits a single graph", response = Graph.class)
+       @ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid graph object", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 403, message = "Invalid graph id", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 404, message = "Graph not found", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 200, message = "Graph edited successfully", response = Graph.class) })
+       public Graph updateGraph(       @ApiParam(value = "Graph id", required = true) @PathParam("graphId") long id,
+                                                               @ApiParam(value = "Updated graph object", required = true) Graph graph) {
+               graph.setId(id);
+               return graphService.updateGraph(graph);
+       }
+
+       @DELETE
+       @Path("/{graphId}")
+       @ApiOperation(httpMethod = "DELETE", value = "Deletes a graph", notes = "Deletes a signle graph")
+       @ApiResponses(value = { @ApiResponse(code = 403, message = "Invalid graph id", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 204, message = "Graph successfully deleted") })
+       public void deleteGraph(@ApiParam(value = "Graph id", required = true) @PathParam("graphId") long id) {
+               graphService.removeGraph(id);
+       }
+
+       @GET
+       @Path("/{graphId}/policy")
+       @ApiOperation(  httpMethod = "GET",
+                                       value = "Verifies a given policy in a graph",
+                                       notes = "In order to verify a given policy (e.g. 'reachability') all nodes of the desired graph must have a valid configuration.")
+       @ApiResponses(value = { @ApiResponse(   code = 403,
+                                                                                       message = "Invalid graph id or invalid configuration for source and/or destination node",
+                                                                                       response = ErrorMessage.class),
+                                                       @ApiResponse(   code = 404,
+                                                                                       message = "Graph not found or source node not found or destination node not found or configuration for source and/or destination node not available",
+                                                                                       response = ErrorMessage.class),
+                                                       @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),})
+       public Verification verifyGraph(@ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId,
+                                                                       @ApiParam(      value = "'source' and 'destination' must refer to names of existing nodes in the same graph, 'type' refers to the required verification between the two (e.g. 'reachability')",
+                                                                                               required = true) @BeanParam VerificationBean verificationBean) {
+
+               return verificationService.verify(graphId, verificationBean);
+       }
+
+       private String getUriForSelf(UriInfo uriInfo, Graph graph) {
+               String uri = uriInfo.getBaseUriBuilder()
+                                                       .path(GraphResource.class)
+                                                       .path(Long.toString(graph.getId()))
+                                                       .build()
+                                                       .toString();
+               return uri;
+       }
+
+       private String getUriForNodes(UriInfo uriInfo, Graph graph) {
+               String uri = uriInfo.getBaseUriBuilder()
+                                                       .path(GraphResource.class)
+                                                       .path(GraphResource.class, "getNodeResource")
+                                                       // .path(NodeResource.class)
+                                                       .resolveTemplate("graphId", graph.getId())
+                                                       .build()
+                                                       .toString();
+               return uri;
+       }
+
+       @Path("/{graphId}/nodes")
+       public NodeResource getNodeResource() {
+               return new NodeResource();
+       }
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/resources/NeighbourResource.java b/verigraph/src/main/java/it/polito/escape/verify/resources/NeighbourResource.java
new file mode 100644 (file)
index 0000000..63376da
--- /dev/null
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.resources;
+
+import java.net.URI;
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import it.polito.escape.verify.model.ErrorMessage;
+import it.polito.escape.verify.model.Neighbour;
+import it.polito.escape.verify.service.NeighbourService;
+
+//@Path("/")
+@Api( hidden= true, value = "", description = "Manage neighbours" )
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class NeighbourResource {
+       private NeighbourService neighboursService = new NeighbourService();
+
+       @GET
+    @ApiOperation(
+           httpMethod = "GET",
+           value = "Returns all neighbours of a given node belonging to a given graph",
+           notes = "Returns an array of neighbours of a given node belonging to a given graph",
+           response = Neighbour.class,
+           responseContainer = "List")
+       @ApiResponses(value = { @ApiResponse(code = 403, message = "Invalid graph and/or node id", response=ErrorMessage.class),
+                                                       @ApiResponse(code = 404, message = "Graph and/or node not found", response=ErrorMessage.class),
+                                                       @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 200, message = "All the neighbours have been returned in the message body", response=Neighbour.class, responseContainer="List")})
+       public List<Neighbour> getAllNeighbours(
+                       @ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId,
+                       @ApiParam(value = "Node id", required = true) @PathParam("nodeId") long nodeId){
+               return neighboursService.getAllNeighbours(graphId, nodeId);
+       }
+
+       @POST
+    @ApiOperation(
+           httpMethod = "POST",
+           value = "Adds a neighbour to a given node belonging to a given graph",
+           notes = "Adds single neighbour to a given node belonging to a given graph",
+           response = Neighbour.class)
+       @ApiResponses(value = { @ApiResponse(code = 403, message = "Invalid graph and/or node id", response=ErrorMessage.class),
+                                                       @ApiResponse(code = 404, message = "Graph and/or node not found", response=ErrorMessage.class),
+                                                       @ApiResponse(code = 400, message = "Invalid neighbour object", response=ErrorMessage.class),
+                                                       @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 201, message = "Neighbour successfully created", response=Neighbour.class)})
+       public Response addNeighbour(
+                       @ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId,
+                       @ApiParam(value = "Node id", required = true) @PathParam("nodeId") long nodeId,
+                       @ApiParam(value = "New neighbour object. Neighbour name must refer to the name of an existing node of the same graph", required = true) Neighbour neighbour,
+                       @Context UriInfo uriInfo){
+               Neighbour newNeighbour = neighboursService.addNeighbour(graphId, nodeId, neighbour);
+               String newId = String.valueOf(newNeighbour.getId());
+        URI uri = uriInfo.getAbsolutePathBuilder().path(newId).build();
+        return Response.created(uri)
+                               .entity(newNeighbour)
+                               .build();
+       }
+
+       @PUT
+       @Path("{neighbourId}")
+       @ApiOperation(
+           httpMethod = "PUT",
+           value = "Edits a neighbour of a given node belonging to a given graph",
+           notes = "Edits a single neighbour of a given node belonging to a given graph",
+           response = Neighbour.class)
+       @ApiResponses(value = { @ApiResponse(code = 403, message = "Invalid graph and/or node and/or neighbour id", response=ErrorMessage.class),
+                                                       @ApiResponse(code = 404, message = "Graph and/or node and /or neighbour not found", response=ErrorMessage.class),
+                                                       @ApiResponse(code = 400, message = "Invalid neighbour object", response=ErrorMessage.class),
+                                                       @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 200, message = "Neighbour edited successfully", response=Neighbour.class)})
+       public Neighbour updateNeighbour(
+                       @ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId,
+                       @ApiParam(value = "Node id", required = true) @PathParam("nodeId") long nodeId,
+                       @ApiParam(value = "Neighbour id", required = true) @PathParam("neighbourId") long neighbourId,
+                       @ApiParam(value = "Updated neighbour object. Neighbour name must refer to the name of an existing node of the same graph", required = true) Neighbour neighbour){
+               neighbour.setId(neighbourId);
+               return neighboursService.updateNeighbour(graphId, nodeId, neighbour);
+       }
+
+       @DELETE
+       @Path("{neighbourId}")
+       @ApiOperation(
+           httpMethod = "DELETE",
+           value = "Removes a neighbour from a given node belonging to a given graph",
+           notes = "Deletes a single neighbour of a given node belonging to a given graph",
+           response = Neighbour.class)
+       @ApiResponses(value = { @ApiResponse(code = 403, message = "Invalid graph and/or node and/or neighbour id", response=ErrorMessage.class),
+                                                       @ApiResponse(code = 404, message = "Graph and/or node not found", response=ErrorMessage.class),
+                                                       @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 204, message = "Node successfully deleted")})
+       public void deleteNeighbour(
+                       @ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId,
+                       @ApiParam(value = "Node id", required = true) @PathParam("nodeId") long nodeId,
+                       @ApiParam(value = "Neighbour id", required = true) @PathParam("neighbourId") long neighbourId){
+               neighboursService.removeNeighbour(graphId, nodeId, neighbourId);
+       }
+
+       @GET
+       @Path("{neighbourId}")
+       @ApiOperation(
+           httpMethod = "GET",
+           value = "Returns a neighbour of a given node belonging to a given graph",
+           notes = "Returns a single neighbour of a given node belonging to a given graph",
+           response = Neighbour.class)
+       @ApiResponses(value = { @ApiResponse(code = 403, message = "Invalid graph and/or node and/or neighbour id", response=ErrorMessage.class),
+                                                       @ApiResponse(code = 404, message = "Graph and/or node and /or neighbour not found", response=ErrorMessage.class),
+                                                       @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 200, message = "The requested neighbour has been returned in the message body", response=Neighbour.class)})
+       public Neighbour getNeighbour(
+                       @ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId,
+                       @ApiParam(value = "Node id", required = true) @PathParam("nodeId") long nodeId,
+                       @ApiParam(value = "Neighbour id", required = true) @PathParam("neighbourId") long neighbourId){
+               return neighboursService.getNeighbour(graphId, nodeId, neighbourId);
+       }
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/resources/NodeResource.java b/verigraph/src/main/java/it/polito/escape/verify/resources/NodeResource.java
new file mode 100644 (file)
index 0000000..58d4064
--- /dev/null
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.resources;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import it.polito.escape.verify.exception.BadRequestException;
+import it.polito.escape.verify.exception.ForbiddenException;
+import it.polito.escape.verify.model.Configuration;
+import it.polito.escape.verify.model.ErrorMessage;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Neighbour;
+import it.polito.escape.verify.model.Node;
+import it.polito.escape.verify.service.GraphService;
+import it.polito.escape.verify.service.NodeService;
+
+@Api( hidden= true, value = "", description = "Manage nodes" )
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+public class NodeResource {
+
+       NodeService nodeService = new NodeService();
+
+
+    @GET
+    @ApiOperation(
+           httpMethod = "GET",
+           value = "Returns all nodes of a given graph",
+           notes = "Returns an array of nodes belonging to a given graph",
+           response = Node.class,
+           responseContainer = "List")
+    @ApiResponses(value = { @ApiResponse(code = 403, message = "Invalid graph id", response = ErrorMessage.class),
+                                               @ApiResponse(code = 404, message = "Graph not found", response = ErrorMessage.class),
+                                               @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
+                                               @ApiResponse(code = 200, message = "All the nodes have been returned in the message body", response = Node.class, responseContainer = "List") })
+    public List<Node> getNodes(@ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId){
+       return nodeService.getAllNodes(graphId);
+    }
+
+    @POST
+    @ApiOperation(
+           httpMethod = "POST",
+           value = "Creates a node in a given graph",
+           notes = "Creates a single node for a given graph",
+           response = Response.class)
+    @ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid node supplied", response = ErrorMessage.class),
+                                               @ApiResponse(code = 403, message = "Invalid graph id", response = ErrorMessage.class),
+                                               @ApiResponse(code = 404, message = "Graph not found", response = ErrorMessage.class),
+                                               @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
+                                               @ApiResponse(code = 201, message = "Node successfully created", response = Node.class)})
+    public Response addNode(
+               @ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId,
+               @ApiParam(value = "New node object", required = true) Node node,
+               @Context UriInfo uriInfo) {
+        Node newNode = nodeService.addNode(graphId, node);
+        String newId = String.valueOf(newNode.getId());
+        URI uri = uriInfo.getAbsolutePathBuilder().path(newId).build();
+        return Response.created(uri)
+                               .entity(newNode)
+                               .build();
+    }
+
+    @GET
+    @Path("{nodeId}")
+    @ApiOperation(
+           httpMethod = "GET",
+           value = "Returns a node of a given graph",
+           notes = "Returns a single node of a given graph",
+           response = Node.class)
+    @ApiResponses(value = { @ApiResponse(code = 403, message = "Invalid graph and/or node id", response = ErrorMessage.class),
+                                               @ApiResponse(code = 404, message = "Graph and/or node not found", response = ErrorMessage.class),
+                                               @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
+                                               @ApiResponse(code = 200, message = "The requested node has been returned in the message body", response = Node.class)})
+    public Node getNode(
+               @ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId,
+               @ApiParam(value = "Node id", required = true) @PathParam("nodeId") long nodeId,
+               @Context UriInfo uriInfo){
+       Node node = nodeService.getNode(graphId, nodeId);
+       node.addLink(getUriForSelf(uriInfo, graphId, node), "self");
+       node.addLink(getUriForNeighbours(uriInfo, graphId, node), "neighbours");
+       return node;
+    }
+
+    @PUT
+    @Path("{nodeId}/configuration")
+    @ApiOperation(
+           httpMethod = "PUT",
+           value = "Adds/edits a configuration to a node of a given graph",
+           notes = "Configures a node. Once all the nodes of a graph have been configured a given policy can be verified for the graph (e.g. 'reachability' between two nodes).")
+    @ApiResponses(value = { @ApiResponse(code = 403, message = "Invalid graph and/or node id", response = ErrorMessage.class),
+                                               @ApiResponse(code = 404, message = "Graph and/or node not found", response = ErrorMessage.class),
+                                               @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
+                                               @ApiResponse(code = 200, message = "Configuration updated for the requested node")})
+    public void addNodeConfiguration(
+               @ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId,
+               @ApiParam(value = "Node id", required = true) @PathParam("nodeId") long nodeId,
+               @ApiParam(value = "Node configuration", required = true) Configuration nodeConfiguration,
+               @Context UriInfo uriInfo){
+       if (graphId <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + graphId);
+               }
+               if (nodeId <= 0) {
+                       throw new ForbiddenException("Illegal node id: " + nodeId);
+               }
+       Graph graph = new GraphService().getGraph(graphId);
+       if (graph == null){
+               throw new BadRequestException("Graph with id " + graphId + " not found");
+       }
+       Node node = nodeService.getNode(graphId, nodeId);
+       if (node == null){
+               throw new BadRequestException("Node with id " + nodeId + " not found in graph with id " + graphId);
+       }
+       Node nodeCopy = new Node();
+       nodeCopy.setId(node.getId());
+       nodeCopy.setName(node.getName());
+       nodeCopy.setFunctional_type(node.getFunctional_type());
+       Map<Long,Neighbour> nodes = new HashMap<Long,Neighbour>();
+       nodes.putAll(node.getNeighbours());
+       nodeCopy.setNeighbours(nodes);
+       nodeConfiguration.setId(nodeCopy.getName());
+       nodeCopy.setConfiguration(nodeConfiguration);
+
+       Graph graphCopy = new Graph();
+               graphCopy.setId(graph.getId());
+               graphCopy.setNodes(new HashMap<Long, Node>(graph.getNodes()));
+               graphCopy.getNodes().remove(node.getId());
+
+               NodeService.validateNode(graphCopy, nodeCopy);
+       graph.getNodes().put(nodeId, nodeCopy);
+    }
+
+
+       @PUT
+    @Path("{nodeId}")
+    @ApiOperation(
+           httpMethod = "PUT",
+           value = "Edits a node of a given graph",
+           notes = "Edits a single node of a given graph",
+           response = Node.class)
+       @ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid node object", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 403, message = "Invalid graph and/or node id", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 404, message = "Graph and/or node not found", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
+                                                       @ApiResponse(code = 200, message = "Node edited successfully", response = Node.class)})
+    public Node updateNode(
+               @ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId,
+               @ApiParam(value = "Node id", required = true) @PathParam("nodeId") long nodeId,
+               @ApiParam(value = "Updated node object", required = true) Node node){
+       node.setId(nodeId);
+       return nodeService.updateNode(graphId, node);
+    }
+
+    @DELETE
+    @Path("{nodeId}")
+    @ApiOperation(
+           httpMethod = "DELETE",
+           value = "Deletes a node of a given graph",
+           notes = "Deletes a single node of a given graph")
+    @ApiResponses(value = { @ApiResponse(code = 403, message = "Invalid graph and/or node id", response = ErrorMessage.class),
+                            @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
+                                               @ApiResponse(code = 204, message = "Node successfully deleted")})
+    public void deleteNode(
+               @ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId,
+               @ApiParam(value = "Node id", required = true) @PathParam("nodeId") long nodeId){
+       nodeService.removeNode(graphId, nodeId);
+    }
+
+    private String getUriForSelf(UriInfo uriInfo, long graphId, Node node) {
+               String uri = uriInfo.getBaseUriBuilder()
+                //.path(NodeResource.class)
+                .path(GraphResource.class)
+                .path(GraphResource.class, "getNodeResource")
+                .resolveTemplate("graphId", graphId)
+                .path(Long.toString(node.getId()))
+                .build()
+                .toString();
+               return uri;
+       }
+
+    private String getUriForNeighbours(UriInfo uriInfo, long graphId, Node node) {
+               String uri = uriInfo.getBaseUriBuilder()
+                               .path(GraphResource.class)
+                               .path(GraphResource.class, "getNodeResource")
+                               .resolveTemplate("graphId", graphId)
+                               .path(Long.toString(node.getId()))
+                               .path("neighbours")
+                               .build()
+                               .toString();
+//      .path(NodeResource.class)
+//              .path(NodeResource.class, "getNeighbourResource")
+//              .path(NeighbourResource.class)
+//              .resolveTemplate("nodeId", node.getId())
+//              .build()
+//              .toString();
+       return uri;
+       }
+
+       @Path("{nodeId}/neighbours")
+       public NeighbourResource getNeighbourResource(){
+               return new NeighbourResource();
+       }
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/resources/beans/VerificationBean.java b/verigraph/src/main/java/it/polito/escape/verify/resources/beans/VerificationBean.java
new file mode 100644 (file)
index 0000000..d6f9ca6
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.resources.beans;
+
+import javax.ws.rs.QueryParam;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel("Verification")
+public class VerificationBean {
+
+       @ApiModelProperty(example = "webclient", value = "Source node. Must refer to an existing node of the same graph")
+       private @QueryParam("source") String            source;
+
+       @ApiModelProperty(      example = "webserver",
+                                               value = "Destination node. Must refer to an existing node of the same graph")
+       private @QueryParam("destination") String       destination;
+
+       @ApiModelProperty(      example = "reachability",
+                                               value = "Verification policy ('reachability', 'isolation', 'traversal')")
+       private @QueryParam("type") String                      type;
+
+       @ApiModelProperty(      example = "firewall",
+                                               value = "Absent if verification type is 'reachability', equal to the name of a middlebox to be avoided if verification type is 'isolation', equal to the name of a middlebox to be traversed if verification type is 'traversal'")
+       private @QueryParam("middlebox") String         middlebox;
+
+       public String getSource() {
+               return source;
+       }
+
+       public void setSource(String source) {
+               this.source = source;
+       }
+
+       public String getDestination() {
+               return destination;
+       }
+
+       public void setDestination(String destination) {
+               this.destination = destination;
+       }
+
+       public String getType() {
+               return type;
+       }
+
+       public void setType(String type) {
+               this.type = type;
+       }
+
+       public String getMiddlebox() {
+               return middlebox;
+       }
+
+       public void setMiddlebox(String middlebox) {
+               this.middlebox = middlebox;
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/serializer/CustomConfigurationSerializer.java b/verigraph/src/main/java/it/polito/escape/verify/serializer/CustomConfigurationSerializer.java
new file mode 100644 (file)
index 0000000..e28273f
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.serializer;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+import it.polito.escape.verify.exception.InternalServerErrorException;
+import it.polito.escape.verify.model.Configuration;
+
+public class CustomConfigurationSerializer extends JsonSerializer<Configuration> {
+
+       @Override
+       public void serialize(Configuration conf, JsonGenerator jgen, SerializerProvider provider)
+                       throws IOException, JsonProcessingException {
+               try {
+                       jgen.writeObject(conf.getConfiguration());
+               } catch (IOException e) {
+                       throw new InternalServerErrorException("I/O error serializing a configuration object: " + e.getMessage());
+               }
+
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/serializer/CustomMapSerializer.java b/verigraph/src/main/java/it/polito/escape/verify/serializer/CustomMapSerializer.java
new file mode 100644 (file)
index 0000000..e811365
--- /dev/null
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.serializer;
+
+import java.io.IOException;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+import it.polito.escape.verify.exception.InternalServerErrorException;
+
+public class CustomMapSerializer extends JsonSerializer<Map<?, ?>> {
+       @Override
+       public void serialize(final Map<?, ?> value, final JsonGenerator jgen, final SerializerProvider provider) {
+               try {
+                       jgen.writeObject(value.values());
+               } catch (IOException e) {
+                       throw new InternalServerErrorException("I/O error serializing a map: " + e.getMessage());
+               }
+       }
+}
\ No newline at end of file
diff --git a/verigraph/src/main/java/it/polito/escape/verify/service/GraphService.java b/verigraph/src/main/java/it/polito/escape/verify/service/GraphService.java
new file mode 100644 (file)
index 0000000..b34eb08
--- /dev/null
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import it.polito.escape.verify.database.DatabaseClass;
+import it.polito.escape.verify.exception.DataNotFoundException;
+import it.polito.escape.verify.exception.ForbiddenException;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Neighbour;
+import it.polito.escape.verify.model.Node;
+
+public class GraphService {
+
+       private Map<Long, Graph> graphs = DatabaseClass.getInstance().getGraphs();
+
+       public GraphService() {
+
+       }
+
+       public List<Graph> getAllGraphs() {
+               return new ArrayList<Graph>(graphs.values());
+       }
+
+       public Graph getGraph(long id) {
+               if (id <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + id);
+               }
+               Graph graph = graphs.get(id);
+               if (graph == null) {
+                       throw new DataNotFoundException("Graph with id " + id + " not found");
+               }
+               return graph;
+       }
+
+       public Graph updateGraph(Graph graph) {
+               if (graph.getId() <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + graph.getId());
+               }
+               Graph localGraph = graphs.get(graph.getId());
+               if (localGraph == null) {
+                       throw new DataNotFoundException("Graph with id " + graph.getId() + " not found");
+               }
+
+               validateGraph(graph);
+
+//             int numberOfNodes = 0;
+//             for (Node node : graph.getNodes().values()) {
+//
+//                     node.setId(++numberOfNodes);
+//
+//                     int numberOfNodeNeighbours = 0;
+//                     for (Neighbour neighbour : node.getNeighbours().values()) {
+//                             neighbour.setId(++numberOfNodeNeighbours);
+//                     }
+//             }
+
+               for (Map.Entry<Long, Node> nodeEntry : graph.getNodes().entrySet()){
+                       nodeEntry.getValue().setId(nodeEntry.getKey());
+
+                       for (Map.Entry<Long, Neighbour> neighbourEntry : nodeEntry.getValue().getNeighbours().entrySet()){
+                               neighbourEntry.getValue().setId(neighbourEntry.getKey());
+                       }
+               }
+
+               synchronized(this){
+                       graphs.put(graph.getId(), graph);
+                       DatabaseClass.persistDatabase();
+                       return graph;
+               }
+       }
+
+       public Graph removeGraph(long id) {
+               if (id <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + id);
+               }
+               synchronized(this){
+                       return graphs.remove(id);
+               }
+       }
+
+       public Graph addGraph(Graph graph) {
+               validateGraph(graph);
+
+               synchronized (this) {
+                       graph.setId(DatabaseClass.getInstance().getNumberOfGraphs() + 1);
+               }
+//             int numberOfNodes = 0;
+//             for (Node node : graph.getNodes().values()) {
+//
+//                     node.setId(++numberOfNodes);
+//
+//                     int numberOfNodeNeighbours = 0;
+//                     for (Neighbour neighbour : node.getNeighbours().values()) {
+//                             neighbour.setId(++numberOfNodeNeighbours);
+//                     }
+//             }
+
+               for (Map.Entry<Long, Node> nodeEntry : graph.getNodes().entrySet()){
+                       nodeEntry.getValue().setId(nodeEntry.getKey());
+
+                       for (Map.Entry<Long, Neighbour> neighbourEntry : nodeEntry.getValue().getNeighbours().entrySet()){
+                               neighbourEntry.getValue().setId(neighbourEntry.getKey());
+                       }
+               }
+
+               synchronized(this){
+                       graphs.put(graph.getId(), graph);
+                       DatabaseClass.persistDatabase();
+                       return graph;
+               }
+       }
+
+       public static void validateGraph(Graph graph) {
+               for (Node node : graph.getNodes().values()) {
+                       NodeService.validateNode(graph, node);
+               }
+       }
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/service/JsonValidationService.java b/verigraph/src/main/java/it/polito/escape/verify/service/JsonValidationService.java
new file mode 100644 (file)
index 0000000..1ac6c1f
--- /dev/null
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.service;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.apache.commons.lang3.text.WordUtils;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import it.polito.escape.verify.exception.BadRequestException;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Node;
+
+public class JsonValidationService {
+
+       private Graph   graph   = new Graph();
+
+       private Node    node    = new Node();
+
+       public JsonValidationService() {
+
+       }
+
+       public JsonValidationService(Graph graph, Node node) {
+               this.graph = graph;
+               this.node = node;
+       }
+
+       public boolean validateFieldAgainstNodeNames(String value) {
+               for (Node node : this.graph.getNodes().values()) {
+                       if (node.getName().equals(value))
+                               return true;
+               }
+               return false;
+       }
+
+       public void validateFieldsAgainstNodeNames(JsonNode node) {
+               if (node.isTextual()) {
+                       boolean isValid = validateFieldAgainstNodeNames(node.asText());
+                       if (!isValid) {
+                               System.out.println(node.asText() + " is not a valid string!");
+                               throw new BadRequestException("String '"        + node.asText()
+                                                                                               + "' is not valid for the configuration of node '" + this.node.getName()
+                                                                                               + "'");
+                       }
+               }
+               if (node.isArray()) {
+                       for (JsonNode object : node) {
+                               validateFieldsAgainstNodeNames(object);
+                       }
+               }
+               if (node.isObject()) {
+                       Iterator<Entry<String, JsonNode>> iter = node.fields();
+
+                       while (iter.hasNext()) {
+                               Entry<String, JsonNode> item = iter.next();
+                               validateFieldsAgainstNodeNames(item.getValue());
+                       }
+               }
+
+       }
+
+       public boolean validateNodeConfiguration() {
+               String className = WordUtils.capitalize(node.getFunctional_type()) + "Validator";
+
+               Class<?> validator;
+               try {
+                       validator = Class.forName("it.polito.escape.verify.validation." + className);
+               }
+               catch (ClassNotFoundException e) {
+                       System.out.println(className    + " not found, configuration properties of node '" + node.getName()
+                                                               + "' will be validated against node names");
+                       return false;
+               }
+
+               Class<?> graphClass;
+               Class<?> nodeClass;
+               Class<?> configurationClass;
+               try {
+                       graphClass = Class.forName("it.polito.escape.verify.model.Graph");
+                       nodeClass = Class.forName("it.polito.escape.verify.model.Node");
+                       configurationClass = Class.forName("it.polito.escape.verify.model.Configuration");
+               }
+               catch (ClassNotFoundException e) {
+                       throw new RuntimeException("Model classes not found");
+               }
+
+               Class<?>[] paramTypes = new Class[3];
+               paramTypes[0] = graphClass;
+               paramTypes[1] = nodeClass;
+               paramTypes[2] = configurationClass;
+
+               String methodName = "validate";
+
+               Object instance;
+               try {
+                       instance = validator.newInstance();
+               }
+               catch (InstantiationException e) {
+                       throw new RuntimeException("'" + className + "' cannot be instantiated");
+               }
+               catch (IllegalAccessException e) {
+                       throw new RuntimeException("Illegal access to '" + className + "' instantiation");
+               }
+
+               Method myMethod;
+               try {
+                       myMethod = validator.getDeclaredMethod(methodName, paramTypes);
+               }
+               catch (NoSuchMethodException e) {
+                       throw new RuntimeException("'" + methodName + "' method has to be implemented in " + className + " class");
+               }
+               try {
+                       myMethod.invoke(instance, graph, node, node.getConfiguration());
+               }
+               catch (IllegalAccessException e) {
+                       throw new RuntimeException("Illegal access to '" + methodName + "' method in " + className + " instance");
+               }
+               catch (InvocationTargetException e) {
+                       throw new BadRequestException("Validation failed for node '"    + node.getName() + "': "
+                                                                                       + e.getTargetException().getMessage());
+               }
+               return true;
+       }
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/service/NeighbourService.java b/verigraph/src/main/java/it/polito/escape/verify/service/NeighbourService.java
new file mode 100644 (file)
index 0000000..ecf4e69
--- /dev/null
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import it.polito.escape.verify.database.DatabaseClass;
+import it.polito.escape.verify.exception.BadRequestException;
+import it.polito.escape.verify.exception.DataNotFoundException;
+import it.polito.escape.verify.exception.ForbiddenException;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Neighbour;
+import it.polito.escape.verify.model.Node;
+
+public class NeighbourService {
+
+       private Map<Long, Graph> graphs = DatabaseClass.getInstance().getGraphs();
+
+       public List<Neighbour> getAllNeighbours(long graphId, long nodeId) {
+               if (graphId <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + graphId);
+               }
+               if (nodeId <= 0) {
+                       throw new ForbiddenException("Illegal node id: " + nodeId);
+               }
+               Graph graph = graphs.get(graphId);
+               if (graph == null)
+                       throw new DataNotFoundException("Graph with id " + graphId + " not found");
+               Map<Long, Node> nodes = graph.getNodes();
+               Node node = nodes.get(nodeId);
+               if (node == null)
+                       throw new DataNotFoundException("Node with id " + nodeId + " not found in graph with id " + graphId);
+               Map<Long, Neighbour> neighbours = node.getNeighbours();
+               return new ArrayList<Neighbour>(neighbours.values());
+       }
+
+       public Neighbour getNeighbour(long graphId, long nodeId, long neighbourId) {
+               if (graphId <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + graphId);
+               }
+               if (nodeId <= 0) {
+                       throw new ForbiddenException("Illegal node id: " + nodeId);
+               }
+               if (neighbourId <= 0) {
+                       throw new ForbiddenException("Illegal neighbour id: " + neighbourId);
+               }
+               Graph graph = graphs.get(graphId);
+               if (graph == null)
+                       throw new DataNotFoundException("Graph with id " + graphId + " not found");
+               Map<Long, Node> nodes = graph.getNodes();
+               Node node = nodes.get(nodeId);
+               if (node == null) {
+                       throw new DataNotFoundException("Node with id " + nodeId + " not found in graph with id " + graphId);
+               }
+               Map<Long, Neighbour> neighbours = node.getNeighbours();
+               Neighbour neighbour = neighbours.get(neighbourId);
+               if (neighbour == null) {
+                       throw new DataNotFoundException("Neighbour with id "    + neighbourId + " not found for node with id " + nodeId
+                                                                                       + " in graph with id " + graphId);
+               }
+               return neighbour;
+       }
+
+       public Neighbour addNeighbour(long graphId, long nodeId, Neighbour neighbour) {
+               if (graphId <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + graphId);
+               }
+               if (nodeId <= 0) {
+                       throw new ForbiddenException("Illegal node id: " + nodeId);
+               }
+               Graph graph = graphs.get(graphId);
+               if (graph == null)
+                       throw new DataNotFoundException("Graph with id " + graphId + " not found");
+               Map<Long, Node> nodes = graph.getNodes();
+               Node node = nodes.get(nodeId);
+               if (node == null) {
+                       throw new DataNotFoundException("Node with id " + nodeId + " not found in graph with id " + graphId);
+               }
+               Map<Long, Neighbour> neighbours = node.getNeighbours();
+
+               validateNeighbour(graph, node, neighbour);
+
+               synchronized (this) {
+                       neighbour.setId(neighbours.size() + 1);
+                       neighbours.put(neighbour.getId(), neighbour);
+                       DatabaseClass.persistDatabase();
+                       return neighbour;
+               }
+       }
+
+       public Neighbour updateNeighbour(long graphId, long nodeId, Neighbour neighbour) {
+               if (graphId <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + graphId);
+               }
+               if (nodeId <= 0) {
+                       throw new ForbiddenException("Illegal node id: " + nodeId);
+               }
+               if (neighbour.getId() <= 0) {
+                       throw new ForbiddenException("Illegal neighbour id: " + nodeId);
+               }
+               Graph graph = graphs.get(graphId);
+               if (graph == null)
+                       throw new DataNotFoundException("Graph with id " + graphId + " not found");
+               Map<Long, Node> nodes = graph.getNodes();
+               Node node = nodes.get(nodeId);
+               if (node == null) {
+                       throw new DataNotFoundException("Node with id " + nodeId + " not found in graph with id " + graphId);
+               }
+               Map<Long, Neighbour> neighbours = node.getNeighbours();
+               Neighbour currentNeighbour = neighbours.get(neighbour.getId());
+               if (currentNeighbour == null) {
+                       throw new DataNotFoundException("Neighbour with id "    + neighbour.getId() + " not found for node with id "
+                                                                                       + nodeId + " in graph with id " + graphId);
+               }
+
+               validateNeighbour(graph, node, neighbour);
+
+               synchronized (this) {
+                       neighbours.put(neighbour.getId(), neighbour);
+                       DatabaseClass.persistDatabase();
+                       return neighbour;
+               }
+       }
+
+       public Neighbour removeNeighbour(long graphId, long nodeId, long neighbourId) {
+               if (graphId <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + graphId);
+               }
+               if (nodeId <= 0) {
+                       throw new ForbiddenException("Illegal node id: " + nodeId);
+               }
+               if (neighbourId <= 0) {
+                       throw new ForbiddenException("Illegal neighbour id: " + nodeId);
+               }
+               Graph graph = graphs.get(graphId);
+               if (graph == null)
+                       throw new DataNotFoundException("Graph with id " + graphId + " not found");
+               Map<Long, Node> nodes = graph.getNodes();
+               Node node = nodes.get(nodeId);
+               if (node == null) {
+                       throw new DataNotFoundException("Node with id " + nodeId + " not found in graph with id " + graphId);
+               }
+               Map<Long, Neighbour> neighbours = node.getNeighbours();
+
+               synchronized(this){
+                       return neighbours.remove(neighbourId);
+               }
+       }
+
+       public static void validateNeighbour(Graph graph, Node node, Neighbour neighbour) {
+               if (graph == null)
+                       throw new BadRequestException("Neighbour validation failed: cannot validate null graph");
+               if (node == null)
+                       throw new BadRequestException("Neighbour validation failed: cannot validate null node");
+               if (neighbour == null)
+                       throw new BadRequestException("Neighbour validation failed: cannot validate null neighbour");
+
+               if (neighbour.getName() == null)
+                       throw new BadRequestException("Neighbour validation failed: neighbour 'name' field cannot be null");
+               if (neighbour.getName().equals(""))
+                       throw new BadRequestException("Neighbour validation failed: neighbour 'name' field cannot be an empty string");
+
+               Node nodeFound = graph.searchNodeByName(neighbour.getName());
+               if ((nodeFound == null) || (nodeFound.getName().equals(node.getName())))
+                       throw new BadRequestException("Neighbour validation failed: '"  + neighbour.getName()
+                                                                                       + "' is not a valid name for a neighbour of node '" + node.getName() + "'");
+
+               Neighbour neighbourFound = node.searchNeighbourByName(neighbour.getName());
+               if ((neighbourFound != null) && (neighbourFound.equals(neighbour) == false))
+                       throw new BadRequestException("Neighbour validation failed: node '"     + node.getName()
+                                                                                       + "' already has a neighbour named '" + neighbour.getName() + "'");
+       }
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/service/NodeService.java b/verigraph/src/main/java/it/polito/escape/verify/service/NodeService.java
new file mode 100644 (file)
index 0000000..e6ad672
--- /dev/null
@@ -0,0 +1,258 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.service;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+
+import javax.ws.rs.InternalServerErrorException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.github.fge.jsonschema.core.exceptions.ProcessingException;
+import com.github.fge.jsonschema.main.JsonSchema;
+
+import it.polito.escape.verify.database.DatabaseClass;
+import it.polito.escape.verify.exception.BadRequestException;
+import it.polito.escape.verify.exception.DataNotFoundException;
+import it.polito.escape.verify.exception.ForbiddenException;
+import it.polito.escape.verify.model.Configuration;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Neighbour;
+import it.polito.escape.verify.model.Node;
+
+public class NodeService {
+
+       private Map<Long, Graph> graphs = DatabaseClass.getInstance().getGraphs();
+
+       public NodeService() {
+
+       }
+
+       public List<Node> getAllNodes(long graphId) {
+               if (graphId <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + graphId);
+               }
+               Graph graph = graphs.get(graphId);
+               if (graph == null)
+                       throw new DataNotFoundException("Graph with id " + graphId + " not found");
+               Map<Long, Node> nodes = graph.getNodes();
+               return new ArrayList<Node>(nodes.values());
+       }
+
+       public Node getNode(long graphId, long nodeId) {
+               if (graphId <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + graphId);
+               }
+               if (nodeId <= 0) {
+                       throw new ForbiddenException("Illegal node id: " + nodeId);
+               }
+               Graph graph = graphs.get(graphId);
+               if (graph == null)
+                       throw new DataNotFoundException("Graph with id " + graphId + " not found");
+               Map<Long, Node> nodes = graph.getNodes();
+               Node node = nodes.get(nodeId);
+               if (node == null) {
+                       throw new DataNotFoundException("Node with id " + nodeId + " not found in graph with id " + graphId);
+               }
+               return node;
+       }
+
+       public Node updateNode(long graphId, Node node) {
+               if (graphId <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + graphId);
+               }
+               if (node.getId() <= 0) {
+                       throw new ForbiddenException("Illegal node id: " + node.getId());
+               }
+               Graph graph = graphs.get(graphId);
+               if (graph == null)
+                       throw new DataNotFoundException("Graph with id " + graphId + " not found");
+               Map<Long, Node> nodes = graph.getNodes();
+               Node localNode = nodes.get(node.getId());
+               if (localNode == null) {
+                       throw new DataNotFoundException("Node with id " + node.getId() + " not found in graph with id " + graphId);
+               }
+
+               Graph graphCopy = new Graph();
+               graphCopy.setId(graph.getId());
+               graphCopy.setNodes(new HashMap<Long, Node>(graph.getNodes()));
+               graphCopy.getNodes().remove(node.getId());
+
+               // int numberOfNeighbours = 0;
+               // for(Neighbour neighbour : node.getNeighbours().values()){
+               // neighbour.setId(++numberOfNeighbours);
+               // }
+
+               for (Map.Entry<Long, Neighbour> neighbourEntry : node.getNeighbours().entrySet()) {
+                       neighbourEntry.getValue().setId(neighbourEntry.getKey());
+               }
+
+               validateNode(graphCopy, node);
+
+               synchronized (this) {
+                       nodes.put(node.getId(), node);
+                       DatabaseClass.persistDatabase();
+                       return node;
+               }
+       }
+
+       public Node removeNode(long graphId, long nodeId) {
+               if (graphId <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + graphId);
+               }
+               if (nodeId <= 0) {
+                       throw new ForbiddenException("Illegal node id: " + nodeId);
+               }
+               Graph graph = graphs.get(graphId);
+               if (graph == null)
+                       throw new DataNotFoundException("Graph with id " + graphId + " not found");
+               Map<Long, Node> nodes = graph.getNodes();
+
+               synchronized (this) {
+                       return nodes.remove(nodeId);
+               }
+       }
+
+       public Node addNode(long graphId, Node node) {
+               if (graphId <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + graphId);
+               }
+               Graph graph = graphs.get(graphId);
+               if (graph == null)
+                       throw new DataNotFoundException("Graph with id " + graphId + " not found");
+               Map<Long, Node> nodes = graph.getNodes();
+
+               validateNode(graph, node);
+
+               synchronized (this) {
+                       node.setId(DatabaseClass.getInstance().getGraphNumberOfNodes(graphId) + 1);
+               }
+
+               // int numberOfNeighbours = 0;
+
+               for (Map.Entry<Long, Neighbour> neighbourEntry : node.getNeighbours().entrySet()) {
+                       neighbourEntry.getValue().setId(neighbourEntry.getKey());
+               }
+
+               // for (Neighbour neighbour : node.getNeighbours().values()) {
+               // neighbour.setId(++numberOfNeighbours);
+               // }
+
+               synchronized (this) {
+                       nodes.put(node.getId(), node);
+                       DatabaseClass.persistDatabase();
+                       return node;
+               }
+       }
+
+       public Node searchByName(long graphId, String nodeName) {
+               if (graphId <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + graphId);
+               }
+               Graph graph = graphs.get(graphId);
+               if (graph == null)
+                       throw new DataNotFoundException("Graph with id " + graphId + " not found");
+               Map<Long, Node> nodes = graph.getNodes();
+
+               for (Node node : nodes.values()) {
+                       if (node.getName().equals(nodeName))
+                               return node;
+               }
+               return null;
+       }
+
+       public static void validateNode(Graph graph, Node node) {
+               if (graph == null)
+                       throw new BadRequestException("Node validation failed: cannot validate null graph");
+               if (node == null)
+                       throw new BadRequestException("Node validation failed: cannot validate null node");
+
+               if (node.getName() == null)
+                       throw new BadRequestException("Node validation failed: node 'name' field cannot be null");
+               if (node.getFunctional_type() == null)
+                       throw new BadRequestException("Node validation failed: node 'functional_type' field cannot be null");
+
+               if (node.getName().equals(""))
+                       throw new BadRequestException("Node validation failed: node 'name' field cannot be an empty string");
+               if (node.getFunctional_type().equals(""))
+                       throw new BadRequestException("Node validation failed: node 'functional_type' field cannot be an empty string");
+
+               Node nodeFound = graph.searchNodeByName(node.getName());
+               if ((nodeFound != null) && (nodeFound.equals(node) == false))
+                       throw new BadRequestException("Node validation failed: graph already has a node named '"        + node.getName()
+                                                                                       + "'");
+               Configuration configuration = node.getConfiguration();
+               if (configuration != null) {
+                       JsonNode configurationJsonNode = configuration.getConfiguration();
+                       // validate configuration against schema file
+                       validateNodeConfigurationAgainstSchemaFile(node, configurationJsonNode);
+                       JsonValidationService jsonValidator = new JsonValidationService(graph, node);
+                       boolean hasCustomValidator = jsonValidator.validateNodeConfiguration();
+                       if (!hasCustomValidator) {
+                               jsonValidator.validateFieldsAgainstNodeNames(configurationJsonNode);
+                       }
+               }
+
+               // validate neighbours
+               Map<Long, Neighbour> nodeNeighboursMap = node.getNeighbours();
+               if (nodeNeighboursMap == null)
+                       throw new BadRequestException("Node validation failed: node 'neighbours' cannot be null");
+               for (Neighbour neighbour : nodeNeighboursMap.values()) {
+                       NeighbourService.validateNeighbour(graph, node, neighbour);
+               }
+       }
+
+       public static void validateNodeConfigurationAgainstSchemaFile(Node node, JsonNode configurationJson) {
+               String schemaFileName = node.getFunctional_type() + ".json";
+
+               File schemaFile = new File(System.getProperty("catalina.base") + "/webapps/verify/json/" + schemaFileName);
+
+               if (!schemaFile.exists()) {
+                       //if no REST client, try gRPC application
+                       schemaFile = new File("src/main/webapp/json/" + schemaFileName);
+
+                       if (!schemaFile.exists()) {
+                               throw new ForbiddenException("Functional type '"        + node.getFunctional_type()
+                                                                                       + "' is not supported! Please edit 'functional_type' field of node '"
+                                                                                       + node.getName() + "'");
+                       }
+               }
+
+               JsonSchema schemaNode = null;
+               try {
+                       schemaNode = ValidationUtils.getSchemaNode(schemaFile);
+               }
+               catch (IOException e) {
+                       throw new InternalServerErrorException("Unable to load '" + schemaFileName + "' schema file");
+               }
+               catch (ProcessingException e) {
+                       throw new InternalServerErrorException("Unable to resolve '"    + schemaFileName
+                                                                                                       + "' schema file as a schema node");
+               }
+
+               try {
+                       ValidationUtils.validateJson(schemaNode, configurationJson);
+               }
+               catch (ProcessingException e) {
+                       throw new BadRequestException("Something went wrong trying to validate node '"  + node.getName()
+                                                                                       + "' with the following configuration: '" + configurationJson.toString()
+                                                                                       + "' against the json schema '" + schemaFile.getName() + "': "
+                                                                                       + e.getMessage());
+
+               }
+
+       }
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/service/ValidationUtils.java b/verigraph/src/main/java/it/polito/escape/verify/service/ValidationUtils.java
new file mode 100644 (file)
index 0000000..77ef4f7
--- /dev/null
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.service;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.github.fge.jackson.JsonLoader;
+import com.github.fge.jsonschema.core.exceptions.ProcessingException;
+import com.github.fge.jsonschema.core.report.ProcessingMessage;
+import com.github.fge.jsonschema.core.report.ProcessingReport;
+import com.github.fge.jsonschema.main.JsonSchema;
+import com.github.fge.jsonschema.main.JsonSchemaFactory;
+
+public class ValidationUtils {
+
+       public static final String      JSON_V4_SCHEMA_IDENTIFIER               = "http://json-schema.org/draft-04/schema#";
+       public static final String      JSON_SCHEMA_IDENTIFIER_ELEMENT  = "$schema";
+
+       public static JsonNode getJsonNode(String jsonText) throws IOException {
+               return JsonLoader.fromString(jsonText);
+       } // getJsonNode(text) ends
+
+       public static JsonNode getJsonNode(File jsonFile) throws IOException {
+               return JsonLoader.fromFile(jsonFile);
+       } // getJsonNode(File) ends
+
+       public static JsonNode getJsonNode(URL url) throws IOException {
+               return JsonLoader.fromURL(url);
+       } // getJsonNode(URL) ends
+
+       public static JsonNode getJsonNodeFromResource(String resource) throws IOException {
+               return JsonLoader.fromResource(resource);
+       } // getJsonNode(Resource) ends
+
+       public static JsonSchema getSchemaNode(String schemaText) throws IOException, ProcessingException {
+               final JsonNode schemaNode = getJsonNode(schemaText);
+               return _getSchemaNode(schemaNode);
+       } // getSchemaNode(text) ends
+
+       public static JsonSchema getSchemaNode(File schemaFile) throws IOException, ProcessingException {
+               final JsonNode schemaNode = getJsonNode(schemaFile);
+               return _getSchemaNode(schemaNode);
+       } // getSchemaNode(File) ends
+
+       public static JsonSchema getSchemaNode(URL schemaFile) throws IOException, ProcessingException {
+               final JsonNode schemaNode = getJsonNode(schemaFile);
+               return _getSchemaNode(schemaNode);
+       } // getSchemaNode(URL) ends
+
+       public static JsonSchema getSchemaNodeFromResource(String resource) throws IOException, ProcessingException {
+               final JsonNode schemaNode = getJsonNodeFromResource(resource);
+               return _getSchemaNode(schemaNode);
+       } // getSchemaNode() ends
+
+       public static void validateJson(JsonSchema jsonSchemaNode, JsonNode jsonNode) throws ProcessingException {
+               ProcessingReport report = jsonSchemaNode.validate(jsonNode);
+               if (!report.isSuccess()) {
+                       for (ProcessingMessage processingMessage : report) {
+                               throw new ProcessingException(processingMessage);
+                       }
+               }
+       } // validateJson(Node) ends
+
+       public static boolean isJsonValid(JsonSchema jsonSchemaNode, JsonNode jsonNode) throws ProcessingException {
+               ProcessingReport report = jsonSchemaNode.validate(jsonNode);
+               return report.isSuccess();
+       } // validateJson(Node) ends
+
+       public static boolean isJsonValid(String schemaText, String jsonText) throws ProcessingException, IOException {
+               final JsonSchema schemaNode = getSchemaNode(schemaText);
+               final JsonNode jsonNode = getJsonNode(jsonText);
+               return isJsonValid(schemaNode, jsonNode);
+       } // validateJson(Node) ends
+
+       public static boolean isJsonValid(File schemaFile, File jsonFile) throws ProcessingException, IOException {
+               final JsonSchema schemaNode = getSchemaNode(schemaFile);
+               final JsonNode jsonNode = getJsonNode(jsonFile);
+               return isJsonValid(schemaNode, jsonNode);
+       } // validateJson(Node) ends
+
+       public static boolean isJsonValid(URL schemaURL, URL jsonURL) throws ProcessingException, IOException {
+               final JsonSchema schemaNode = getSchemaNode(schemaURL);
+               final JsonNode jsonNode = getJsonNode(jsonURL);
+               return isJsonValid(schemaNode, jsonNode);
+       } // validateJson(Node) ends
+
+       public static void validateJson(String schemaText, String jsonText) throws IOException, ProcessingException {
+               final JsonSchema schemaNode = getSchemaNode(schemaText);
+               final JsonNode jsonNode = getJsonNode(jsonText);
+               validateJson(schemaNode, jsonNode);
+       } // validateJson(text) ends
+
+       public static void validateJson(File schemaFile, File jsonFile) throws IOException, ProcessingException {
+               final JsonSchema schemaNode = getSchemaNode(schemaFile);
+               final JsonNode jsonNode = getJsonNode(jsonFile);
+               validateJson(schemaNode, jsonNode);
+       } // validateJson(File) ends
+
+       public static void validateJson(URL schemaDocument, URL jsonDocument) throws IOException, ProcessingException {
+               final JsonSchema schemaNode = getSchemaNode(schemaDocument);
+               final JsonNode jsonNode = getJsonNode(jsonDocument);
+               validateJson(schemaNode, jsonNode);
+       } // validateJson(URL) ends
+
+       public static void validateJsonResource(String schemaResource, String jsonResource)     throws IOException,
+                                                                                                                                                                               ProcessingException {
+               final JsonSchema schemaNode = getSchemaNode(schemaResource);
+               final JsonNode jsonNode = getJsonNodeFromResource(jsonResource);
+               validateJson(schemaNode, jsonNode);
+       } // validateJsonResource() ends
+
+       private static JsonSchema _getSchemaNode(JsonNode jsonNode) throws ProcessingException {
+               final JsonNode schemaIdentifier = jsonNode.get(JSON_SCHEMA_IDENTIFIER_ELEMENT);
+               if (null == schemaIdentifier) {
+                       ((ObjectNode) jsonNode).put(JSON_SCHEMA_IDENTIFIER_ELEMENT, JSON_V4_SCHEMA_IDENTIFIER);
+               }
+
+               final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
+               return factory.getJsonSchema(jsonNode);
+       } // _getSchemaNode() ends
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/service/VerificationService.java b/verigraph/src/main/java/it/polito/escape/verify/service/VerificationService.java
new file mode 100644 (file)
index 0000000..1d31ae9
--- /dev/null
@@ -0,0 +1,1185 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.service;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+import javax.ws.rs.ProcessingException;
+import javax.xml.bind.JAXBException;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import it.polito.escape.verify.client.Neo4jManagerClient;
+import it.polito.escape.verify.exception.BadRequestException;
+import it.polito.escape.verify.exception.DataNotFoundException;
+import it.polito.escape.verify.exception.ForbiddenException;
+import it.polito.escape.verify.exception.InternalServerErrorException;
+import it.polito.escape.verify.model.Configuration;
+import it.polito.escape.verify.model.Entry;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Neighbour;
+import it.polito.escape.verify.model.Node;
+import it.polito.escape.verify.model.Test;
+import it.polito.escape.verify.model.Verification;
+import it.polito.escape.verify.resources.beans.VerificationBean;
+import it.polito.nffg.neo4j.jaxb.Paths;
+import qj.util.ReflectUtil;
+import qj.util.lang.DynamicClassLoader;
+
+public class VerificationService {
+
+       private static final String     generatorFolder         = System.getProperty("catalina.base")
+                                                                                                               + "/webapps/verify/WEB-INF/classes/tests/j-verigraph-generator";
+
+       private static final String     generatorFolderForGrpc  = "service/src/tests/j-verigraph-generator";
+
+       private String                          testClassGenerator      = generatorFolder + "/test_class_generator.py";
+
+       private String                          testGenerator           = generatorFolder + "/test_generator.py";
+
+       public VerificationService() {
+
+       }
+
+       private Paths getPaths(Graph graph, Node sourceNode, Node destinationNode) {
+
+               String source = sourceNode.getName() + "_" + sourceNode.getId();
+               String destination = destinationNode.getName() + "_" + destinationNode.getId();
+
+               List<String> endpoints = new ArrayList<>();
+               List<String> firewalls = new ArrayList<>();
+               Map<String, List<Entry>> routingTable = new HashMap<>();
+
+               for (Node node : graph.getNodes().values()) {
+                       // if firewall
+                       if (node.getFunctional_type().equals("NF")) {
+                               // add 2 connection points to RT
+                               routingTable.put(node.getName() + "_" + node.getId() + "_in", new ArrayList<Entry>());
+                               routingTable.put(node.getName() + "_" + node.getId() + "_out", new ArrayList<Entry>());
+                               // add node to firewalls
+                               firewalls.add(node.getName() + "_" + node.getId());
+                               // scan neighbours
+                               for (Neighbour neighbour : node.getNeighbours().values()) {
+                                       // check if neighbour is a firewall
+                                       Node hop = graph.searchNodeByName(neighbour.getName());
+                                       // if neighbour is a firewall connect to its input port
+                                       if (hop.getFunctional_type().equals("NF"))
+                                               routingTable.get(node.getName() + "_" + node.getId() + "_out")
+                                                                       .add(new Entry("output", neighbour.getName() + "_" + hop.getId() + "_in"));
+                                       else
+                                                                                                                               // connect
+                                                                                                                               // normally to
+                                                                                                                               // node
+                                                                                                                               routingTable.get(node.getName() + "_" + node.getId()
+                                                                                                                                                                       + "_out")
+                                                                                                                                                       .add(new Entry( "output",
+                                                                                                                                                                                       neighbour.getName()     + "_"
+                                                                                                                                                                                                               + hop.getId()));
+                               }
+                       }
+                       // if endpoint
+                       else {
+                               // add endpoint to RT
+                               routingTable.put(node.getName() + "_" + node.getId(), new ArrayList<Entry>());
+                               // add to endpoints
+                               endpoints.add(node.getName() + "_" + node.getId());
+                               // scan neighbours
+                               for (Neighbour neighbour : node.getNeighbours().values()) {
+                                       // check if neighbour is a firewall
+                                       Node hop = graph.searchNodeByName(neighbour.getName());
+                                       // if neighbour is a firewall connect to its input port
+                                       if (hop.getFunctional_type().equals("NF"))
+                                               routingTable.get(node.getName() + "_" + node.getId())
+                                                                       .add(new Entry("output", neighbour.getName() + "_" + hop.getId() + "_in"));
+                                       else {
+                                               // connect
+                                               // normally to
+                                               // node
+                                               routingTable.get(node.getName() + "_" + node.getId())
+                                                                       .add(new Entry("output", neighbour.getName() + "_" + hop.getId()));
+                                       }
+                               }
+                       }
+
+                       // end node scan
+               }
+               // debug print
+               System.out.println("Endpoints:");
+               for (String endpoint : endpoints) {
+                       System.out.println(endpoint);
+               }
+               System.out.println("Firewalls:");
+               for (String firewall : firewalls) {
+                       System.out.println(firewall);
+               }
+               System.out.println("Source: " + source);
+               System.out.println("Destination: " + destination);
+               for (String key : routingTable.keySet()) {
+                       System.out.println("RT for node " + key);
+                       for (Entry entry : routingTable.get(key)) {
+                               System.out.println("\t" + entry.getDirection() + "->" + entry.getDestination());
+                       }
+               }
+               // end debug print
+
+               Neo4jManagerClient client = new Neo4jManagerClient(     "http://localhost:8080/neo4jmanager/rest/",
+                                                                                                                       source,
+                                                                                                                       destination,
+                                                                                                                       endpoints,
+                                                                                                                       firewalls,
+                                                                                                                       routingTable);
+
+               Paths paths = null;
+               try {
+                       paths = client.getPaths();
+               }
+               catch (JAXBException e) {
+                       throw new InternalServerErrorException("Error generating input for neo4jmanager: " + e.getMessage());
+               }
+               catch (ProcessingException e) {
+                       throw new InternalServerErrorException("Response of neo4jmanager doesn't contain any path: "
+                                                                                                       + e.getMessage());
+               }
+               catch (IllegalStateException e) {
+                       throw new InternalServerErrorException("Error getting a response from neo4jmanager, no input stream for paths or input stream already consumed: "
+                                                                                                       + e.getMessage());
+               }
+               catch (Exception e) {
+                       throw new InternalServerErrorException("Unable to continue due to a neo4jmanager error: " + e.getMessage());
+               }
+
+               return paths;
+
+       }
+
+       private List<String> sanitizePath(String path) {
+               List<String> newPath = new ArrayList<String>();
+               // find all nodes, i.e. all names between parentheses
+               Matcher m = Pattern.compile("\\(([^)]+)\\)").matcher(path);
+               while (m.find()) {
+                       String node = m.group(1);
+
+                       int spaceIndex = node.lastIndexOf("_");
+                       if (spaceIndex != -1) {
+                               node = node.substring(0, spaceIndex);
+                               newPath.add(node);
+                       }
+               }
+               return newPath;
+
+       }
+
+       private List<List<String>> sanitizePaths(Paths paths) {
+               List<List<String>> sanitizedPaths = new ArrayList<List<String>>();
+               for (String path : paths.getPath()) {
+                       System.out.println("Original path: " + path);
+                       List<String> newPath = sanitizePath(path);
+                       sanitizedPaths.add(newPath);
+               }
+               return sanitizedPaths;
+       }
+
+       static private Map<String, Long> toMap(List<String> lst) {
+               return lst.stream().collect(Collectors.groupingBy(s -> s, Collectors.counting()));
+       }
+
+       private void eliminateLoopsInPaths(List<List<String>> sanitizedPaths) {
+               List<List<String>> pathsToBeRemoved = new ArrayList<List<String>>();
+
+               for (List<String> path : sanitizedPaths) {
+                       Map<String, Long> occurrencesMap = toMap(path);
+                       for (long occurrences : occurrencesMap.values()) {
+                               if (occurrences > 1) {
+                                       pathsToBeRemoved.add(path);
+                                       break;
+                               }
+                       }
+               }
+               for (List<String> path : pathsToBeRemoved) {
+                       sanitizedPaths.remove(path);
+               }
+       }
+
+       private void printListsOfStrings(String message, List<List<String>> lists) {
+               System.out.println(message);
+               for (List<String> element : lists) {
+                       System.out.println(element);
+               }
+       }
+
+       private static File createTempDir(String prefix) throws IOException {
+               String tmpDirStr = System.getProperty("java.io.tmpdir");
+               if (tmpDirStr == null) {
+                       throw new IOException("System property 'java.io.tmpdir' does not specify a tmp dir");
+               }
+
+               File tmpDir = new File(tmpDirStr);
+               if (!tmpDir.exists()) {
+                       boolean created = tmpDir.mkdirs();
+                       if (!created) {
+                               throw new IOException("Unable to create tmp dir " + tmpDir);
+                       }
+               }
+
+               File resultDir = null;
+               int suffix = (int) System.currentTimeMillis();
+               int failureCount = 0;
+               do {
+                       resultDir = new File(tmpDir, prefix + suffix % 10000);
+                       suffix++;
+                       failureCount++;
+               } while (resultDir.exists() && failureCount < 50);
+
+               if (resultDir.exists()) {
+                       throw new IOException(failureCount
+                                                                       + " attempts to generate a non-existent directory name failed, giving up");
+               }
+               boolean created = resultDir.mkdir();
+               if (!created) {
+                       throw new IOException("Failed to create tmp directory");
+               }
+
+               return resultDir;
+       }
+
+       @SuppressWarnings("unchecked")
+       private void generateChainsFile(Graph graph, List<List<String>> sanitizedPaths, String chainsFile) {
+               JSONObject root = new JSONObject();
+               JSONArray chains = new JSONArray();
+
+               int chainCounter = 0;
+
+               for (List<String> path : sanitizedPaths) {
+                       Iterator<String> pathsIterator = path.iterator();
+                       JSONObject chain = new JSONObject();
+                       chain.put("id", ++chainCounter);
+                       chain.put("flowspace", "tcp=80");
+                       JSONArray nodes = new JSONArray();
+                       while (pathsIterator.hasNext()) {
+                               String nodeName = (String) pathsIterator.next();
+                               Node currentNode = graph.searchNodeByName(nodeName);
+                               if (currentNode == null) {
+                                       throw new InternalServerErrorException("Unable to generate 'chains.json' for neo4jmanager: node "
+                                                                                                                       + nodeName + " not found");
+                               }
+                               JSONObject node = new JSONObject();
+                               node.put("name", currentNode.getName());
+                               // if(currentNode.getFunctional_type().equals("firewall"))
+                               // node.put("address", "ip_nat");
+                               // else
+                               node.put("address", "ip_" + currentNode.getName());
+                               node.put("functional_type", currentNode.getFunctional_type());
+                               nodes.add(node);
+                               chain.put("nodes", nodes);
+                       }
+                       chains.add(chain);
+               }
+               root.put("chains", chains);
+
+               try (FileWriter file = new FileWriter(chainsFile)) {
+                       file.write(root.toJSONString());
+                       System.out.println("Successfully created 'chains.json' with the following content:");
+                       System.out.println(root);
+               }
+               catch (IOException e) {
+                       throw new InternalServerErrorException("Error saving 'chains.json' for neo4jmanager");
+               }
+
+       }
+
+       @SuppressWarnings("unchecked")
+       private void generateConfigFile(Graph graph, String configFile) {
+               JSONObject root = new JSONObject();
+               JSONArray nodes = new JSONArray();
+
+               for (Node n : graph.getNodes().values()) {
+                       JSONObject node = new JSONObject();
+                       // JSONArray configuration = new JSONArray();
+                       Configuration nodeConfig = n.getConfiguration();
+                       JsonNode configuration = nodeConfig.getConfiguration();
+
+                       node.put("configuration", configuration);
+                       node.put("id", nodeConfig.getId());
+                       node.put("description", nodeConfig.getDescription());
+
+                       nodes.add(node);
+
+               }
+               root.put("nodes", nodes);
+
+               try (FileWriter file = new FileWriter(configFile)) {
+                       file.write(root.toJSONString());
+                       System.out.println("Successfully created 'config.json' with the following content:");
+                       System.out.println(root);
+               }
+               catch (IOException e) {
+                       throw new InternalServerErrorException("Error saving 'config.json' for neo4jmanager");
+               }
+
+       }
+
+       private void printCommand(String[] cmd) {
+               for (String c : cmd) {
+                       System.out.printf(c + " ");
+               }
+               System.out.println("");
+       }
+
+       private String platfromIndependentPath(String path) {
+               path = path.replaceAll("/", Matcher.quoteReplacement(Character.toString(File.separatorChar)));
+               return path;
+       }
+
+       private void generateTestScenarios(String chainsFile, String configFile, String scenarioFile) {
+
+               String[] cmd = {        "python", platfromIndependentPath(testClassGenerator), "-c",
+                                                       platfromIndependentPath(chainsFile), "-f", platfromIndependentPath(configFile), "-o",
+                                                       platfromIndependentPath(scenarioFile) };
+               printCommand(cmd);
+
+               ProcessBuilder pb = new ProcessBuilder(cmd);
+               pb.redirectErrorStream(true);
+               Process process;
+               try {
+                       process = pb.start();
+
+                       BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+                       String line;
+                       while ((line = reader.readLine()) != null)
+                               System.out.println("test_class_generator.py: " + line);
+                       process.waitFor();
+                       if (process.exitValue() != 0) {
+                               throw new InternalServerErrorException("Unable to generate test scenario file for the verification request: test_class_generator returned "
+                                                                                                               + process.exitValue());
+                       }
+               }
+               catch (IOException e) {
+                       throw new InternalServerErrorException("Error generating tests for Z3: unable to execute generator");
+               }
+               catch (InterruptedException e) {
+                       throw new InternalServerErrorException("Error generating tests for Z3: generator got interrupted during execution");
+               }
+
+       }
+
+       private void generateTests(     int scenariosCounter, String scenariosBasename, String source, String destination,
+                                                               String testsBasename) {
+
+               List<String> scenarios = new ArrayList<String>();
+               List<String> tests = new ArrayList<String>();
+               for (int i = 0; i < scenariosCounter; i++) {
+                       scenarios.add(scenariosBasename + "_" + (i + 1) + ".java");
+                       tests.add(testsBasename + "_" + (i + 1) + ".java");
+               }
+
+               for (int i = 0; i < scenariosCounter; i++) {
+                       String[] cmd = {        "python", platfromIndependentPath(testGenerator), "-i",
+                                                               platfromIndependentPath(scenarios.get(i)), "-o", platfromIndependentPath(tests.get(i)),
+                                                               "-s", source, "-d", destination };
+                       printCommand(cmd);
+
+                       ProcessBuilder pb = new ProcessBuilder(cmd);
+                       pb.redirectErrorStream(true);
+                       Process process;
+                       try {
+                               process = pb.start();
+
+                               BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+                               String line;
+                               while ((line = reader.readLine()) != null)
+                                       System.out.println("test_generator.py: " + line);
+                               process.waitFor();
+                               if (process.exitValue() != 0) {
+                                       throw new InternalServerErrorException("Unable to generate test file for the verification request: test_generator returned "
+                                                                                                                       + process.exitValue());
+                               }
+                       }
+                       catch (IOException e) {
+                               throw new InternalServerErrorException("Error generating tests for Z3: unable to execute generator");
+                       }
+                       catch (InterruptedException e) {
+                               throw new InternalServerErrorException("Error generating tests for Z3: generator got interrupted during execution");
+                       }
+
+               }
+
+       }
+
+       private void prepareForCompilationAndExecution( int scenariosCounter, String scenarioBasename, String testBasename,
+                                                                                                       List<File> sourceFiles, List<File> classFiles) {
+               for (int i = 0; i < scenariosCounter; i++) {
+                       String scenario = scenarioBasename + "_" + (i + 1) + ".java";
+                       sourceFiles.add(new File(scenario));
+                       System.out.println("Scenario file " + scenario + " added to compilation");
+
+                       String testSource = testBasename + "_" + (i + 1) + ".java";
+                       String testClass = testBasename + "_" + (i + 1);
+
+                       sourceFiles.add(new File(testSource));
+                       System.out.println("Test file " + testSource + " added to copilation");
+                       classFiles.add(new File(testClass));
+                       System.out.println("Test file " + testClass + " added to execution");
+               }
+       }
+
+       private void compileFiles(List<File> files, String folder) {
+
+               JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+               if (compiler == null) {
+                       throw new InternalServerErrorException("Error getting the Java compiler: JDK >= 1.8 required");
+               }
+               StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
+
+               try {
+                       // fileManager.setLocation(StandardLocation.CLASS_OUTPUT,
+                       // Arrays.asList(new File(projectFolder)));
+
+                       // String z3 = "/usr/lib/com.microsoft.z3.jar";
+                       // List<String> optionList = new ArrayList<String>();
+                       // optionList.add("-classpath");
+                       // optionList.add(System.getProperty("java.class.path") + ":" + z3);
+                       List<String> optionList = new ArrayList<String>();
+                       optionList.add("-d");
+                       optionList.add(folder);
+                       DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
+
+                       boolean success = compiler
+                                                                               .getTask(       null,
+                                                                                                       fileManager,
+                                                                                                       diagnostics,
+                                                                                                       optionList,
+                                                                                                       null,
+                                                                                                       fileManager.getJavaFileObjectsFromFiles(files))
+                                                                               .call();
+                       if (!success) {
+                               Locale myLocale = Locale.getDefault();
+                               StringBuilder msg = new StringBuilder();
+                               msg.append("Error compiling Z3 test files: ");
+                               for (Diagnostic<? extends JavaFileObject> err : diagnostics.getDiagnostics()) {
+                                       msg.append('\n');
+                                       msg.append(err.getKind());
+                                       msg.append(": ");
+                                       if (err.getSource() != null) {
+                                               msg.append(err.getSource().getName());
+                                       }
+                                       msg.append(':');
+                                       msg.append(err.getLineNumber());
+                                       msg.append(": ");
+                                       msg.append(err.getMessage(myLocale));
+                               }
+                               throw new InternalServerErrorException(msg.toString());
+                       }
+                       fileManager.close();
+
+               }
+               catch (IOException e) {
+                       throw new InternalServerErrorException("Unable to set the location of the Z3 test files to be compiled");
+               }
+
+       }
+
+       private int runIt(File filename, String folder) {
+               int endIndex = filename.getName().lastIndexOf(".");
+               String filenameNoExtension;
+               if (endIndex == -1) {
+                       filenameNoExtension = filename.getName();
+               }
+               else {
+                       filenameNoExtension = filename.getName().substring(0, endIndex);
+                       if (!filenameNoExtension.matches("\\w+")) {
+                               filenameNoExtension = filename.getName();
+                       }
+               }
+
+               System.out.println("Filename is: " + filenameNoExtension);
+               try {
+                       Class<?> userClass = new DynamicClassLoader(folder).load("tests." + filenameNoExtension);
+                       Object context = ReflectUtil.newInstance(userClass);
+                       Object result = ReflectUtil.invoke("run", context);
+                       return (int) result;
+               }
+               catch (Exception e) {
+                       StringWriter errors = new StringWriter();
+                       e.printStackTrace(new PrintWriter(errors));
+                       throw new InternalServerErrorException("Error executing Z3 tests: "     + e.getMessage()
+                                                                                                       + ". There are errors in the Z3 model.");
+               }
+       }
+
+       private List<Test> runFiles(String folder, List<List<String>> paths, Graph graph, List<File> files) {
+               List<Test> tests = new ArrayList<Test>();
+               for (int i = 0; i < files.size(); i++) {
+                       System.out.println("Running test file \"" + files.get(i).getAbsolutePath() + "\"");
+                       int result = runIt(files.get(i), folder);
+                       System.out.println("Execution returned: " + result);
+
+                       List<Node> path = new ArrayList<Node>();
+                       for (String nodeString : paths.get(i)) {
+                               Node node = graph.searchNodeByName(nodeString);
+                               path.add(node);
+                       }
+                       Test t = new Test(path, result);
+                       tests.add(t);
+               }
+
+               return tests;
+       }
+
+       @SuppressWarnings("unused")
+       private static boolean deleteDir(File dir) {
+               if (dir.isDirectory()) {
+                       String[] children = dir.list();
+                       for (int i = 0; i < children.length; i++) {
+                               boolean success = deleteDir(new File(dir, children[i]));
+                               if (!success) {
+                                       return false;
+                               }
+                       }
+               }
+
+               return dir.delete();
+
+       }
+
+       @SuppressWarnings("unused")
+       private void deleteFilesWithPrefix(String directory, String prefix, String extension) {
+               final File scenarioFolder = new File(directory);
+               final File[] scenarioFiles = scenarioFolder.listFiles(new FilenameFilter() {
+
+                       @Override
+                       public boolean accept(final File dir, final String name) {
+                               return name.matches(prefix + ".*\\." + extension);
+                       }
+               });
+               for (final File file : scenarioFiles) {
+                       if (!file.delete()) {
+                               System.err.println("Can't remove " + file.getAbsolutePath());
+                       }
+                       else {
+                               System.out.println("Removed file " + file.getAbsolutePath());
+                       }
+               }
+       }
+
+       public Verification verify(long graphId, VerificationBean verificationBean) {
+               if (graphId <= 0) {
+                       throw new ForbiddenException("Illegal graph id: " + graphId);
+               }
+               GraphService graphService = new GraphService();
+               Graph graph = graphService.getGraph(graphId);
+               if (graph == null) {
+                       throw new DataNotFoundException("Graph with id " + graphId + " not found");
+               }
+               String source = verificationBean.getSource();
+               String destination = verificationBean.getDestination();
+               String type = verificationBean.getType();
+               if (source == null || source.equals("")) {
+                       throw new BadRequestException("Please specify the 'source' parameter in your request");
+               }
+               if (destination == null || destination.equals("")) {
+                       throw new BadRequestException("Please specify the 'destination' parameter in your request");
+               }
+               if (type == null || type.equals("")) {
+                       throw new BadRequestException("Please specify the 'type' parameter in your request");
+               }
+
+               Node sourceNode = graph.searchNodeByName(verificationBean.getSource());
+               Node destinationNode = graph.searchNodeByName(verificationBean.getDestination());
+
+               if (sourceNode == null) {
+                       throw new BadRequestException("The 'source' parameter '" + source + "' is not valid, please insert the name of an existing node");
+               }
+               if (destinationNode == null) {
+                       throw new BadRequestException("The 'destination' parameter '" + destination + "' is not valid, please insert the name of an existing node");
+               }
+               if ((!type.equals("reachability")) && (!type.equals("isolation")) && (!type.equals("traversal"))) {
+                       throw new BadRequestException("The 'type' parameter '"  + type
+                                                                                       + "' is not valid: valid types are: 'reachability', 'isolation' and 'traversal'");
+               }
+
+               Verification v = null;
+               String middlebox;
+               Node middleboxNode;
+               switch (type) {
+                       case "reachability":
+                               v = reachabilityVerification(graph, sourceNode, destinationNode);
+                               break;
+                       case "isolation":
+                               middlebox = verificationBean.getMiddlebox();
+                               if (middlebox == null || middlebox.equals("")) {
+                                       throw new BadRequestException("Please specify the 'middlebox' parameter in your request");
+                               }
+
+                               middleboxNode = graph.searchNodeByName(middlebox);
+                               if (middleboxNode == null) {
+                                       throw new BadRequestException("The 'middlebox' parameter '" + middlebox + "' is not valid, please insert the name of an existing node");
+                               }
+                               if (middleboxNode.getFunctional_type().equals("endpoint")) {
+                                       throw new BadRequestException("'"       + middlebox
+                                                                                                       + "' is of type 'endpoint', please choose a valid middlebox");
+                               }
+                               v = isolationVerification(graph, sourceNode, destinationNode, middleboxNode);
+                               break;
+                       case "traversal":
+                               middlebox = verificationBean.getMiddlebox();
+                               if (middlebox == null || middlebox.equals("")) {
+                                       throw new BadRequestException("Please specify the 'middlebox' parameter in your request");
+                               }
+
+                               middleboxNode = graph.searchNodeByName(middlebox);
+                               if (middleboxNode == null) {
+                                       throw new BadRequestException("The 'middlebox' parameter '" + middlebox + "' is not valid, please insert the name of an existing node");
+                               }
+                               if (middleboxNode.getFunctional_type().equals("endpoint")) {
+                                       throw new BadRequestException("'"       + middlebox
+                                                                                                       + "' is of type 'endpoint', please choose a valid middlebox");
+                               }
+                               v = traversalVerification(graph, sourceNode, destinationNode, middleboxNode);
+                               break;
+                       default:
+                               break;
+               }
+
+               return v;
+       }
+
+       private Verification isolationVerification(Graph graph, Node sourceNode, Node destinationNode, Node middleboxNode) {
+
+               Paths paths = getPaths(graph, sourceNode, destinationNode);
+               if (paths.getPath().size() == 0) {
+                       return new Verification("UNSAT",
+                                                                       "There are no available paths between '"        + sourceNode.getName() + "' and '"
+                                                                                               + destinationNode.getName() + "'");
+               }
+
+               List<List<String>> sanitizedPaths = sanitizePaths(paths);
+
+               printListsOfStrings("Before loops removal", sanitizedPaths);
+
+               eliminateLoopsInPaths(sanitizedPaths);
+
+               printListsOfStrings("After loops removal", sanitizedPaths);
+
+               if (sanitizedPaths.isEmpty()) {
+                       return new Verification("UNSAT",
+                                                                       "There are no available paths between '"        + sourceNode.getName() + "' and '"
+                                                                                               + destinationNode.getName() + "'");
+               }
+
+               List<Test> tests = extractTestsFromPaths(graph, sanitizedPaths, "UNKNWON");
+
+               extractPathsWithMiddlebox(sanitizedPaths, middleboxNode.getName());
+
+               if (sanitizedPaths.isEmpty()) {
+                       return new Verification("UNSAT",
+                                                                       tests,
+                                                                       "There are no available paths between '"        + sourceNode.getName() + "' and '"
+                                                                                       + destinationNode.getName() + "' which traverse middlebox '"
+                                                                                       + middleboxNode.getName() + "'. See below all the available paths.");
+               }
+
+               printListsOfStrings("Paths with middlebox '" + middleboxNode.getName() + "'", sanitizedPaths);
+
+               File tempDir = null;
+
+               try {
+                       tempDir = createTempDir("isolation");
+               }
+               catch (IOException e) {
+                       throw new InternalServerErrorException("Unable to perform verification: " + e.getMessage());
+               }
+
+               String chainsFile = tempDir.getAbsolutePath() + "/chains.json";
+               generateChainsFile(graph, sanitizedPaths, chainsFile);
+
+               String configFile = tempDir.getAbsolutePath() + "/config.json";
+               generateConfigFile(graph, configFile);
+
+               String isolationScenariosBasename = tempDir.getAbsolutePath() + "/IsolationScenario";
+               try{
+                       generateTestScenarios(chainsFile, configFile, isolationScenariosBasename);
+               }catch(Exception ex){
+                       testClassGenerator = generatorFolderForGrpc + "/test_class_generator.py";
+                       generateTestScenarios(chainsFile, configFile, isolationScenariosBasename);
+               }
+
+               String isolationTestsBasename = tempDir.getAbsolutePath() + "/IsolationTest";
+               try{
+                       generateTests(  sanitizedPaths.size(),
+                                       isolationScenariosBasename,
+                                       sourceNode.getName(),
+                                       middleboxNode.getName(),
+                                       isolationTestsBasename);
+               }catch(InternalServerErrorException ex){
+                       testGenerator = generatorFolderForGrpc + "/test_generator.py";
+                       generateTests(  sanitizedPaths.size(),
+                                       isolationScenariosBasename,
+                                       sourceNode.getName(),
+                                       middleboxNode.getName(),
+                                       isolationTestsBasename);
+               }
+
+               List<File> sourceFiles = new ArrayList<File>();
+               List<File> classFiles = new ArrayList<File>();
+               prepareForCompilationAndExecution(      sanitizedPaths.size(),
+                               isolationScenariosBasename,
+                                                                                       isolationTestsBasename,
+                                                                                       sourceFiles,
+                                                                                       classFiles);
+
+               compileFiles(sourceFiles, tempDir.getAbsolutePath());
+
+               tests = runFiles(tempDir.getAbsolutePath(), sanitizedPaths, graph, classFiles);
+
+               return evaluateIsolationResults(tests,
+                                                                               sourceNode.getName(),
+                                                                               destinationNode.getName(),
+                                                                               middleboxNode.getName());
+
+       }
+
+       private List<Test> extractTestsFromPaths(Graph graph, List<List<String>> paths, String result) {
+               List<Test> tests = new ArrayList<Test>();
+               for (List<String> path : paths) {
+                       List<Node> nodes = new ArrayList<Node>();
+                       for (String nodeName : path) {
+                               nodes.add(graph.searchNodeByName(nodeName));
+                       }
+                       tests.add(new Test(nodes, result));
+               }
+               return tests;
+       }
+
+       private Verification evaluateIsolationResults(  List<Test> tests, String source, String destination,
+                                                                                                       String middlebox) {
+               Verification v = new Verification();
+               boolean isSat = false;
+               int unsatCounter = 0;
+               for (Test t : tests) {
+                       v.getTests().add(t);
+
+                       if (t.getResult().equals("SAT")) {
+                               isSat = true;
+                       }
+                       else if (t.getResult().equals("UNKNOWN")) {
+                               v.setResult("UNKNWON");
+                               v.setComment("Isolation property with source '" + source + "', destination '" + destination
+                                                               + "' and middlebox '" + middlebox + "' is UNKNOWN because although '" + source
+                                                               + "' cannot reach '" + middlebox + "' in any path from '" + source + "' to '"
+                                                               + destination + "' which traverses middlebox '" + middlebox
+                                                               + "' at least one reachability test between '" + source + "' and '" + middlebox
+                                                               + "' returned UNKNOWN (see below all the paths that have been checked)");
+                       }
+                       else if (t.getResult().equals("UNSAT")) {
+                               unsatCounter++;
+                       }
+               }
+               if (isSat) {
+                       v.setResult("UNSAT");
+                       v.setComment("Isolation property with source '" + source + "', destination '" + destination
+                                                       + "' and middlebox '" + middlebox + "' is UNSATISFIED because reachability between '"
+                                                       + source + "' and '" + middlebox + "' is SATISFIED in at least one path between '" + source
+                                                       + "' and '" + destination + "' which traverses middlebox '" + middlebox
+                                                       + "' (see below all the paths that have been checked)");
+               }
+               else if (unsatCounter == tests.size()) {
+                       v.setResult("SAT");
+                       v.setComment("Isolation property with source '" + source + "', destination '" + destination
+                                                       + "' and middlebox '" + middlebox + "' is SATISFIED because reachability between '" + source
+                                                       + "' and '" + middlebox + "' is UNSATISFIED in all paths between '" + source + "' and '"
+                                                       + destination + "' which traverse middlebox '" + middlebox
+                                                       + "' (see below all the paths that have been checked)");
+               }
+               return v;
+
+       }
+
+       private void extractPathsWithMiddlebox(List<List<String>> sanitizedPaths, String middleboxName) {
+               List<List<String>> pathsToBeRemoved = new ArrayList<List<String>>();
+               for (List<String> path : sanitizedPaths) {
+                       boolean middleboxFound = false;
+                       for (String node : path) {
+                               if (node.equals(middleboxName)) {
+                                       middleboxFound = true;
+                                       break;
+                               }
+                       }
+                       if (!middleboxFound) {
+                               pathsToBeRemoved.add(path);
+                       }
+               }
+
+               for (List<String> path : pathsToBeRemoved) {
+                       sanitizedPaths.remove(path);
+               }
+
+       }
+
+       private void extractPathsWithoutMiddlebox(List<List<String>> sanitizedPaths, String middleboxName) {
+               List<List<String>> pathsToBeRemoved = new ArrayList<List<String>>();
+               for (List<String> path : sanitizedPaths) {
+                       boolean middleboxFound = false;
+                       for (String node : path) {
+                               if (node.equals(middleboxName)) {
+                                       middleboxFound = true;
+                                       break;
+                               }
+                       }
+                       if (middleboxFound) {
+                               pathsToBeRemoved.add(path);
+                       }
+               }
+
+               for (List<String> path : pathsToBeRemoved) {
+                       sanitizedPaths.remove(path);
+               }
+
+       }
+
+       private Verification traversalVerification(Graph graph, Node sourceNode, Node destinationNode, Node middleboxNode) {
+
+               Paths paths = getPaths(graph, sourceNode, destinationNode);
+               if (paths.getPath().size() == 0) {
+                       return new Verification("UNSAT",
+                                                                       "There are no available paths between '"        + sourceNode.getName() + "' and '"
+                                                                                               + destinationNode.getName() + "'");
+               }
+
+               List<List<String>> pathsBetweenSourceAndDestination = sanitizePaths(paths);
+
+               printListsOfStrings("Before loops removal", pathsBetweenSourceAndDestination);
+
+               eliminateLoopsInPaths(pathsBetweenSourceAndDestination);
+
+               printListsOfStrings("After loops removal", pathsBetweenSourceAndDestination);
+
+               if (pathsBetweenSourceAndDestination.isEmpty()) {
+                       return new Verification("UNSAT",
+                                                                       "There are no available paths between '"        + sourceNode.getName() + "' and '"
+                                                                                               + destinationNode.getName() + "'");
+               }
+
+               List<Test> tests = extractTestsFromPaths(graph, pathsBetweenSourceAndDestination, "UNKNOWN");
+
+               List<List<String>> pathsWithMiddlebox = new ArrayList<List<String>>();
+               for (List<String> path : pathsBetweenSourceAndDestination) {
+                       pathsWithMiddlebox.add(path);
+               }
+
+               extractPathsWithMiddlebox(pathsWithMiddlebox, middleboxNode.getName());
+
+               if (pathsWithMiddlebox.isEmpty()) {
+                       return new Verification("UNSAT",
+                                                                       tests,
+                                                                       "There are no paths between '"  + sourceNode.getName() + "' and '"
+                                                                                       + destinationNode.getName() + "' which traverse middlebox '"
+                                                                                       + middleboxNode.getName() + "'. See below all the available paths");
+               }
+
+               printListsOfStrings("Paths with middlebox '" + middleboxNode.getName() + "'", pathsWithMiddlebox);
+
+               File tempDir = null;
+
+               try {
+                       tempDir = createTempDir("traversal");
+               }
+               catch (IOException e) {
+                       throw new InternalServerErrorException("Unable to perform verification: " + e.getMessage());
+               }
+
+               String chainsFile = tempDir.getAbsolutePath() + "/chains.json";
+               generateChainsFile(graph, pathsWithMiddlebox, chainsFile);
+
+               String configFile = tempDir.getAbsolutePath() + "/config.json";
+               generateConfigFile(graph, configFile);
+
+               String traversalScenariosBasename = tempDir.getAbsolutePath() + "/TraversalScenario";
+               try{
+                       generateTestScenarios(chainsFile, configFile, traversalScenariosBasename);
+               }catch(Exception ex){
+                       testClassGenerator = generatorFolderForGrpc + "/test_class_generator.py";
+                       generateTestScenarios(chainsFile, configFile, traversalScenariosBasename);
+               }
+
+               String traversalTestsBasename = tempDir.getAbsolutePath() + "/TraversalTest";
+               try{
+                       generateTests(  pathsWithMiddlebox.size(),
+                                       traversalScenariosBasename,
+                                       sourceNode.getName(),
+                                       destinationNode.getName(),
+                                       traversalTestsBasename);
+               }catch(InternalServerErrorException ex){
+                       testGenerator = generatorFolderForGrpc + "/test_generator.py";
+                       generateTests(  pathsWithMiddlebox.size(),
+                                       traversalScenariosBasename,
+                                       sourceNode.getName(),
+                                       destinationNode.getName(),
+                                       traversalTestsBasename);
+               }
+               List<File> sourceFiles = new ArrayList<File>();
+               List<File> classFiles = new ArrayList<File>();
+               prepareForCompilationAndExecution(      pathsWithMiddlebox.size(),
+                                                                                       traversalScenariosBasename,
+                                                                                       traversalTestsBasename,
+                                                                                       sourceFiles,
+                                                                                       classFiles);
+
+               compileFiles(sourceFiles, tempDir.getAbsolutePath());
+
+               tests = runFiles(tempDir.getAbsolutePath(), pathsWithMiddlebox, graph, classFiles);
+
+               for (Test t : tests) {
+                       if (t.getResult().equals("UNSAT")) {
+                               return new Verification("UNSAT",
+                                                                               tests,
+                                                                               "There is at least a path between '"    + sourceNode.getName() + "' and '"
+                                                                                               + destinationNode.getName() + "' traversing middlebox '"
+                                                                                               + middleboxNode.getName() + "' where '" + sourceNode.getName()
+                                                                                               + "' cannot reach '" + destinationNode.getName()
+                                                                                               + "'. See below the paths that have been checked");
+                       }
+                       if (t.getResult().equals("UNKNOWN")) {
+                               return new Verification("UNKNOWN",
+                                                                               tests,
+                                                                               "There is at least a path between '"    + sourceNode.getName() + "' and '"
+                                                                                               + destinationNode.getName() + "' traversing middlebox '"
+                                                                                               + middleboxNode.getName() + "' where it is not guaranteed that '"
+                                                                                               + sourceNode.getName() + "' can effectively reach '"
+                                                                                               + destinationNode.getName()
+                                                                                               + "'. See below the paths that have been checked");
+                       }
+               }
+
+               extractPathsWithoutMiddlebox(pathsBetweenSourceAndDestination, middleboxNode.getName());
+               printListsOfStrings("Paths without middlebox '" + middleboxNode.getName() + "'", pathsBetweenSourceAndDestination);
+
+               if (pathsBetweenSourceAndDestination.isEmpty()) {
+                       return new Verification("SAT",
+                                                                       tests,
+                                                                       "All the paths between node '"  + sourceNode.getName() + "' and '"
+                                                                                       + destinationNode.getName() + "' traverse middlebox '"
+                                                                                       + middleboxNode.getName() + "'");
+               }
+
+               tempDir = null;
+
+               try {
+                       tempDir = createTempDir("traversal");
+               }
+               catch (IOException e) {
+                       throw new InternalServerErrorException("Unable to perform verification: " + e.getMessage());
+               }
+
+               chainsFile = tempDir.getAbsolutePath() + "/chains.json";
+               generateChainsFile(graph, pathsBetweenSourceAndDestination, chainsFile);
+
+               configFile = tempDir.getAbsolutePath() + "/config.json";
+               generateConfigFile(graph, configFile);
+
+               traversalScenariosBasename = tempDir.getAbsolutePath() + "/TraversalScenario";
+               generateTestScenarios(chainsFile, configFile, traversalScenariosBasename);
+
+               traversalTestsBasename = tempDir.getAbsolutePath() + "/TraversalTest";
+               generateTests(  pathsBetweenSourceAndDestination.size(),
+                                               traversalScenariosBasename,
+                                               sourceNode.getName(),
+                                               destinationNode.getName(),
+                                               traversalTestsBasename);
+
+               sourceFiles = new ArrayList<File>();
+               classFiles = new ArrayList<File>();
+               prepareForCompilationAndExecution(      pathsBetweenSourceAndDestination.size(),
+                                                                                       traversalScenariosBasename,
+                                                                                       traversalTestsBasename,
+                                                                                       sourceFiles,
+                                                                                       classFiles);
+
+               compileFiles(sourceFiles, tempDir.getAbsolutePath());
+
+               tests = runFiles(tempDir.getAbsolutePath(), pathsBetweenSourceAndDestination, graph, classFiles);
+
+               return evaluateTraversalResults(tests,
+                                                                               sourceNode.getName(),
+                                                                               destinationNode.getName(),
+                                                                               middleboxNode.getName());
+
+       }
+
+       private Verification evaluateTraversalResults(  List<Test> tests, String source, String destination,
+                                                                                                       String middlebox) {
+               Verification v = new Verification();
+               boolean isSat = false;
+               int unsatCounter = 0;
+               for (Test t : tests) {
+                       v.getTests().add(t);
+
+                       if (t.getResult().equals("SAT")) {
+                               isSat = true;
+                       }
+                       else if (t.getResult().equals("UNKNOWN")) {
+                               v.setResult("UNKNWON");
+                               v.setComment("There is at least one path from '"        + source + "' to '" + destination
+                                                               + "' that doesn't traverse middlebox '" + middlebox
+                                                               + "' (see below all the paths that have been checked)");
+                       }
+                       else if (t.getResult().equals("UNSAT")) {
+                               unsatCounter++;
+                       }
+               }
+               if (isSat) {
+                       v.setResult("UNSAT");
+                       v.setComment("There is at least one path from '"        + source + "' to '" + destination
+                                                       + "' that doesn't traverse middlebox '" + middlebox
+                                                       + "' (see below all the paths that have been checked)");
+               }
+               else if (unsatCounter == tests.size()) {
+                       v.setResult("SAT");
+                       v.setComment("The only available paths from '"  + source + "' to '" + destination
+                                                       + "' are those that traverse middlebox '" + middlebox
+                                                       + "' (see below the alternative paths that have been checked and are unusable)");
+               }
+               return v;
+       }
+
+       private Verification reachabilityVerification(Graph graph, Node sourceNode, Node destinationNode) {
+               Paths paths = getPaths(graph, sourceNode, destinationNode);
+
+               if (paths.getPath().size() == 0) {
+                       return new Verification("UNSAT",
+                                                                       "There are no available paths between '"        + sourceNode.getName() + "' and '"
+                                                                                               + destinationNode.getName() + "'");
+               }
+
+               List<List<String>> sanitizedPaths = sanitizePaths(paths);
+
+               printListsOfStrings("Before loops removal", sanitizedPaths);
+
+               eliminateLoopsInPaths(sanitizedPaths);
+
+               printListsOfStrings("After loops removal", sanitizedPaths);
+
+               if (sanitizedPaths.isEmpty()) {
+                       return new Verification("UNSAT",
+                                                                       "There are no available paths between '"        + sourceNode.getName() + "' and '"
+                                                                                               + destinationNode.getName() + "'");
+               }
+
+               File tempDir = null;
+
+               try {
+                       tempDir = createTempDir("reachability");
+               }
+               catch (IOException e) {
+                       throw new InternalServerErrorException("Unable to perform verification: " + e.getMessage());
+               }
+
+               String chainsFile = tempDir.getAbsolutePath() + "/chains.json";
+               generateChainsFile(graph, sanitizedPaths, chainsFile);
+
+               String configFile = tempDir.getAbsolutePath() + "/config.json";
+               generateConfigFile(graph, configFile);
+
+               String reachabilityScenariosBasename = tempDir.getAbsolutePath() + "/ReachabilityScenario";
+               try{
+                       generateTestScenarios(chainsFile, configFile, reachabilityScenariosBasename);
+               }catch(InternalServerErrorException ex){
+                       testClassGenerator = generatorFolderForGrpc + "/test_class_generator.py";
+                       generateTestScenarios(chainsFile, configFile, reachabilityScenariosBasename);
+               }
+
+
+               String reachabilityTestsBasename = tempDir.getAbsolutePath() + "/ReachabilityTest";
+               try{
+                       generateTests(  sanitizedPaths.size(),
+                                       reachabilityScenariosBasename,
+                                       sourceNode.getName(),
+                                       destinationNode.getName(),
+                                       reachabilityTestsBasename);
+               }catch(InternalServerErrorException ex){
+                       testGenerator = generatorFolderForGrpc + "/test_generator.py";
+                       generateTests(  sanitizedPaths.size(),
+                                       reachabilityScenariosBasename,
+                                       sourceNode.getName(),
+                                       destinationNode.getName(),
+                                       reachabilityTestsBasename);
+               }
+               List<File> sourceFiles = new ArrayList<File>();
+               List<File> classFiles = new ArrayList<File>();
+               prepareForCompilationAndExecution(      sanitizedPaths.size(),
+                                                                                       reachabilityScenariosBasename,
+                                                                                       reachabilityTestsBasename,
+                                                                                       sourceFiles,
+                                                                                       classFiles);
+
+               compileFiles(sourceFiles, tempDir.getAbsolutePath());
+
+               List<Test> tests = runFiles(tempDir.getAbsolutePath(), sanitizedPaths, graph, classFiles);
+
+               return evaluateReachabilityResult(tests, sourceNode.getName(), destinationNode.getName());
+       }
+
+       private Verification evaluateReachabilityResult(List<Test> tests, String source, String destination) {
+               Verification v = new Verification();
+               boolean sat = false;
+               int unsat = 0;
+               for (Test t : tests) {
+                       v.getTests().add(t);
+
+                       if (t.getResult().equals("SAT")) {
+                               sat = true;
+                       }
+                       else if (t.getResult().equals("UNKNOWN")) {
+                               v.setResult("UNKNWON");
+                               v.setComment("Reachability from '"      + source + "' to '" + destination
+                                                               + "' is unknown. See all the checked paths below");
+                       }
+                       else if (t.getResult().equals("UNSAT")) {
+                               unsat++;
+                       }
+               }
+               if (sat) {
+                       v.setResult("SAT");
+                       v.setComment("There is at least one path '"     + source + "' can use to reach '" + destination
+                                                       + "'. See all the available paths below");
+               }
+               else if (unsat == tests.size()) {
+                       v.setResult("UNSAT");
+                       v.setComment("There isn't any path '"   + source + "' can use to reach '" + destination
+                                                       + "'. See all the checked paths below");
+               }
+               return v;
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/test/MultiThreadedTestCase.java b/verigraph/src/main/java/it/polito/escape/verify/test/MultiThreadedTestCase.java
new file mode 100644 (file)
index 0000000..7989b37
--- /dev/null
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import javax.ws.rs.core.Response;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import it.polito.escape.verify.client.VerifyClient;
+import it.polito.escape.verify.client.VerifyClientException;
+import it.polito.escape.verify.model.Configuration;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Node;
+
+public class MultiThreadedTestCase {
+
+       private void testUpdateGraphStatus(final int threadCount) throws InterruptedException, ExecutionException, JsonParseException, JsonMappingException, IOException, VerifyClientException {
+               final VerifyClient verifyClient = new VerifyClient("http://localhost:8080/verify/api");
+
+               Response retrieveGraphResponse = verifyClient.retrieveGraph(1);
+               String responseString = retrieveGraphResponse.readEntity(String.class);
+               System.out.println(responseString);
+
+               Graph graph = new ObjectMapper().readValue(responseString, Graph.class);
+
+               UpdateGraph task = new UpdateGraph(verifyClient, 1, graph);
+
+               List<MultiThreadedTestCase.UpdateGraph> tasks = Collections.nCopies(threadCount, task);
+               ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
+
+               List<Future<Response>> futures = executorService.invokeAll(tasks);
+               List<Integer> resultList = new ArrayList<Integer>(futures.size());
+
+               // Check for exceptions
+               for (Future<Response> future : futures) {
+                       // Throws an exception if an exception was thrown by the task.
+                       resultList.add(future.get().getStatus());
+               }
+               // Validate the dimensions
+               Assert.assertEquals(threadCount, futures.size());
+               List<Integer> expectedList = new ArrayList<Integer>(threadCount);
+               for (int i = 1; i <= threadCount; i++) {
+                       expectedList.add(200);
+               }
+               // Validate expected results
+               Assert.assertEquals(expectedList, resultList);
+       }
+
+       private void testUpdateGraph(final int threadCount) throws InterruptedException, ExecutionException, JsonParseException, JsonMappingException, IOException, VerifyClientException {
+               final VerifyClient verifyClient = new VerifyClient("http://localhost:8080/verify/api");
+
+               Response retrieveGraphResponse = verifyClient.retrieveGraph(2L);
+               String responseString = retrieveGraphResponse.readEntity(String.class);
+               System.out.println(responseString);
+
+               Graph graph = new ObjectMapper().readValue(responseString, Graph.class);
+
+               Node nodeToEdit = graph.getNodes().get(1L);
+               nodeToEdit.setFunctional_type("endpoint");
+               nodeToEdit.setConfiguration(new Configuration(nodeToEdit.getName(), "", new ObjectMapper().createArrayNode()));
+
+               String graphAsString = new ObjectMapper().writeValueAsString(graph);
+               System.out.println(graphAsString);
+
+               UpdateGraph task = new UpdateGraph(verifyClient, 2, graph);
+
+               List<MultiThreadedTestCase.UpdateGraph> tasks = Collections.nCopies(threadCount, task);
+               ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
+
+               List<Future<Response>> futures = executorService.invokeAll(tasks);
+               List<String> resultList = new ArrayList<String>(futures.size());
+
+               // Check for exceptions
+               for (Future<Response> future : futures) {
+                       // Throws an exception if an exception was thrown by the task.
+                       resultList.add(future.get().readEntity(String.class));
+               }
+               // Validate dimensions
+               Assert.assertEquals(threadCount, futures.size());
+
+               List<String> expectedList = new ArrayList<String>(threadCount);
+               for (int i = 1; i <= threadCount; i++) {
+                       expectedList.add(graphAsString);
+               }
+               // Validate expected results
+               Assert.assertEquals(expectedList, resultList);
+       }
+
+       private void testCreateGraphStatus(final int threadCount, Graph graph) throws InterruptedException, ExecutionException, JsonParseException, JsonMappingException, IOException {
+               final VerifyClient verifyClient = new VerifyClient("http://localhost:8080/verify/api");
+
+               CreateGraph task = new CreateGraph(verifyClient, graph);
+
+               List<MultiThreadedTestCase.CreateGraph> tasks = Collections.nCopies(threadCount, task);
+               ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
+
+               List<Future<Response>> futures = executorService.invokeAll(tasks);
+               List<Integer> resultList = new ArrayList<Integer>(futures.size());
+
+               // Check for exceptions
+               for (Future<Response> future : futures) {
+                       // Throws an exception if an exception was thrown by the task.
+                       resultList.add(future.get().getStatus());
+               }
+               // Validate the IDs
+               Assert.assertEquals(threadCount, futures.size());
+
+               List<Integer> expectedList = new ArrayList<Integer>(threadCount);
+               for (int i = 1; i <= threadCount; i++) {
+                       expectedList.add(201);
+               }
+               // Validate expected results
+               Assert.assertEquals(expectedList, resultList);
+       }
+
+       private int randInt(int min, int max){
+               Random rand = new Random();
+           int randomNum = rand.nextInt((max - min) + 1) + min;
+           return randomNum;
+       }
+
+       @Test
+       public void updateGraphStatusCheck() throws InterruptedException, ExecutionException, JsonParseException, JsonMappingException, IOException, VerifyClientException {
+               testUpdateGraphStatus(64);
+       }
+
+       @Test
+       public void updateGraphResponseCheck() throws InterruptedException, ExecutionException, JsonParseException, JsonMappingException, IOException, VerifyClientException {
+               testUpdateGraph(16);
+       }
+
+       @Test
+       public void createGraphStatusCheck() throws JsonParseException, JsonMappingException, InterruptedException, ExecutionException, IOException {
+               Graph graph = new Graph();
+               testCreateGraphStatus(8, graph);
+       }
+
+       class UpdateGraph implements Callable<Response> {
+
+               private VerifyClient    verifyClient;
+
+               private int                             graphId;
+
+               private Graph                   graph;
+
+               public UpdateGraph(VerifyClient verifyClient, int graphId, Graph graph) {
+                       this.graphId = graphId;
+                       this.graph = graph;
+                       this.verifyClient = verifyClient;
+               }
+
+               @Override
+               public Response call() throws Exception {
+                       Thread.sleep(randInt(0,2000));
+                       Response updateGraphResponse = this.verifyClient.updateGraph(this.graphId, this.graph);
+                       return updateGraphResponse;
+               }
+       }
+
+       class CreateGraph implements Callable<Response> {
+
+               private VerifyClient    verifyClient;
+
+               private Graph                   graph;
+
+               public CreateGraph(VerifyClient verifyClient, Graph graph) {
+                       this.graph = graph;
+                       this.verifyClient = verifyClient;
+               }
+
+               @Override
+               public Response call() throws Exception {
+                       Thread.sleep(randInt(0,2000));
+                       return this.verifyClient.createGraph(this.graph);
+               }
+               
+       }
+}
\ No newline at end of file
diff --git a/verigraph/src/main/java/it/polito/escape/verify/test/Scalability.java b/verigraph/src/main/java/it/polito/escape/verify/test/Scalability.java
new file mode 100644 (file)
index 0000000..3039ca0
--- /dev/null
@@ -0,0 +1,409 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.test;
+
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import it.polito.escape.verify.client.VerifyClient;
+import it.polito.escape.verify.client.VerifyClientException;
+import it.polito.escape.verify.model.Configuration;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Neighbour;
+import it.polito.escape.verify.model.Node;
+import it.polito.escape.verify.model.Verification;
+
+public class Scalability {
+
+       private VerifyClient client = new VerifyClient("http://localhost:8080/verify/api");
+
+       public static void main(String[] args) throws VerifyClientException {
+               Scalability s = new Scalability();
+
+               reachabilityTest(s, 10);
+
+               isolationTest(s,1500);
+               traversalTest(s,600);
+       }
+
+       private static void reachabilityTest(Scalability s, int n) throws VerifyClientException {
+               System.out.printf("Reachability test with N=" + n + ": ");
+               printTimestamp();
+               Graph graph = generateNatScenario(n);
+               Graph createdGraph = s.client.createGraph(graph).readEntity(Graph.class);
+               Verification result = s.client.getReachability(createdGraph.getId(), "client", "server");
+               System.out.println("Test returned " + result.getResult());
+               System.out.printf("Finished reachability test with N=" + n + ": ");
+               printTimestamp();
+               System.out.println();
+       }
+
+       private static void isolationTest(Scalability s, int n) throws VerifyClientException {
+               System.out.printf("Isolation test with N=" + n + ": ");
+               printTimestamp();
+               Graph graph = generateNatScenario(n);
+               Graph createdGraph = s.client.createGraph(graph).readEntity(Graph.class);
+               Verification result = s.client.getIsolation(createdGraph.getId(), "client", "server", "firewall");
+               System.out.println("Test returned " + result.getResult());
+               System.out.printf("Finished isolation test with N=" + n + ": ");
+               printTimestamp();
+               System.out.println();
+       }
+
+       private static void traversalTest(Scalability s, int n) throws VerifyClientException {
+               System.out.printf("Traversal test with N=" + n + ": ");
+               printTimestamp();
+               Graph graph = generateNatScenario(n);
+               Graph createdGraph = s.client.createGraph(graph).readEntity(Graph.class);
+               Verification result = s.client.getTraversal(createdGraph.getId(), "client", "server", "firewall");
+               System.out.println("Test returned " + result.getResult());
+//             System.out.println("Result explanation: " + result.getComment());
+               System.out.printf("Finished traversal test with N=" + n + ": ");
+               printTimestamp();
+               System.out.println();
+       }
+
+       private static void printTimestamp() {
+               java.util.Date date= new java.util.Date();
+               System.out.println(new Timestamp(date.getTime()));
+       }
+
+       private static Graph generateNatScenario(int n) {
+               List<Node> nodes = new ArrayList<Node>();
+
+               Node client = new Node();
+               client.setName("client");
+               client.setFunctional_type("endhost");
+               ArrayNode clientConfigArray = new ObjectMapper().createArrayNode();
+               JsonNode clientConfig = new ObjectMapper().createObjectNode();
+               ((ObjectNode)clientConfig).put("url", "www.facebook.com");
+               ((ObjectNode)clientConfig).put("body", "word");
+               ((ObjectNode)clientConfig).put("destination","server");
+               ((ObjectNode)clientConfig).put("protocol", "HTTP_REQUEST");
+               clientConfigArray.add(clientConfig);
+               client.setConfiguration(new Configuration(client.getName(),"", clientConfigArray));
+
+               Map<Long, Neighbour> clientNeighbours = new HashMap<Long, Neighbour>();
+               clientNeighbours.put(1L, new Neighbour(1L, "nat1"));
+               client.setNeighbours(clientNeighbours );
+               //add client to list
+               nodes.add(client);
+
+               for(int i=0; i< n;i++){
+                       Node nat = new Node();
+                       nat.setId(i+1);
+                       nat.setName("nat" + (i+1));
+                       nat.setFunctional_type("nat");
+                       ArrayNode configArray = new ObjectMapper().createArrayNode();
+
+                       Map<Long, Neighbour> natNeighbours = new HashMap<Long, Neighbour>();
+
+                       //set left neighbour for each node except the first
+                       if(nat.getId() != 1){
+                               natNeighbours.put(1L, new Neighbour(1L, "nat" + i));
+                               configArray.add("client");
+                               for (int j=1; j <= i; j++){
+                                       configArray.add("nat" + j);
+                               }
+                       }
+                       //first nat: set only client as neighbour and natted node
+                       else{
+                               natNeighbours.put(1L, new Neighbour(1L, "client"));
+                               configArray.add("client");
+                       }
+                       //set right neighbour for each node except the last
+                       if(nat.getId() != n){
+                               natNeighbours.put(2L, new Neighbour(1L, "nat" + (i+2)));
+                       }
+                       //last nat: set server as neighbour
+                       else{
+                               natNeighbours.put(2L, new Neighbour(1L, "server"));
+                       }
+
+                       nat.setNeighbours(natNeighbours);
+                       nat.setConfiguration(new Configuration(nat.getName(),"", configArray));
+                       
+                       //add nat to list
+                       nodes.add(nat);
+               }
+
+               Node server = new Node();
+               server.setName("server");
+               server.setFunctional_type("webserver");
+               ArrayNode serverConfigArray = new ObjectMapper().createArrayNode();
+               server.setConfiguration(new Configuration(server.getName(),"", serverConfigArray));
+
+               Map<Long, Neighbour> serverNeighbours = new HashMap<Long, Neighbour>();
+               serverNeighbours.put(1L, new Neighbour(1L, "nat" + (n)));
+               server.setNeighbours(serverNeighbours );
+
+               //add server to list
+               nodes.add(server);
+
+               //create graph
+               Graph g = new Graph();
+               Map<Long, Node> graphNodes = new HashMap<Long, Node>();
+               long index = 1L;
+               for (Node node : nodes){
+                       graphNodes.put(index, node);
+                       index++;
+               }
+               g.setNodes(graphNodes);
+
+               return g;
+       }
+
+       private static Graph generateFirewallScenario(int n) {
+               List<Node> nodes = new ArrayList<Node>();
+
+               Node client = new Node();
+               client.setName("client");
+               client.setFunctional_type("endhost");
+               ArrayNode clientConfigArray = new ObjectMapper().createArrayNode();
+               JsonNode clientConfig = new ObjectMapper().createObjectNode();
+               ((ObjectNode)clientConfig).put("url", "www.facebook.com");
+               ((ObjectNode)clientConfig).put("body", "word");
+               ((ObjectNode)clientConfig).put("destination","server");
+               ((ObjectNode)clientConfig).put("protocol", "HTTP_REQUEST");
+               clientConfigArray.add(clientConfig);
+               client.setConfiguration(new Configuration(client.getName(),"", clientConfigArray));
+
+               Map<Long, Neighbour> clientNeighbours = new HashMap<Long, Neighbour>();
+               clientNeighbours.put(1L, new Neighbour(1L, "firewall1"));
+               client.setNeighbours(clientNeighbours );
+               //add client to list
+               nodes.add(client);
+
+               for(int i=0; i< n;i++){
+                       Node firewall = new Node();
+                       firewall.setId(i+1);
+                       firewall.setName("firewall" + (i+1));
+                       firewall.setFunctional_type("firewall");
+                       ArrayNode configArray = new ObjectMapper().createArrayNode();
+
+                       Map<Long, Neighbour> natNeighbours = new HashMap<Long, Neighbour>();
+
+                       //set left neighbour for each node except the first
+                       if(firewall.getId() != 1){
+                               natNeighbours.put(1L, new Neighbour(1L, "firewall" + i));
+                       }
+                       //first firewall: set only client as neighbour and natted node
+                       else{
+                               natNeighbours.put(1L, new Neighbour(1L, "client"));
+                       }
+                       //set right neighbour for each node except the last
+                       if(firewall.getId() != n){
+                               natNeighbours.put(2L, new Neighbour(1L, "firewall" + (i+2)));
+                       }
+                       //last firewall: set server as neighbour
+                       else{
+                               natNeighbours.put(2L, new Neighbour(1L, "server"));
+                       }
+
+                       firewall.setNeighbours(natNeighbours);
+                       firewall.setConfiguration(new Configuration(firewall.getName(),"", configArray));
+
+                       //add nat to list
+                       nodes.add(firewall);
+               }
+
+               Node server = new Node();
+               server.setName("server");
+               server.setFunctional_type("webserver");
+               ArrayNode serverConfigArray = new ObjectMapper().createArrayNode();
+               server.setConfiguration(new Configuration(server.getName(),"", serverConfigArray));
+
+               Map<Long, Neighbour> serverNeighbours = new HashMap<Long, Neighbour>();
+               serverNeighbours.put(1L, new Neighbour(1L, "firewall" + (n)));
+               server.setNeighbours(serverNeighbours );
+
+               //add server to list
+               nodes.add(server);
+
+               //create graph
+               Graph g = new Graph();
+               Map<Long, Node> graphNodes = new HashMap<Long, Node>();
+               long index = 1L;
+               for (Node node : nodes){
+                       graphNodes.put(index, node);
+                       index++;
+               }
+               g.setNodes(graphNodes);
+
+               return g;
+       }
+
+       private static Graph generateScenario(int n) {
+               List<Node> nodes = new ArrayList<Node>();
+
+               Node firewall = new Node();
+               firewall.setName("firewall");
+               firewall.setFunctional_type("firewall");
+               ArrayNode firewallConfigArray = new ObjectMapper().createArrayNode();
+               Map<Long, Neighbour> firewallNeighbours = new HashMap<Long, Neighbour>();
+
+               for (int i=0; i < n; i++){
+                       if(i!=0){
+                               JsonNode firewallEntry = new ObjectMapper().createObjectNode();
+                               ((ObjectNode) firewallEntry).put("server", "client" + (i+1));
+                               firewallConfigArray.add(firewallEntry);
+                       }
+                       firewallNeighbours.put(new Long(i+1), new Neighbour(new Long(i+1), "client" + (i+1)));
+               }
+
+               firewallNeighbours.put(new Long(n+1), new Neighbour(new Long(n+1), "server"));
+               
+               firewall.setConfiguration(new Configuration(firewall.getName(),"", firewallConfigArray));
+
+
+               firewall.setNeighbours(firewallNeighbours );
+               //add client to list
+               nodes.add(firewall);
+
+               for(int i=0; i< n;i++){
+                       Node client = new Node();
+                       client.setId(i+1);
+                       client.setName("client" + (i+1));
+                       client.setFunctional_type("endhost");
+                       ArrayNode clientConfigArray = new ObjectMapper().createArrayNode();
+                       JsonNode clientConfig = new ObjectMapper().createObjectNode();
+                       ((ObjectNode)clientConfig).put("url", "www.facebook.com");
+                       ((ObjectNode)clientConfig).put("body", "word");
+                       ((ObjectNode)clientConfig).put("destination","server");
+                       ((ObjectNode)clientConfig).put("protocol", "HTTP_REQUEST");
+                       clientConfigArray.add(clientConfig);
+
+                       Map<Long, Neighbour> clientNeighbours = new HashMap<Long, Neighbour>();
+
+                       clientNeighbours.put(1L, new Neighbour(1L, "firewall"));
+                                                                       
+                       client.setNeighbours(clientNeighbours);
+                       client.setConfiguration(new Configuration(client.getName(),"", clientConfigArray));
+
+                       //add client to list
+                       nodes.add(client);
+               }
+
+               Node server = new Node();
+               server.setName("server");
+               server.setFunctional_type("webserver");
+               ArrayNode serverConfigArray = new ObjectMapper().createArrayNode();
+               server.setConfiguration(new Configuration(server.getName(),"", serverConfigArray));
+
+               Map<Long, Neighbour> serverNeighbours = new HashMap<Long, Neighbour>();
+               serverNeighbours.put(1L, new Neighbour(1L, "firewall"));
+               server.setNeighbours(serverNeighbours );
+
+               //add server to list
+               nodes.add(server);
+
+               //create graph
+               Graph g = new Graph();
+               Map<Long, Node> graphNodes = new HashMap<Long, Node>();
+               long index = 1L;
+               for (Node node : nodes){
+                       graphNodes.put(index, node);
+                       index++;
+               }
+               g.setNodes(graphNodes);
+
+               return g;
+       }
+
+       private static Graph generateDpiScenario(int n) {
+               List<Node> nodes = new ArrayList<Node>();
+
+               Node client = new Node();
+               client.setName("client");
+               client.setFunctional_type("endhost");
+               ArrayNode clientConfigArray = new ObjectMapper().createArrayNode();
+               JsonNode clientConfig = new ObjectMapper().createObjectNode();
+               ((ObjectNode)clientConfig).put("url", "www.facebook.com");
+               ((ObjectNode)clientConfig).put("body", "word");
+               ((ObjectNode)clientConfig).put("destination","server");
+               ((ObjectNode)clientConfig).put("protocol", "HTTP_REQUEST");
+               clientConfigArray.add(clientConfig);
+               client.setConfiguration(new Configuration(client.getName(),"", clientConfigArray));
+
+               Map<Long, Neighbour> clientNeighbours = new HashMap<Long, Neighbour>();
+               clientNeighbours.put(1L, new Neighbour(1L, "dpi1"));
+               client.setNeighbours(clientNeighbours );
+               //add client to list
+               nodes.add(client);
+
+               for(int i=0; i< n;i++){
+                       Node dpi = new Node();
+                       dpi.setId(i+1);
+                       dpi.setName("dpi" + (i+1));
+                       dpi.setFunctional_type("dpi");
+                       ArrayNode configArray = new ObjectMapper().createArrayNode();
+                       configArray.add("drug");
+
+                       Map<Long, Neighbour> natNeighbours = new HashMap<Long, Neighbour>();
+
+                       //set left neighbour for each node except the first
+                       if(dpi.getId() != 1){
+                               natNeighbours.put(1L, new Neighbour(1L, "dpi" + i));
+                       }
+                       //first firewall: set only client as neighbour and natted node
+                       else{
+                               natNeighbours.put(1L, new Neighbour(1L, "client"));
+                       }
+                       //set right neighbour for each node except the last
+                       if(dpi.getId() != n){
+                               natNeighbours.put(2L, new Neighbour(1L, "dpi" + (i+2)));
+                       }
+                       //last firewall: set server as neighbour
+                       else{
+                               natNeighbours.put(2L, new Neighbour(1L, "server"));
+                       }
+
+                       dpi.setNeighbours(natNeighbours);
+                       dpi.setConfiguration(new Configuration(dpi.getName(),"", configArray));
+
+                       //add nat to list
+                       nodes.add(dpi);
+               }
+
+               Node server = new Node();
+               server.setName("server");
+               server.setFunctional_type("webserver");
+               ArrayNode serverConfigArray = new ObjectMapper().createArrayNode();
+               server.setConfiguration(new Configuration(server.getName(),"", serverConfigArray));
+
+               Map<Long, Neighbour> serverNeighbours = new HashMap<Long, Neighbour>();
+               serverNeighbours.put(1L, new Neighbour(1L, "dpi" + (n)));
+               server.setNeighbours(serverNeighbours );
+
+               //add server to list
+               nodes.add(server);
+
+               //create graph
+               Graph g = new Graph();
+               Map<Long, Node> graphNodes = new HashMap<Long, Node>();
+               long index = 1L;
+               for (Node node : nodes){
+                       graphNodes.put(index, node);
+                       index++;
+               }
+               g.setNodes(graphNodes);
+
+               return g;
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/test/TestCase.java b/verigraph/src/main/java/it/polito/escape/verify/test/TestCase.java
new file mode 100644 (file)
index 0000000..a4c85ab
--- /dev/null
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+import it.polito.escape.verify.model.Graph;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({ "id", "name", "description", "policy_url_parameters", "result", "graph" })
+public class TestCase {
+
+       @JsonProperty("id")
+       private Integer                         id;
+
+       @JsonProperty("name")
+       private String                          name;
+
+       @JsonProperty("description")
+       private String                          description;
+
+       @JsonProperty("policy_url_parameters")
+       private String                          policyUrlParameters;
+
+       @JsonProperty("result")
+       private String                          result;
+
+       @JsonProperty("graph")
+       private Graph                           graph;
+
+       @JsonIgnore
+       private Map<String, Object>     additionalProperties    = new HashMap<String, Object>();
+
+       /**
+        * @return The id
+        */
+       @JsonProperty("id")
+       public Integer getId() {
+               return id;
+       }
+
+       /**
+        * @param id
+        *            The id
+        */
+       @JsonProperty("id")
+       public void setId(Integer id) {
+               this.id = id;
+       }
+
+       /**
+        * @return The name
+        */
+       @JsonProperty("name")
+       public String getName() {
+               return name;
+       }
+
+       /**
+        * @param name
+        *            The name
+        */
+       @JsonProperty("name")
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       /**
+        * @return The description
+        */
+       @JsonProperty("description")
+       public String getDescription() {
+               return description;
+       }
+
+       /**
+        * @param description
+        *            The description
+        */
+       @JsonProperty("description")
+       public void setDescription(String description) {
+               this.description = description;
+       }
+
+       /**
+        * @return The policyUrlParameters
+        */
+       @JsonProperty("policy_url_parameters")
+       public String getPolicyUrlParameters() {
+               return policyUrlParameters;
+       }
+
+       /**
+        * @param policyUrlParameters
+        *            The policy_url_parameters
+        */
+       @JsonProperty("policy_url_parameters")
+       public void setPolicyUrlParameters(String policyUrlParameters) {
+               this.policyUrlParameters = policyUrlParameters;
+       }
+
+       /**
+        * @return The result
+        */
+       @JsonProperty("result")
+       public String getResult() {
+               return result;
+       }
+
+       /**
+        * @param result
+        *            The result
+        */
+       @JsonProperty("result")
+       public void setResult(String result) {
+               this.result = result;
+       }
+
+       /**
+        * @return The graph
+        */
+       @JsonProperty("graph")
+       public Graph getGraph() {
+               return graph;
+       }
+
+       /**
+        * @param graph
+        *            The graph
+        */
+       @JsonProperty("graph")
+       public void setGraph(Graph graph) {
+               this.graph = graph;
+       }
+
+       @JsonAnyGetter
+       public Map<String, Object> getAdditionalProperties() {
+               return this.additionalProperties;
+       }
+
+       @JsonAnySetter
+       public void setAdditionalProperty(String name, Object value) {
+               this.additionalProperties.put(name, value);
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/test/TestExecutionException.java b/verigraph/src/main/java/it/polito/escape/verify/test/TestExecutionException.java
new file mode 100644 (file)
index 0000000..8babe7b
--- /dev/null
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.test;
+
+
+public class TestExecutionException extends Exception{
+
+       /**
+        *
+        */
+       private static final long serialVersionUID = 4749065055436886197L;
+
+       public TestExecutionException(String message){
+               super(message);
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/test/Tester.java b/verigraph/src/main/java/it/polito/escape/verify/test/Tester.java
new file mode 100644 (file)
index 0000000..4b85e1e
--- /dev/null
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.test;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.ResponseProcessingException;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Response;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.jsonschema.core.exceptions.ProcessingException;
+import com.github.fge.jsonschema.main.JsonSchema;
+
+import it.polito.escape.verify.client.VerifyClient;
+import it.polito.escape.verify.client.VerifyClientException;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Verification;
+import it.polito.escape.verify.service.ValidationUtils;
+
+public class Tester {
+
+       private File                    schema;
+
+       private List<File>              testFiles       = new ArrayList<File>();
+
+       private List<TestCase>  testCases       = new ArrayList<TestCase>();
+
+       private String                  target;
+
+       private VerifyClient    verifyClient;
+
+       public Tester(String target, File schema, File folder)  throws JsonParseException, JsonMappingException, IOException,
+                                                                                                                       Exception {
+               init(target, schema, folder);
+       }
+
+       private void init(String target, File schema, File folder)      throws JsonParseException, JsonMappingException,
+                                                                                                                               IOException, Exception {
+               this.target = target;
+               this.verifyClient = new VerifyClient(this.target);
+               this.schema = schema;
+               this.testFiles = getTests(folder);
+               this.testCases = getTestCases(this.testFiles);
+       }
+
+       public List<File> getTests(File folder) {
+               List<File> filesList = new ArrayList<File>();
+
+               System.out.println("Test folder set to '" + folder.getAbsolutePath() + "'");
+
+               File[] files = folder.listFiles(new FilenameFilter() {
+
+                       @Override
+                       public boolean accept(File dir, String name) {
+                               return name.endsWith(".json");
+                       }
+               });
+
+               for (File f : files) {
+                       filesList.add(f);
+                       System.out.println("File '" + f.getName() + "' added to test files");
+               }
+
+               return filesList;
+       }
+
+       public List<TestCase> getTestCases(List<File> files)    throws JsonParseException, JsonMappingException, IOException,
+                                                                                                                       Exception {
+               List<TestCase> testCases = new ArrayList<TestCase>();
+
+               for (File file : files) {
+                       validateTestFile(file);
+                       try {
+                               TestCase tc = new ObjectMapper().readValue(file, TestCase.class);
+                               testCases.add(tc);
+                       }
+                       catch (Exception e) {
+                               throw e;
+                       }
+               }
+
+               return testCases;
+       }
+
+       private void runTestCases() throws VerifyClientException, TestExecutionException {
+               int counter = 0;
+               for (TestCase tc : this.testCases) {
+                       String result = runTestCase(tc);
+                       if (!result.equals(tc.getResult()))
+                               throw new TestExecutionException("Error running test given in file '"   + this.testFiles.get(counter).getName()
+                                                                       + "'. Test returned '" + result + "' instead of '" + tc.getResult() + "'.");
+                       else
+                               System.out.println("Test given in file '"       + this.testFiles.get(counter).getName() + "' returned '"
+                                                                       + result + "' as expected");
+                       counter++;
+               }
+               System.out.println("All tests PASSED");
+       }
+
+       private String runTestCase(TestCase tc) throws VerifyClientException, TestExecutionException{
+               Client client = ClientBuilder.newClient();
+
+               Graph graph = tc.getGraph();
+               Response response = null;
+               try{
+                       response = this.verifyClient.createGraph(graph);
+               }
+               catch(ResponseProcessingException e){
+                       throw new TestExecutionException("Response processing has failed: " + e.getResponse().readEntity(String.class));
+               }
+               catch(javax.ws.rs.ProcessingException e){
+                       throw new TestExecutionException("HTTP request failed");
+               }
+               Graph createdGraph = response.readEntity(Graph.class);
+               String urlParams = tc.getPolicyUrlParameters();
+               WebTarget target = client.target(this.target + "/graphs/" + createdGraph.getId() + "/policy" + urlParams);
+
+               response = target.request().get();
+               Verification verification = response.readEntity(Verification.class);
+               return verification.getResult();
+       }
+
+       public void validateTestFile(File testFile) throws Exception {
+               JsonSchema schemaNode = null;
+               try {
+                       schemaNode = ValidationUtils.getSchemaNode(schema);
+               }
+               catch (IOException e) {
+                       throw new Exception("Unable to load '" + schema.getAbsolutePath() + "' schema file");
+               }
+               catch (ProcessingException e) {
+                       throw new Exception("Unable to resolve '" + schema.getAbsolutePath() + "' schema file as a schema node");
+               }
+
+               JsonNode jsonNode;
+               try {
+                       jsonNode = ValidationUtils.getJsonNode(testFile);
+               }
+               catch (IOException e) {
+                       throw new Exception("Unable to load '" + testFile.getAbsolutePath() + "' as a json node");
+               }
+
+               try {
+                       ValidationUtils.validateJson(schemaNode, jsonNode);
+               }
+               catch (ProcessingException e) {
+                       throw new Exception("There were errors in the validation of file '"     + testFile.getAbsolutePath()
+                                                               + "' against the json schema '" + schema.getAbsolutePath() + "': " + e.getMessage());
+
+               }
+       }
+
+       public static void main(String[] args)  throws JsonParseException, JsonMappingException, IOException,
+                                                                                       VerifyClientException, Exception {
+               String folderName = System.getProperty("user.dir") + "/tester/testcases";
+               File folder = new File(folderName);
+               if (!folder.exists()) {
+                       BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+                   String s;
+                   do{
+                       System.out.println("Please enter the testcases folder path: ");
+                       s = in.readLine();
+                       if (isValidpath(s)){
+                               folder = new File(s);
+                               break;
+                       }
+                   }while (s != null && s.length() != 0);
+                   if(s == null)
+                       System.exit(0);
+               }
+               String schemaName = System.getProperty("user.dir") + "/tester/testcase_schema.json";
+               File schema = new File(schemaName);
+               if (!schema.exists()) {
+                       BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+                   String s;
+                   do{
+                       System.out.println("Please enter the full path of 'testcase_schema.json': ");
+                       s = in.readLine();
+                       if (isValidpath(s)){
+                               folder = new File(s);
+                               break;
+                       }
+                   }while (s != null && s.length() != 0);
+                   if(s == null)
+                       System.exit(0);
+               }
+
+               Tester tester = new Tester("http://localhost:8080/verify/api", schema, folder);
+
+               tester.runTestCases();
+
+       }
+
+       private static boolean isValidpath(String s) {
+               if (s==null)
+                       return false;
+               File file = new File(s);
+               return file.exists();
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/validation/DpiValidator.java b/verigraph/src/main/java/it/polito/escape/verify/validation/DpiValidator.java
new file mode 100644 (file)
index 0000000..2666755
--- /dev/null
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.validation;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import it.polito.escape.verify.model.Configuration;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Node;
+import it.polito.escape.verify.validation.exception.ValidationException;
+
+public class DpiValidator implements ValidationInterface {
+
+       public DpiValidator(){
+
+       }
+
+       private void validateKey(String key) throws ValidationException {
+               if (!key.matches("\\w+"))
+                       throw new ValidationException("'" + key + "' is not a valid configuration string for a 'dpi'");
+       }
+
+       @Override
+       public void validate(Graph graph, Node node, Configuration configuration) throws ValidationException {
+
+               JsonNode conf = configuration.getConfiguration();
+
+               if (!conf.isArray()) {
+                       throw new ValidationException("Configuration of a 'dpi' must be an array");
+               }
+               for (JsonNode key : conf) {
+                       if (!key.isTextual())
+                               throw new ValidationException("Configuration of a 'dpi' must be an array of strings");
+                       validateKey(key.asText());
+               }
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/validation/EndhostValidator.java b/verigraph/src/main/java/it/polito/escape/verify/validation/EndhostValidator.java
new file mode 100644 (file)
index 0000000..3d9eb75
--- /dev/null
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.validation;
+
+import it.polito.escape.verify.model.Configuration;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Node;
+import it.polito.escape.verify.validation.exception.ValidationException;
+
+
+public class EndhostValidator implements ValidationInterface {
+
+       @Override
+       public void validate(Graph graph, Node node, Configuration configuration) throws ValidationException {
+
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/validation/ValidationInterface.java b/verigraph/src/main/java/it/polito/escape/verify/validation/ValidationInterface.java
new file mode 100644 (file)
index 0000000..25608dd
--- /dev/null
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.validation;
+
+import it.polito.escape.verify.model.Configuration;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Node;
+import it.polito.escape.verify.validation.exception.ValidationException;
+
+public interface ValidationInterface {
+
+       void validate(Graph graph, Node node, Configuration configuration) throws ValidationException;
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/validation/VpnaccessValidator.java b/verigraph/src/main/java/it/polito/escape/verify/validation/VpnaccessValidator.java
new file mode 100644 (file)
index 0000000..6abd603
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.validation;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import it.polito.escape.verify.model.Configuration;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Node;
+import it.polito.escape.verify.validation.exception.ValidationException;
+
+public class VpnaccessValidator implements ValidationInterface {
+
+       @Override
+       public void validate(Graph graph, Node node, Configuration configuration) throws ValidationException {
+               JsonNode configurationNode = configuration.getConfiguration();
+
+               if (!configurationNode.isArray())
+                       throw new ValidationException("configuration must be an array");
+
+               for (JsonNode object : configurationNode) {
+                       JsonNode vpnexit = object.get("vpnexit");
+                       if (!vpnexit.isTextual())
+                               throw new ValidationException("value corresponding to the key 'vpnexit' must be a string");
+                       validateObject(graph, node, vpnexit.asText());
+               }
+
+       }
+
+       private void validateObject(Graph g, Node node, String field) throws ValidationException {
+               boolean isValid = false;
+               for (Node n : g.getNodes().values()) {
+                       if ((n.getFunctional_type().equals("vpnexit")) && (n.getName().equals(field)))
+                               isValid = true;
+               }
+
+               if (!isValid)
+                       throw new ValidationException("'"       + field + "' is not a valid value for the configuration of a type '"
+                                                                                       + node.getFunctional_type()
+                                                                                       + "'. Please use the name of an existing node of type 'vpnexit'.");
+
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/validation/VpnexitValidator.java b/verigraph/src/main/java/it/polito/escape/verify/validation/VpnexitValidator.java
new file mode 100644 (file)
index 0000000..782e124
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.validation;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import it.polito.escape.verify.model.Configuration;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Node;
+import it.polito.escape.verify.validation.exception.ValidationException;
+
+public class VpnexitValidator implements ValidationInterface {
+
+       @Override
+       public void validate(Graph graph, Node node, Configuration configuration) throws ValidationException {
+               JsonNode configurationNode = configuration.getConfiguration();
+
+               if (!configurationNode.isArray())
+                       throw new ValidationException("configuration must be an array");
+
+               for (JsonNode object : configurationNode) {
+                       JsonNode vpnexit = object.get("vpnaccess");
+                       if (!vpnexit.isTextual())
+                               throw new ValidationException("value corresponding to the key 'vpnaccess' must be a string");
+                       validateObject(graph, node, vpnexit.asText());
+               }
+
+       }
+
+       private void validateObject(Graph g, Node node, String field) throws ValidationException {
+               boolean isValid = false;
+               for (Node n : g.getNodes().values()) {
+                       if ((n.getFunctional_type().equals("vpnaccess")) && (n.getName().equals(field)))
+                               isValid = true;
+               }
+
+               if (!isValid)
+                       throw new ValidationException("'"       + field + "' is not a valid value for the configuration of a type '"
+                                                                                       + node.getFunctional_type()
+                                                                                       + "'. Please use the name of an existing node of type 'vpnaccess'.");
+
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/escape/verify/validation/exception/ValidationException.java b/verigraph/src/main/java/it/polito/escape/verify/validation/exception/ValidationException.java
new file mode 100644 (file)
index 0000000..8b94748
--- /dev/null
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.escape.verify.validation.exception;
+
+
+public class ValidationException extends Exception {
+
+       /**
+        *
+        */
+       private static final long serialVersionUID = -8251271078519549101L;
+
+       private String message;
+
+       public ValidationException(String message){
+//             super(message);
+               this.message = message;
+       }
+
+       @Override
+       public String getMessage() {
+               return this.message;
+       }
+}
diff --git a/verigraph/src/main/java/it/polito/grpc/Client.java b/verigraph/src/main/java/it/polito/grpc/Client.java
new file mode 100644 (file)
index 0000000..adc16da
--- /dev/null
@@ -0,0 +1,550 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.grpc;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import com.google.protobuf.Message;
+
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.StatusRuntimeException;
+import io.grpc.verigraph.ConfigurationGrpc;
+import io.grpc.verigraph.GetRequest;
+import io.grpc.verigraph.GraphGrpc;
+import io.grpc.verigraph.NeighbourGrpc;
+import io.grpc.verigraph.NewGraph;
+import io.grpc.verigraph.NewNeighbour;
+import io.grpc.verigraph.NewNode;
+import io.grpc.verigraph.NodeGrpc;
+import io.grpc.verigraph.NodeGrpc.FunctionalType;
+import io.grpc.verigraph.Policy;
+import io.grpc.verigraph.Policy.PolicyType;
+import io.grpc.verigraph.RequestID;
+import io.grpc.verigraph.Status;
+import io.grpc.verigraph.TestGrpc;
+import io.grpc.verigraph.VerificationGrpc;
+import io.grpc.verigraph.VerigraphGrpc;
+
+public class Client {
+
+       private final ManagedChannel channel;
+       private final VerigraphGrpc.VerigraphBlockingStub blockingStub;
+
+       public Client(String host, int port) {
+               this(ManagedChannelBuilder.forAddress(host, port).usePlaintext(true));
+       }
+
+       /** Construct client for accessing RouteGuide server using the existing channel. */
+       public Client(ManagedChannelBuilder<?> channelBuilder) {
+               channel = channelBuilder.build();
+               blockingStub = VerigraphGrpc.newBlockingStub(channel);
+       }
+
+       /** Get array of graphs */
+       public List<GraphGrpc> getGraphs() {
+               List<GraphGrpc> graphsRecveived = new ArrayList<GraphGrpc>();
+               GetRequest request = GetRequest.newBuilder().build();
+               Iterator<GraphGrpc> graphs;
+               try {
+                       graphs = blockingStub.getGraphs(request);
+                       while (graphs.hasNext()) {
+                               GraphGrpc graph = graphs.next();
+                               System.out.println("Graph id : "+graph.getId());
+                               if(graph.getErrorMessage().equals("")){
+                                       System.out.println("Node id : "+graph.getId());
+                                       graphsRecveived.add(graph);
+                               }else{
+                                       System.out.println("Error : " + graph.getErrorMessage());
+                                       return graphsRecveived;
+                               }
+                       }
+               } catch (StatusRuntimeException ex) {
+                       System.err.println("RPC failed: " + ex.getStatus());
+               }
+               return graphsRecveived;
+       }
+
+       /** Create new Graph */
+       public NewGraph createGraph(GraphGrpc gr) {
+               NewGraph response;
+               try {
+                       response = blockingStub.createGraph(gr);
+                       if(response.getSuccess()){
+                               System.out.println("Successful operation ");
+                       }else{
+                               System.out.println("Unsuccessful operation: " + response.getErrorMessage());
+                       }
+               } catch (StatusRuntimeException e) {
+                       System.err.println("RPC failed: " + e.getStatus());
+                       return NewGraph.newBuilder().setSuccess(false).build();
+               }
+               return response;
+       }
+
+       /** Delete a Graph */
+       public boolean deleteGraph(long idGraph) {
+
+               RequestID id = RequestID.newBuilder().setIdGraph(idGraph).build();
+               Status response;
+               try {
+                       response = blockingStub.deleteGraph(id);
+                       if(response.getSuccess()){
+                               System.out.println("Successful operation ");
+                               return true;
+                       }else{
+                               System.out.println("Unsuccessful operation: " + response.getErrorMessage());
+                       }
+               } catch (StatusRuntimeException e) {
+                       System.err.println("RPC failed: " + e.getStatus());
+               }
+               return false;
+       }
+
+       /** Edits a single graph */
+       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("Successful operation ");
+                       }else{
+                               System.out.println("Unsuccessful operation: " + response.getErrorMessage());
+                       }
+               } catch (StatusRuntimeException e) {
+                       System.err.println("RPC failed: " + e.getStatus());
+                       return NewGraph.newBuilder().setSuccess(false).build();
+               }
+               return response;
+       }
+
+       /** Get a single graph*/
+       public GraphGrpc getGraph(long idGraph) {
+
+               RequestID request = RequestID.newBuilder().setIdGraph(idGraph).build() ;
+               try {
+                       GraphGrpc graph = blockingStub.getGraph(request);
+                       if(!graph.getErrorMessage().equals("")){
+                               System.out.println("Error in operation: " + graph.getErrorMessage());
+                       }
+                       return graph;
+               } catch (StatusRuntimeException ex) {
+                       System.err.println("RPC failed: " + ex.getStatus());
+                       return null;
+               }
+       }
+
+       /** Verify a given policy*/
+       public VerificationGrpc verify(Policy policy) {
+
+               VerificationGrpc response;
+               try {
+                       response = blockingStub.verifyPolicy(policy);
+                       if(!response.getErrorMessage().equals("")){
+                               System.out.println("Error in operation: " + response.getErrorMessage());
+                       }
+                       System.out.println("Result : "+response.getResult());
+                       System.out.println("Comment : "+response.getComment());
+                       //uncomment if you want to print the paths
+                       /*for(TestGrpc test:response.getTestList()){
+                               System.out.println("Test : "+test.getResult()+". Traversed nodes:");
+                               for(NodeGrpc node:test.getNodeList()){
+                                       //prints only the name
+                                       System.out.println("Node "+node.getName());
+                               }
+                       }*/
+                       return response;
+               } catch (StatusRuntimeException e) {
+                       System.err.println("RPC failed: " + e.getStatus());
+                       return null;
+               }
+       }
+
+       /*Node part*/
+
+       /** Get array of nodes */
+       public List<NodeGrpc> getNodes(long idGraph) {
+               List<NodeGrpc> nodesReceived = new ArrayList<NodeGrpc>();
+               RequestID request = RequestID.newBuilder().setIdGraph(idGraph).build() ;
+               Iterator<NodeGrpc> nodes;
+               try {
+                       nodes = blockingStub.getNodes(request);
+                       while (nodes.hasNext()) {
+                               NodeGrpc node = nodes.next();
+                               if(node.getErrorMessage().equals("")){
+                                       System.out.println("Node id : "+node.getId());
+                                       nodesReceived.add(node);
+                               }else{
+                                       System.out.println("Error : " + node.getErrorMessage());
+                                       return nodesReceived;
+                               }
+                       }
+               } catch (StatusRuntimeException ex) {
+                       System.err.println("RPC failed: " + ex.getStatus());
+               }
+               return nodesReceived;
+       }
+
+       /** Create new Node */
+       public NewNode createNode(NodeGrpc node, long idGraph) {
+
+               NewNode response;
+               try {
+                       NodeGrpc n = NodeGrpc.newBuilder(node).setIdGraph(idGraph).build();
+                       response = blockingStub.createNode(n);
+                       if(response.getSuccess()){
+                               System.out.println("Successful operation ");
+                       }else{
+                               System.out.println("Unsuccessful operation: " + response.getErrorMessage());
+                       }
+               } catch (StatusRuntimeException e) {
+                       System.err.println("RPC failed: " + e.getStatus());
+                       return NewNode.newBuilder().setSuccess(false).build();
+               }
+               return response;
+       }
+
+       /** Delete a Node */
+       public boolean deleteNode(long idGraph, long idNode) {
+
+               RequestID id = RequestID.newBuilder().setIdGraph(idGraph).setIdNode(idNode).build();
+               Status response;
+               try {
+                       response = blockingStub.deleteNode(id);
+                       if(response.getSuccess()){
+                               System.out.println("Successful operation ");
+                               return true;
+                       }else{
+                               System.out.println("Unsuccessful operation: " + response.getErrorMessage());
+                       }
+               } catch (StatusRuntimeException e) {
+                       System.err.println("RPC failed: " + e.getStatus());
+               }
+               return false;
+       }
+
+       /** Edits a single Node */
+       public NewNode updateNode(long idGraph, long idNode, NodeGrpc node) {
+
+               NodeGrpc nu = NodeGrpc.newBuilder(node).setIdGraph(idGraph).setId(idNode).build();
+               NewNode response;
+               try {
+                       response = blockingStub.updateNode(nu);
+                       if(response.getSuccess()){
+                               System.out.println("Successful operation ");
+                       }else{
+                               System.out.println("Unsuccessful operation: " + response.getErrorMessage());
+                       }
+               } catch (StatusRuntimeException e) {
+                       System.err.println("RPC failed: " + e.getStatus());
+                       return NewNode.newBuilder().setSuccess(false).build();
+               }
+               return response;
+       }
+
+       /** Get a single Node*/
+       public NodeGrpc getNode(long idGraph, long idNode) {
+
+               RequestID request = RequestID.newBuilder().setIdGraph(idGraph).setIdNode(idNode).build() ;
+               try {
+                       NodeGrpc node = blockingStub.getNode(request);
+                       if(!node.getErrorMessage().equals("")){
+                               System.out.println("Error in operation: " + node.getErrorMessage());
+                       }
+                       return  node;
+               } catch (StatusRuntimeException ex) {
+                       System.err.println("RPC failed: " + ex.getStatus());
+                       return null;
+               }
+       }
+
+       /** Configure a single Node*/
+       public boolean configureNode(long idGraph, long idNode, ConfigurationGrpc configuration) {
+
+               try {
+                       ConfigurationGrpc request = ConfigurationGrpc.newBuilder(configuration)
+                                       .setIdGraph(idGraph).setIdNode(idNode).build() ;
+
+                       Status response = blockingStub.configureNode(request);
+                       if(response.getSuccess()){
+                               System.out.println("Successful operation ");
+                               return true;
+                       }else{
+                               System.out.println("Unsuccessful operation: " + response.getErrorMessage());
+                       }
+               } catch (StatusRuntimeException e) {
+                       System.err.println("RPC failed: " + e.getStatus());
+               }
+               return false;
+       }
+
+       /*Neighbour part*/
+
+       /** Get array of neighbours */
+       public List<NeighbourGrpc> getNeighbours(long idGraph, long idNode) {
+
+               List<NeighbourGrpc> neighboursReceived = new ArrayList<NeighbourGrpc>();
+               RequestID request = RequestID.newBuilder().setIdGraph(idGraph).setIdNode(idNode).build() ;
+               Iterator<NeighbourGrpc> neighbours;
+               try {
+                       neighbours = blockingStub.getNeighbours(request);
+                       while (neighbours.hasNext()) {
+                               NeighbourGrpc neighbour = neighbours.next();
+                               if(neighbour.getErrorMessage().equals("")){
+                                       System.out.println("Neighbour id : "+neighbour.getId());
+                                       neighboursReceived.add(neighbour);
+                               }else{
+                                       System.out.println("Error : " + neighbour.getErrorMessage());
+                                       return neighboursReceived;
+                               }
+                       }
+               } catch (StatusRuntimeException ex) {
+                       System.err.println("RPC failed: " + ex.getStatus());
+               }
+               return neighboursReceived;
+       }
+
+       /** Create new Neighbour */
+       public NewNeighbour createNeighbour(NeighbourGrpc neighbour, long idGraph, long idNode) {
+
+               NewNeighbour response;
+               try {
+                       NeighbourGrpc n = NeighbourGrpc.newBuilder(neighbour).setIdGraph(idGraph)
+                                       .setIdNode(idNode).build();
+                       response = blockingStub.createNeighbour(n);
+                       if(response.getSuccess()){
+                               System.out.println("Successful operation ");
+                       }else{
+                               System.out.println("Unsuccessful operation: " + response.getErrorMessage());
+                       }
+               } catch (StatusRuntimeException e) {
+                       System.err.println("RPC failed: " + e.getStatus());
+                       return NewNeighbour.newBuilder().setSuccess(false).build();
+               }
+               return response;
+       }
+
+       /** Delete a Neighbour */
+       public boolean deleteNeighbour(long idGraph, long idNode, long idNeighbour) {
+
+               RequestID id = RequestID.newBuilder().setIdGraph(idGraph).setIdNode(idNode).setIdNeighbour(idNeighbour).build();
+               Status response;
+               try {
+                       response = blockingStub.deleteNeighbour(id);
+                       if(response.getSuccess()){
+                               System.out.println("Successful operation ");
+                               return true;
+                       }else{
+                               System.out.println("Unsuccesful operation: " + response.getErrorMessage());
+                       }
+               } catch (StatusRuntimeException e) {
+                       System.err.println("RPC failed: " + e.getStatus());
+               }
+               return false;
+       }
+
+       /** Edits a single Neighbour */
+       public NewNeighbour updateNeighbour(long idGraph, long idNode, long idNeighbour, NeighbourGrpc neighbour) {
+
+               NeighbourGrpc nu = NeighbourGrpc.newBuilder(neighbour).setIdGraph(idGraph).setIdNode(idNode)
+                                                                               .setId(idNeighbour).build();
+               NewNeighbour response;
+               try {
+                       response = blockingStub.updateNeighbour(nu);
+                       if(response.getSuccess()){
+                               System.out.println("Successful operation ");
+                       }else{
+                               System.out.println("Unsuccessful operation: " + response.getErrorMessage());
+                       }
+               } catch (StatusRuntimeException e) {
+                       System.err.println("RPC failed: " + e.getStatus());
+                       return NewNeighbour.newBuilder().setSuccess(false).build();
+               }
+               return response;
+       }
+
+       /** Get a single Neighbour*/
+       public NeighbourGrpc getNeighbour(long idGraph, long idNode, long idNeighbour) {
+
+               RequestID request = RequestID.newBuilder().setIdGraph(idGraph).setIdNode(idNode).setIdNeighbour(idNeighbour).build() ;
+               try {
+                       NeighbourGrpc neighbour = blockingStub.getNeighbour(request);
+                       if(!neighbour.getErrorMessage().equals("")){
+                               System.out.println("Error in operation: " + neighbour.getErrorMessage());
+                       }
+                       return neighbour;
+               } catch (StatusRuntimeException ex) {
+                       System.err.println("RPC failed: " + ex.getStatus());
+                       return null;
+               }
+       }
+
+       public void shutdown() throws InterruptedException {
+               channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
+       }
+
+       /** Test on the Server. */
+       public static void main(String[] args) throws Exception {
+
+               List<Long> listGraph = new ArrayList<Long>();   //list of ID
+
+               Client client = new Client("localhost" , 50051);
+               try {
+                       NodeGrpc node1 = createNodeGrpc("Node1", "endhost", null, null);
+                       List<NeighbourGrpc> neighbours = new ArrayList<NeighbourGrpc>();
+                       NeighbourGrpc nb = createNeighbourGrpc("Node1");
+                       neighbours.add(nb);
+                       NodeGrpc node2 = createNodeGrpc("Node2", "endpoint", neighbours, null);
+                       List<NodeGrpc> nodes = new ArrayList<NodeGrpc>();
+                       nodes.add(node1);
+                       nodes.add(node2);
+
+                       GraphGrpc graph = createGraphGrpc(nodes);
+
+                       NewGraph createdGraph = client.createGraph(graph);
+                       if(createdGraph.getSuccess() == true){
+                               listGraph.add(createdGraph.getGraph().getId());
+                               System.out.println("Created graph with id :"+ createdGraph.getGraph().getId());
+                       }
+
+                       client.getGraphs();
+               } catch(Exception ex){
+                       System.out.println("Error: " + ex.getMessage());
+                       ex.printStackTrace();
+               }finally {
+                       client.shutdown();
+               }
+       }
+
+       public static NeighbourGrpc createNeighbourGrpc(String name){
+               return NeighbourGrpc.newBuilder().setName(name).build();
+       }
+
+       public static NodeGrpc createNodeGrpc(String name, String functionalType, List<NeighbourGrpc> neighbours, ConfigurationGrpc conf) throws Exception{
+               NodeGrpc.Builder nb = NodeGrpc.newBuilder();
+
+               if(name != null)
+                       nb.setName(name);
+               else
+                       throw new Exception("Node must have a name");
+
+               if(functionalType != null)
+                       nb.setFunctionalType(FunctionalType.valueOf(functionalType));
+               else
+                       throw new Exception("Node must have a functional type");
+
+               if( neighbours!= null){
+                       for(NeighbourGrpc value:neighbours)
+                               nb.addNeighbour(value);
+               }
+               if(conf == null){
+                       try{
+                               conf = createConfigurationGrpc(null, null, null, null);
+                       }catch(Exception e){
+                               throw new Exception(e.getMessage());
+                       }
+               }
+               nb.setConfiguration(conf);
+               return nb.build();
+       }
+
+       public static GraphGrpc createGraphGrpc(List<NodeGrpc> nodes){
+               GraphGrpc.Builder gb = GraphGrpc.newBuilder();
+               if(nodes != null){
+                       for(NodeGrpc value:nodes)
+                               gb.addNode(value);
+               }
+               return gb.build();
+       }
+
+       public static Policy createPolicy(String src, String dst, String type, String middlebox, long idGraph) throws IllegalArgumentException{
+               if(!validMiddlebox(type, middlebox))
+                       throw new IllegalArgumentException("Not valid middlebox valid with this type");
+               Policy.Builder policy = Policy.newBuilder();
+               policy.setIdGraph(idGraph);
+               if(src != null)
+                       policy.setSource(src);
+               else{
+                       throw new IllegalArgumentException("Please insert source field");
+               }
+               if(dst != null)
+                       policy.setDestination(dst);
+               else{
+                       throw new IllegalArgumentException("Please insert destination field");
+               }
+               if(type != null)
+                       policy.setType(PolicyType.valueOf(type));
+               if(middlebox != null)
+                       policy.setMiddlebox(middlebox);
+               return policy.build();
+       }
+
+       public static ConfigurationGrpc createConfigurationGrpc(Map<String,String> parameters, List<String> lists, String id, String description) throws Exception{
+               ConfigurationGrpc.Builder cb = ConfigurationGrpc.newBuilder();
+               StringBuilder sb = new StringBuilder("[");
+               if(parameters != null && lists == null){
+                       int i = 0;
+                       sb.append("{");
+                       for (String key: parameters.keySet()) {
+                               sb.append("\"");
+                               sb.append(key);
+                               sb.append("\":\"");
+                               sb.append(parameters.get(key));
+                               sb.append("\"");
+                               if((i+1)<parameters.keySet().size()){
+                                       sb.append(", ");
+                               }
+                               i++;
+                       }
+                       sb.append("}");
+               }
+               else if(parameters == null && lists != null){
+                       int i = 0;
+                       for (String value: lists) {
+                               sb.append("\"");
+                               sb.append(value);
+                               sb.append("\"");
+                               if((i+1)<lists.size()){
+                                       sb.append(", ");
+                               }
+                               i++;
+                       }
+               }
+               else if(parameters != null && lists != null){
+                       throw new Exception("Error, configuration must contains or a sequence name:value or sequence"
+                                       + "of string, but not both");
+               }
+               sb.append("]");
+               cb.setConfiguration(sb.toString());
+               if(id != null)
+                       cb.setId(id);
+               if(description != null)
+                       cb.setDescription(description);
+               return cb.build();
+       }
+
+       private static boolean validMiddlebox(String type, String middlebox) {
+               if(type == null)
+                       return false;
+               if(type.equals("reachability") && (middlebox == null || middlebox.equals("")))
+                       return true;
+               if(type.equals("isolation") && !(middlebox == null || middlebox.equals("")))
+                       return true;
+               if(type.equals("traversal") && !(middlebox == null || middlebox.equals("")))
+                       return true;
+               return false;
+       }
+}
diff --git a/verigraph/src/main/java/it/polito/grpc/GrpcUtils.java b/verigraph/src/main/java/it/polito/grpc/GrpcUtils.java
new file mode 100644 (file)
index 0000000..0ed002c
--- /dev/null
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.grpc;
+
+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 io.grpc.verigraph.ConfigurationGrpc;
+import io.grpc.verigraph.GraphGrpc;
+import io.grpc.verigraph.NeighbourGrpc;
+import io.grpc.verigraph.NodeGrpc;
+import io.grpc.verigraph.TestGrpc;
+import io.grpc.verigraph.VerificationGrpc;
+import io.grpc.verigraph.NodeGrpc.FunctionalType;
+import it.polito.escape.verify.model.Configuration;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Neighbour;
+import it.polito.escape.verify.model.Node;
+import it.polito.escape.verify.model.Test;
+import it.polito.escape.verify.model.Verification;
+
+public class GrpcUtils {
+       private static final Logger logger = Logger.getLogger(GrpcUtils.class.getName());
+
+       public static NeighbourGrpc obtainNeighbour(Neighbour ne){
+                 return NeighbourGrpc.newBuilder()
+                                 .setId(ne.getId())
+                                 .setName(ne.getName())
+                                 .build();
+         }
+
+         public static Neighbour deriveNeighbour(NeighbourGrpc request) {
+                 //id is not present
+                 Neighbour ne = new Neighbour();
+                 ne.setName(request.getName());
+                 return ne;
+         }
+
+         public static ConfigurationGrpc obtainConfiguration(Configuration conf){
+                 return ConfigurationGrpc.newBuilder()
+                                 .setId(conf.getId())
+                                 .setDescription(conf.getDescription())
+                                 .setConfiguration(conf.getConfiguration().toString())
+                                 .build();
+         }
+
+         public static Configuration deriveConfiguration(ConfigurationGrpc request) {
+                 Configuration conf = new Configuration();
+                 conf.setId(request.getId());
+                 conf.setDescription(request.getDescription());
+                 ObjectMapper mapper = new ObjectMapper();
+                 JsonNode rootNode = null;
+                 try {
+                         if ("".equals(request.getConfiguration()))
+                                 rootNode=mapper.readTree("[]");
+                         else
+                                 rootNode = mapper.readTree(request.getConfiguration());
+                 } catch (IOException e) {
+                         logger.log(Level.WARNING, e.getMessage());
+                 }
+                 conf.setConfiguration(rootNode);
+                 return conf;
+         }
+
+         public static NodeGrpc obtainNode(Node node) {
+                 NodeGrpc.Builder nr = NodeGrpc.newBuilder();
+                 nr.setId(node.getId());
+                 nr.setName(node.getName());
+                 nr.setFunctionalType(FunctionalType.valueOf(node.getFunctional_type()));
+                 for(Neighbour neighbour:node.getNeighbours().values()){
+                         NeighbourGrpc ng = obtainNeighbour(neighbour);
+                         nr.addNeighbour(ng);
+                 }
+                 nr.setConfiguration(obtainConfiguration(node.getConfiguration()));
+                 return nr.build();
+         }
+
+         public static Node deriveNode(NodeGrpc request) {
+                 //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);
+
+                 Map<Long,Neighbour> neighours = node.getNeighbours();
+                 long i = 1;
+                 for(NeighbourGrpc neighbour:request.getNeighbourList()){
+                         Neighbour ng = deriveNeighbour(neighbour);
+                         neighours.put(i++, ng);
+                 }
+
+                 return node;
+         }
+
+         public static GraphGrpc obtainGraph(Graph graph){
+                 GraphGrpc.Builder gr = GraphGrpc.newBuilder();
+                 gr.setId(graph.getId());
+                 for(Node node:graph.getNodes().values()){
+                         NodeGrpc ng = obtainNode(node);
+                         gr.addNode(ng);
+                 }
+                 return gr.build();
+         }
+
+         public static Graph deriveGraph(GraphGrpc request) {
+               //id is not present
+                 Graph graph = new Graph();
+
+                 long i=1;
+                 Map<Long, Node> nodes = graph.getNodes();
+                 for(NodeGrpc node:request.getNodeList()){
+                         Node ng = deriveNode(node);
+                         nodes.put(i++, ng);
+                 }
+
+                 return graph;
+         }
+
+         public static VerificationGrpc obtainVerification(Verification verify){
+                 VerificationGrpc.Builder ver = VerificationGrpc.newBuilder();
+                 ver.setComment(verify.getComment());
+                 ver.setResult(verify.getResult());
+                 for(Test test:verify.getTests()){
+                         TestGrpc.Builder tst = TestGrpc.newBuilder().setResult(test.getResult());
+                         for(Node node:test.getPath()){
+                                 NodeGrpc ng = obtainNode(node);
+                                 tst.addNode(ng);
+                         }
+                         ver.addTest(tst);
+                 }
+                 return ver.build();
+         }
+
+         /**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/main/java/it/polito/grpc/README.rst b/verigraph/src/main/java/it/polito/grpc/README.rst
new file mode 100644 (file)
index 0000000..d089908
--- /dev/null
@@ -0,0 +1,442 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+
+gRPC Project
+============
+
+This project contains the interfaces for a web service based on gRPC.
+
+How to install:
+---------------
+
+For gRPC interface, add to your ``pom.xml`` (in the project this part is
+already present):
+
+::
+
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+            <version>${grpc.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+            <version>${grpc.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+            <version>${grpc.version}</version>
+        </dependency>
+
+For protobuf-based codegen integrated with the Maven build system, you
+can use protobuf-maven-plugin :
+
+::
+
+        <build>
+            <extensions>
+                <extension>
+                    <groupId>kr.motd.maven</groupId>
+                    <artifactId>os-maven-plugin</artifactId>
+                    <version>1.4.1.Final</version>
+                </extension>
+            </extensions>
+            <plugins>
+                <plugin>
+                    <groupId>org.xolstice.maven.plugins</groupId>
+                    <artifactId>protobuf-maven-plugin</artifactId>
+                    <version>0.5.0</version>
+                    <configuration>
+                        <protocArtifact>com.google.protobuf:protoc:3.1.0:exe:${os.detected.classifier}</protocArtifact>
+                        <pluginId>grpc-java</pluginId>
+                        <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
+                    </configuration>
+                    <executions>
+                        <execution>
+                            <goals>
+                                <goal>compile</goal>
+                                <goal>compile-custom</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+            </plugins>
+        </build>
+
+| In order to run the gRPC server and the junit test, you need to download the Manven Ant Task library
+  from `here <https://mvnrepository.com/artifact/org.apache.maven/maven-ant-tasks/2.1.3>`__
+  and copy into ``[verigraph]/lib/``
+
+| Due to the fact that the project is intended for Eclipse, you need to
+  install an additional Eclipse plugin because
+  `m2e <https://www.eclipse.org/m2e/>`__ does not evaluate the extension
+  specified in a ``pom.xml``. `Download
+  ``os-maven-plugin-1.5.0.Final.jar`` <http://repo1.maven.org/maven2/kr/motd/maven/os-maven-plugin/1.5.0.Final/os-maven-plugin-1.5.0.Final.jar>`__
+  and put it into the ``<ECLIPSE_HOME>/plugins`` directory.
+| (As you might have noticed, ``os-maven-plugin`` is a Maven extension,
+  a Maven plugin, and an Eclipse plugin.)
+
+If you are using IntelliJ IDEA, you should not have any problem.
+
+If you are using other IDEs such as NetBeans, you need to set the system
+properties ``os-maven-plugin`` sets manually when your IDE is launched.
+You usually use JVM's ``-D`` flags like the following:
+
+    | -Dos.detected.name=linux
+    | -Dos.detected.arch=x86\_64
+    | -Dos.detected.classifier=linux-x86\_64
+
+Included files:
+---------------
+
+Here you can find a brief description about useful files for the gRPC
+interface:
+
+**src/main/java:**
+
+-  *it.polito.grpc:*
+
+This package includes 2 classes that represent the client and server.
+
+    **Client.java:**
+
+    | Client of gRPC application. It implements all possible methods
+      necessary for communicate with server.
+    | It prints out the received response.
+    | Moreover it provides some static methods that are used for
+      creating the instances of requests.
+
+    **Service.java:**
+
+    | Server of gRPC application. It implements all possible methods
+      necessary for communicate with client.
+    | It saves the received request on log.
+    | This server could be accessed by multiple clients, because
+      synchronizes concurrent accesses.
+    | Each method that is possible to call is has the equivalent
+      operation in REST-interface.
+
+    **GrpcUtils.java:**
+
+    | This class provides some static methods that are used by
+      ``Service.java`` in order to translate a request into a class that
+      is accepted by Verigraph.
+    | Other methods are used to translate the class of Verigraph in the
+      proper gRPC response.
+    | These functionalities are exploited by test classes.
+    | Furthermore this set of methods is public, so in your application
+      you could call them, even if this should not be useful because
+      ``Client.java`` provides other high-level functions.
+
+-  *it.polito.grpc.test:*
+
+   This package includes classes for testing the gRPC application.
+
+    **GrpcServerTest.java:**
+
+    | For each possible method we test if works correctly.
+    | We create a fake client (so this test doesn't use the method that
+      are present in client class) and test if it receives the expected
+      response.
+    | In a nutshell, it tests the methods of Client in case of a fake
+      server.
+    | Please notice that the test prints some errors but this is
+      intentional, because the program tests also error case.
+    | Indeed, not all methods are tested, because we have another class
+      (ReachabilityTest.java) that is specialized for testing the
+      verification method.
+
+    **GrpcTest.java:**
+
+    | This set of tests is intended to control the most common use
+      cases, in particular all methods that are callable in Client and
+      Service class, apart from verifyPolicy for the same reason as
+      before.
+    | It tries also to raise an exception and verify if the behavior is
+      as expected.
+
+    **MultiThreadTest.java:**
+
+    | This test creates multiple clients that connect to the server and
+      verify is the result is correct. These methods test the
+      synchronization on
+    | server-side.
+
+    **ReachabilityTest.java:**
+
+    | This file tests the verification method, it exploits the test case
+      already present in the project and consequently has the certainty
+      of testing not so simple case. In particular it reads the file in
+      "src/main/webapp/json" and use this as starting point.
+    | Some exceptions are thrown in order to verify if they are handled
+      in a correct way.
+
+**src/main/proto:**
+
+    **verigraph.proto:**
+
+    | File containing the description of the service. This includes the
+      definition of all classes used in the application.
+    | Moreover contains the definition of the methods that is possible
+      to call.
+    | Each possible method called by REST API is mapped on a proper gRPC
+      method.
+    | In case of error a message containing the reason is returned to
+      the client.
+    | More details are available in the section about Proto Buffer.
+
+**taget/generated-sources/protobuf/java:**
+
+-  *io.grpc.verigraph:*
+
+   This package includes all classes generated from verigraph.proto by
+   means of protoc. For each object you can find 2 classes :
+
+       **{NameObject}Grpc.java**
+
+       **{NameObject}GrpcOrBuilder.java**
+
+       The first is the real implementation, the second is the
+       interface.
+
+**taget/generated-sources/protobuf/grpc-java:**
+
+-  *io.grpc.verigraph:*
+
+   This package includes a single class generated from verigraph.proto
+   by means of protoc.
+
+       **VerigraphGrpc.java:**
+
+       This is useful in order to create the stubs that are necessary to
+       communicate both for client and server.
+
+**lib:**
+
+This folder includes a jar used for compiling the project with Ant.
+
+    \*\*maven-ant-tasks-2.1.3.\ jar:**
+
+    This file is used by build.xml in order to include the maven
+    dependencies.
+
+**pom.xml:**
+
+| Modified in order to add all necessary dependencies. It contains also
+  the build tag used for create the generated-sources folders.
+| This part is added according to documentation of gRPC for java as
+  explained above in How To Install section.
+| For further clarification go to `this
+  link <https://github.com/grpc/grpc-java/blob/master/README.md>`__.
+
+**build.xml:**
+
+This ant file permit to run and compile the program in a simple way, it
+exploits the maven-ant-tasks-2.1.3.jar already present in project.
+
+It contains 3 fundamental tasks for gRPC interface:
+
+-  **build:** compile the program
+
+-  **run:** run both client and server
+
+-  **run-client :** run only client
+
+-  **run-server :** run only server
+
+-  **run-test :** launch all tests that are present in the package,
+   prints out the partial results and global result.
+
+Note that the execution of these tests may take up to 1-2 minutes when
+successful, according to your computer architecture.
+
+More Information About Proto Buffer:
+------------------------------------
+
+Further clarification about verigraph.proto:
+
+-  A ``simple RPC`` where the client sends a request to the server using
+   the stub and waits for a response to come back, just like a normal
+   function call.
+
+   .. code:: xml
+
+       // Obtains a graph
+       rpc GetGraph (RequestID) returns (GraphGrpc) {}
+
+In this case we send a request that contains the id of the graph and the
+response is a Graph.
+
+-  A ``server-side streaming RPC`` where the client sends a request to
+   the server and gets a stream to read a sequence of messages back. The
+   client reads from the returned stream until there are no more
+   messages. As you can see in our example, you specify a server-side
+   streaming method by placing the stream keyword before the response
+   type.
+
+   .. code:: xml
+
+
+       // Obtains a list of Nodes
+       rpc GetNodes (RequestID) returns (stream NodeGrpc) {}
+
+In this case we send a request that contains the id of the graph and the
+response is a list of Nodes that are inside graph.
+
+Further possibilities are available but in this project are not
+expolied. If you are curious see
+`here <http://www.grpc.io/docs/tutorials/basic/java.html#defining-the-service>`__.
+
+Our ``.proto`` file also contains protocol buffer message type
+definitions for all the request and response types used in our service
+methods - for example, here\92s the ``RequestID`` message type:
+
+.. code:: xml
+
+        message RequestID {
+            int64 idGraph = 1;
+            int64 idNode = 2;
+            int64 idNeighbour = 3;
+        }   
+
+The " = 1", " = 2" markers on each element identify the unique "tag"
+that field uses in the binary encoding. Tag numbers 1-15 require one
+less byte to encode than higher numbers, so as an optimization you can
+decide to use those tags for the commonly used or repeated elements,
+leaving tags 16 and higher for less-commonly used optional elements.
+Each element in a repeated field requires re-encoding the tag number, so
+repeated fields are particularly good candidates for this optimization.
+
+Protocol buffers are the flexible, efficient, automated solution to
+solve exactly the problem of serialization. With protocol buffers, you
+write a .proto description of the data structure you wish to store. From
+that, the protocol buffer compiler creates a class that implements
+automatic encoding and parsing of the protocol buffer data with an
+efficient binary format. The generated class provides getters and
+setters for the fields that make up a protocol buffer and takes care of
+the details of reading and writing the protocol buffer as a unit.
+Importantly, the protocol buffer format supports the idea of extending
+the format over time in such a way that the code can still read data
+encoded with the old format.
+
+::
+
+    syntax = "proto3";
+
+    package verigraph;
+
+    option java_multiple_files = true;
+    option java_package = "io.grpc.verigraph";
+    option java_outer_classname = "VerigraphProto";
+    ```
+
+This .proto file works for protobuf 3, that is slightly different from
+the version 2, so be careful if you have code already installed.
+
+The .proto file starts with a package declaration, which helps to
+prevent naming conflicts between different projects. In Java, the
+package name is used as the ``Java package`` unless you have explicitly
+specified a java\_package, as we have here. Even if you do provide a
+``java_package``, you should still define a normal ``package`` as well
+to avoid name collisions in the Protocol Buffers name space as well as
+in non-Java languages.
+
+| After the package declaration, you can see two options that are
+  Java-specific: ``java_package`` and ``java_outer_classname``.
+  ``java_package`` specifies in what Java package name your generated
+  classes should live. If you don't specify this explicitly, it simply
+  matches the package name given by the package declaration, but these
+  names usually aren't appropriate Java package names (since they
+  usually don't start with a domain name). The ``java_outer_classname``
+  option defines the class name which should contain all of the classes
+  in this file. If you don't give a ``java_outer_classname explicitly``,
+  it will be generated by converting the file name to camel case. For
+  example, "my\_proto.proto" would, by default, use "MyProto" as the
+  outer class name.
+| In this case this file is not generated, because
+  ``java_multiple_files`` option is true, so for each message we
+  generate a different class.
+
+For further clarifications see
+`here <https://developers.google.com/protocol-buffers/docs/javatutorial>`__
+
+Notes
+-----
+
+For gRPC interface you need that neo4jmanager service is already
+deployed, so if this is not the case, please follow the instructions at
+this
+`link <https://github.com/netgroup-polito/verigraph/blob/a3c008a971a8b16552a20bf2484ebf8717735dd6/README.md>`__.
+
+In this version there are some modified files compared to the original
+`Verigraph project <https://github.com/netgroup-polito/verigraph>`__
+
+**it.polito.escape.verify.service.NodeService:**
+
+At line 213 we modified the path, because this service is intended to
+run not only in container, as Tomcat, so we added other possibility that
+files is placed in src/main/webapp/json/ folder.
+
+**it.polito.escape.verify.service.VerificationService:**
+
+In the original case it searches for python files in "webapps" folder,
+that is present if the service is deployed in a container, but absent
+otherwise. So we added another string that will be used in the case the
+service doesn't run in Tomcat.
+
+**it.polito.escape.verify.databese.DatabaseClass:**
+
+Like before we added the possibility that files are not in "webapps"
+folder, so is modified in order to run in any environment. Modification
+in method loadDataBase() and persistDatabase().
+
+| Pay attention that Python is needed for the project. If it is not
+  already present on your computer, please `download
+  it <https://www.python.org/download/releases/2.7.3/>`__.
+| It works fine with Python 2.7.3, or in general Python 2.
+
+| If you have downloaded a Python version for 64-bit architecture please
+  copy the files in "service/z3\_64" and paste in "service/build" and
+  substitute them,
+| because this project works with Python for 32-bit architecture.
+
+Python and Z3 must support the same architetcure.
+
+Moreover you need the following dependencies installed on your python
+distribution:
+
+- "requests" python package ->
+http://docs.python-requests.org/en/master/
+
+- "jsonschema" python package -> https://pypi.python.org/pypi/jsonschema
+
+| HINT - to install a package you can raise the following command (Bash
+  on Linux or DOS shell on Windows): python -m pip install jsonschema
+  python -m pip install requests
+| Pay attention that it is possible that you have to modify the PATH
+  environment variable because is necessary to address the python
+  folder, used for verification phase.
+
+Remember to read the
+`README.rtf <https://gitlab.com/serena.spinoso/DP2.2017.SpecialProject2.gRPC/tree/master>`__
+and to follow the instructions in order to deploy the Verigraph service.
+
+| In the latest version of Maven there is the possibility that the
+  downloaded files are incompatible with Java Version of the project
+  (1.8).
+| In this case you have to modify the file ``hk2-parent-2.4.0-b31.pom``
+  under your local Maven repository (e.g.
+  'C:\\Users\\Standard.m2\\repository')
+| and in the path ``\org\glassfish\hk2\hk2-parent\2.4.0-b31`` find the
+  file and modify at line 1098 (in section ``profile``) the ``jdk``
+  version to ``[1.8,)`` .
+
+| Admittedly, the version that is supported by the downloaded files from
+  Maven Dependencies is incompatible with jdk of the project.
+| So modify the file ``gson-2.3.pom`` in Maven repository, under
+  ``com\google\code\gson\gson\2.3`` directory, in particular line 91,
+  from ``[1.8,`` to ``[1.8,)``.
+
+This project was also tested on Linux Ubuntu 15.10.
diff --git a/verigraph/src/main/java/it/polito/grpc/Service.java b/verigraph/src/main/java/it/polito/grpc/Service.java
new file mode 100644 (file)
index 0000000..8a77d05
--- /dev/null
@@ -0,0 +1,462 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.grpc;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import io.grpc.Server;
+import io.grpc.ServerBuilder;
+import io.grpc.stub.StreamObserver;
+import io.grpc.verigraph.ConfigurationGrpc;
+import io.grpc.verigraph.GetRequest;
+import io.grpc.verigraph.GraphGrpc;
+import io.grpc.verigraph.NeighbourGrpc;
+import io.grpc.verigraph.NewGraph;
+import io.grpc.verigraph.NewNeighbour;
+import io.grpc.verigraph.NewNode;
+import io.grpc.verigraph.NodeGrpc;
+import io.grpc.verigraph.Policy;
+import io.grpc.verigraph.RequestID;
+import io.grpc.verigraph.Status;
+import io.grpc.verigraph.VerificationGrpc;
+import io.grpc.verigraph.VerigraphGrpc;
+import it.polito.escape.verify.exception.BadRequestException;
+import it.polito.escape.verify.exception.DataNotFoundException;
+import it.polito.escape.verify.exception.ForbiddenException;
+import it.polito.escape.verify.model.Configuration;
+import it.polito.escape.verify.model.Graph;
+import it.polito.escape.verify.model.Neighbour;
+import it.polito.escape.verify.model.Node;
+import it.polito.escape.verify.model.Verification;
+import it.polito.escape.verify.resources.beans.VerificationBean;
+import it.polito.escape.verify.service.GraphService;
+import it.polito.escape.verify.service.NeighbourService;
+import it.polito.escape.verify.service.NodeService;
+import it.polito.escape.verify.service.VerificationService;
+
+public class Service {
+         /** Port on which the server should run. */
+         private static final Logger logger = Logger.getLogger(Service.class.getName());
+         private static final int port = 50051;
+         private static final String internalError = "Internal Server Error";
+         private Server server;
+         private GraphService graphService     = new GraphService();
+         private VerificationService verificationService = new VerificationService();
+         private NodeService nodeService = new NodeService();
+         private NeighbourService neighboursService = new NeighbourService();
+
+         public Service(int port)  {
+                 this(ServerBuilder.forPort(port), port);
+         }
+
+         /** Create a RouteGuide server using serverBuilder as a base and features as data. */
+         public Service(ServerBuilder<?> serverBuilder, int port) {
+                 server = serverBuilder.addService(new VerigraphImpl())
+                                 .build();
+         }
+
+         public void start() throws IOException {
+                 server.start();
+                 logger.info("Server started, listening on "+ port);
+                 Runtime.getRuntime().addShutdownHook(new Thread() {
+                         @Override
+                         public void run() {
+                                 logger.info("*** Shutting down gRPC server since JVM is shutting down");
+                                 Service.this.stop();
+                                 logger.info("*** Server shut down");
+                         }
+                 });
+         }
+
+         public void stop() {
+                 if (server != null) {
+                         server.shutdown();
+                 }
+         }
+
+         private void blockUntilShutdown() throws InterruptedException {
+                 if (server != null) {
+                         server.awaitTermination();
+                 }
+         }
+
+         /** Main function to launch server from cmd. */
+         public static void main(String[] args) throws IOException, InterruptedException {
+                 try{
+                         Service server = new Service(port);
+                         server.start();
+                         server.blockUntilShutdown();
+                 }
+                 catch(Exception ex){
+                         logger.log(Level.WARNING, ex.getMessage());
+                 }
+         }
+
+         /**Here start method of my impementation*/
+         private class VerigraphImpl extends VerigraphGrpc.VerigraphImplBase{
+
+                 /** Here start methods of GraphResource*/
+                 @Override
+                 public void getGraphs(GetRequest request, StreamObserver<GraphGrpc> responseObserver) {
+                         try{
+                                 for(Graph item : graphService.getAllGraphs()) {
+                                         GraphGrpc gr = GrpcUtils.obtainGraph(item);
+                                         responseObserver.onNext(gr);
+                                 }
+                         }catch(Exception ex){
+                                 GraphGrpc nr = GraphGrpc.newBuilder().setErrorMessage(internalError).build();
+                                 responseObserver.onNext(nr);
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }
+                         responseObserver.onCompleted();
+                 }
+
+                 @Override
+                 public void createGraph(GraphGrpc request, StreamObserver<NewGraph> responseObserver) {
+                         NewGraph.Builder response = NewGraph.newBuilder();
+                         try{
+                                 Graph graph = GrpcUtils.deriveGraph(request);
+                                 Graph newGraph = graphService.addGraph(graph);
+                                 response.setSuccess(true).setGraph(GrpcUtils.obtainGraph(newGraph));
+                         }catch(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 deleteGraph(RequestID request, StreamObserver<Status> responseObserver) {
+
+                         Status.Builder response = Status.newBuilder();
+                         try{
+                                 graphService.removeGraph(request.getIdGraph());
+                                 response.setSuccess(true);
+                         }catch(ForbiddenException 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 getGraph(RequestID request, StreamObserver<GraphGrpc> responseObserver) {
+                         try{
+                                 Graph graph = graphService.getGraph(request.getIdGraph());
+                                 GraphGrpc gr = GrpcUtils.obtainGraph(graph);
+                                 responseObserver.onNext(gr);
+                         }catch(ForbiddenException | DataNotFoundException ex){
+                                 GraphGrpc grError = GraphGrpc.newBuilder().setErrorMessage(ex.getMessage()).build();
+                                 responseObserver.onNext(grError);
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }catch(Exception ex){
+                                 GraphGrpc grError = GraphGrpc.newBuilder().setErrorMessage(internalError).build();
+                                 responseObserver.onNext(grError);
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }
+                         responseObserver.onCompleted();
+                 }
+
+                 @Override
+                 public void updateGraph(GraphGrpc request, StreamObserver<NewGraph> responseObserver) {
+                         NewGraph.Builder response = NewGraph.newBuilder();
+                         try{
+                                 Graph graph = GrpcUtils.deriveGraph(request);
+                                 graph.setId(request.getId());
+                                 Graph newGraph = graphService.updateGraph(graph);
+                                 response.setSuccess(true).setGraph(GrpcUtils.obtainGraph(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 verifyPolicy(Policy request, StreamObserver<VerificationGrpc> responseObserver) {
+
+                         VerificationGrpc.Builder verification;
+                         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
+                                 Verification ver = verificationService.verify(request.getIdGraph(), verify);
+                                 verification = VerificationGrpc.newBuilder(GrpcUtils.obtainVerification(ver))
+                                                                       .setSuccessOfOperation(true);
+                         }catch(ForbiddenException | DataNotFoundException | BadRequestException ex){
+                                 verification = VerificationGrpc.newBuilder().setSuccessOfOperation(false)
+                                                                       .setErrorMessage(ex.getMessage());
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }     catch(Exception ex){
+                                 verification = VerificationGrpc.newBuilder().setSuccessOfOperation(false)
+                                                                       .setErrorMessage(internalError);
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }
+                         responseObserver.onNext(verification.build());
+                         responseObserver.onCompleted();
+                 }
+
+                 /** Here start methods of NodeResource*/
+
+                 @Override
+                 public void getNodes(RequestID request, StreamObserver<NodeGrpc> responseObserver) {
+                         try{
+                                 for (Node item : nodeService.getAllNodes(request.getIdGraph())) {
+                                         NodeGrpc nr = GrpcUtils.obtainNode(item);
+                                         responseObserver.onNext(nr);
+                                 }
+                         }catch(ForbiddenException | DataNotFoundException ex){
+                                 NodeGrpc nr = NodeGrpc.newBuilder().setErrorMessage(ex.getMessage()).build();
+                                 responseObserver.onNext(nr);
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }     catch(Exception ex){
+                                 NodeGrpc nr = NodeGrpc.newBuilder().setErrorMessage(internalError).build();
+                                 responseObserver.onNext(nr);
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }
+                         responseObserver.onCompleted();
+                 }
+
+                 @Override
+                 public void createNode(NodeGrpc request, StreamObserver<NewNode> responseObserver) {
+                         NewNode.Builder response = NewNode.newBuilder();
+                         try{
+                                 Node node = GrpcUtils.deriveNode(request);
+                                 Node newNode = nodeService.addNode(request.getIdGraph(), node);
+                                 response.setSuccess(true).setNode(GrpcUtils.obtainNode(newNode));
+                         }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 deleteNode(RequestID request, StreamObserver<Status> responseObserver) {
+                         Status.Builder response = Status.newBuilder();
+                         try{
+                                 nodeService.removeNode(request.getIdGraph(), request.getIdNode());
+                                 response.setSuccess(true);
+                         }catch(ForbiddenException | DataNotFoundException 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 getNode(RequestID request, StreamObserver<NodeGrpc> responseObserver) {
+                         NodeGrpc nr;
+                         try{
+                                 Node node = nodeService.getNode(request.getIdGraph(), request.getIdNode());
+                                 nr= GrpcUtils.obtainNode(node);
+                         }catch(ForbiddenException | DataNotFoundException ex){
+                                 nr = NodeGrpc.newBuilder().setErrorMessage(ex.getMessage()).build();
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }catch(Exception ex){
+                                 nr = NodeGrpc.newBuilder().setErrorMessage(internalError).build();
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }
+                         responseObserver.onNext(nr);
+                         responseObserver.onCompleted();
+                 }
+
+                 @Override
+                 public void updateNode(NodeGrpc request, StreamObserver<NewNode> responseObserver) {
+                         NewNode.Builder response = NewNode.newBuilder();
+                         try{
+                                 Node node = GrpcUtils.deriveNode(request);
+                                 node.setId(request.getId());
+                                 Node newNode = nodeService.updateNode(request.getIdGraph(), node);
+                                 response.setSuccess(true).setNode(GrpcUtils.obtainNode(newNode));
+                         }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 configureNode(ConfigurationGrpc request, StreamObserver<Status> responseObserver) {
+                         Status.Builder response = Status.newBuilder();
+                         try{
+                                 if (request.getIdGraph() <= 0) {
+                                         throw new ForbiddenException("Illegal graph id: " + request.getIdGraph());
+                                 }
+                                 if (request.getIdNode() <= 0) {
+                                         throw new ForbiddenException("Illegal node id: " + request.getIdNode());
+                                 }
+                                 Graph graph = new GraphService().getGraph(request.getIdGraph());
+                                 if (graph == null){
+                                         throw new BadRequestException("Graph with id " + request.getIdGraph() + " not found");
+                                 }
+                                 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());
+                                 }
+                                 Configuration nodeConfiguration = GrpcUtils.deriveConfiguration(request);
+                                 Node nodeCopy = new Node();
+                                 nodeCopy.setId(node.getId());
+                                 nodeCopy.setName(node.getName());
+                                 nodeCopy.setFunctional_type(node.getFunctional_type());
+                                 Map<Long,Neighbour> nodes = new HashMap<Long,Neighbour>();
+                                 nodes.putAll(node.getNeighbours());
+                                 nodeCopy.setNeighbours(nodes);
+                                 nodeConfiguration.setId(nodeCopy.getName());
+                                 nodeCopy.setConfiguration(nodeConfiguration);
+
+                                 Graph graphCopy = new Graph();
+                                 graphCopy.setId(graph.getId());
+                                 graphCopy.setNodes(new HashMap<Long, Node>(graph.getNodes()));
+                                 graphCopy.getNodes().remove(node.getId());
+
+                                 NodeService.validateNode(graphCopy, nodeCopy);
+
+                                 graph.getNodes().put(request.getIdNode(), nodeCopy);
+                                 response.setSuccess(true);
+                         }catch(ForbiddenException | 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();
+                 }
+
+                 /** Here start methods of NeighbourResource*/
+                 @Override
+                 public void getNeighbours(RequestID request, StreamObserver<NeighbourGrpc> responseObserver) {
+                         try{
+                                 for(Neighbour item : neighboursService.getAllNeighbours(request.getIdGraph(), request.getIdNode())) {
+                                         NeighbourGrpc nr = GrpcUtils.obtainNeighbour(item);
+                                         responseObserver.onNext(nr);
+                                 }
+                         }catch(ForbiddenException | DataNotFoundException ex){
+                                 NeighbourGrpc nr = NeighbourGrpc.newBuilder().setErrorMessage(ex.getMessage()).build();
+                                 responseObserver.onNext(nr);
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }catch(Exception ex){
+                                 NeighbourGrpc nr = NeighbourGrpc.newBuilder().setErrorMessage(internalError).build();
+                                 responseObserver.onNext(nr);
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }
+                         responseObserver.onCompleted();
+                 }
+
+                 @Override
+                 public void createNeighbour(NeighbourGrpc request, StreamObserver<NewNeighbour> responseObserver) {
+                         NewNeighbour.Builder response = NewNeighbour.newBuilder();
+                         try{
+                                 Neighbour neighbour = GrpcUtils.deriveNeighbour(request);
+                                 Neighbour newNeighbour = neighboursService.addNeighbour(request.getIdGraph(), request.getIdNode(), neighbour);
+                                 response.setSuccess(true).setNeighbour(GrpcUtils.obtainNeighbour(newNeighbour));
+                         }catch(ForbiddenException | DataNotFoundException | BadRequestException ex){
+                                 response.setSuccess(false).setErrorMessage(ex.getMessage());
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }catch(Exception ex){
+                                 response.setSuccess(false).setErrorMessage(ex.getMessage());
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }
+                         responseObserver.onNext(response.build());
+                         responseObserver.onCompleted();
+                 }
+
+                 @Override
+                 public void deleteNeighbour(RequestID request, StreamObserver<Status> responseObserver) {
+                         Status.Builder response = Status.newBuilder();
+                         try{
+                                 neighboursService.removeNeighbour(request.getIdGraph(), request.getIdNode(), request.getIdNeighbour());
+                                 response.setSuccess(true);
+                         }catch(ForbiddenException | DataNotFoundException ex){
+                                 response.setSuccess(false).setErrorMessage(ex.getMessage());
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }catch(Exception ex){
+                                 response.setSuccess(false).setErrorMessage(ex.getMessage());
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }
+                         responseObserver.onNext(response.build());
+                         responseObserver.onCompleted();
+                 }
+
+                 @Override
+                 public void getNeighbour(RequestID request, StreamObserver<NeighbourGrpc> responseObserver) {
+                         NeighbourGrpc nr;
+                         try{
+                                 Neighbour neighbour = neighboursService.getNeighbour(request.getIdGraph(),
+                                                 request.getIdNode(), request.getIdNeighbour());
+                                 nr = GrpcUtils.obtainNeighbour(neighbour);
+
+                         }catch(ForbiddenException | DataNotFoundException ex){
+                                 nr = NeighbourGrpc.newBuilder().setErrorMessage(ex.getMessage()).build();
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }catch(Exception ex){
+                                 nr = NeighbourGrpc.newBuilder().setErrorMessage(internalError).build();
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }
+                         responseObserver.onNext(nr);
+                         responseObserver.onCompleted();
+                 }
+
+                 @Override
+                 public void updateNeighbour(NeighbourGrpc request, StreamObserver<NewNeighbour> responseObserver) {
+                         NewNeighbour.Builder response = NewNeighbour.newBuilder();
+                         try{
+                                 Neighbour neighbour = GrpcUtils.deriveNeighbour(request);
+                                 neighbour.setId(request.getId());
+                                 Neighbour newNeighbour = neighboursService.updateNeighbour(request.getIdGraph(), request.getIdNode(), neighbour);
+                                 response.setSuccess(true).setNeighbour(GrpcUtils.obtainNeighbour(newNeighbour));
+                         }catch(ForbiddenException | DataNotFoundException | BadRequestException ex){
+                                 response.setSuccess(false).setErrorMessage(ex.getMessage());
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }catch(Exception ex){
+                                 response.setSuccess(false).setErrorMessage(ex.getMessage());
+                                 logger.log(Level.WARNING, ex.getMessage());
+                         }
+                         responseObserver.onNext(response.build());
+                         responseObserver.onCompleted();
+                 }
+         }
+}
diff --git a/verigraph/src/main/java/it/polito/grpc/test/GrpcServerTest.java b/verigraph/src/main/java/it/polito/grpc/test/GrpcServerTest.java
new file mode 100644 (file)
index 0000000..7344447
--- /dev/null
@@ -0,0 +1,292 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.grpc.test;
+
+import static org.junit.Assert.assertEquals;
+
+import io.grpc.ManagedChannel;
+import io.grpc.inprocess.InProcessChannelBuilder;
+import io.grpc.inprocess.InProcessServerBuilder;
+import io.grpc.verigraph.ConfigurationGrpc;
+import io.grpc.verigraph.GetRequest;
+import io.grpc.verigraph.GraphGrpc;
+import io.grpc.verigraph.NeighbourGrpc;
+import io.grpc.verigraph.NewGraph;
+import io.grpc.verigraph.NewNeighbour;
+import io.grpc.verigraph.NewNode;
+import io.grpc.verigraph.NodeGrpc;
+import io.grpc.verigraph.NodeGrpc.FunctionalType;
+import io.grpc.verigraph.RequestID;
+import io.grpc.verigraph.Status;
+import io.grpc.verigraph.VerigraphGrpc;
+import it.polito.grpc.Client;
+import it.polito.grpc.Service;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Unit tests for {@link Service}.
+ * For testing basic gRPC unit test only.
+ * Not intended to provide a high code coverage or to test every major usecase.
+ */
+@RunWith(JUnit4.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class GrpcServerTest {
+       private Service server;
+       private ManagedChannel inProcessChannel;
+
+       @Before
+       public void setUp() throws Exception {
+               String uniqueServerName = "in-process server for " + getClass();
+               // use directExecutor for both InProcessServerBuilder and InProcessChannelBuilder can reduce the
+               // usage timeouts and latches in test. But we still add timeout and latches where they would be
+               // needed if no directExecutor were used, just for demo purpose.
+               server = new Service(InProcessServerBuilder.forName(uniqueServerName).directExecutor(),0);
+               server.start();
+               inProcessChannel = InProcessChannelBuilder.forName(uniqueServerName).directExecutor().build();
+       }
+
+       @After
+       public void tearDown() throws Exception {
+               inProcessChannel.shutdownNow();
+               server.stop();
+       }
+
+       @Test
+       public void test1Graph() throws Exception {
+               RequestID request = RequestID.newBuilder().setIdGraph(1).build() ;//id not present
+               GraphGrpc ufoundedGraph = GraphGrpc.newBuilder()
+                               .setErrorMessage("Graph with id 1 not found").build();
+               VerigraphGrpc.VerigraphBlockingStub stub = VerigraphGrpc.newBlockingStub(inProcessChannel);
+
+               // graph not found in the server
+               GraphGrpc graph = stub.getGraph(request);
+
+               assertEquals(ufoundedGraph, graph);
+
+               // getGraph in the server, but first add it
+               GraphGrpc addedGraph = GraphGrpc.newBuilder().build();
+               NewGraph response = stub.createGraph(addedGraph);
+               addedGraph = response.getGraph();
+               request = RequestID.newBuilder().setIdGraph(1).build() ;
+               graph = stub.getGraph(request);
+
+               assertEquals(addedGraph.getId(), graph.getId());
+
+               //updateGraph
+               GraphGrpc updatedGraph = GraphGrpc.newBuilder().setId(response.getGraph().getId()).build();
+               response = stub.updateGraph(updatedGraph);
+
+               assertEquals(response.getSuccess(),true);
+       }
+
+       @Test
+       public void test2Graphs() throws Exception {
+               // setup
+               GetRequest request = GetRequest.newBuilder().build();
+               GraphGrpc g1 = GraphGrpc.newBuilder().build();
+               GraphGrpc g2 = GraphGrpc.newBuilder().build();
+               GraphGrpc g3 = GraphGrpc.newBuilder().build();
+               GraphGrpc g4 = GraphGrpc.newBuilder().build();
+
+               VerigraphGrpc.VerigraphBlockingStub stub = VerigraphGrpc.newBlockingStub(inProcessChannel);
+
+               stub.createGraph(g1);
+               stub.createGraph(g2);
+               stub.createGraph(g3);
+               stub.createGraph(g4);
+               g1 = GraphGrpc.newBuilder(g1).setId(1).build();
+               g2 = GraphGrpc.newBuilder(g2).setId(2).build();
+               g3 = GraphGrpc.newBuilder(g3).setId(3).build();
+               g4 = GraphGrpc.newBuilder(g4).setId(4).build();
+               // run
+               Iterator<GraphGrpc> graphs = stub.getGraphs(request);
+
+               assertEquals(graphs.next(), g1);
+               assertEquals(graphs.next(), g2);
+               assertEquals(graphs.next(), g3);
+               assertEquals(graphs.next(), g4);
+
+               //deleteGraph
+               RequestID req = RequestID.newBuilder().setIdGraph(g1.getId()).build();
+               stub.deleteGraph(req);
+               // run
+               graphs = stub.getGraphs(request);
+
+               assertEquals(graphs.next(), g2);
+               assertEquals(graphs.next(), g3);
+               assertEquals(graphs.next(), g4);
+       }
+
+       @Test
+       public void test3Node() throws Exception {
+               RequestID request = RequestID.newBuilder().setIdGraph(2).setIdNode(1).build() ;//id not present
+               NodeGrpc ufoundedGraph = NodeGrpc.newBuilder()
+                                       .setErrorMessage("Node with id 1 not found in graph with id 2").build();
+               VerigraphGrpc.VerigraphBlockingStub stub = VerigraphGrpc.newBlockingStub(inProcessChannel);
+
+               // graph not found in the server
+               NodeGrpc node = stub.getNode(request);
+
+               assertEquals(ufoundedGraph, node);
+
+               // graph found in the server, but first add it
+               NodeGrpc addedNode = NodeGrpc.newBuilder().setName("client").setIdGraph(2)
+                               .setFunctionalType(FunctionalType.endhost).build();
+               NewNode response = stub.createNode(addedNode);
+               addedNode = response.getNode();
+               request = RequestID.newBuilder().setIdGraph(2).setIdNode(1).build() ;
+               node = stub.getNode(request);
+
+               assertEquals(addedNode.getId(), node.getId());
+               assertEquals(addedNode.getName(),"client");
+
+               //updateNode
+               NodeGrpc updatedNode = NodeGrpc.newBuilder().setName("Nodo2").setIdGraph(2).setId(1)
+                               .setFunctionalType(FunctionalType.endhost).build();
+               response = stub.updateNode(updatedNode);
+
+               assertEquals(response.getSuccess(),true);
+               assertEquals(response.getNode().getName(),"Nodo2");
+
+               //configureNode
+               Map<String,String> params = new HashMap<String,String>();
+               params.put("url", "www.facebook.com");
+               params.put("body", "word");
+               params.put("destination","server");
+               params.put("protocol", "HTTP_REQUEST");
+               ConfigurationGrpc configuration = Client.createConfigurationGrpc(params, null, null, null);
+               ConfigurationGrpc config = ConfigurationGrpc.newBuilder(configuration).setIdGraph(2)
+                                                       .setIdNode(1).build();
+
+               Status status = stub.configureNode(config);
+
+               assertEquals(status.getSuccess(),true);
+       }
+
+       @Test
+       public void test4Nodes() throws Exception {
+               // setup
+               RequestID request = RequestID.newBuilder().setIdGraph(2).build();
+               NodeGrpc n1 = NodeGrpc.newBuilder(Client.createNodeGrpc("Node5", "endhost", null, null))
+                               .setIdGraph(2).build();
+               NodeGrpc n2 =  NodeGrpc.newBuilder(Client.createNodeGrpc("Node3", "endhost", null, null))
+                               .setIdGraph(2).build();
+               NodeGrpc n3 =  NodeGrpc.newBuilder(Client.createNodeGrpc("Node4", "endhost", null, null))
+                               .setIdGraph(2).build();
+               NodeGrpc n4 =  NodeGrpc.newBuilder(Client.createNodeGrpc("client", "endhost", null, null))
+                               .setIdGraph(2).build();
+
+               VerigraphGrpc.VerigraphBlockingStub stub = VerigraphGrpc.newBlockingStub(inProcessChannel);
+
+               stub.createNode(n1);
+               stub.createNode(n2);
+               stub.createNode(n3);
+               stub.createNode(n4);
+               n1 = NodeGrpc.newBuilder(n1).setId(2).setIdGraph(0).build();
+               n2 = NodeGrpc.newBuilder(n2).setId(3).setIdGraph(0).build();
+               n3 = NodeGrpc.newBuilder(n3).setId(4).setIdGraph(0).build();
+               n4 = NodeGrpc.newBuilder(n4).setId(5).setIdGraph(0).build();
+               // run
+               Iterator<NodeGrpc> nodes = stub.getNodes(request);
+
+               nodes.next();
+               assertEquals(nodes.next(), n1);
+               assertEquals(nodes.next(), n2);
+               assertEquals(nodes.next(), n3);
+               assertEquals(nodes.next(), n4);
+
+               //deleteNode
+               RequestID req = RequestID.newBuilder().setIdGraph(2).setIdNode(1).build();
+               stub.deleteNode(req);
+               // run
+               nodes = stub.getNodes(request);
+
+               assertEquals(nodes.next(), n1);
+               assertEquals(nodes.next(), n2);
+               assertEquals(nodes.next(), n3);
+               assertEquals(nodes.next(), n4);
+       }
+
+       @Test
+       public void test5Neighbours() throws Exception {
+               RequestID request = RequestID.newBuilder().setIdGraph(2).setIdNode(2).setIdNeighbour(1).build() ;//id not present
+               NeighbourGrpc ufoundedNeighbour = NeighbourGrpc.newBuilder()
+                                               .setErrorMessage("Neighbour with id 1 not found for node with id 2 in graph with id 2").build();;
+               VerigraphGrpc.VerigraphBlockingStub stub = VerigraphGrpc.newBlockingStub(inProcessChannel);
+
+               // Neighbour not found in the server
+               NeighbourGrpc neighbour = stub.getNeighbour(request);
+
+               assertEquals(ufoundedNeighbour, neighbour);
+
+               // getNeighbour, but first add it
+               NeighbourGrpc addedNeighbour = NeighbourGrpc.newBuilder().setIdGraph(2).setIdNode(2)
+                                                                               .setName("client").build();
+               NewNeighbour response = stub.createNeighbour(addedNeighbour);
+               addedNeighbour = response.getNeighbour();
+               request = RequestID.newBuilder().setIdGraph(2).setIdNode(2)
+                                               .setIdNeighbour(addedNeighbour.getId()).build();
+               neighbour = stub.getNeighbour(request);
+
+               assertEquals(addedNeighbour.getId(), neighbour.getId());
+
+               //updateNeighbour
+               NeighbourGrpc updatedNeighbour = Client.createNeighbourGrpc("Node4");
+               NeighbourGrpc nu = NeighbourGrpc.newBuilder(updatedNeighbour)
+                               .setId(response.getNeighbour().getId()).setIdGraph(2).setIdNode(2).build();
+               response = stub.updateNeighbour(nu);
+
+               assertEquals(response.getSuccess(),true);
+               assertEquals(response.getNeighbour().getName(),"Node4");
+       }
+
+       @Test
+       public void test6Neighbours() throws Exception {
+               // setup
+               RequestID request = RequestID.newBuilder().setIdGraph(2).setIdNode(2).build();
+               NeighbourGrpc n1 = NeighbourGrpc.newBuilder().setIdGraph(2).setIdNode(2)
+                                                       .setName("Node3").build();
+               NeighbourGrpc n2 = NeighbourGrpc.newBuilder().setIdGraph(2).setIdNode(2)
+                                                       .setName("client").build();
+
+               VerigraphGrpc.VerigraphBlockingStub stub = VerigraphGrpc.newBlockingStub(inProcessChannel);
+
+               stub.createNeighbour(n1);
+               stub.createNeighbour(n2);
+               n1 = NeighbourGrpc.newBuilder(n1).setId(2).setIdGraph(0).setIdNode(0).build();
+               n2 = NeighbourGrpc.newBuilder(n2).setId(3).setIdGraph(0).setIdNode(0).build();
+               // run
+               Iterator<NeighbourGrpc> neighbours = stub.getNeighbours(request);
+
+               neighbours.next();
+               assertEquals(neighbours.next(), n1);
+               assertEquals(neighbours.next(), n2);
+
+               //deleteNeighbour
+               RequestID req = RequestID.newBuilder().setIdGraph(2).setIdNode(2).setIdNeighbour(1).build();
+               stub.deleteNeighbour(req);
+               // run
+               neighbours = stub.getNeighbours(request);
+
+               assertEquals(neighbours.next(), n1);
+               assertEquals(neighbours.next(), n2);
+       }
+}
diff --git a/verigraph/src/main/java/it/polito/grpc/test/GrpcTest.java b/verigraph/src/main/java/it/polito/grpc/test/GrpcTest.java
new file mode 100644 (file)
index 0000000..41f9cad
--- /dev/null
@@ -0,0 +1,349 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.grpc.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.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+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 io.grpc.verigraph.ConfigurationGrpc;
+import io.grpc.verigraph.GraphGrpc;
+import io.grpc.verigraph.NeighbourGrpc;
+import io.grpc.verigraph.NewGraph;
+import io.grpc.verigraph.NewNeighbour;
+import io.grpc.verigraph.NewNode;
+import io.grpc.verigraph.NodeGrpc;
+import it.polito.grpc.Client;
+import it.polito.grpc.Service;
+
+@RunWith(JUnit4.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class GrpcTest {
+       private Service server;
+       private Client client;
+
+       @Before
+       public void setUpBeforeClass() throws Exception {
+               client = new Client("localhost" , 50051);
+               server = new Service(50051);
+               server.start();
+       }
+
+       @After
+       public void tearDown() throws Exception {
+               server.stop();
+               client.shutdown();
+       }
+
+       // method for comparing two non-null strings
+       private void compareString(String rs, String ts, String meaning) {
+               assertNotNull("NULL "+meaning, ts);
+               assertEquals("Wrong "+meaning, rs, ts);
+       }
+
+       @Test
+       public final void test1Load() throws Exception{
+               String funcType1 = "vpnaccess";
+               String funcType2 = "vpnexit";
+
+               // load an existing graph with 2 nodes
+               Map<String,String> map = new HashMap<String,String>();
+               map.put("vpnexit", "Node2");
+               ConfigurationGrpc conf = Client.createConfigurationGrpc(map, null, null, null);
+               NodeGrpc node1 = Client.createNodeGrpc("Node1", funcType1, null, conf);
+               List<NeighbourGrpc> neighbours = new ArrayList<NeighbourGrpc>();
+               NeighbourGrpc nb = Client.createNeighbourGrpc("Node1");
+               neighbours.add(nb);
+               map.clear();
+               map.put("vpnaccess", "Node1");
+               conf = Client.createConfigurationGrpc(map, null, null, null);
+               NodeGrpc node2 = Client.createNodeGrpc("Node2", funcType2, neighbours, conf);
+               List<NodeGrpc> nodes = new ArrayList<NodeGrpc>();
+               nodes.add(node1);
+               nodes.add(node2);
+               GraphGrpc graph = Client.createGraphGrpc(nodes);
+               //createGraph
+               graph = client.createGraph(graph).getGraph();
+
+               //getGraph
+               GraphGrpc retreivedGraph = client.getGraph(graph.getId());
+
+               assertNotNull("NULL Graph ",retreivedGraph);
+               assertEquals(graph.getId(), retreivedGraph.getId());
+
+               // check the name of first node and the id
+               compareString(retreivedGraph.getNodeList().get(0).getName(), graph.getNodeList().get(0).getName(), "node name");
+               assertEquals(retreivedGraph.getNodeList().get(0).getId(), graph.getNodeList().get(0).getId());
+
+               // check the name of second node and the id
+               compareString(retreivedGraph.getNodeList().get(1).getName(), graph.getNodeList().get(1).getName(), "node name");
+               assertEquals(retreivedGraph.getNodeList().get(1).getId(), graph.getNodeList().get(1).getId());
+
+               //updateGraph
+               GraphGrpc updatedGraph = GraphGrpc.newBuilder().build();
+               NewGraph response = client.updateGraph(graph.getId(),updatedGraph);
+
+               assertEquals(response.getSuccess(),true);
+       }
+
+       @Test
+       public final void test2LoadWithError() throws Exception{
+               // try to load a graph with node without functionalType
+               NodeGrpc node = null;
+               try{
+                       node = Client.createNodeGrpc("Node1", null, null, null);
+                       fail( "createNodeGrpc didn't throw when I expected it to" );
+               }
+               catch(Exception ex){
+               }
+               List<NodeGrpc> nodes = new ArrayList<NodeGrpc>();
+               if(node != null)
+                       nodes.add(node);
+
+               GraphGrpc graph = Client.createGraphGrpc(nodes);
+               graph = client.createGraph(graph).getGraph();
+
+               assertEquals(graph.getId(), 2);
+
+               //getGraphs
+               Iterator<GraphGrpc> graphs = client.getGraphs().iterator();
+
+               assertEquals(graphs.next().getId(), 1);
+               assertEquals(graphs.next(), graph);
+
+               //deleteGraph
+               boolean resp= client.deleteGraph(graph.getId());
+               assertEquals(resp, true);
+
+               List<GraphGrpc> listGraphs = client.getGraphs();
+
+               assertEquals(listGraphs.size(), 1);
+               assertEquals(listGraphs.get(0).getId(), 1);
+       }
+
+       @Test
+       public void test3Node() throws Exception {
+               NodeGrpc ufoundedGraph = NodeGrpc.newBuilder()
+                               .setErrorMessage("Node with id 1 not found in graph with id 1").build();
+
+               // graph not found in the server
+               NodeGrpc node = client.getNode(1, 1);//id not present
+
+               assertEquals(ufoundedGraph, node);
+
+               // graph found in the server, but first add it
+               NodeGrpc addedNode = Client.createNodeGrpc("Node4", "firewall", null, null);
+               NewNode response = client.createNode(addedNode, 1);
+               addedNode = response.getNode();
+               node = client.getNode(1, 1);
+
+               assertEquals(addedNode.getId(), node.getId());
+
+               //updateNode
+               NodeGrpc updatedNode = Client.createNodeGrpc("Node9", "endhost", null, null);
+               response = client.updateNode(1, addedNode.getId(), updatedNode);
+
+               assertEquals(response.getSuccess(),true);
+
+               //configureNode
+               //this configuration is valid only on endhost!
+               Map<String,String> params = new HashMap<String,String>();
+               params.put("url", "www.facebook.com");
+               params.put("body", "word");
+               params.put("destination","server");
+               params.put("protocol", "HTTP_REQUEST");
+               ConfigurationGrpc configuration = Client.createConfigurationGrpc(params, null, null, null);
+
+               boolean status = client.configureNode(1, 1, configuration);
+
+               assertEquals(status,true);
+       }
+
+       @Test
+       public void test4Nodes() throws Exception {
+               // setup
+               GraphGrpc graph = Client.createGraphGrpc(null);
+               //createGraph
+               graph = client.createGraph(graph).getGraph();
+
+               List<NeighbourGrpc> neighbours = new ArrayList<NeighbourGrpc>();
+               NeighbourGrpc nb = Client.createNeighbourGrpc("Node6");
+               neighbours.add(nb);
+               NodeGrpc n1 = Client.createNodeGrpc("Node6", "mailserver", null, null);
+               NodeGrpc n2 = Client.createNodeGrpc("Node9", "endhost", neighbours, null);
+               Map<String,String> map = new HashMap<String,String>();
+               map.put("mailserver", "Node6");
+               ConfigurationGrpc conf = Client.createConfigurationGrpc(map, null, null, null);
+               NodeGrpc n3 = Client.createNodeGrpc("Node10", "mailclient", null, conf);
+               NodeGrpc n4 = Client.createNodeGrpc("Node11", "nat", null, null);
+
+               NewNode nw1 = client.createNode(n1, graph.getId());
+               NewNode nw2 = client.createNode(n2, graph.getId());
+               NewNode nw3 = client.createNode(n3, graph.getId());
+               NewNode nw4 = client.createNode(n4, graph.getId());
+               assertEquals(nw1.getSuccess(),true);
+               assertEquals(nw2.getSuccess(),true);
+               assertEquals(nw3.getSuccess(),true);
+               assertEquals(nw4.getSuccess(),true);
+               n1 = NodeGrpc.newBuilder(n1).setId(nw1.getNode().getId()).build();
+               n2 = NodeGrpc.newBuilder(n2).setId(nw2.getNode().getId()).build();
+               n3 = NodeGrpc.newBuilder(n3).setId(nw3.getNode().getId()).build();
+               n4 = NodeGrpc.newBuilder(n4).setId(nw4.getNode().getId()).build();
+
+               // getNodes
+               Iterator<NodeGrpc> nodes = client.getNodes(graph.getId()).iterator();
+
+               assertEquals(nodes.next().getName(), n1.getName());
+               assertEquals(nodes.next().getName(), n2.getName());
+               assertEquals(nodes.next().getName(), n3.getName());
+               assertEquals(nodes.next().getName(), n4.getName());
+
+               //deleteNode
+               client.deleteNode(graph.getId(), 1);
+               // run
+               nodes = client.getNodes(graph.getId()).iterator();
+
+               assertEquals(nodes.next().getName(), n2.getName());
+               assertEquals(nodes.next().getName(), n3.getName());
+               assertEquals(nodes.next().getName(), n4.getName());
+       }
+
+       @Test
+       public void test5Neighbours() throws Exception {
+               NeighbourGrpc ufoundedNeighbour = NeighbourGrpc.newBuilder()
+                               .setErrorMessage("Neighbour with id 1 not found for node with id 1 in graph with id 1").build();;
+
+               // Neighbour not found in the server
+               NeighbourGrpc neighbour = client.getNeighbour(1, 1, 1);//id not present
+
+               assertEquals(ufoundedNeighbour, neighbour);
+
+               GraphGrpc graph = Client.createGraphGrpc(null);
+               graph = client.createGraph(graph).getGraph();
+
+               List<NeighbourGrpc> neighbours = new ArrayList<NeighbourGrpc>();
+               NeighbourGrpc nb = Client.createNeighbourGrpc("Node1");
+               neighbours.add(nb);
+               NodeGrpc n1 = Client.createNodeGrpc("Node1", "antispam", null, null);
+               NodeGrpc n2 = Client.createNodeGrpc("Node2", "endhost", neighbours, null);
+               NodeGrpc n3 = Client.createNodeGrpc("Node3", "endhost", null, null);
+               NodeGrpc n4 = Client.createNodeGrpc("Node4", "endpoint", null, null);
+               NodeGrpc n5 = Client.createNodeGrpc("Node5", "webserver", null, null);
+               Map<String,String> map = new HashMap<String,String>();
+               map.put("webserver", "Node5");
+               ConfigurationGrpc conf = Client.createConfigurationGrpc(map, null, null, null);
+               NodeGrpc n6 = Client.createNodeGrpc("Node6", "webclient", null, conf);
+               NodeGrpc n7 = Client.createNodeGrpc("Node7", "cache", null, null);
+               NodeGrpc n8 = Client.createNodeGrpc("Node8", "firewall", null, null);
+               NodeGrpc n9 = Client.createNodeGrpc("Node9", "fieldmodifier", null, null);
+               NodeGrpc n10 = Client.createNodeGrpc("Node10", "dpi", null, null);
+               NewNode nw1 = client.createNode(n1, graph.getId());
+               NewNode nw2 = client.createNode(n2, graph.getId());
+               NewNode nw3 = client.createNode(n3, graph.getId());
+               NewNode nw4 = client.createNode(n4, graph.getId());
+               NewNode nw5 = client.createNode(n5, graph.getId());
+               NewNode nw6 = client.createNode(n6, graph.getId());
+               NewNode nw7 = client.createNode(n7, graph.getId());
+               NewNode nw8 = client.createNode(n8, graph.getId());
+               NewNode nw9 = client.createNode(n9, graph.getId());
+               NewNode nw10 = client.createNode(n10, graph.getId());
+               assertEquals(nw1.getSuccess(),true);
+               assertEquals(nw2.getSuccess(),true);
+               assertEquals(nw3.getSuccess(),true);
+               assertEquals(nw4.getSuccess(),true);
+               assertEquals(nw5.getSuccess(),true);
+               assertEquals(nw6.getSuccess(),true);
+               assertEquals(nw7.getSuccess(),true);
+               assertEquals(nw8.getSuccess(),true);
+               assertEquals(nw9.getSuccess(),true);
+               assertEquals(nw10.getSuccess(),true);
+
+               // getNeighbour, but first add it
+               NeighbourGrpc addedNeighbour = Client.createNeighbourGrpc("Node9");
+               NewNeighbour response = client.createNeighbour(addedNeighbour, graph.getId(), nw1.getNode().getId());
+               addedNeighbour = response.getNeighbour();
+               neighbour = client.getNeighbour(graph.getId(), nw1.getNode().getId(), addedNeighbour.getId());
+
+               assertEquals(addedNeighbour.getId(), neighbour.getId());
+
+               //updateNeighbour
+               NeighbourGrpc updatedNeighbour = Client.createNeighbourGrpc("Node10");
+
+               response = client.updateNeighbour(graph.getId(), 1, addedNeighbour.getId(),updatedNeighbour);
+
+               assertEquals(response.getSuccess(),true);
+               assertEquals(response.getNeighbour().getName(),"Node10");
+       }
+
+       @Test
+       public void test6Neighbours() throws Exception {
+               // setup
+               GraphGrpc graph = Client.createGraphGrpc(null);
+               //createGraph
+               graph = client.createGraph(graph).getGraph();
+
+               NodeGrpc n1 = Client.createNodeGrpc("Node1", "antispam", null, null);
+               NodeGrpc n2 = Client.createNodeGrpc("Node2", "endhost", null, null);
+               NodeGrpc n3 = Client.createNodeGrpc("Node3", "endhost", null, null);
+               NodeGrpc n4 = Client.createNodeGrpc("Node4", "endpoint", null, null);
+               NewNode nw1 = client.createNode(n1, graph.getId());
+               NewNode nw2 = client.createNode(n2, graph.getId());
+               NewNode nw3 = client.createNode(n3, graph.getId());
+               NewNode nw4 = client.createNode(n4, graph.getId());
+               assertEquals(nw1.getSuccess(),true);
+               assertEquals(nw2.getSuccess(),true);
+               assertEquals(nw3.getSuccess(),true);
+               assertEquals(nw4.getSuccess(),true);
+
+               //createNeighbour
+               NeighbourGrpc nn1 = Client.createNeighbourGrpc("Node2");
+               NewNeighbour addedNeighbour1 = client.createNeighbour(nn1, graph.getId(), nw1.getNode().getId());
+               assertEquals(addedNeighbour1.getSuccess(),true);
+               NeighbourGrpc nn2 = Client.createNeighbourGrpc("Node3");
+               NewNeighbour addedNeighbour2 = client.createNeighbour(nn2, graph.getId(), nw1.getNode().getId());
+               assertEquals(addedNeighbour2.getSuccess(),true);
+               NeighbourGrpc nn3 = Client.createNeighbourGrpc("Node4");
+               NewNeighbour addedNeighbour3 = client.createNeighbour(nn3, graph.getId(), nw1.getNode().getId());
+               assertEquals(addedNeighbour3.getSuccess(),true);
+
+               nn1 = NeighbourGrpc.newBuilder(nn1).setId(1).build();
+               nn2 = NeighbourGrpc.newBuilder(nn2).setId(2).build();
+               nn3 = NeighbourGrpc.newBuilder(nn3).setId(3).build();
+               // run
+               Iterator<NeighbourGrpc> neighbours = client.getNeighbours(graph.getId(), nw1.getNode().getId()).iterator();
+
+               assertEquals(neighbours.next(), nn1);
+               assertEquals(neighbours.next(), nn2);
+               assertEquals(neighbours.next(), nn3);
+
+               //deleteNeighbour
+               boolean succ = client.deleteNeighbour(graph.getId(), nw1.getNode().getId(), 1);
+               assertEquals(succ, true);
+               // run
+               neighbours = client.getNeighbours(graph.getId(), nw1.getNode().getId()).iterator();
+
+               assertEquals(neighbours.next(), nn2);
+               assertEquals(neighbours.next(), nn3);
+       }
+}
diff --git a/verigraph/src/main/java/it/polito/grpc/test/MultiThreadTest.java b/verigraph/src/main/java/it/polito/grpc/test/MultiThreadTest.java
new file mode 100644 (file)
index 0000000..5b76bea
--- /dev/null
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.grpc.test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.junit.After;
+import org.junit.Assert;
+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 com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+
+import io.grpc.verigraph.GraphGrpc;
+import io.grpc.verigraph.NewGraph;
+import io.grpc.verigraph.NodeGrpc;
+import it.polito.escape.verify.client.VerifyClientException;
+import it.polito.grpc.Client;
+import it.polito.grpc.Service;
+
+/**
+ * Unit tests for gRPC project.
+ * For testing concurrency on server side.
+ */
+@RunWith(JUnit4.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class MultiThreadTest {
+       private Service server;
+       private Client client;
+
+       @Before
+       public void setUp() throws Exception {
+               client = new Client("localhost" , 50051);
+               server = new Service(50051);
+
+               server.start();
+       }
+
+       @After
+       public void tearDown() throws Exception {
+               server.stop();
+               client.shutdown();
+       }
+
+       private void testUpdateGraphStatus(final int threadCount) throws InterruptedException, ExecutionException, JsonParseException, JsonMappingException, IOException, VerifyClientException {
+               GraphGrpc retrieveGraphResponse =client.getGraph(1);
+
+               UpdateGraph task = new UpdateGraph(client, 1, retrieveGraphResponse);
+
+               List<MultiThreadTest.UpdateGraph> tasks = Collections.nCopies(threadCount, task);
+               ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
+
+               List<Future<NewGraph>> futures = executorService.invokeAll(tasks);
+               List<Boolean> resultList = new ArrayList<Boolean>(futures.size());
+
+               // Check for exceptions
+               for (Future<NewGraph> future : futures) {
+                       // Throws an exception if an exception was thrown by the task.
+                       resultList.add(future.get().getSuccess());
+               }
+               // Validate the dimensions
+               Assert.assertEquals(threadCount, futures.size());
+
+               List<Boolean> expectedList = new ArrayList<Boolean>(threadCount);
+               for (int i = 1; i <= threadCount; i++) {
+                       expectedList.add(true);
+               }
+               // Validate expected results
+               Assert.assertEquals(expectedList, resultList);
+       }
+
+       private void testUpdateGraph(final int threadCount) throws Exception {
+               GraphGrpc retrieveGraph = client.getGraph(2L);
+               NodeGrpc nodeToEdit = Client.createNodeGrpc("client",
+                                                               "endpoint",
+                                                               null,
+                                                               Client.createConfigurationGrpc(null, null, "client", ""));
+
+               GraphGrpc graphToUpdate = GraphGrpc.newBuilder(retrieveGraph).addNode(nodeToEdit).build();
+
+               String graphAsString = graphToUpdate.toString();
+
+               UpdateGraph task = new UpdateGraph(client, 2, graphToUpdate);
+
+               List<MultiThreadTest.UpdateGraph> tasks = Collections.nCopies(threadCount, task);
+               ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
+
+               List<Future<NewGraph>> futures = executorService.invokeAll(tasks);
+               List<String> resultList = new ArrayList<String>(futures.size());
+
+               // Check for exceptions
+               for (Future<NewGraph> future : futures) {
+                       // Throws an exception if an exception was thrown by the task.
+                       GraphGrpc graphReceived = future.get().getGraph();
+                       NodeGrpc node = NodeGrpc.newBuilder(graphReceived.getNode(0)).setId(0).build();
+                       GraphGrpc graph = GraphGrpc.newBuilder(graphReceived).setNode(0, node).build();
+                       resultList.add(graph.toString());
+               }
+               // Validate dimensions
+               Assert.assertEquals(threadCount, futures.size());
+
+               List<String> expectedList = new ArrayList<String>(threadCount);
+               for (int i = 1; i <= threadCount; i++) {
+                       expectedList.add(graphAsString);
+               }
+               // Validate expected results
+               Assert.assertEquals(expectedList, resultList);
+       }
+
+       private void testCreateGraphStatus(final int threadCount) throws InterruptedException, ExecutionException, JsonParseException, JsonMappingException, IOException {
+
+               GraphGrpc graph = GraphGrpc.newBuilder().build();
+
+               CreateGraph task = new CreateGraph(client, graph);
+
+               List<MultiThreadTest.CreateGraph> tasks = Collections.nCopies(threadCount, task);
+               ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
+
+               List<Future<Boolean>> futures = executorService.invokeAll(tasks);
+               List<Boolean> resultList = new ArrayList<Boolean>(futures.size());
+
+               // Check for exceptions
+               for (Future<Boolean> future : futures) {
+                       // Throws an exception if an exception was thrown by the task.
+                       resultList.add(future.get());
+               }
+               // Validate the IDs
+               Assert.assertEquals(threadCount, futures.size());
+
+               List<Boolean> expectedList = new ArrayList<Boolean>(threadCount);
+               for (int i = 1; i <= threadCount; i++) {
+                       expectedList.add(true);
+               }
+               // Validate expected results
+               Assert.assertEquals(expectedList, resultList);
+       }
+
+       private int randInt(int min, int max){
+               Random rand = new Random();
+           int randomNum = rand.nextInt((max - min) + 1) + min;
+           return randomNum;
+       }
+
+       @Test
+       public void updateGraphStatusCheck() throws InterruptedException, ExecutionException, JsonParseException, JsonMappingException, IOException, VerifyClientException {
+               testUpdateGraphStatus(64);
+       }
+
+       @Test
+       public void updateGraphResponseCheck() throws Exception {
+               testUpdateGraph(16);
+       }
+
+       @Test
+       public void createGraphStatusCheck() throws JsonParseException, JsonMappingException, InterruptedException, ExecutionException, IOException {
+               testCreateGraphStatus(8);
+       }
+
+       class UpdateGraph implements Callable<NewGraph> {
+
+               private Client  verifyClient;
+
+               private int                             graphId;
+
+               private GraphGrpc                       graph;
+
+               public UpdateGraph(Client verifyClient, int graphId, GraphGrpc graph) {
+                       this.graphId = graphId;
+                       this.graph = graph;
+                       this.verifyClient = verifyClient;
+               }
+
+               @Override
+               public NewGraph call() throws Exception {
+                       Thread.sleep(randInt(0,2000));
+                       return this.verifyClient.updateGraph(this.graphId, this.graph);
+               }
+       }
+
+       class CreateGraph implements Callable<Boolean> {
+
+               private Client  verifyClient;
+
+               private GraphGrpc               graph;
+
+               public CreateGraph(Client verifyClient, GraphGrpc graph) {
+                       this.graph = graph;
+                       this.verifyClient = verifyClient;
+               }
+
+               @Override
+               public Boolean call() throws Exception {
+                       Thread.sleep(randInt(0,2000));
+                       return this.verifyClient.createGraph(this.graph).getSuccess();
+               }
+
+       }
+
+}
diff --git a/verigraph/src/main/java/it/polito/grpc/test/ReachabilityTest.java b/verigraph/src/main/java/it/polito/grpc/test/ReachabilityTest.java
new file mode 100644 (file)
index 0000000..a120aff
--- /dev/null
@@ -0,0 +1,252 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.grpc.test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+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 static org.junit.Assert.assertEquals;
+
+import java.io.BufferedReader;
+import java.io.FilenameFilter;
+import java.io.InputStreamReader;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.jsonschema.core.exceptions.ProcessingException;
+import com.github.fge.jsonschema.main.JsonSchema;
+
+import io.grpc.verigraph.GraphGrpc;
+import io.grpc.verigraph.NewGraph;
+import io.grpc.verigraph.Policy;
+import io.grpc.verigraph.VerificationGrpc;
+import it.polito.escape.verify.client.VerifyClientException;
+import it.polito.escape.verify.service.ValidationUtils;
+import it.polito.escape.verify.test.TestCase;
+import it.polito.escape.verify.test.TestExecutionException;
+import it.polito.grpc.Client;
+import it.polito.grpc.GrpcUtils;
+import it.polito.grpc.Service;
+
+@RunWith(JUnit4.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class ReachabilityTest {
+       private File                    schema;
+       private List<File>              testFiles       = new ArrayList<File>();
+       private List<TestCase>  testCases       = new ArrayList<TestCase>();
+       private Client  client;
+       private Service server;
+
+       @Before
+       public void setUpBeforeClass() throws Exception {
+               client = new Client("localhost" , 50051);
+               server = new Service(50051);
+               server.start();
+
+               String folderName = System.getProperty("user.dir") + "/tester/testcases";
+               File folder = new File(folderName);
+               if (!folder.exists()) {
+                       BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+                   String s;
+                   do{
+                       System.out.println("Please enter the testcases folder path: ");
+                       s = in.readLine();
+                       if (isValidpath(s)){
+                               folder = new File(s);
+                               break;
+                       }
+                   }while (s != null && s.length() != 0);
+                   if(s == null)
+                       System.exit(0);
+               }
+               String schemaName = System.getProperty("user.dir") + "/tester/testcase_schema.json";
+               File schema = new File(schemaName);
+               if (!schema.exists()) {
+                       BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+                   String s;
+                   do{
+                       System.out.println("Please enter the full path of 'testcase_schema.json': ");
+                       s = in.readLine();
+                       if (isValidpath(s)){
+                               folder = new File(s);
+                               break;
+                       }
+                   }while (s != null && s.length() != 0);
+                   if(s == null)
+                       System.exit(0);
+               }
+
+               this.schema = schema;
+               this.testFiles = getTests(folder);
+               this.testCases = getTestCases(this.testFiles);
+       }
+
+       @After
+       public void tearDown() throws Exception {
+               server.stop();
+               client.shutdown();
+       }
+
+       @Test
+       public final void wrongReachability() {
+               System.out.println("DEBUG: starting testWrongReachability");
+
+               VerificationGrpc nullVer = VerificationGrpc.newBuilder()
+                                                       .setErrorMessage("Graph with id 52 not found").build();
+               //verification on uncreated graph
+               Policy policyToVerify = Client.createPolicy("Node1", "Node4", "reachability", null, 52);
+               VerificationGrpc ver = client.verify(policyToVerify);
+               assertEquals(ver, nullVer);
+
+               //verification on uncreated nodes
+               nullVer = VerificationGrpc.newBuilder()
+                               .setErrorMessage("The \'source\' parameter \'Node5\' is not valid, please insert the name of an existing node").build();
+               policyToVerify = Client.createPolicy("Node5", "Node4", "reachability", null, 1);
+               ver = client.verify(policyToVerify);
+               assertEquals(ver, nullVer);
+
+               //verification on uncreated nodes
+               nullVer = VerificationGrpc.newBuilder()
+                               .setErrorMessage("The \'source\' parameter \'Node1\' is not valid, please insert the name of an existing node").build();
+
+               policyToVerify = Client.createPolicy("Node1", "Node10", "reachability", null, 1);
+               ver = client.verify(policyToVerify);
+               assertEquals(ver, nullVer);
+
+       }
+
+       public List<File> getTests(File folder) {
+               List<File> filesList = new ArrayList<File>();
+
+               System.out.println("Test folder set to '" + folder.getAbsolutePath() + "'");
+
+               File[] files = folder.listFiles(new FilenameFilter() {
+
+                       @Override
+                       public boolean accept(File dir, String name) {
+                               return name.endsWith(".json");
+                       }
+               });
+
+               for (File f : files) {
+                       filesList.add(f);
+                       System.out.println("File '" + f.getName() + "' added to test files");
+               }
+
+               return filesList;
+       }
+
+       public List<TestCase> getTestCases(List<File> files)    throws JsonParseException, JsonMappingException, IOException,
+                                                                                                                       Exception {
+               List<TestCase> testCases = new ArrayList<TestCase>();
+
+               for (File file : files) {
+                       validateTestFile(file);
+                       try {
+                               TestCase tc = new ObjectMapper().readValue(file, TestCase.class);
+                               testCases.add(tc);
+                       }
+                       catch (Exception e) {
+                               throw e;
+                       }
+               }
+
+               return testCases;
+       }
+
+       @Test
+       public void runTestCases() throws VerifyClientException, TestExecutionException {
+               int counter = 0;
+               for (TestCase tc : this.testCases) {
+                       String result = runTestCase(tc);
+                       if (!result.equals(tc.getResult()))
+                               throw new TestExecutionException("Error running test given in file '"   + this.testFiles.get(counter).getName()
+                                                                       + "'. Test returned '" + result + "' instead of '" + tc.getResult() + "'.");
+                       else
+                               System.out.println("Test given in file '"       + this.testFiles.get(counter).getName() + "' returned '"
+                                                                       + result + "' as expected");
+                       counter++;
+
+               }
+               System.out.println("All tests PASSED");
+       }
+
+       private String runTestCase(TestCase tc) throws VerifyClientException, TestExecutionException{
+               GraphGrpc graph = GrpcUtils.obtainGraph(tc.getGraph());
+
+               NewGraph newGraph = this.client.createGraph(graph);
+               if(newGraph.getSuccess() == false)
+                       throw new VerifyClientException("gRPC request failed");
+               GraphGrpc createdGraph = newGraph.getGraph();
+
+               GraphGrpc addedgraph = client.getGraph(createdGraph.getId());
+               System.out.println(addedgraph);
+
+               final Map<String, String> map = GrpcUtils.getParamGivenString(tc.getPolicyUrlParameters());
+
+               Policy policy = Client.createPolicy(map.get("source"),
+                                                                                       map.get("destination"),
+                                                                                       map.get("type"),
+                                                                                       map.get("middlebox"),
+                                                                                       createdGraph.getId());
+               VerificationGrpc verification = this.client.verify(policy);
+               return verification.getResult();
+       }
+
+       public void validateTestFile(File testFile) throws Exception {
+               JsonSchema schemaNode = null;
+               try {
+                       schemaNode = ValidationUtils.getSchemaNode(schema);
+               }
+               catch (IOException e) {
+                       throw new Exception("Unable to load '" + schema.getAbsolutePath() + "' schema file");
+               }
+               catch (ProcessingException e) {
+                       throw new Exception("Unable to resolve '" + schema.getAbsolutePath() + "' schema file as a schema node");
+               }
+
+               JsonNode jsonNode;
+               try {
+                       jsonNode = ValidationUtils.getJsonNode(testFile);
+               }
+               catch (IOException e) {
+                       throw new Exception("Unable to load '" + testFile.getAbsolutePath() + "' as a json node");
+               }
+
+               try {
+                       ValidationUtils.validateJson(schemaNode, jsonNode);
+               }
+               catch (ProcessingException e) {
+                       throw new Exception("There were errors in the validation of file '"     + testFile.getAbsolutePath()
+                                                               + "' against the json schema '" + schema.getAbsolutePath() + "': " + e.getMessage());
+
+               }
+       }
+
+       private static boolean isValidpath(String s) {
+               if (s==null)
+                       return false;
+               File file = new File(s);
+               return file.exists();
+       }
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ActionEnumType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ActionEnumType.java
new file mode 100644 (file)
index 0000000..e7504b5
--- /dev/null
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlEnumValue;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for actionEnumType.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * <pre>
+ * &lt;simpleType name="actionEnumType">
+ *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ *     &lt;enumeration value="discard"/>
+ *     &lt;enumeration value="output"/>
+ *   &lt;/restriction>
+ * &lt;/simpleType>
+ * </pre>
+ *
+ */
+@XmlType(name = "actionEnumType")
+@XmlEnum
+public enum ActionEnumType {
+
+    @XmlEnumValue("discard")
+    DISCARD("discard"),
+    @XmlEnumValue("output")
+    OUTPUT("output");
+    private final String value;
+
+    ActionEnumType(String v) {
+        value = v;
+    }
+
+    public String value() {
+        return value;
+    }
+
+    public static ActionEnumType fromValue(String v) {
+        for (ActionEnumType c: ActionEnumType.values()) {
+            if (c.value.equals(v)) {
+                return c;
+            }
+        }
+        throw new IllegalArgumentException(v);
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ActionType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ActionType.java
new file mode 100644 (file)
index 0000000..db86975
--- /dev/null
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for actionType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="actionType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;attribute name="type" use="required" type="{http://www.example.org/nffg/}actionEnumType" />
+ *       &lt;attribute name="port" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "actionType")
+public class ActionType {
+
+    @XmlAttribute(name = "type", required = true)
+    protected ActionEnumType type;
+    @XmlAttribute(name = "port")
+    protected String port;
+
+    /**
+     * Gets the value of the type property.
+     * @return
+     *     possible object is
+     *     {@link ActionEnumType }
+     */
+    public ActionEnumType getType() {
+        return type;
+    }
+
+    /**
+     * Sets the value of the type property.
+     * @param value
+     *     allowed object is
+     *     {@link ActionEnumType }
+     */
+    public void setType(ActionEnumType value) {
+        this.type = value;
+    }
+
+    /**
+     * Gets the value of the port property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getPort() {
+        return port;
+    }
+
+    /**
+     * Sets the value of the port property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setPort(String value) {
+        this.port = value;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ActionsType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ActionsType.java
new file mode 100644 (file)
index 0000000..5b81ae7
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for actionsType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="actionsType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="action" type="{http://www.example.org/nffg/}actionType" maxOccurs="unbounded"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "actionsType", propOrder = {
+    "action"
+})
+public class ActionsType {
+
+    @XmlElement(required = true)
+    protected List<ActionType> action;
+
+    /**
+     * Gets the value of the action property.
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the action property.
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getAction().add(newItem);
+     * </pre>
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link ActionType }
+     */
+    public List<ActionType> getAction() {
+        if (action == null) {
+            action = new ArrayList<ActionType>();
+        }
+        return this.action;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CiType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CiType.java
new file mode 100644 (file)
index 0000000..9a82728
--- /dev/null
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for ciType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="ciType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="attributes">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;sequence>
+ *                   &lt;element name="attribute" maxOccurs="unbounded" minOccurs="0">
+ *                     &lt;complexType>
+ *                       &lt;complexContent>
+ *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                           &lt;attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                         &lt;/restriction>
+ *                       &lt;/complexContent>
+ *                     &lt;/complexType>
+ *                   &lt;/element>
+ *                 &lt;/sequence>
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *       &lt;/sequence>
+ *       &lt;attribute name="id" use="required" type="{http://www.example.org/nffg/}ciIdType" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "ciType", propOrder = {
+    "attributes"
+})
+public class CiType {
+
+    @XmlElement(required = true)
+    protected CiType.Attributes attributes;
+    @XmlAttribute(name = "id", required = true)
+    protected String id;
+
+    /**
+     * Gets the value of the attributes property.
+     * @return
+     *     possible object is
+     *     {@link CiType.Attributes }
+     */
+    public CiType.Attributes getAttributes() {
+        return attributes;
+    }
+
+    /**
+     * Sets the value of the attributes property.
+     * @param value
+     *     allowed object is
+     *     {@link CiType.Attributes }
+     */
+    public void setAttributes(CiType.Attributes value) {
+        this.attributes = value;
+    }
+
+    /**
+     * Gets the value of the id property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;sequence>
+     *         &lt;element name="attribute" maxOccurs="unbounded" minOccurs="0">
+     *           &lt;complexType>
+     *             &lt;complexContent>
+     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                 &lt;attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *               &lt;/restriction>
+     *             &lt;/complexContent>
+     *           &lt;/complexType>
+     *         &lt;/element>
+     *       &lt;/sequence>
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = {
+        "attribute"
+    })
+    public static class Attributes {
+
+        protected List<CiType.Attributes.Attribute> attribute;
+
+        /**
+         * Gets the value of the attribute property.
+         * <p>
+         * This accessor method returns a reference to the live list,
+         * not a snapshot. Therefore any modification you make to the
+         * returned list will be present inside the JAXB object.
+         * This is why there is not a <CODE>set</CODE> method for the attribute property.
+         * <p>
+         * For example, to add a new item, do as follows:
+         * <pre>
+         *    getAttribute().add(newItem);
+         * </pre>
+         * <p>
+         * Objects of the following type(s) are allowed in the list
+         * {@link CiType.Attributes.Attribute }
+         */
+        public List<CiType.Attributes.Attribute> getAttribute() {
+            if (attribute == null) {
+                attribute = new ArrayList<CiType.Attributes.Attribute>();
+            }
+            return this.attribute;
+        }
+
+
+        /**
+         * <p>Java class for anonymous complex type.
+         * <p>The following schema fragment specifies the expected content contained within this class.
+         * <pre>
+         * &lt;complexType>
+         *   &lt;complexContent>
+         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *       &lt;attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+         *     &lt;/restriction>
+         *   &lt;/complexContent>
+         * &lt;/complexType>
+         * </pre>
+         */
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "")
+        public static class Attribute {
+
+            @XmlAttribute(name = "value", required = true)
+            protected String value;
+
+            /**
+             * Gets the value of the value property.
+             * @return
+             *     possible object is
+             *     {@link String }
+             */
+            public String getValue() {
+                return value;
+            }
+
+            /**
+             * Sets the value of the value property.
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             */
+            public void setValue(String value) {
+                this.value = value;
+            }
+
+        }
+
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CpType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CpType.java
new file mode 100644 (file)
index 0000000..4a67b79
--- /dev/null
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for cpType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="cpType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="port" type="{http://www.example.org/nffg/}portType"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="id" use="required" type="{http://www.example.org/nffg/}cpIdType" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "cpType", propOrder = {
+    "port"
+})
+public class CpType {
+
+    @XmlElement(required = true)
+    protected PortType port;
+    @XmlAttribute(name = "id", required = true)
+    protected String id;
+
+    /**
+     * Gets the value of the port property.
+     * @return
+     *     possible object is
+     *     {@link PortType }
+     */
+    public PortType getPort() {
+        return port;
+    }
+
+    /**
+     * Sets the value of the port property.
+     * @param value
+     *     allowed object is
+     *     {@link PortType }
+     */
+    public void setPort(PortType value) {
+        this.port = value;
+    }
+
+    /**
+     * Gets the value of the id property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CpointsType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CpointsType.java
new file mode 100644 (file)
index 0000000..4c820ed
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for cpointsType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="cpointsType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="connection_point" type="{http://www.example.org/nffg/}cpType" maxOccurs="unbounded"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "cpointsType", propOrder = {
+    "connectionPoint"
+})
+public class CpointsType {
+
+    @XmlElement(name = "connection_point", required = true)
+    protected List<CpType> connectionPoint;
+
+    /**
+     * Gets the value of the connectionPoint property.
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the connectionPoint property.
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getConnectionPoint().add(newItem);
+     * </pre>
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link CpType }
+     */
+    public List<CpType> getConnectionPoint() {
+        if (connectionPoint == null) {
+            connectionPoint = new ArrayList<CpType>();
+        }
+        return this.connectionPoint;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CtrlInterfacesType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CtrlInterfacesType.java
new file mode 100644 (file)
index 0000000..02ad675
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for ctrlInterfacesType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="ctrlInterfacesType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="control_interface" type="{http://www.example.org/nffg/}ciType" maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "ctrlInterfacesType", propOrder = {
+    "controlInterface"
+})
+public class CtrlInterfacesType {
+
+    @XmlElement(name = "control_interface")
+    protected List<CiType> controlInterface;
+
+    /**
+     * Gets the value of the controlInterface property.
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the controlInterface property.
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getControlInterface().add(newItem);
+     * </pre>
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link CiType }
+     */
+    public List<CiType> getControlInterface() {
+        if (controlInterface == null) {
+            controlInterface = new ArrayList<CiType>();
+        }
+        return this.controlInterface;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpCpType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpCpType.java
new file mode 100644 (file)
index 0000000..a9448c1
--- /dev/null
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for ep-cpType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="ep-cpType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="flowrules" type="{http://www.example.org/nffg/}flowrulesType" maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="id_ref" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "ep-cpType", propOrder = {
+    "flowrules"
+})
+public class EpCpType {
+
+    protected List<FlowrulesType> flowrules;
+    @XmlAttribute(name = "id_ref", required = true)
+    protected String idRef;
+
+    /**
+     * Gets the value of the flowrules property.
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the flowrules property.
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getFlowrules().add(newItem);
+     * </pre>
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link FlowrulesType }
+     */
+    public List<FlowrulesType> getFlowrules() {
+        if (flowrules == null) {
+            flowrules = new ArrayList<FlowrulesType>();
+        }
+        return this.flowrules;
+    }
+
+    /**
+     * Gets the value of the idRef property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getIdRef() {
+        return idRef;
+    }
+
+    /**
+     * Sets the value of the idRef property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setIdRef(String value) {
+        this.idRef = value;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpType.java
new file mode 100644 (file)
index 0000000..2ae875d
--- /dev/null
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for epType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="epType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="flowspace">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;sequence>
+ *                   &lt;group ref="{http://www.example.org/nffg/}L2HeaderParameters"/>
+ *                   &lt;group ref="{http://www.example.org/nffg/}L3HeaderParameters"/>
+ *                   &lt;group ref="{http://www.example.org/nffg/}L4HeaderParameters"/>
+ *                 &lt;/sequence>
+ *                 &lt;attribute name="nodeId" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                 &lt;attribute name="ingPhysPort" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *       &lt;/sequence>
+ *       &lt;attribute name="id" use="required" type="{http://www.example.org/nffg/}epIdType" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "epType", propOrder = {
+    "flowspace"
+})
+public class EpType {
+
+    @XmlElement(required = true)
+    protected EpType.Flowspace flowspace;
+    @XmlAttribute(name = "id", required = true)
+    protected String id;
+
+    /**
+     * Gets the value of the flowspace property.
+     * @return
+     *     possible object is
+     *     {@link EpType.Flowspace }
+     */
+    public EpType.Flowspace getFlowspace() {
+        return flowspace;
+    }
+
+    /**
+     * Sets the value of the flowspace property.
+     * @param value
+     *     allowed object is
+     *     {@link EpType.Flowspace }
+     */
+    public void setFlowspace(EpType.Flowspace value) {
+        this.flowspace = value;
+    }
+
+    /**
+     * Gets the value of the id property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;sequence>
+     *         &lt;group ref="{http://www.example.org/nffg/}L2HeaderParameters"/>
+     *         &lt;group ref="{http://www.example.org/nffg/}L3HeaderParameters"/>
+     *         &lt;group ref="{http://www.example.org/nffg/}L4HeaderParameters"/>
+     *       &lt;/sequence>
+     *       &lt;attribute name="nodeId" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       &lt;attribute name="ingPhysPort" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = {
+        "mac",
+        "ip",
+        "tcp",
+        "udp"
+    })
+    public static class Flowspace {
+
+        protected it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Mac mac;
+        protected it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Ip ip;
+        protected it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Tcp tcp;
+        protected it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Udp udp;
+        @XmlAttribute(name = "nodeId")
+        protected String nodeId;
+        @XmlAttribute(name = "ingPhysPort")
+        protected String ingPhysPort;
+
+        /**
+         * Gets the value of the mac property.
+         * @return
+         *     possible object is
+         *     {@link it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Mac }
+         */
+        public it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Mac getMac() {
+            return mac;
+        }
+
+        /**
+         * Sets the value of the mac property.
+         * @param value
+         *     allowed object is
+         *     {@link it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Mac }
+         */
+        public void setMac(it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Mac value) {
+            this.mac = value;
+        }
+
+        /**
+         * Gets the value of the ip property.
+         * @return
+         *     possible object is
+         *     {@link it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Ip }
+         */
+        public it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Ip getIp() {
+            return ip;
+        }
+
+        /**
+         * Sets the value of the ip property.
+         * @param value
+         *     allowed object is
+         *     {@link it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Ip }
+         */
+        public void setIp(it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Ip value) {
+            this.ip = value;
+        }
+
+        /**
+         * Gets the value of the tcp property.
+         * @return
+         *     possible object is
+         *     {@link it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Tcp }
+         */
+        public it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Tcp getTcp() {
+            return tcp;
+        }
+
+        /**
+         * Sets the value of the tcp property.
+         * @param value
+         *     allowed object is
+         *     {@link it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Tcp }
+         */
+        public void setTcp(it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Tcp value) {
+            this.tcp = value;
+        }
+
+        /**
+         * Gets the value of the udp property.
+         * @return
+         *     possible object is
+         *     {@link it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Udp }
+         */
+        public it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Udp getUdp() {
+            return udp;
+        }
+
+        /**
+         * Sets the value of the udp property.
+         * @param value
+         *     allowed object is
+         *     {@link it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Udp }
+         */
+        public void setUdp(it.polito.nffg.neo4j.jaxb.FlowrulesType.Flowspace.Udp value) {
+            this.udp = value;
+        }
+
+        /**
+         * Gets the value of the nodeId property.
+         * @return
+         *     possible object is
+         *     {@link String }
+         */
+        public String getNodeId() {
+            return nodeId;
+        }
+
+        /**
+         * Sets the value of the nodeId property.
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         */
+        public void setNodeId(String value) {
+            this.nodeId = value;
+        }
+
+        /**
+         * Gets the value of the ingPhysPort property.
+         * @return
+         *     possible object is
+         *     {@link String }
+         */
+        public String getIngPhysPort() {
+            return ingPhysPort;
+        }
+
+        /**
+         * Sets the value of the ingPhysPort property.
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         */
+        public void setIngPhysPort(String value) {
+            this.ingPhysPort = value;
+        }
+
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpointsType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpointsType.java
new file mode 100644 (file)
index 0000000..850d8b6
--- /dev/null
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for epointsType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="epointsType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="endpoint" type="{http://www.example.org/nffg/}epType" maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "epointsType", propOrder = {
+    "endpoint"
+})
+public class EpointsType {
+
+    protected List<EpType> endpoint;
+
+    /**
+     * Gets the value of the endpoint property.
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the endpoint property.
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getEndpoint().add(newItem);
+     * </pre>
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link EpType }
+     */
+    public List<EpType> getEndpoint() {
+        if (endpoint == null) {
+            endpoint = new ArrayList<EpType>();
+        }
+        return this.endpoint;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpsCpsType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpsCpsType.java
new file mode 100644 (file)
index 0000000..181085e
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for eps-cpsType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="eps-cpsType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="ep-cp" type="{http://www.example.org/nffg/}ep-cpType" maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "eps-cpsType", propOrder = {
+    "epCp"
+})
+public class EpsCpsType {
+
+    @XmlElement(name = "ep-cp")
+    protected List<EpCpType> epCp;
+
+    /**
+     * Gets the value of the epCp property.
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the epCp property.
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getEpCp().add(newItem);
+     * </pre>
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link EpCpType }
+     */
+    public List<EpCpType> getEpCp() {
+        if (epCp == null) {
+            epCp = new ArrayList<EpCpType>();
+        }
+        return this.epCp;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/FlowrulesType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/FlowrulesType.java
new file mode 100644 (file)
index 0000000..53c8f79
--- /dev/null
@@ -0,0 +1,619 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for flowrulesType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="flowrulesType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="flowspace">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;sequence>
+ *                   &lt;group ref="{http://www.example.org/nffg/}L2HeaderParameters"/>
+ *                   &lt;group ref="{http://www.example.org/nffg/}L3HeaderParameters"/>
+ *                   &lt;group ref="{http://www.example.org/nffg/}L4HeaderParameters"/>
+ *                 &lt;/sequence>
+ *                 &lt;attribute name="ingPort" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *         &lt;element name="actions" type="{http://www.example.org/nffg/}actionsType"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "flowrulesType", propOrder = {
+    "flowspace",
+    "actions"
+})
+public class FlowrulesType {
+
+    @XmlElement(required = true)
+    protected FlowrulesType.Flowspace flowspace;
+    @XmlElement(required = true)
+    protected ActionsType actions;
+
+    /**
+     * Gets the value of the flowspace property.
+     * @return
+     *     possible object is
+     *     {@link FlowrulesType.Flowspace }
+     */
+    public FlowrulesType.Flowspace getFlowspace() {
+        return flowspace;
+    }
+
+    /**
+     * Sets the value of the flowspace property.
+     * @param value
+     *     allowed object is
+     *     {@link FlowrulesType.Flowspace }
+     */
+    public void setFlowspace(FlowrulesType.Flowspace value) {
+        this.flowspace = value;
+    }
+
+    /**
+     * Gets the value of the actions property.
+     * @return
+     *     possible object is
+     *     {@link ActionsType }
+     */
+    public ActionsType getActions() {
+        return actions;
+    }
+
+    /**
+     * Sets the value of the actions property.
+     * @param value
+     *     allowed object is
+     *     {@link ActionsType }
+     */
+    public void setActions(ActionsType value) {
+        this.actions = value;
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;sequence>
+     *         &lt;group ref="{http://www.example.org/nffg/}L2HeaderParameters"/>
+     *         &lt;group ref="{http://www.example.org/nffg/}L3HeaderParameters"/>
+     *         &lt;group ref="{http://www.example.org/nffg/}L4HeaderParameters"/>
+     *       &lt;/sequence>
+     *       &lt;attribute name="ingPort" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = {
+        "mac",
+        "ip",
+        "tcp",
+        "udp"
+    })
+    public static class Flowspace {
+
+        protected FlowrulesType.Flowspace.Mac mac;
+        protected FlowrulesType.Flowspace.Ip ip;
+        protected FlowrulesType.Flowspace.Tcp tcp;
+        protected FlowrulesType.Flowspace.Udp udp;
+        @XmlAttribute(name = "ingPort")
+        protected String ingPort;
+
+        /**
+         * Gets the value of the mac property.
+         * @return
+         *     possible object is
+         *     {@link FlowrulesType.Flowspace.Mac }
+         */
+        public FlowrulesType.Flowspace.Mac getMac() {
+            return mac;
+        }
+
+        /**
+         * Sets the value of the mac property.
+         * @param value
+         *     allowed object is
+         *     {@link FlowrulesType.Flowspace.Mac }
+         */
+        public void setMac(FlowrulesType.Flowspace.Mac value) {
+            this.mac = value;
+        }
+
+        /**
+         * Gets the value of the ip property.
+         * @return
+         *     possible object is
+         *     {@link FlowrulesType.Flowspace.Ip }
+         */
+        public FlowrulesType.Flowspace.Ip getIp() {
+            return ip;
+        }
+
+        /**
+         * Sets the value of the ip property.
+         * @param value
+         *     allowed object is
+         *     {@link FlowrulesType.Flowspace.Ip }
+         */
+        public void setIp(FlowrulesType.Flowspace.Ip value) {
+            this.ip = value;
+        }
+
+        /**
+         * Gets the value of the tcp property.
+         * @return
+         *     possible object is
+         *     {@link FlowrulesType.Flowspace.Tcp }
+         */
+        public FlowrulesType.Flowspace.Tcp getTcp() {
+            return tcp;
+        }
+
+        /**
+         * Sets the value of the tcp property.
+         * @param value
+         *     allowed object is
+         *     {@link FlowrulesType.Flowspace.Tcp }
+         */
+        public void setTcp(FlowrulesType.Flowspace.Tcp value) {
+            this.tcp = value;
+        }
+
+        /**
+         * Gets the value of the udp property.
+         * @return
+         *     possible object is
+         *     {@link FlowrulesType.Flowspace.Udp }
+         */
+        public FlowrulesType.Flowspace.Udp getUdp() {
+            return udp;
+        }
+
+        /**
+         * Sets the value of the udp property.
+         * @param value
+         *     allowed object is
+         *     {@link FlowrulesType.Flowspace.Udp }
+         */
+        public void setUdp(FlowrulesType.Flowspace.Udp value) {
+            this.udp = value;
+        }
+
+        /**
+         * Gets the value of the ingPort property.
+         * @return
+         *     possible object is
+         *     {@link String }
+         */
+        public String getIngPort() {
+            return ingPort;
+        }
+
+        /**
+         * Sets the value of the ingPort property.
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         */
+        public void setIngPort(String value) {
+            this.ingPort = value;
+        }
+
+
+        /**
+         * <p>Java class for anonymous complex type.
+         * <p>The following schema fragment specifies the expected content contained within this class.
+         * <pre>
+         * &lt;complexType>
+         *   &lt;complexContent>
+         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *       &lt;attribute name="src" type="{http://www.example.org/net/}ipAddressType" />
+         *       &lt;attribute name="dst" type="{http://www.example.org/net/}ipAddressType" />
+         *       &lt;attribute name="ipProtocol" type="{http://www.w3.org/2001/XMLSchema}unsignedByte" />
+         *       &lt;attribute name="tos" type="{http://www.w3.org/2001/XMLSchema}unsignedByte" />
+         *     &lt;/restriction>
+         *   &lt;/complexContent>
+         * &lt;/complexType>
+         * </pre>
+         */
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "")
+        public static class Ip {
+
+            @XmlAttribute(name = "src")
+            protected String src;
+            @XmlAttribute(name = "dst")
+            protected String dst;
+            @XmlAttribute(name = "ipProtocol")
+            @XmlSchemaType(name = "unsignedByte")
+            protected Short ipProtocol;
+            @XmlAttribute(name = "tos")
+            @XmlSchemaType(name = "unsignedByte")
+            protected Short tos;
+
+            /**
+             * Gets the value of the src property.
+             * @return
+             *     possible object is
+             *     {@link String }
+             */
+            public String getSrc() {
+                return src;
+            }
+
+            /**
+             * Sets the value of the src property.
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             */
+            public void setSrc(String value) {
+                this.src = value;
+            }
+
+            /**
+             * Gets the value of the dst property.
+             * @return
+             *     possible object is
+             *     {@link String }
+             */
+            public String getDst() {
+                return dst;
+            }
+
+            /**
+             * Sets the value of the dst property.
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             */
+            public void setDst(String value) {
+                this.dst = value;
+            }
+
+            /**
+             * Gets the value of the ipProtocol property.
+             * @return
+             *     possible object is
+             *     {@link Short }
+             */
+            public Short getIpProtocol() {
+                return ipProtocol;
+            }
+
+            /**
+             * Sets the value of the ipProtocol property.
+             * @param value
+             *     allowed object is
+             *     {@link Short }
+             */
+            public void setIpProtocol(Short value) {
+                this.ipProtocol = value;
+            }
+
+            /**
+             * Gets the value of the tos property.
+             * @return
+             *     possible object is
+             *     {@link Short }
+             */
+            public Short getTos() {
+                return tos;
+            }
+
+            /**
+             * Sets the value of the tos property.
+             * @param value
+             *     allowed object is
+             *     {@link Short }
+             */
+            public void setTos(Short value) {
+                this.tos = value;
+            }
+
+        }
+
+
+        /**
+         * <p>Java class for anonymous complex type.
+         * <p>The following schema fragment specifies the expected content contained within this class.
+         * <pre>
+         * &lt;complexType>
+         *   &lt;complexContent>
+         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *       &lt;attribute name="src" type="{http://www.example.org/net/}macAddressType" />
+         *       &lt;attribute name="dst" type="{http://www.example.org/net/}macAddressType" />
+         *       &lt;attribute name="ethertype" type="{http://www.example.org/net/}ethertypeType" />
+         *       &lt;attribute name="vlanId" type="{http://www.example.org/net/}vlanIdType" />
+         *       &lt;attribute name="vlanPcp" type="{http://www.example.org/net/}vlanPcpType" />
+         *     &lt;/restriction>
+         *   &lt;/complexContent>
+         * &lt;/complexType>
+         * </pre>
+         */
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "")
+        public static class Mac {
+
+            @XmlAttribute(name = "src")
+            protected String src;
+            @XmlAttribute(name = "dst")
+            protected String dst;
+            @XmlAttribute(name = "ethertype")
+            protected Integer ethertype;
+            @XmlAttribute(name = "vlanId")
+            protected Integer vlanId;
+            @XmlAttribute(name = "vlanPcp")
+            protected Integer vlanPcp;
+
+            /**
+             * Gets the value of the src property.
+             * @return
+             *     possible object is
+             *     {@link String }
+             */
+            public String getSrc() {
+                return src;
+            }
+
+            /**
+             * Sets the value of the src property.
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             */
+            public void setSrc(String value) {
+                this.src = value;
+            }
+
+            /**
+             * Gets the value of the dst property.
+             * @return
+             *     possible object is
+             *     {@link String }
+             */
+            public String getDst() {
+                return dst;
+            }
+
+            /**
+             * Sets the value of the dst property.
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             */
+            public void setDst(String value) {
+                this.dst = value;
+            }
+
+            /**
+             * Gets the value of the ethertype property.
+             * @return
+             *     possible object is
+             *     {@link Integer }
+             */
+            public Integer getEthertype() {
+                return ethertype;
+            }
+
+            /**
+             * Sets the value of the ethertype property.
+             * @param value
+             *     allowed object is
+             *     {@link Integer }
+             */
+            public void setEthertype(Integer value) {
+                this.ethertype = value;
+            }
+
+            /**
+             * Gets the value of the vlanId property.
+             * @return
+             *     possible object is
+             *     {@link Integer }
+             */
+            public Integer getVlanId() {
+                return vlanId;
+            }
+
+            /**
+             * Sets the value of the vlanId property.
+             * @param value
+             *     allowed object is
+             *     {@link Integer }
+             */
+            public void setVlanId(Integer value) {
+                this.vlanId = value;
+            }
+
+            /**
+             * Gets the value of the vlanPcp property.
+             * @return
+             *     possible object is
+             *     {@link Integer }
+             */
+            public Integer getVlanPcp() {
+                return vlanPcp;
+            }
+
+            /**
+             * Sets the value of the vlanPcp property.
+             * @param value
+             *     allowed object is
+             *     {@link Integer }
+             */
+            public void setVlanPcp(Integer value) {
+                this.vlanPcp = value;
+            }
+
+        }
+
+
+        /**
+         * <p>Java class for anonymous complex type.
+         * <p>The following schema fragment specifies the expected content contained within this class.
+         * <pre>
+         * &lt;complexType>
+         *   &lt;complexContent>
+         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *       &lt;attribute name="src" type="{http://www.example.org/net/}portNumberType" />
+         *       &lt;attribute name="dst" type="{http://www.example.org/net/}portNumberType" />
+         *     &lt;/restriction>
+         *   &lt;/complexContent>
+         * &lt;/complexType>
+         * </pre>
+         */
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "")
+        public static class Tcp {
+
+            @XmlAttribute(name = "src")
+            protected Integer src;
+            @XmlAttribute(name = "dst")
+            protected Integer dst;
+
+            /**
+             * Gets the value of the src property.
+             * @return
+             *     possible object is
+             *     {@link Integer }
+             */
+            public Integer getSrc() {
+                return src;
+            }
+
+            /**
+             * Sets the value of the src property.
+             * @param value
+             *     allowed object is
+             *     {@link Integer }
+             */
+            public void setSrc(Integer value) {
+                this.src = value;
+            }
+
+            /**
+             * Gets the value of the dst property.
+             * @return
+             *     possible object is
+             *     {@link Integer }
+             */
+            public Integer getDst() {
+                return dst;
+            }
+
+            /**
+             * Sets the value of the dst property.
+             * @param value
+             *     allowed object is
+             *     {@link Integer }
+             */
+            public void setDst(Integer value) {
+                this.dst = value;
+            }
+
+        }
+
+
+        /**
+         * <p>Java class for anonymous complex type.
+         * <p>The following schema fragment specifies the expected content contained within this class.
+         * <pre>
+         * &lt;complexType>
+         *   &lt;complexContent>
+         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *       &lt;attribute name="src" type="{http://www.example.org/net/}portNumberType" />
+         *       &lt;attribute name="dst" type="{http://www.example.org/net/}portNumberType" />
+         *     &lt;/restriction>
+         *   &lt;/complexContent>
+         * &lt;/complexType>
+         * </pre>
+         */
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "")
+        public static class Udp {
+
+            @XmlAttribute(name = "src")
+            protected Integer src;
+            @XmlAttribute(name = "dst")
+            protected Integer dst;
+
+            /**
+             * Gets the value of the src property.
+             * @return
+             *     possible object is
+             *     {@link Integer }
+             */
+            public Integer getSrc() {
+                return src;
+            }
+
+            /**
+             * Sets the value of the src property.
+             * @param value
+             *     allowed object is
+             *     {@link Integer }
+             */
+            public void setSrc(Integer value) {
+                this.src = value;
+            }
+
+            /**
+             * Gets the value of the dst property.
+             * @return
+             *     possible object is
+             *     {@link Integer }
+             */
+            public Integer getDst() {
+                return dst;
+            }
+
+            /**
+             * Sets the value of the dst property.
+             * @param value
+             *     allowed object is
+             *     {@link Integer }
+             */
+            public void setDst(Integer value) {
+                this.dst = value;
+            }
+
+        }
+
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/HttpMessage.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/HttpMessage.java
new file mode 100644 (file)
index 0000000..5dc7c29
--- /dev/null
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for anonymous complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType>
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="statusCode" type="{http://www.w3.org/2001/XMLSchema}unsignedShort"/>
+ *         &lt;element name="reasonPhrase" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         &lt;element name="message" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {
+    "statusCode",
+    "reasonPhrase",
+    "message"
+})
+@XmlRootElement(name = "httpMessage", namespace = "http://www.example.org/response/")
+public class HttpMessage {
+
+    @XmlElement(namespace = "http://www.example.org/response/", defaultValue = "500")
+    @XmlSchemaType(name = "unsignedShort")
+    protected int statusCode;
+    @XmlElement(namespace = "http://www.example.org/response/", required = true, defaultValue = "Internal Server Error")
+    protected String reasonPhrase;
+    @XmlElement(namespace = "http://www.example.org/response/")
+    protected String message;
+
+    /**
+     * Gets the value of the statusCode property.
+     */
+    public int getStatusCode() {
+        return statusCode;
+    }
+
+    /**
+     * Sets the value of the statusCode property.
+     */
+    public void setStatusCode(int value) {
+        this.statusCode = value;
+    }
+
+    /**
+     * Gets the value of the reasonPhrase property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getReasonPhrase() {
+        return reasonPhrase;
+    }
+
+    /**
+     * Sets the value of the reasonPhrase property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setReasonPhrase(String value) {
+        this.reasonPhrase = value;
+    }
+
+    /**
+     * Gets the value of the message property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getMessage() {
+        return message;
+    }
+
+    /**
+     * Sets the value of the message property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setMessage(String value) {
+        this.message = value;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/MonParamsType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/MonParamsType.java
new file mode 100644 (file)
index 0000000..8651966
--- /dev/null
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for monParamsType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="monParamsType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="parameter" maxOccurs="unbounded" minOccurs="0">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}NMTOKENS" />
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "monParamsType", propOrder = {
+    "parameter"
+})
+public class MonParamsType {
+
+    protected List<MonParamsType.Parameter> parameter;
+
+    /**
+     * Gets the value of the parameter property.
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the parameter property.
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getParameter().add(newItem);
+     * </pre>
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link MonParamsType.Parameter }
+     */
+    public List<MonParamsType.Parameter> getParameter() {
+        if (parameter == null) {
+            parameter = new ArrayList<MonParamsType.Parameter>();
+        }
+        return this.parameter;
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}NMTOKENS" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class Parameter {
+
+        @XmlAttribute(name = "value", required = true)
+        @XmlSchemaType(name = "NMTOKENS")
+        protected List<String> value;
+
+        /**
+         * Gets the value of the value property.
+         * <p>
+         * This accessor method returns a reference to the live list,
+         * not a snapshot. Therefore any modification you make to the
+         * returned list will be present inside the JAXB object.
+         * This is why there is not a <CODE>set</CODE> method for the value property.
+         * <p>
+         * For example, to add a new item, do as follows:
+         * <pre>
+         *    getValue().add(newItem);
+         * </pre>
+         * <p>
+         * Objects of the following type(s) are allowed in the list
+         * {@link String }
+         */
+        public List<String> getValue() {
+            if (value == null) {
+                value = new ArrayList<String>();
+            }
+            return this.value;
+        }
+
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NeType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NeType.java
new file mode 100644 (file)
index 0000000..9cdecdd
--- /dev/null
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for neType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="neType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="eps-cps" type="{http://www.example.org/nffg/}eps-cpsType"/>
+ *         &lt;element name="monitoring_parameters" type="{http://www.example.org/nffg/}monParamsType"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="id" use="required" type="{http://www.example.org/nffg/}neIdType" />
+ *       &lt;attribute name="type" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "neType", propOrder = {
+    "epsCps",
+    "monitoringParameters"
+})
+public class NeType {
+
+    @XmlElement(name = "eps-cps", required = true)
+    protected EpsCpsType epsCps;
+    @XmlElement(name = "monitoring_parameters", required = true)
+    protected MonParamsType monitoringParameters;
+    @XmlAttribute(name = "id", required = true)
+    protected String id;
+    @XmlAttribute(name = "type", required = true)
+    protected String type;
+
+    /**
+     * Gets the value of the epsCps property.
+     * @return
+     *     possible object is
+     *     {@link EpsCpsType }
+     */
+    public EpsCpsType getEpsCps() {
+        return epsCps;
+    }
+
+    /**
+     * Sets the value of the epsCps property.
+     * @param value
+     *     allowed object is
+     *     {@link EpsCpsType }
+     */
+    public void setEpsCps(EpsCpsType value) {
+        this.epsCps = value;
+    }
+
+    /**
+     * Gets the value of the monitoringParameters property.
+     * @return
+     *     possible object is
+     *     {@link MonParamsType }
+     */
+    public MonParamsType getMonitoringParameters() {
+        return monitoringParameters;
+    }
+
+    /**
+     * Sets the value of the monitoringParameters property.
+     * @param value
+     *     allowed object is
+     *     {@link MonParamsType }
+     */
+    public void setMonitoringParameters(MonParamsType value) {
+        this.monitoringParameters = value;
+    }
+
+    /**
+     * Gets the value of the id property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+    /**
+     * Gets the value of the type property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * Sets the value of the type property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setType(String value) {
+        this.type = value;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NelementsType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NelementsType.java
new file mode 100644 (file)
index 0000000..0ccef60
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for nelementsType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="nelementsType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="network_element" type="{http://www.example.org/nffg/}neType" maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "nelementsType", propOrder = {
+    "networkElement"
+})
+public class NelementsType {
+
+    @XmlElement(name = "network_element")
+    protected List<NeType> networkElement;
+
+    /**
+     * Gets the value of the networkElement property.
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the networkElement property.
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getNetworkElement().add(newItem);
+     * </pre>
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link NeType }
+     */
+    public List<NeType> getNetworkElement() {
+        if (networkElement == null) {
+            networkElement = new ArrayList<NeType>();
+        }
+        return this.networkElement;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NfType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NfType.java
new file mode 100644 (file)
index 0000000..f2b50ea
--- /dev/null
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for nfType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="nfType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="specification" type="{http://www.example.org/nffg/}specType"/>
+ *         &lt;element name="connection_points" type="{http://www.example.org/nffg/}cpointsType"/>
+ *         &lt;element name="control_interfaces" type="{http://www.example.org/nffg/}ctrlInterfacesType"/>
+ *         &lt;element name="monitoring_parameters" type="{http://www.example.org/nffg/}monParamsType"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="id" use="required" type="{http://www.example.org/nffg/}nfIdType" />
+ *       &lt;attribute name="functionalType" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "nfType", propOrder = {
+    "specification",
+    "connectionPoints",
+    "controlInterfaces",
+    "monitoringParameters"
+})
+public class NfType {
+
+    @XmlElement(required = true)
+    protected SpecType specification;
+    @XmlElement(name = "connection_points", required = true)
+    protected CpointsType connectionPoints;
+    @XmlElement(name = "control_interfaces", required = true)
+    protected CtrlInterfacesType controlInterfaces;
+    @XmlElement(name = "monitoring_parameters", required = true)
+    protected MonParamsType monitoringParameters;
+    @XmlAttribute(name = "id", required = true)
+    protected String id;
+    @XmlAttribute(name = "functionalType", required = true)
+    protected String functionalType;
+
+    /**
+     * Gets the value of the specification property.
+     * @return
+     *     possible object is
+     *     {@link SpecType }
+     */
+    public SpecType getSpecification() {
+        return specification;
+    }
+
+    /**
+     * Sets the value of the specification property.
+     * @param value
+     *     allowed object is
+     *     {@link SpecType }
+     */
+    public void setSpecification(SpecType value) {
+        this.specification = value;
+    }
+
+    /**
+     * Gets the value of the connectionPoints property.
+     * @return
+     *     possible object is
+     *     {@link CpointsType }
+     */
+    public CpointsType getConnectionPoints() {
+        return connectionPoints;
+    }
+
+    /**
+     * Sets the value of the connectionPoints property.
+     * @param value
+     *     allowed object is
+     *     {@link CpointsType }
+     */
+    public void setConnectionPoints(CpointsType value) {
+        this.connectionPoints = value;
+    }
+
+    /**
+     * Gets the value of the controlInterfaces property.
+     * @return
+     *     possible object is
+     *     {@link CtrlInterfacesType }
+     */
+    public CtrlInterfacesType getControlInterfaces() {
+        return controlInterfaces;
+    }
+
+    /**
+     * Sets the value of the controlInterfaces property.
+     * @param value
+     *     allowed object is
+     *     {@link CtrlInterfacesType }
+     */
+    public void setControlInterfaces(CtrlInterfacesType value) {
+        this.controlInterfaces = value;
+    }
+
+    /**
+     * Gets the value of the monitoringParameters property.
+     * @return
+     *     possible object is
+     *     {@link MonParamsType }
+     */
+    public MonParamsType getMonitoringParameters() {
+        return monitoringParameters;
+    }
+
+    /**
+     * Sets the value of the monitoringParameters property.
+     * @param value
+     *     allowed object is
+     *     {@link MonParamsType }
+     */
+    public void setMonitoringParameters(MonParamsType value) {
+        this.monitoringParameters = value;
+    }
+
+    /**
+     * Gets the value of the id property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+    /**
+     * Gets the value of the functionalType property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getFunctionalType() {
+        return functionalType;
+    }
+
+    /**
+     * Sets the value of the functionalType property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setFunctionalType(String value) {
+        this.functionalType = value;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/Nffg.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/Nffg.java
new file mode 100644 (file)
index 0000000..54e6daf
--- /dev/null
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for anonymous complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType>
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="endpoints" type="{http://www.example.org/nffg/}epointsType"/>
+ *         &lt;element name="network_functions" type="{http://www.example.org/nffg/}nfunctionsType"/>
+ *         &lt;element name="network_elements" type="{http://www.example.org/nffg/}nelementsType"/>
+ *         &lt;element name="monitoring_parameters" type="{http://www.example.org/nffg/}monParamsType"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="id" type="{http://www.example.org/nffg/}nffgIdType" />
+ *       &lt;attribute name="version" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {
+    "endpoints",
+    "networkFunctions",
+    "networkElements",
+    "monitoringParameters"
+})
+@XmlRootElement(name = "nffg")
+public class Nffg {
+
+    @XmlElement(required = true)
+    protected EpointsType endpoints;
+    @XmlElement(name = "network_functions", required = true)
+    protected NfunctionsType networkFunctions;
+    @XmlElement(name = "network_elements", required = true)
+    protected NelementsType networkElements;
+    @XmlElement(name = "monitoring_parameters", required = true)
+    protected MonParamsType monitoringParameters;
+    @XmlAttribute(name = "id")
+    protected String id;
+    @XmlAttribute(name = "version")
+    protected String version;
+
+    /**
+     * Gets the value of the endpoints property.
+     * @return
+     *     possible object is
+     *     {@link EpointsType }
+     */
+    public EpointsType getEndpoints() {
+        return endpoints;
+    }
+
+    /**
+     * Sets the value of the endpoints property.
+     * @param value
+     *     allowed object is
+     *     {@link EpointsType }
+     */
+    public void setEndpoints(EpointsType value) {
+        this.endpoints = value;
+    }
+
+    /**
+     * Gets the value of the networkFunctions property.
+     * @return
+     *     possible object is
+     *     {@link NfunctionsType }
+     */
+    public NfunctionsType getNetworkFunctions() {
+        return networkFunctions;
+    }
+
+    /**
+     * Sets the value of the networkFunctions property.
+     * @param value
+     *     allowed object is
+     *     {@link NfunctionsType }
+     */
+    public void setNetworkFunctions(NfunctionsType value) {
+        this.networkFunctions = value;
+    }
+
+    /**
+     * Gets the value of the networkElements property.
+     * @return
+     *     possible object is
+     *     {@link NelementsType }
+     */
+    public NelementsType getNetworkElements() {
+        return networkElements;
+    }
+
+    /**
+     * Sets the value of the networkElements property.
+     * @param value
+     *     allowed object is
+     *     {@link NelementsType }
+     */
+    public void setNetworkElements(NelementsType value) {
+        this.networkElements = value;
+    }
+
+    /**
+     * Gets the value of the monitoringParameters property.
+     * @return
+     *     possible object is
+     *     {@link MonParamsType }
+     */
+    public MonParamsType getMonitoringParameters() {
+        return monitoringParameters;
+    }
+
+    /**
+     * Sets the value of the monitoringParameters property.
+     * @param value
+     *     allowed object is
+     *     {@link MonParamsType }
+     */
+    public void setMonitoringParameters(MonParamsType value) {
+        this.monitoringParameters = value;
+    }
+
+    /**
+     * Gets the value of the id property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+    /**
+     * Gets the value of the version property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getVersion() {
+        return version;
+    }
+
+    /**
+     * Sets the value of the version property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setVersion(String value) {
+        this.version = value;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NffgSet.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NffgSet.java
new file mode 100644 (file)
index 0000000..8fdc137
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for anonymous complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType>
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element ref="{http://www.example.org/nffg/}nffg" maxOccurs="unbounded"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {
+    "nffg"
+})
+@XmlRootElement(name = "nffg-set")
+public class NffgSet {
+
+    @XmlElement(required = true)
+    protected List<Nffg> nffg;
+
+    /**
+     * Gets the value of the nffg property.
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the nffg property.
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getNffg().add(newItem);
+     * </pre>
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link Nffg }
+     */
+    public List<Nffg> getNffg() {
+        if (nffg == null) {
+            nffg = new ArrayList<Nffg>();
+        }
+        return this.nffg;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NfunctionsType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NfunctionsType.java
new file mode 100644 (file)
index 0000000..7b26ac3
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for nfunctionsType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="nfunctionsType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="network_function" type="{http://www.example.org/nffg/}nfType" maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "nfunctionsType", propOrder = {
+    "networkFunction"
+})
+public class NfunctionsType {
+
+    @XmlElement(name = "network_function")
+    protected List<NfType> networkFunction;
+
+    /**
+     * Gets the value of the networkFunction property.
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the networkFunction property.
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getNetworkFunction().add(newItem);
+     * </pre>
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link NfType }
+     */
+    public List<NfType> getNetworkFunction() {
+        if (networkFunction == null) {
+            networkFunction = new ArrayList<NfType>();
+        }
+        return this.networkFunction;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ObjectFactory.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ObjectFactory.java
new file mode 100644 (file)
index 0000000..1c7c7f5
--- /dev/null
@@ -0,0 +1,319 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.annotation.XmlElementDecl;
+import javax.xml.bind.annotation.XmlRegistry;
+import javax.xml.namespace.QName;
+
+
+/**
+ * This object contains factory methods for each 
+ * Java content interface and Java element interface 
+ * generated in the it.polito.nffg.neo4j.jaxb package. 
+ * <p>An ObjectFactory allows you to programatically 
+ * construct new instances of the Java representation 
+ * for XML content. The Java representation of XML 
+ * content can consist of schema derived interfaces 
+ * and classes representing the binding of schema 
+ * type definitions, element declarations and model 
+ * groups.  Factory methods for each of these are 
+ * provided in this class.
+ */
+@XmlRegistry
+public class ObjectFactory {
+
+    private final static QName _Nffg_QNAME = new QName("http://www.example.org/nffg/", "nffg");
+    private final static QName _NffgSet_QNAME = new QName("http://www.example.org/nffg/", "nffg-set");
+
+
+    /**
+     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: it.polito.nffg.neo4j.jaxb
+     */
+    public ObjectFactory() {
+    }
+
+    /**
+     * Create an instance of {@link FlowrulesType }
+     */
+    public FlowrulesType createFlowrulesType() {
+        return new FlowrulesType();
+    }
+
+    /**
+     * Create an instance of {@link FlowrulesType.Flowspace }
+     */
+    public FlowrulesType.Flowspace createFlowrulesTypeFlowspace() {
+        return new FlowrulesType.Flowspace();
+    }
+
+    /**
+     * Create an instance of {@link CiType }
+     */
+    public CiType createCiType() {
+        return new CiType();
+    }
+
+    /**
+     * Create an instance of {@link CiType.Attributes }
+     */
+    public CiType.Attributes createCiTypeAttributes() {
+        return new CiType.Attributes();
+    }
+
+    /**
+     * Create an instance of {@link EpType }
+     */
+    public EpType createEpType() {
+        return new EpType();
+    }
+
+    /**
+     * Create an instance of {@link SpecType }
+     */
+    public SpecType createSpecType() {
+        return new SpecType();
+    }
+
+    /**
+     * Create an instance of {@link MonParamsType }
+     */
+    public MonParamsType createMonParamsType() {
+        return new MonParamsType();
+    }
+
+    /**
+     * Create an instance of {@link NffgSet }
+     */
+    public NffgSet createNffgSet() {
+        return new NffgSet();
+    }
+
+    /**
+     * Create an instance of {@link Nffg }
+     */
+    public Nffg createNffg() {
+        return new Nffg();
+    }
+
+    /**
+     * Create an instance of {@link EpointsType }
+     */
+    public EpointsType createEpointsType() {
+        return new EpointsType();
+    }
+
+    /**
+     * Create an instance of {@link NfunctionsType }
+     */
+    public NfunctionsType createNfunctionsType() {
+        return new NfunctionsType();
+    }
+
+    /**
+     * Create an instance of {@link NelementsType }
+     */
+    public NelementsType createNelementsType() {
+        return new NelementsType();
+    }
+
+    /**
+     * Create an instance of {@link CpointsType }
+     */
+    public CpointsType createCpointsType() {
+        return new CpointsType();
+    }
+
+    /**
+     * Create an instance of {@link NfType }
+     */
+    public NfType createNfType() {
+        return new NfType();
+    }
+
+    /**
+     * Create an instance of {@link EpCpType }
+     */
+    public EpCpType createEpCpType() {
+        return new EpCpType();
+    }
+
+    /**
+     * Create an instance of {@link EpsCpsType }
+     */
+    public EpsCpsType createEpsCpsType() {
+        return new EpsCpsType();
+    }
+
+    /**
+     * Create an instance of {@link ActionsType }
+     */
+    public ActionsType createActionsType() {
+        return new ActionsType();
+    }
+
+    /**
+     * Create an instance of {@link ActionType }
+     */
+    public ActionType createActionType() {
+        return new ActionType();
+    }
+
+    /**
+     * Create an instance of {@link PortType }
+     */
+    public PortType createPortType() {
+        return new PortType();
+    }
+
+    /**
+     * Create an instance of {@link CpType }
+     */
+    public CpType createCpType() {
+        return new CpType();
+    }
+
+    /**
+     * Create an instance of {@link CtrlInterfacesType }
+     */
+    public CtrlInterfacesType createCtrlInterfacesType() {
+        return new CtrlInterfacesType();
+    }
+
+    /**
+     * Create an instance of {@link NeType }
+     */
+    public NeType createNeType() {
+        return new NeType();
+    }
+
+    /**
+     * Create an instance of {@link Paths }
+     */
+    public Paths createPaths() {
+        return new Paths();
+    }
+
+    /**
+     * Create an instance of {@link HttpMessage }
+     */
+    public HttpMessage createHttpMessage() {
+        return new HttpMessage();
+    }
+
+    /**
+     * Create an instance of {@link Property }
+     */
+    public Property createProperty() {
+        return new Property();
+    }
+
+    /**
+     * Create an instance of {@link FlowrulesType.Flowspace.Mac }
+     */
+    public FlowrulesType.Flowspace.Mac createFlowrulesTypeFlowspaceMac() {
+        return new FlowrulesType.Flowspace.Mac();
+    }
+
+    /**
+     * Create an instance of {@link FlowrulesType.Flowspace.Ip }
+     */
+    public FlowrulesType.Flowspace.Ip createFlowrulesTypeFlowspaceIp() {
+        return new FlowrulesType.Flowspace.Ip();
+    }
+
+    /**
+     * Create an instance of {@link FlowrulesType.Flowspace.Tcp }
+     */
+    public FlowrulesType.Flowspace.Tcp createFlowrulesTypeFlowspaceTcp() {
+        return new FlowrulesType.Flowspace.Tcp();
+    }
+
+    /**
+     * Create an instance of {@link FlowrulesType.Flowspace.Udp }
+     */
+    public FlowrulesType.Flowspace.Udp createFlowrulesTypeFlowspaceUdp() {
+        return new FlowrulesType.Flowspace.Udp();
+    }
+
+    /**
+     * Create an instance of {@link CiType.Attributes.Attribute }
+     */
+    public CiType.Attributes.Attribute createCiTypeAttributesAttribute() {
+        return new CiType.Attributes.Attribute();
+    }
+
+    /**
+     * Create an instance of {@link EpType.Flowspace }
+     */
+    public EpType.Flowspace createEpTypeFlowspace() {
+        return new EpType.Flowspace();
+    }
+
+    /**
+     * Create an instance of {@link SpecType.Deployment }
+     */
+    public SpecType.Deployment createSpecTypeDeployment() {
+        return new SpecType.Deployment();
+    }
+
+    /**
+     * Create an instance of {@link SpecType.Image }
+     */
+    public SpecType.Image createSpecTypeImage() {
+        return new SpecType.Image();
+    }
+
+    /**
+     * Create an instance of {@link SpecType.Cpu }
+     */
+    public SpecType.Cpu createSpecTypeCpu() {
+        return new SpecType.Cpu();
+    }
+
+    /**
+     * Create an instance of {@link SpecType.Memory }
+     */
+    public SpecType.Memory createSpecTypeMemory() {
+        return new SpecType.Memory();
+    }
+
+    /**
+     * Create an instance of {@link SpecType.Storage }
+     */
+    public SpecType.Storage createSpecTypeStorage() {
+        return new SpecType.Storage();
+    }
+
+    /**
+     * Create an instance of {@link MonParamsType.Parameter }
+     */
+    public MonParamsType.Parameter createMonParamsTypeParameter() {
+        return new MonParamsType.Parameter();
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link NffgType }{@code >}}
+     */
+    @XmlElementDecl(namespace = "http://www.example.org/nffg/", name = "nffg")
+    public JAXBElement<Nffg> createNffg(Nffg value) {
+        return new JAXBElement<Nffg>(_Nffg_QNAME, Nffg.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link NffgSetType }{@code >}}
+     */
+    @XmlElementDecl(namespace = "http://www.example.org/nffg/", name = "nffg-set")
+    public JAXBElement<NffgSet> createNffgSet(NffgSet value) {
+        return new JAXBElement<NffgSet>(_NffgSet_QNAME, NffgSet.class, null, value);
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/Paths.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/Paths.java
new file mode 100644 (file)
index 0000000..f097b30
--- /dev/null
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for anonymous complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType>
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;choice>
+ *         &lt;element name="message" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         &lt;element name="path" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded"/>
+ *       &lt;/choice>
+ *       &lt;attribute name="source" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="destination" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="direction" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {
+    "message",
+    "path"
+})
+@XmlRootElement(name = "paths", namespace = "http://www.example.org/response/")
+public class Paths {
+
+    @XmlElement(namespace = "http://www.example.org/response/")
+    protected String message;
+    @XmlElement(namespace = "http://www.example.org/response/")
+    protected List<String> path;
+    @XmlAttribute(name = "source")
+    protected String source;
+    @XmlAttribute(name = "destination")
+    protected String destination;
+    @XmlAttribute(name = "direction")
+    protected String direction;
+
+    /**
+     * Gets the value of the message property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getMessage() {
+        return message;
+    }
+
+    /**
+     * Sets the value of the message property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setMessage(String value) {
+        this.message = value;
+    }
+
+    /**
+     * Gets the value of the path property.
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the path property.
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getPath().add(newItem);
+     * </pre>
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link String }
+     */
+    public List<String> getPath() {
+        if (path == null) {
+            path = new ArrayList<String>();
+        }
+        return this.path;
+    }
+
+    /**
+     * Gets the value of the source property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getSource() {
+        return source;
+    }
+
+    /**
+     * Sets the value of the source property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setSource(String value) {
+        this.source = value;
+    }
+
+    /**
+     * Gets the value of the destination property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getDestination() {
+        return destination;
+    }
+
+    /**
+     * Sets the value of the destination property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setDestination(String value) {
+        this.destination = value;
+    }
+
+    /**
+     * Gets the value of the direction property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getDirection() {
+        return direction;
+    }
+
+    /**
+     * Sets the value of the direction property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setDirection(String value) {
+        this.direction = value;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/PortDirEnumType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/PortDirEnumType.java
new file mode 100644 (file)
index 0000000..f98907d
--- /dev/null
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlEnumValue;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for portDirEnumType.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * <pre>
+ * &lt;simpleType name="portDirEnumType">
+ *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ *     &lt;enumeration value="in"/>
+ *     &lt;enumeration value="out"/>
+ *     &lt;enumeration value="both"/>
+ *   &lt;/restriction>
+ * &lt;/simpleType>
+ * </pre>
+ */
+@XmlType(name = "portDirEnumType")
+@XmlEnum
+public enum PortDirEnumType {
+
+    @XmlEnumValue("in")
+    IN("in"),
+    @XmlEnumValue("out")
+    OUT("out"),
+    @XmlEnumValue("both")
+    BOTH("both");
+    private final String value;
+
+    PortDirEnumType(String v) {
+        value = v;
+    }
+
+    public String value() {
+        return value;
+    }
+
+    public static PortDirEnumType fromValue(String v) {
+        for (PortDirEnumType c: PortDirEnumType.values()) {
+            if (c.value.equals(v)) {
+                return c;
+            }
+        }
+        throw new IllegalArgumentException(v);
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/PortType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/PortType.java
new file mode 100644 (file)
index 0000000..4d44cf5
--- /dev/null
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for portType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="portType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}unsignedShort" />
+ *       &lt;attribute name="direction" use="required" type="{http://www.example.org/nffg/}portDirEnumType" />
+ *       &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "portType")
+public class PortType {
+
+    @XmlAttribute(name = "id", required = true)
+    @XmlSchemaType(name = "unsignedShort")
+    protected int id;
+    @XmlAttribute(name = "direction", required = true)
+    protected PortDirEnumType direction;
+    @XmlAttribute(name = "type")
+    protected String type;
+
+    /**
+     * Gets the value of the id property.
+     */
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     */
+    public void setId(int value) {
+        this.id = value;
+    }
+
+    /**
+     * Gets the value of the direction property.
+     * @return
+     *     possible object is
+     *     {@link PortDirEnumType }
+     */
+    public PortDirEnumType getDirection() {
+        return direction;
+    }
+
+    /**
+     * Sets the value of the direction property.
+     * @param value
+     *     allowed object is
+     *     {@link PortDirEnumType }
+     */
+    public void setDirection(PortDirEnumType value) {
+        this.direction = value;
+    }
+
+    /**
+     * Gets the value of the type property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getType() {
+        if (type == null) {
+            return "N.A.";
+        } else {
+            return type;
+        }
+    }
+
+    /**
+     * Sets the value of the type property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setType(String value) {
+        this.type = value;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/Property.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/Property.java
new file mode 100644 (file)
index 0000000..973eaf8
--- /dev/null
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for anonymous complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType>
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="name" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         &lt;element name="response" type="{http://www.w3.org/2001/XMLSchema}boolean"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="source" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="destination" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="direction" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {
+    "name",
+    "response"
+})
+@XmlRootElement(name = "property", namespace = "http://www.example.org/response/")
+public class Property {
+
+    @XmlElement(namespace = "http://www.example.org/response/", required = true)
+    protected String name;
+    @XmlElement(namespace = "http://www.example.org/response/")
+    protected boolean response;
+    @XmlAttribute(name = "source")
+    protected String source;
+    @XmlAttribute(name = "destination")
+    protected String destination;
+    @XmlAttribute(name = "direction")
+    protected String direction;
+
+    /**
+     * Gets the value of the name property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets the value of the name property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setName(String value) {
+        this.name = value;
+    }
+
+    /**
+     * Gets the value of the response property.
+     */
+    public boolean isResponse() {
+        return response;
+    }
+
+    /**
+     * Sets the value of the response property.
+     */
+    public void setResponse(boolean value) {
+        this.response = value;
+    }
+
+    /**
+     * Gets the value of the source property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getSource() {
+        return source;
+    }
+
+    /**
+     * Sets the value of the source property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setSource(String value) {
+        this.source = value;
+    }
+
+    /**
+     * Gets the value of the destination property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getDestination() {
+        return destination;
+    }
+
+    /**
+     * Sets the value of the destination property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setDestination(String value) {
+        this.destination = value;
+    }
+
+    /**
+     * Gets the value of the direction property.
+     * @return
+     *     possible object is
+     *     {@link String }
+     */
+    public String getDirection() {
+        return direction;
+    }
+
+    /**
+     * Sets the value of the direction property.
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     */
+    public void setDirection(String value) {
+        this.direction = value;
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/SpecType.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/SpecType.java
new file mode 100644 (file)
index 0000000..e4d434b
--- /dev/null
@@ -0,0 +1,577 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.nffg.neo4j.jaxb;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for specType complex type.
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <pre>
+ * &lt;complexType name="specType">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="deployment">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *         &lt;element name="image">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;attribute name="uri" type="{http://www.w3.org/2001/XMLSchema}anyURI" default="N.A." />
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *         &lt;element name="cpu">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;attribute name="model" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+ *                 &lt;attribute name="architecture" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+ *                 &lt;attribute name="numCores" type="{http://www.w3.org/2001/XMLSchema}unsignedByte" default="1" />
+ *                 &lt;attribute name="clockSpeed" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *         &lt;element name="memory">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+ *                 &lt;attribute name="size" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *         &lt;element name="storage">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+ *                 &lt;attribute name="size" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "specType", propOrder = {
+    "deployment",
+    "image",
+    "cpu",
+    "memory",
+    "storage"
+})
+public class SpecType {
+
+    @XmlElement(required = true)
+    protected SpecType.Deployment deployment;
+    @XmlElement(required = true)
+    protected SpecType.Image image;
+    @XmlElement(required = true)
+    protected SpecType.Cpu cpu;
+    @XmlElement(required = true)
+    protected SpecType.Memory memory;
+    @XmlElement(required = true)
+    protected SpecType.Storage storage;
+
+    /**
+     * Gets the value of the deployment property.
+     * @return
+     *     possible object is
+     *     {@link SpecType.Deployment }
+     */
+    public SpecType.Deployment getDeployment() {
+        return deployment;
+    }
+
+    /**
+     * Sets the value of the deployment property.
+     * @param value
+     *     allowed object is
+     *     {@link SpecType.Deployment }
+     */
+    public void setDeployment(SpecType.Deployment value) {
+        this.deployment = value;
+    }
+
+    /**
+     * Gets the value of the image property.
+     * @return
+     *     possible object is
+     *     {@link SpecType.Image }
+     */
+    public SpecType.Image getImage() {
+        return image;
+    }
+
+    /**
+     * Sets the value of the image property.
+     * @param value
+     *     allowed object is
+     *     {@link SpecType.Image }
+     */
+    public void setImage(SpecType.Image value) {
+        this.image = value;
+    }
+
+    /**
+     * Gets the value of the cpu property.
+     * @return
+     *     possible object is
+     *     {@link SpecType.Cpu }
+     */
+    public SpecType.Cpu getCpu() {
+        return cpu;
+    }
+
+    /**
+     * Sets the value of the cpu property.
+     * @param value
+     *     allowed object is
+     *     {@link SpecType.Cpu }
+     */
+    public void setCpu(SpecType.Cpu value) {
+        this.cpu = value;
+    }
+
+    /**
+     * Gets the value of the memory property.
+     * @return
+     *     possible object is
+     *     {@link SpecType.Memory }
+     */
+    public SpecType.Memory getMemory() {
+        return memory;
+    }
+
+    /**
+     * Sets the value of the memory property.
+     * @param value
+     *     allowed object is
+     *     {@link SpecType.Memory }
+     */
+    public void setMemory(SpecType.Memory value) {
+        this.memory = value;
+    }
+
+    /**
+     * Gets the value of the storage property.
+     * @return
+     *     possible object is
+     *     {@link SpecType.Storage }
+     */
+    public SpecType.Storage getStorage() {
+        return storage;
+    }
+
+    /**
+     * Sets the value of the storage property.
+     * @param value
+     *     allowed object is
+     *     {@link SpecType.Storage }
+     */
+    public void setStorage(SpecType.Storage value) {
+        this.storage = value;
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attribute name="model" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+     *       &lt;attribute name="architecture" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+     *       &lt;attribute name="numCores" type="{http://www.w3.org/2001/XMLSchema}unsignedByte" default="1" />
+     *       &lt;attribute name="clockSpeed" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class Cpu {
+
+        @XmlAttribute(name = "model")
+        protected String model;
+        @XmlAttribute(name = "architecture")
+        protected String architecture;
+        @XmlAttribute(name = "numCores")
+        @XmlSchemaType(name = "unsignedByte")
+        protected Short numCores;
+        @XmlAttribute(name = "clockSpeed")
+        protected String clockSpeed;
+
+        /**
+         * Gets the value of the model property.
+         * @return
+         *     possible object is
+         *     {@link String }
+         */
+        public String getModel() {
+            if (model == null) {
+                return "N.A.";
+            } else {
+                return model;
+            }
+        }
+
+        /**
+         * Sets the value of the model property.
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         */
+        public void setModel(String value) {
+            this.model = value;
+        }
+
+        /**
+         * Gets the value of the architecture property.
+         * @return
+         *     possible object is
+         *     {@link String }
+         */
+        public String getArchitecture() {
+            if (architecture == null) {
+                return "N.A.";
+            } else {
+                return architecture;
+            }
+        }
+
+        /**
+         * Sets the value of the architecture property.
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         */
+        public void setArchitecture(String value) {
+            this.architecture = value;
+        }
+
+        /**
+         * Gets the value of the numCores property.
+         * @return
+         *     possible object is
+         *     {@link Short }
+         */
+        public short getNumCores() {
+            if (numCores == null) {
+                return ((short) 1);
+            } else {
+                return numCores;
+            }
+        }
+
+        /**
+         * Sets the value of the numCores property.
+         * @param value
+         *     allowed object is
+         *     {@link Short }
+         */
+        public void setNumCores(Short value) {
+            this.numCores = value;
+        }
+
+        /**
+         * Gets the value of the clockSpeed property.
+         * @return
+         *     possible object is
+         *     {@link String }
+         */
+        public String getClockSpeed() {
+            if (clockSpeed == null) {
+                return "N.A.";
+            } else {
+                return clockSpeed;
+            }
+        }
+
+        /**
+         * Sets the value of the clockSpeed property.
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         */
+        public void setClockSpeed(String value) {
+            this.clockSpeed = value;
+        }
+
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class Deployment {
+
+        @XmlAttribute(name = "type")
+        protected String type;
+
+        /**
+         * Gets the value of the type property.
+         * @return
+         *     possible object is
+         *     {@link String }
+         */
+        public String getType() {
+            if (type == null) {
+                return "N.A.";
+            } else {
+                return type;
+            }
+        }
+
+        /**
+         * Sets the value of the type property.
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         */
+        public void setType(String value) {
+            this.type = value;
+        }
+
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attribute name="uri" type="{http://www.w3.org/2001/XMLSchema}anyURI" default="N.A." />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class Image {
+
+        @XmlAttribute(name = "uri")
+        @XmlSchemaType(name = "anyURI")
+        protected String uri;
+
+        /**
+         * Gets the value of the uri property.
+         * @return
+         *     possible object is
+         *     {@link String }
+         */
+        public String getUri() {
+            if (uri == null) {
+                return "N.A.";
+            } else {
+                return uri;
+            }
+        }
+
+        /**
+         * Sets the value of the uri property.
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         */
+        public void setUri(String value) {
+            this.uri = value;
+        }
+
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+     *       &lt;attribute name="size" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class Memory {
+
+        @XmlAttribute(name = "type")
+        protected String type;
+        @XmlAttribute(name = "size")
+        protected String size;
+
+        /**
+         * Gets the value of the type property.
+         * @return
+         *     possible object is
+         *     {@link String }
+         */
+        public String getType() {
+            if (type == null) {
+                return "N.A.";
+            } else {
+                return type;
+            }
+        }
+
+        /**
+         * Sets the value of the type property.
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         */
+        public void setType(String value) {
+            this.type = value;
+        }
+
+        /**
+         * Gets the value of the size property.
+         * @return
+         *     possible object is
+         *     {@link String }
+         */
+        public String getSize() {
+            if (size == null) {
+                return "N.A.";
+            } else {
+                return size;
+            }
+        }
+
+        /**
+         * Sets the value of the size property.
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         */
+        public void setSize(String value) {
+            this.size = value;
+        }
+
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+     *       &lt;attribute name="size" type="{http://www.w3.org/2001/XMLSchema}string" default="N.A." />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class Storage {
+
+        @XmlAttribute(name = "type")
+        protected String type;
+        @XmlAttribute(name = "size")
+        protected String size;
+
+        /**
+         * Gets the value of the type property.
+         * @return
+         *     possible object is
+         *     {@link String }
+         */
+        public String getType() {
+            if (type == null) {
+                return "N.A.";
+            } else {
+                return type;
+            }
+        }
+
+        /**
+         * Sets the value of the type property.
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         */
+        public void setType(String value) {
+            this.type = value;
+        }
+
+        /**
+         * Gets the value of the size property.
+         * @return
+         *     possible object is
+         *     {@link String }
+         */
+        public String getSize() {
+            if (size == null) {
+                return "N.A.";
+            } else {
+                return size;
+            }
+        }
+
+        /**
+         * Sets the value of the size property.
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         */
+        public void setSize(String value) {
+            this.size = value;
+        }
+
+    }
+
+}
diff --git a/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/package-info.java b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/package-info.java
new file mode 100644 (file)
index 0000000..3d3c7b4
--- /dev/null
@@ -0,0 +1,11 @@
+/*******************************************************************************
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.org/nffg/", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
+package it.polito.nffg.neo4j.jaxb;
diff --git a/verigraph/src/main/proto/verigraph.proto b/verigraph/src/main/proto/verigraph.proto
new file mode 100644 (file)
index 0000000..5f77c78
--- /dev/null
@@ -0,0 +1,154 @@
+syntax = "proto3";
+
+package verigraph;
+
+option java_multiple_files = true;
+option java_package = "io.grpc.verigraph";
+option java_outer_classname = "VerigraphProto";
+
+// The service definition.
+service Verigraph {
+  // Obtains a list of graphs
+  rpc GetGraphs (GetRequest) returns (stream GraphGrpc) {}
+  // Obtains a graph
+  rpc GetGraph (RequestID) returns (GraphGrpc) {}
+  // Obtains a list of Nodes
+  rpc GetNodes (RequestID) returns (stream NodeGrpc) {}
+  // Obtains a node
+  rpc GetNode (RequestID) returns (NodeGrpc) {}
+  // Obtains a list of Neighbours
+  rpc GetNeighbours (RequestID) returns (stream NeighbourGrpc) {}
+  // Obtains a Neighbour
+  rpc GetNeighbour (RequestID) returns (NeighbourGrpc) {}
+
+  // Creates a graph
+  rpc CreateGraph (GraphGrpc) returns (NewGraph) {}
+  // Delete a graph
+  rpc DeleteGraph (RequestID) returns (Status) {}
+  // Updates a graph
+  rpc UpdateGraph (GraphGrpc) returns (NewGraph) {}
+  // Verify a policy
+  rpc VerifyPolicy (Policy) returns (VerificationGrpc) {}
+
+  // Creates a Node
+  rpc CreateNode (NodeGrpc) returns (NewNode) {}
+  // Delete a Node
+  rpc DeleteNode (RequestID) returns (Status) {}
+  // Updates a Node
+  rpc UpdateNode (NodeGrpc) returns (NewNode) {}
+  // Configures a Node
+  rpc ConfigureNode (ConfigurationGrpc) returns (Status) {}
+
+  // Creates a neighbour
+  rpc CreateNeighbour (NeighbourGrpc) returns (NewNeighbour) {}
+  // Delete a neighbour
+  rpc DeleteNeighbour (RequestID) returns (Status) {}
+  // Updates a neighbour
+  rpc UpdateNeighbour (NeighbourGrpc) returns (NewNeighbour) {}
+}
+
+message GetRequest {
+}
+
+message RequestID {
+  int64 idGraph = 1;
+  int64 idNode = 2;
+  int64 idNeighbour = 3;
+}
+
+message Policy{
+       int64 idGraph = 1;
+       string source = 2;
+       string destination = 3;
+       enum PolicyType {
+               reachability = 0;
+               isolation = 1;
+               traversal = 2;
+       }
+       PolicyType type = 4;
+       string middlebox = 5;
+}
+
+message ConfigurationGrpc{
+       int64 idGraph = 1;
+       int64 idNode = 2;
+       string description = 3;
+       string configuration = 4;
+       string id = 5;
+}
+
+message NodeGrpc{
+       int64 idGraph = 1;
+       string name = 2;
+       int64 id = 3;   //long
+       enum FunctionalType {
+               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;
+       }
+       FunctionalType functional_type = 4;
+       repeated NeighbourGrpc neighbour = 5;
+       ConfigurationGrpc configuration = 6;
+       string errorMessage = 7;
+}
+
+message GraphGrpc{
+       int64 id = 1;   //long
+       repeated NodeGrpc node = 2;
+       string errorMessage = 3;
+}
+
+message NeighbourGrpc{
+       int64 idGraph = 1;
+       int64 idNode = 2;
+       string name = 3;
+       int64 id = 4;   //long
+       string errorMessage = 5;
+}
+
+message NewGraph{
+       bool success = 1;
+       GraphGrpc graph = 2;
+       string errorMessage = 3;
+}
+
+message NewNode{
+       bool success = 1;
+       NodeGrpc node = 2;
+       string errorMessage = 3;
+}
+
+message NewNeighbour{
+       bool success = 1;
+       NeighbourGrpc neighbour = 2;
+       string errorMessage = 3;
+}
+
+message TestGrpc {
+       repeated NodeGrpc node = 1;
+       string result = 2;
+}
+
+message VerificationGrpc{
+       bool successOfOperation = 1;
+       string result = 2;
+       string comment = 3;
+       repeated TestGrpc test = 4;
+       string errorMessage = 5;
+}
+
+message Status{
+       bool success = 1;
+       string errorMessage = 2;
+}
\ No newline at end of file
diff --git a/verigraph/src/main/schema/net_types.xsd b/verigraph/src/main/schema/net_types.xsd
new file mode 100644 (file)
index 0000000..c99c7a6
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+        xmlns:net="http://www.example.org/net/"
+        targetNamespace="http://www.example.org/net/"
+        elementFormDefault="qualified">
+
+       <annotation>
+       <documentation>
+               Copyright (C) 2006-2007 Code Synthesis Tools CC
+
+                       Redistribution and use with or without modification are permitted
+                   under the terms of the new BSD license. See the accompanying LICENSE
+                   file.
+       </documentation>
+       </annotation>
+
+       <simpleType name="macAddressType">
+               <restriction base="string">
+                       <pattern value="(([a-fA-F0-9]{2})-){5,7}[a-fA-F0-9]{2}"/>
+               </restriction>
+       </simpleType>
+
+       <simpleType name="ipAddressType">
+       <restriction base="string">
+               <pattern value="((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])"/>
+               <pattern value="(([0-9a-fA-F]{1,4}:){6})(([0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))"/>
+               <pattern value="(([0-9a-fA-F]{1,4}:)*|([0-9a-fA-F]{1,4}))*(::)(([0-9a-fA-F]{1,4}:)*|([0-9a-fA-F]{1,4}))*"/>
+       </restriction>
+       </simpleType>
+
+       <simpleType name="portNumberType">
+       <restriction base="unsignedShort">
+               <minInclusive value="1"/>
+       </restriction>
+       </simpleType>
+
+       <!-- <complexType name="ipEndpointStructType">
+       <sequence>
+               <element name="address" type="net:ipAddressType"/>
+               <element name="port" type="net:portNumberType"/>
+       </sequence>
+       </complexType> -->
+
+       <simpleType name="ethertypeType">
+               <restriction base="unsignedShort">
+                       <minInclusive value="1536"/>
+               </restriction>
+       </simpleType>
+
+       <simpleType name="vlanIdType">
+               <restriction base="unsignedShort">
+                       <minInclusive value="1"/>
+                       <maxInclusive value="4095"/>
+               </restriction>
+       </simpleType>
+
+       <simpleType name="vlanPcpType">
+               <restriction base="unsignedShort">
+                       <maxInclusive value="7"/>
+               </restriction>
+       </simpleType>
+</schema>
\ No newline at end of file
diff --git a/verigraph/src/main/schema/nffg.xsd b/verigraph/src/main/schema/nffg.xsd
new file mode 100644 (file)
index 0000000..77e6f40
--- /dev/null
@@ -0,0 +1,363 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+               xmlns:tns="http://www.example.org/nffg/"
+               xmlns:net="http://www.example.org/net/"
+               targetNamespace="http://www.example.org/nffg/"
+               elementFormDefault="qualified">
+
+       <import namespace="http://www.example.org/net/" schemaLocation="net_types.xsd"/>
+
+       <annotation>
+       <documentation xml:lang="it">
+                Il formato prevede si possa avere come radice "nffg-set" oppure "nffg".
+                Nel primo caso ci sono più nf-fg contenuti nello stesso documento XML.
+       </documentation>
+       </annotation>
+
+       <group name="L2HeaderParameters">
+               <sequence>
+                       <element name="Mac" minOccurs="0">
+                               <complexType>
+                                       <attribute name="src" type="net:macAddressType" use="optional"/>
+                                       <attribute name="dst" type="net:macAddressType" use="optional"/>
+                                       <attribute name="ethertype" type="net:ethertypeType" use="optional"/>
+                                       <attribute name="vlanId" type="net:vlanIdType" use="optional"/>
+                                       <attribute name="vlanPcp" type="net:vlanPcpType" use="optional"/>
+                               </complexType>
+                       </element>
+               </sequence>
+       </group>
+
+       <group name="L3HeaderParameters">
+               <sequence>
+                       <element name="Ip" minOccurs="0">
+                               <complexType>
+                                       <attribute name="src" type="net:ipAddressType" use="optional"/>
+                                       <attribute name="dst" type="net:ipAddressType" use="optional"/>
+                                       <attribute name="ipProtocol" type="unsignedByte" use="optional"/>
+                                       <attribute name="tos" type="unsignedByte" use="optional"/>
+                               </complexType>
+                       </element>
+               </sequence>
+       </group>
+
+       <!-- controllare nel programma che non ci siano combinazioni non ammesse -->
+       <group name="L4HeaderParameters">
+               <choice>
+                       <element name="Tcp" minOccurs="0">
+                               <complexType>
+                                       <attribute name="src" type="net:portNumberType" use="optional"/>
+                                       <attribute name="dst" type="net:portNumberType" use="optional"/>
+                               </complexType>
+                       </element>
+                       <element name="Udp" minOccurs="0">
+                               <complexType>
+                                       <attribute name="src" type="net:portNumberType" use="optional"/>
+                                       <attribute name="dst" type="net:portNumberType" use="optional"/>
+                               </complexType>
+                       </element>
+               </choice>
+       </group>
+
+       <!-- alla fine controlloare tutti gli xpath perchè dopo dei cambiamenti potrebbero non andare più bene -->
+       <element name="nffg-set" type="tns:nffg-setType">
+               <unique name="nffgIdUnique">
+               <selector xpath="tns:nf-fg"/>
+               <field xpath="@id"/>
+           </unique>
+
+           <!-- forse la NF va spostata dentro graphs e resa referenziabile (condivisibile da più nffg) -->
+           <!-- così facendo però, si deve trovare un modo per avere le NF dentro nffg nel caso sia questo la radice -->
+           <unique name="nfIdUnique">
+               <selector xpath="tns:nf-fg/tns:network_functions/tns:network_function"/>
+               <field xpath="@id"/>
+           </unique>
+       </element>
+
+       <element name="nffg" type="tns:nffgType">
+               <unique name="epIdUnique">
+               <selector xpath="tns:endpoints/tns:endpoint"/>
+               <field xpath="@id"/>
+           </unique>
+
+           <unique name="cpIdUnique">
+               <selector xpath="tns:network_functions/tns:network_function/tns:connection_points/tns:connection_point"/>
+               <field xpath="@id"/>
+           </unique>
+
+           <unique name="portIdUnique">
+               <selector xpath="tns:network_functions/tns:network_function/tns:connection_points/tns:connection_point/tns:port"/>
+               <field xpath="@id"/>
+           </unique>
+
+           <unique name="ciIdUnique">
+               <selector xpath="tns:network_functions/tns:network_function/tns:control_interfaces/tns:control_interface"/>
+               <field xpath="@id"/>
+           </unique>
+
+           <unique name="neIdUnique">
+               <selector xpath="tns:network_elements/tns:network_element"/>
+               <field xpath="@id"/>
+           </unique>
+
+           <unique name="epcpIdRefUnique">
+               <selector xpath="tns:network_elements/tns:network_element/tns:eps-cps/tns:ep-cp"/>
+               <field xpath="@id_ref"/>
+           </unique>
+       </element>
+
+       <complexType name="monParamsType">
+               <sequence>
+                       <element name="parameter" maxOccurs="unbounded">
+                               <complexType>
+                                       <attribute name="value" type="NMTOKENS" use="required"/>
+                               </complexType>
+                       </element>
+               </sequence>
+       </complexType>
+
+    <complexType name="nffg-setType">
+               <sequence>
+                       <element ref="tns:nffg" maxOccurs="unbounded"/>
+               </sequence>
+       </complexType>
+
+    <complexType name="nffgType">
+       <sequence>
+               <element name="endpoints" type="tns:epointsType" nillable="true"/>
+               <element name="network_functions" type="tns:nfunctionsType" nillable="true"/>
+               <element name="network_elements" type="tns:nelementsType" nillable="true"/>
+               <element name="monitoring_parameters" type="tns:monParamsType" nillable="true"/>
+       </sequence>
+       <attribute name="id" type="tns:nffgIdType" use="optional"/>
+       <attribute name="version" type="string" use="optional"/>
+    </complexType>
+
+    <simpleType name="nffgIdType">
+       <restriction base="string">
+               <pattern value="nffg_\d+"/>
+       </restriction>
+    </simpleType>
+
+    <complexType name="epointsType">
+       <sequence>
+               <element name="endpoint" type="tns:epType" maxOccurs="unbounded"/>
+       </sequence>
+    </complexType>
+
+    <complexType name="epType">
+       <sequence>
+               <!-- valutare se renderlo nillable o tenere la cardinalità a * -->
+                       <element name="flowspace">
+                       <complexType>
+                               <sequence>
+                                       <group ref="tns:L2HeaderParameters"/>
+                                       <group ref="tns:L3HeaderParameters"/>
+                                       <group ref="tns:L4HeaderParameters"/>
+                               </sequence>
+                               <attribute name="nodeId" type="string" use="optional"/>
+                               <attribute name="ingPhysPort" type="string" use="optional"/>
+                       </complexType>
+                   </element>
+       </sequence>
+       <attribute name="id" type="tns:epIdType" use="required"/>
+    </complexType>
+
+    <simpleType name="epIdType">
+       <restriction base="string">
+               <pattern value="[a-z]*_\d+"/>
+       </restriction>
+    </simpleType>
+
+    <complexType name="nfunctionsType">
+       <sequence>
+               <element name="network_function" type="tns:nfType" maxOccurs="unbounded"/>
+       </sequence>
+    </complexType>
+
+    <complexType name="nfType">
+       <sequence>
+               <element name="specification" type="tns:specType"/>
+               <element name="connection_points" type="tns:cpointsType"/>
+               <element name="control_interfaces" type="tns:ctrlInterfacesType"/>
+               <element name="monitoring_parameters" type="tns:monParamsType" nillable="true"/>
+       </sequence>
+       <attribute name="id" type="tns:nfIdType" use="required"/>
+       <attribute name="functionalType" type="string" use="required"/>
+    </complexType>
+
+    <simpleType name="nfIdType">
+       <restriction base="string">
+               <pattern value="[a-z]*_\d+"/>
+       </restriction>
+    </simpleType>
+
+    <complexType name="specType">
+       <sequence>
+               <element name="deployment">
+                       <complexType>
+                               <attribute name="type" type="string" use="optional" default="N.A."/>
+                       </complexType>
+               </element>
+               <element name="image">
+                       <complexType>
+                               <!-- controllare come viene mappata la info -->
+                               <attribute name="uri" type="anyURI" use="optional" default="N.A."/>
+                       </complexType>
+               </element>
+               <element name="cpu">
+                       <complexType>
+                               <attribute name="model" type="string" use="optional" default="N.A."/>
+                               <attribute name="architecture" type="string" use="optional" default="N.A."/>
+                               <attribute name="numCores" type="unsignedByte" use="optional" default="1"/>
+                               <attribute name="clockSpeed" type="string" use="optional" default="N.A."/>
+                       </complexType>
+               </element>
+               <element name="memory">
+                       <complexType>
+                               <attribute name="type" type="string" use="optional" default="N.A."/>
+                               <attribute name="size" type="string" use="optional" default="N.A."/>
+                       </complexType>
+               </element>
+               <element name="storage">
+                       <complexType>
+                               <attribute name="type" type="string" use="optional" default="N.A."/>
+                               <attribute name="size" type="string" use="optional" default="N.A."/>
+                       </complexType>
+               </element>
+       </sequence>
+    </complexType>
+
+    <complexType name="cpointsType">
+       <sequence>
+               <element name="connection_point" type="tns:cpType" maxOccurs="unbounded"/>
+       </sequence>
+    </complexType>
+
+    <complexType name="cpType">
+       <sequence>
+               <element name="port" type="tns:portType"/>
+       </sequence>
+       <attribute name="id" type="tns:cpIdType" use="required"/>
+    </complexType>
+
+    <complexType name="portType">
+       <attribute name="id" type="unsignedShort" use="required"/>
+       <attribute name="direction" type="tns:portDirEnumType" use="required"/>
+       <attribute name="type" type="string" use="optional" default="N.A."/>
+    </complexType>
+
+    <simpleType name="portDirEnumType">
+       <restriction base="string">
+               <enumeration value="in"/>
+               <enumeration value="out"/>
+               <enumeration value="both"/>
+       </restriction>
+    </simpleType>
+
+    <simpleType name="cpIdType">
+       <restriction base="string">
+               <pattern value="cp_\d+"/>
+       </restriction>
+    </simpleType>
+
+    <complexType name="ctrlInterfacesType">
+       <sequence>
+               <!-- valutare se renderlo nillable -->
+               <element name="control_interface" type="tns:ciType" minOccurs="0" maxOccurs="unbounded"/>
+       </sequence>
+    </complexType>
+
+    <complexType name="ciType">
+       <sequence>
+               <element name="attributes">
+                       <complexType>
+                               <sequence>
+                                       <element name="attribute" minOccurs="0" maxOccurs="unbounded">
+                                               <complexType>
+                                                       <attribute name="value" type="string" use="required"/>
+                                               </complexType>
+                                       </element>
+                               </sequence>
+                       </complexType>
+               </element>
+       </sequence>
+       <attribute name="id" type="tns:ciIdType" use="required"/>
+    </complexType>
+
+    <simpleType name="ciIdType">
+       <restriction base="string">
+               <pattern value="ci_\d+"/>
+       </restriction>
+    </simpleType>
+
+    <complexType name="nelementsType">
+       <sequence>
+               <element name="network_element" type="tns:neType" maxOccurs="unbounded"/>
+       </sequence>
+    </complexType>
+
+    <complexType name="neType">
+       <sequence>
+               <element name="eps-cps" type="tns:eps-cpsType"/>
+               <element name="monitoring_parameters" type="tns:monParamsType" nillable="true"/>
+       </sequence>
+       <attribute name="id" type="tns:neIdType" use="required"/>
+       <attribute name="type" type="string" use="required"/>
+    </complexType>
+
+    <simpleType name="neIdType">
+       <restriction base="string">
+               <pattern value="ne_\d+"/>
+       </restriction>
+    </simpleType>
+
+    <complexType name="eps-cpsType">
+       <sequence>
+               <element name="ep-cp" type="tns:ep-cpType" minOccurs="0" maxOccurs="unbounded"/>
+       </sequence>
+    </complexType>
+
+    <complexType name="ep-cpType">
+       <sequence>
+               <element name="flowrules" type="tns:flowrulesType" minOccurs="0" maxOccurs="unbounded"/>
+       </sequence>
+       <attribute name="id_ref" type="string" use="required"/>
+    </complexType>
+
+    <complexType name="flowrulesType">
+       <sequence>
+               <!-- da fare valutazioni analoghe al flowspace di sopra -->
+               <element name="flowspace">
+                       <complexType>
+                               <sequence>
+                                       <group ref="tns:L2HeaderParameters"/>
+                                       <group ref="tns:L3HeaderParameters"/>
+                                       <group ref="tns:L4HeaderParameters"/>
+                               </sequence>
+                               <attribute name="ingPort" type="string" use="optional"/>
+                       </complexType>
+               </element>
+               <element name="actions" type="tns:actionsType"/>
+       </sequence>
+    </complexType>
+
+    <complexType name="actionsType">
+           <sequence>
+               <element name="action" type="tns:actionType" maxOccurs="unbounded"/>
+           </sequence>
+    </complexType>
+
+    <complexType name="actionType">
+       <attribute name="type" type="tns:actionEnumType" use="required"/>
+       <attribute name="port" type="string" use="optional"/>
+    </complexType>
+
+    <!-- controllare via SW che se l'aziione Ã¨ output la porta deve esserci -->
+       <simpleType name="actionEnumType">
+       <restriction base="string">
+               <enumeration value="discard"/>
+               <enumeration value="output"/>
+       </restriction>
+    </simpleType>
+</schema>
\ No newline at end of file
diff --git a/verigraph/src/main/webapp/json/antispam.json b/verigraph/src/main/webapp/json/antispam.json
new file mode 100644 (file)
index 0000000..dae3db9
--- /dev/null
@@ -0,0 +1,11 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Antispam",
+    "description": "Polito Antispam",
+    "type": "array",
+    "items": {
+        "type": "string"
+    },
+    "minItems": 0,
+    "uniqueItems": true
+}
\ No newline at end of file
diff --git a/verigraph/src/main/webapp/json/cache.json b/verigraph/src/main/webapp/json/cache.json
new file mode 100644 (file)
index 0000000..0511e7b
--- /dev/null
@@ -0,0 +1,11 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Cache",
+    "description": "Polito Cache",
+    "type": "array",
+    "items": {
+        "type": "string"
+    },
+    "minItems": 0,
+    "uniqueItems": true
+}
\ No newline at end of file
diff --git a/verigraph/src/main/webapp/json/database.json b/verigraph/src/main/webapp/json/database.json
new file mode 100644 (file)
index 0000000..5b02a50
--- /dev/null
@@ -0,0 +1,5 @@
+[
+
+
+
+]
diff --git a/verigraph/src/main/webapp/json/dpi.json b/verigraph/src/main/webapp/json/dpi.json
new file mode 100644 (file)
index 0000000..6e4dd6f
--- /dev/null
@@ -0,0 +1,11 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Dpi",
+    "description": "Polito IDS",
+    "type": "array",
+    "items": {
+        "type": "string"
+    },
+    "minItems": 0,
+    "uniqueItems": true
+}
\ No newline at end of file
diff --git a/verigraph/src/main/webapp/json/endhost.json b/verigraph/src/main/webapp/json/endhost.json
new file mode 100644 (file)
index 0000000..37c8881
--- /dev/null
@@ -0,0 +1,42 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Endhost",
+    "description": "Polito Endhost",
+    "type": "array",
+    "items": {
+        "type": "object",
+        "properties": {
+            "body": {
+                "description": "HTTP body",
+                "type": "string"
+            },
+            "sequence": {
+                "description": "Sequence number",
+                "type": "integer"
+            },
+            "protocol": {
+                "description": "Protocol",
+                "type": "string",
+                "enum": ["HTTP_REQUEST", "HTTP_RESPONSE", "POP3_REQUEST", "POP3_RESPONSE"]
+            },
+            "email_from": {
+                "description": "E-mail sender",
+                "type": "string"
+            },
+            "url": {
+                "description": "URL",
+                "type": "string"
+            },
+            "options": {
+                "description": "Options",
+                "type": "string"
+            },
+            "destination": {
+                "description": "Destination node",
+                "type": "string"
+            }
+        },
+        "additionalProperties": false
+    },
+    "maxItems": 1
+}
\ No newline at end of file
diff --git a/verigraph/src/main/webapp/json/endpoint.json b/verigraph/src/main/webapp/json/endpoint.json
new file mode 100644 (file)
index 0000000..1e6a521
--- /dev/null
@@ -0,0 +1,9 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Endpoint",
+    "description": "Polito Endpoint",
+    "type": "array",
+    "minItems": 0,
+    "maxItems":0,
+    "uniqueItems": true
+}
\ No newline at end of file
diff --git a/verigraph/src/main/webapp/json/fieldmodifier.json b/verigraph/src/main/webapp/json/fieldmodifier.json
new file mode 100644 (file)
index 0000000..8be9419
--- /dev/null
@@ -0,0 +1,12 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Field Modifier",
+    "description": "Polito Field Modifier",
+    "type": "array",
+    "items": {
+        "type": "object"
+    },
+    "minItems": 0,
+    "maxItems":0,
+    "uniqueItems": true
+}
\ No newline at end of file
diff --git a/verigraph/src/main/webapp/json/firewall.json b/verigraph/src/main/webapp/json/firewall.json
new file mode 100644 (file)
index 0000000..01ec63f
--- /dev/null
@@ -0,0 +1,11 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Firewall",
+    "description": "Polito Firewall",
+    "type": "array",
+    "items": {
+        "type": "object"
+    },
+    "minItems": 0,
+    "uniqueItems": true
+}
\ No newline at end of file
diff --git a/verigraph/src/main/webapp/json/mailclient.json b/verigraph/src/main/webapp/json/mailclient.json
new file mode 100644 (file)
index 0000000..cacfd5f
--- /dev/null
@@ -0,0 +1,22 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Mail Client",
+    "description": "Polito Mail Client",
+    "type": "array",
+    "items": {
+        "type": "object",
+        "properties": {
+            "mailserver": {
+                "description": "Mail server name",
+                "type": "string"
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "mailserver"
+        ]
+    },
+    "minItems": 1,
+    "maxItems": 1,
+    "uniqueItems": true
+}
\ No newline at end of file
diff --git a/verigraph/src/main/webapp/json/mailserver.json b/verigraph/src/main/webapp/json/mailserver.json
new file mode 100644 (file)
index 0000000..974b560
--- /dev/null
@@ -0,0 +1,12 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Mail Server",
+    "description": "Polito Mail Server",
+    "type": "array",
+    "items": {
+        "type": "object"
+    },
+    "minItems": 0,
+    "maxItems": 0,
+    "uniqueItems": true
+}
\ No newline at end of file
diff --git a/verigraph/src/main/webapp/json/nat.json b/verigraph/src/main/webapp/json/nat.json
new file mode 100644 (file)
index 0000000..f2b973a
--- /dev/null
@@ -0,0 +1,11 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Nat",
+    "description": "Polito Nat",
+    "type": "array",
+    "items": {
+        "type": "string"
+    },
+    "minItems": 0,
+    "uniqueItems": true
+}
\ No newline at end of file
diff --git a/verigraph/src/main/webapp/json/vpnaccess.json b/verigraph/src/main/webapp/json/vpnaccess.json
new file mode 100644 (file)
index 0000000..907118d
--- /dev/null
@@ -0,0 +1,22 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Vpn Access",
+    "description": "Polito Vpn Access",
+    "type": "array",
+    "items": {
+        "type": "object",
+        "properties": {
+            "vpnexit": {
+                "description": "Vpn Exit",
+                "type": "string"
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "vpnexit"
+        ]
+    },
+    "minItems": 1,
+    "maxItems": 1,
+    "uniqueItems": true
+}
\ No newline at end of file
diff --git a/verigraph/src/main/webapp/json/vpnexit.json b/verigraph/src/main/webapp/json/vpnexit.json
new file mode 100644 (file)
index 0000000..c80a138
--- /dev/null
@@ -0,0 +1,22 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Vpn Exit",
+    "description": "Polito Vpn Exit",
+    "type": "array",
+    "items": {
+        "type": "object",
+        "properties": {
+            "vpnaccess": {
+                "description": "Vpn Access",
+                "type": "string"
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "vpnaccess"
+        ]
+    },
+    "minItems": 1,
+    "maxItems": 1,
+    "uniqueItems": true
+}
\ No newline at end of file
diff --git a/verigraph/src/main/webapp/json/webclient.json b/verigraph/src/main/webapp/json/webclient.json
new file mode 100644 (file)
index 0000000..dfbc55e
--- /dev/null
@@ -0,0 +1,22 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Web client",
+    "description": "Polito Web Client",
+    "type": "array",
+    "items": {
+        "type": "object",
+        "properties": {
+            "webserver": {
+                "description": "Web server name",
+                "type": "string"
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "webserver"
+        ]
+    },
+    "minItems": 1,
+    "maxItems": 1,
+    "uniqueItems": true
+}
\ No newline at end of file
diff --git a/verigraph/src/main/webapp/json/webserver.json b/verigraph/src/main/webapp/json/webserver.json
new file mode 100644 (file)
index 0000000..5d7a1c4
--- /dev/null
@@ -0,0 +1,12 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Web Server",
+    "description": "Polito Web Server",
+    "type": "array",
+    "items": {
+        "type": "object"
+    },
+    "minItems": 0,
+    "maxItems": 0,
+    "uniqueItems": true
+}
\ No newline at end of file
diff --git a/verigraph/target/m2e-wtp/web-resources/META-INF/MANIFEST.MF b/verigraph/target/m2e-wtp/web-resources/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..6cec037
--- /dev/null
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0\r
+Built-By: verigraph\r
+Build-Jdk: 1.8.0_121\r
+Created-By: Maven Integration for Eclipse\r
+\r
diff --git a/verigraph/target/m2e-wtp/web-resources/META-INF/maven/it.polito.escape/verify/pom.properties b/verigraph/target/m2e-wtp/web-resources/META-INF/maven/it.polito.escape/verify/pom.properties
new file mode 100644 (file)
index 0000000..0d84612
--- /dev/null
@@ -0,0 +1,7 @@
+#Generated by Maven Integration for Eclipse
+#Sat Feb 25 09:43:36 CET 2017
+version=0.0.1-SNAPSHOT
+groupId=it.polito.escape
+m2e.projectName=Verigraph4Parser
+m2e.projectLocation=/home/verigraph/workspace/Verigraph4Parser
+artifactId=verify
diff --git a/verigraph/target/m2e-wtp/web-resources/META-INF/maven/it.polito.escape/verify/pom.xml b/verigraph/target/m2e-wtp/web-resources/META-INF/maven/it.polito.escape/verify/pom.xml
new file mode 100644 (file)
index 0000000..cc211f1
--- /dev/null
@@ -0,0 +1,211 @@
+<!-- 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 http://www.apache.org/licenses/LICENSE-2.0 -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+       <modelVersion>4.0.0</modelVersion>
+
+       <groupId>it.polito.escape</groupId>
+       <artifactId>verify</artifactId>
+       <packaging>war</packaging>
+       <version>0.0.1-SNAPSHOT</version>
+       <name>verify</name>
+       <url>http://maven.apache.org</url>
+       <properties>
+               <grpc.version>1.0.3</grpc.version><!-- CURRENT_GRPC_VERSION -->
+               <jersey.version>2.22.1</jersey.version>
+               <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+       </properties>
+       <build>
+               <finalName>verify</finalName>
+               <extensions>
+                       <extension>
+                               <groupId>kr.motd.maven</groupId>
+                               <artifactId>os-maven-plugin</artifactId>
+                               <version>1.4.1.Final</version>
+                       </extension>
+               </extensions>
+               <plugins>
+                       <plugin>
+                               <groupId>org.xolstice.maven.plugins</groupId>
+                               <artifactId>protobuf-maven-plugin</artifactId>
+                               <version>0.5.0</version>
+                               <configuration>
+                                       <protocArtifact>com.google.protobuf:protoc:3.1.0:exe:${os.detected.classifier}</protocArtifact>
+                                       <pluginId>grpc-java</pluginId>
+                                       <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
+                               </configuration>
+                               <executions>
+                                       <execution>
+                                               <goals>
+                                                       <goal>compile</goal>
+                                                       <goal>compile-custom</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                               <version>2.5.1</version>
+                               <inherited>true</inherited>
+                               <configuration>
+                                       <source>1.8</source>
+                                       <target>1.8</target>
+                               </configuration>
+                       </plugin>
+               </plugins>
+               <pluginManagement>
+                       <plugins>
+                               <plugin>
+                                       <groupId>org.eclipse.m2e</groupId>
+                                       <artifactId>lifecycle-mapping</artifactId>
+                                       <version>1.0.0</version>
+                                       <configuration>
+                                               <lifecycleMappingMetadata>
+                                                       <pluginExecutions>
+                                                               <pluginExecution>
+                                                                       <pluginExecutionFilter>
+                                                                               <groupId>org.apache.maven.plugins</groupId>
+                                                                               <artifactId>maven-enforcer-plugin</artifactId>
+                                                                               <versionRange>[1.0.0,)</versionRange>
+                                                                               <goals>
+                                                                                       <goal>enforce</goal>
+                                                                               </goals>
+                                                                       </pluginExecutionFilter>
+                                                                       <action>
+                                                                               <ignore />
+                                                                       </action>
+                                                               </pluginExecution>
+                                                       </pluginExecutions>
+                                               </lifecycleMappingMetadata>
+                                       </configuration>
+                               </plugin>
+                       </plugins>
+               </pluginManagement>
+       </build>
+
+       <dependencyManagement>
+               <dependencies>
+                       <dependency>
+                               <groupId>org.glassfish.jersey</groupId>
+                               <artifactId>jersey-bom</artifactId>
+                               <version>${jersey.version}</version>
+                               <type>pom</type>
+                               <scope>import</scope>
+                       </dependency>
+               </dependencies>
+       </dependencyManagement>
+
+       <dependencies>
+               <dependency>
+                       <groupId>org.glassfish.jersey.containers</groupId>
+                       <artifactId>jersey-container-servlet-core</artifactId>
+                       <!-- use the following artifactId if you don't need servlet 2.x compatibility -->
+                       <!-- artifactId>jersey-container-servlet</artifactId -->
+               </dependency>
+
+               <dependency>
+                       <groupId>org.glassfish.jersey.bundles</groupId>
+                       <artifactId>jaxrs-ri</artifactId>
+               </dependency>
+
+               <!-- <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-moxy</artifactId> 
+                       </dependency> -->
+
+               <dependency>
+                       <groupId>org.glassfish.jersey.media</groupId>
+                       <artifactId>jersey-media-json-jackson</artifactId>
+               </dependency>
+
+               <dependency>
+                       <groupId>io.swagger</groupId>
+                       <artifactId>swagger-jersey2-jaxrs</artifactId>
+                       <version>1.5.0</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>com.googlecode.json-simple</groupId>
+                       <artifactId>json-simple</artifactId>
+                       <version>1.1</version>
+               </dependency>
+
+               <!-- added to retrieve server path -->
+               <!-- <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> 
+                       <version>3.1.0</version> <scope>provided</scope> </dependency> -->
+
+               <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
+               <dependency>
+                       <groupId>org.slf4j</groupId>
+                       <artifactId>slf4j-log4j12</artifactId>
+                       <version>1.5.6</version>
+               </dependency>
+
+
+               <dependency>
+                       <groupId>com.github.fge</groupId>
+                       <artifactId>json-schema-validator</artifactId>
+                       <version>2.2.6</version>
+               </dependency>
+
+               <!-- http://mvnrepository.com/artifact/org.json/json -->
+               <dependency>
+                       <groupId>org.json</groupId>
+                       <artifactId>json</artifactId>
+                       <version>20160212</version>
+               </dependency>
+
+               <!-- https://mvnrepository.com/artifact/junit/junit -->
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <version>4.12</version>
+               </dependency>
+
+
+               <dependency>
+                       <groupId>javax.servlet</groupId>
+                       <artifactId>javax.servlet-api</artifactId>
+                       <version>3.1.0</version>
+                       <scope>provided</scope>
+               </dependency>
+
+               <!-- here start dependencies for grpc -->
+               <dependency>
+                       <groupId>org.apache.thrift</groupId>
+                       <artifactId>libthrift</artifactId>
+                       <version>0.9.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>io.grpc</groupId>
+                       <artifactId>grpc-netty</artifactId>
+                       <version>${grpc.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>io.grpc</groupId>
+                       <artifactId>grpc-protobuf</artifactId>
+                       <version>${grpc.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>io.grpc</groupId>
+                       <artifactId>grpc-stub</artifactId>
+                       <version>${grpc.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.mockito</groupId>
+                       <artifactId>mockito-core</artifactId>
+                       <version>1.9.5</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>com.google.protobuf</groupId>
+                       <artifactId>protobuf-java</artifactId>
+                       <version>3.0.2</version>
+               </dependency>
+
+       </dependencies>
+
+</project>
diff --git a/verigraph/tester/README.rst b/verigraph/tester/README.rst
new file mode 100644 (file)
index 0000000..35396a3
--- /dev/null
@@ -0,0 +1,38 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+
+In order to run the automatic testing script test.py, you need the
+following dependencies installed on your python distribution:
+
+-  "requests" python package ->
+   http://docs.python-requests.org/en/master/
+-  "jsonschema" python package ->
+   https://pypi.python.org/pypi/jsonschema
+
+IMPORTANT - If you have multiple versions of Python installed on your
+machine, check carefully that the version you are actually using when
+running the script, has the required packages installed. Requested
+version is Python 3+
+
+| HINT - to install a package you can raise the following command (Bash
+  on Linux or DOS shell on Windows):
+| python -m pip install jsonschema
+| python -m pip install requests
+
+Tested on PYTHON 3.4.3
+
+To add a new test, just put a new .json file inside the testcases
+folder. The corresponding JSON schema is in the testcase\_schema.json
+file and some examples are already available. Each json file should
+specify:
+
+-  id, an integer for the testcase;
+-  name, the name for the testcase;
+-  description, an optional description;
+-  policy\_url\_parameters, the parameters to be appended after the
+   verification URL (including the '?' character);
+-  result, the expected verification result;
+-  graph, the graph to be tested (the same object that you usually POST
+   to VeriGraph to create a new graph).
+   The test.py script will test each .json file contained into the
+   testcases folder and will provide a complete output.
diff --git a/verigraph/tester/test.py b/verigraph/tester/test.py
new file mode 100644 (file)
index 0000000..ad0b82a
--- /dev/null
@@ -0,0 +1,115 @@
+#!/usr/bin/python
+
+##############################################################################
+# 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from __future__ import print_function
+from jsonschema import validate
+from pprint import pprint
+import sys
+import requests
+from requests.exceptions import *
+from jsonschema.exceptions import *
+import json
+import getopt
+import os
+import subprocess
+
+# Constants (change them, if appropriate)
+VERIGRAPH_PORT = "8080"
+TEST_CASES_DIR = "testcases"
+BASE_URL = "http://localhost:"+VERIGRAPH_PORT+"/verify/api/graphs/"
+SCHEMA_FILE = "testcase_schema.json"
+
+# Variables
+success = 0
+run = 0
+
+# Utils
+def eprint(toPrint):
+    sys.stdout.flush()
+    print(toPrint, file=sys.stderr)
+    sys.stderr.flush()
+
+# Print PYTHON ver
+print("PYTHON " + sys.version)
+
+# Loading schema file
+try:
+    schema = json.load(open(SCHEMA_FILE))
+except ValueError:
+    eprint("Invalid json schema (check your "+SCHEMA_FILE+")!\nExiting.")
+    exit(-1)
+
+# Iterate over .json files contained in the TEST_CASES_DIR
+for i in os.listdir(TEST_CASES_DIR):
+    if i.endswith(".json"): 
+        with open(TEST_CASES_DIR+os.path.sep+i) as data_file:
+            try:
+                # Load json file (raise exception if malformed)
+                data = json.load(data_file)
+
+                # Validate input json against schema (raise exception if invalid)
+                validate(data, schema)
+
+                run += 1
+                print("Test case ID: "+str(data["id"]))
+                print("\tFILE NAME: "+i)
+                print("\tTEST NAME: "+data["name"])
+                print("\tTEST DESCRIPTION: "+data["description"])
+
+                # POST the graph
+                r = requests.post(BASE_URL, json=data["graph"])
+                if r.status_code == 201:
+                    graph_id = r.json()["id"]
+                    print("\tCreated Graph has ID " + str(graph_id) + " on VeriGraph")
+
+                    # GET the policy verification result
+                    policy = requests.get(BASE_URL+str(graph_id)+"/policy"+data["policy_url_parameters"])
+
+                    # Check the response
+                    if policy.status_code == 200:
+                        print("\tVerification result is " + policy.json()["result"])
+
+                        # Check the result with the expected one
+                        if policy.json()["result"] == data["result"]:
+                            # SUCCESS
+                            print("\t+++ Test passed +++")
+                            success += 1
+                        else:
+                            # FAIL
+                            eprint("\t[ERROR] Expected result was " + data["result"] + " but VeriGraph returned " + policy.json()["result"])
+                            print("\t--- Test failed ---")
+                    else:
+                        print("\tVeriGraph returned an unexpected response -> " + str(policy.status_code), policy.reason)
+                        print("\t--- Test failed ---")
+                print()
+            except ValueError:
+                print("Malformed json!\nSkipping "+i+" file")
+                print("\t--- Test failed ---")
+            except ValidationError:
+                print("Invalid json (see Schema file)!\nSkipping "+i+" file")
+                print("\t--- Test failed ---")
+            except ConnectionError:
+                print("Connection refused!")
+                print("\t--- Test failed ---")
+            except HTTPError:
+                print("HTTP error!")
+                print("\t--- Test failed ---")
+
+# Final output
+print("\nTest run = "+str(run))
+print("Test succeded = "+str(success))
+if run != 0:
+    if success != run:
+        print("\n --- Some tests failed. See the output. ---")
+    else:
+        print("\n +++ All tests passed +++")
+else:
+    print("\n\n +++ 0 tests executed +++")
\ No newline at end of file
diff --git a/verigraph/tester/testcase_schema.json b/verigraph/tester/testcase_schema.json
new file mode 100644 (file)
index 0000000..b069705
--- /dev/null
@@ -0,0 +1,33 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Testcase",
+    "description": "A testcase for VeriGraph",
+    "type": "object",
+    "properties": {
+        "id": {
+            "description": "The unique identifier for a testcase",
+            "type": "integer"
+        },
+        "name": {
+            "description": "Name of the testcase",
+            "type": "string"
+        },
+        "description": {
+            "description": "A description for the testcase, specifying what is going to be tested",
+            "type": "string"
+        },
+        "policy_url_parameters": {
+            "description": "The set of parameters to be passed in GET request to the verification service",
+            "type": "string"
+        },
+        "result": {
+            "description": "The set of parameters to be passed in GET request to the verification service",
+            "type": "string"
+        },
+        "graph": {
+               "description": "The graph to be tested",
+               "type": "object"
+        }
+    },
+    "required": ["id", "name", "policy_url_parameters", "result", "graph"]
+}
\ No newline at end of file
diff --git a/verigraph/tester/testcases/test_budapest_sap1_webserver_sat.json b/verigraph/tester/testcases/test_budapest_sap1_webserver_sat.json
new file mode 100644 (file)
index 0000000..62b4eb5
--- /dev/null
@@ -0,0 +1,122 @@
+{
+   "id":6,
+   "name":"budapest_test_case_sat",
+   "description":"This test case verifies budapest scenario, chain sap1->webserver1",
+   "policy_url_parameters":"?type=reachability&source=sap1&destination=webserver1",
+   "result":"SAT",
+   "graph": {
+      "nodes":[
+         {
+            "neighbours":[
+               {
+                  "name":"webserver1"
+               },
+               {
+                  "name":"nat"
+               }
+            ],
+            "configuration":[
+               {
+                  "ip_sap1":"webserver1"
+               }
+            ],
+            "name":"fw",
+            "functional_type":"firewall"
+         },
+         {
+            "neighbours":[
+               {
+                  "name":"sap3"
+               },
+               {
+                  "name":"fw"
+               }
+            ],
+            "name":"webserver1",
+            "functional_type":"webserver"
+         },
+         {
+            "neighbours":[
+               {
+                  "name":"sap1"
+               },
+               {
+                  "name":"dpi"
+               },
+               {
+                  "name":"fw"
+               }
+            ],
+            "configuration":[
+               "sap1",
+               "sap2"
+            ],
+            "name":"nat",
+            "functional_type":"nat"
+         },
+         {
+            "neighbours":[
+               {
+                  "name":"sap2"
+               }
+            ],
+            "configuration":[
+               "drug"
+            ],
+            "name":"dpi",
+            "functional_type":"dpi"
+         },
+         {
+            "neighbours":[
+               {
+                  "name":"nat"
+               }
+            ],
+            "configuration":[
+               {
+                  "url":"www.facebook.com",
+                  "body":"cats",
+                  "destination":"webserver1",
+                  "protocol":"HTTP_REQUEST"
+               }
+            ],
+            "name":"sap2",
+            "functional_type":"endhost"
+         },
+         {
+            "neighbours":[
+               {
+                  "name":"nat"
+               }
+            ],
+            "configuration":[
+               {  
+                  "url":"www.facebook.com",
+                  "body":"cats",
+                  "destination":"webserver1",
+                  "protocol":"HTTP_REQUEST"
+               }
+            ],
+            "name":"sap1",
+            "functional_type":"endhost"
+         },
+         {
+            "neighbours":[
+               {
+                  "name":"webserver1"
+               }
+            ],
+            "configuration":[
+               {
+                  "url":"www.facebook.com",
+                  "body":"cats",
+                  "destination":"webserver1",
+                  "protocol":"HTTP_REQUEST"
+               }
+            ],
+            "name":"sap3",
+            "functional_type":"endhost"
+         }
+      ]
+   }
+}
\ No newline at end of file
diff --git a/verigraph/tester/testcases/test_budapest_sap1_webserver_unsat.json b/verigraph/tester/testcases/test_budapest_sap1_webserver_unsat.json
new file mode 100644 (file)
index 0000000..211b310
--- /dev/null
@@ -0,0 +1,122 @@
+{  
+   "id":7,
+   "name":"budapest_test_case_unsat",
+   "description":"This test case verifies budapest scenario, chain sap1->webserver1 with fw blocking",
+   "policy_url_parameters":"?type=reachability&source=sap1&destination=webserver1",
+   "result":"UNSAT",
+   "graph":{
+      "nodes":[
+         {
+            "neighbours":[
+               {
+                  "name":"webserver1"
+               },
+               {
+                  "name":"nat"
+               }
+            ],
+            "configuration":[
+               {
+                  "webserver1":"nat"
+               }
+            ],
+            "name":"fw",
+            "functional_type":"firewall"
+         },
+         {
+            "neighbours":[
+               {
+                  "name":"sap3"
+               },
+               {
+                  "name":"fw"
+               }
+            ],
+            "name":"webserver1",
+            "functional_type":"webserver"
+         },
+         {
+            "neighbours":[
+               {
+                  "name":"sap1"
+               },
+               {
+                  "name":"dpi"
+               },
+               {
+                  "name":"fw"
+               }
+            ],
+            "configuration":[
+               "sap1",
+               "sap2"
+            ],
+            "name":"nat",
+            "functional_type":"nat"
+         },
+         {
+            "neighbours":[
+               {
+                  "name":"sap2"
+               }
+            ],
+            "configuration":[
+               "drug"
+            ],
+            "name":"dpi",
+            "functional_type":"dpi"
+         },
+         {
+            "neighbours":[
+               {
+                  "name":"nat"
+               }
+            ],
+            "configuration":[
+               {
+                  "url":"www.facebook.com",
+                  "body":"cats",
+                  "destination":"webserver1",
+                  "protocol":"HTTP_REQUEST"
+               }
+            ],
+            "name":"sap2",
+            "functional_type":"endhost"
+         },
+         {
+            "neighbours":[
+               {
+                  "name":"nat"
+               }
+            ],
+            "configuration":[
+               {
+                  "url":"www.facebook.com",
+                  "body":"cats",
+                  "destination":"webserver1",
+                  "protocol":"HTTP_REQUEST"
+               }
+            ],
+            "name":"sap1",
+            "functional_type":"endhost"
+         },
+         {
+            "neighbours":[
+               {
+                  "name":"webserver1"
+               }
+            ],
+            "configuration":[
+               {
+                  "url":"www.facebook.com",
+                  "body":"cats",
+                  "destination":"webserver1",
+                  "protocol":"HTTP_REQUEST"
+               }
+            ],
+            "name":"sap3",
+            "functional_type":"endhost"
+         }
+      ]
+   }
+}
\ No newline at end of file
diff --git a/verigraph/tester/testcases/test_user_nat_dpi_webserver_trafficAllowed.json b/verigraph/tester/testcases/test_user_nat_dpi_webserver_trafficAllowed.json
new file mode 100644 (file)
index 0000000..8e19352
--- /dev/null
@@ -0,0 +1,59 @@
+{
+       "id": 2,
+       "name": "simple_test_case",
+       "description": "This test case contains a graph with client, firewall and server",
+       "policy_url_parameters": "?type=reachability&source=user1&destination=webserver",
+       "result": "SAT",
+       "graph": {
+          "nodes":[
+             {
+                "name":"user1",
+                "functional_type":"endhost",
+                "neighbours":[
+                   {
+                      "name":"nat"
+                   }
+                ],
+               "configuration": 
+                   [
+                                       {
+                                               "body": "cartoon",
+                                               "protocol": "HTTP_REQUEST",
+                                               "destination": "webserver"
+                                       }
+                   ]
+             },
+             {
+                "name":"nat",
+                "functional_type":"nat",
+                "neighbours":[
+                   {
+                      "name":"dpi"
+                   }
+                ],
+                "configuration":[
+                   "user1"
+                ]
+             },
+             {
+                "name":"dpi",
+                "functional_type":"dpi",
+                "neighbours":[
+                   {
+                      "name":"webserver"
+                   }
+                ],
+                "configuration":[
+                  "sex", "droga"
+                ]
+             },
+             {
+                "name":"webserver",
+                "functional_type":"webserver",
+                "neighbours":[
+       
+                ]
+             }
+          ]
+       }
+}
\ No newline at end of file
diff --git a/verigraph/tester/testcases/test_user_nat_dpi_webserver_trafficBlocked.json b/verigraph/tester/testcases/test_user_nat_dpi_webserver_trafficBlocked.json
new file mode 100644 (file)
index 0000000..285ecf2
--- /dev/null
@@ -0,0 +1,59 @@
+{
+       "id": 1,
+       "name": "simple_test_case",
+       "description": "This test case contains a graph with client, firewall and server",
+       "policy_url_parameters": "?type=reachability&source=user1&destination=webserver",
+       "result": "UNSAT",
+       "graph": {
+          "nodes":[
+             {
+                "name":"user1",
+                "functional_type":"endhost",
+                "neighbours":[
+                   {
+                      "name":"nat"
+                   }
+                ],
+               "configuration": 
+                   [
+                                       {
+                                               "body": "sex",
+                                               "protocol": "HTTP_REQUEST",
+                                               "destination": "webserver"
+                                       }
+                   ]
+             },
+             {
+                "name":"nat",
+                "functional_type":"nat",
+                "neighbours":[
+                   {
+                      "name":"dpi"
+                   }
+                ],
+                "configuration":[
+                   "user1"
+                ]
+             },
+             {
+                "name":"dpi",
+                "functional_type":"dpi",
+                "neighbours":[
+                   {
+                      "name":"webserver"
+                   }
+                ],
+                "configuration":[
+                  "sex", "droga"
+                ]
+             },
+             {
+                "name":"webserver",
+                "functional_type":"webserver",
+                "neighbours":[
+       
+                ]
+             }
+          ]
+       }
+}
\ No newline at end of file
diff --git a/verigraph/tester/testcases/test_user_nat_vpn_fieldmod_webserver_unsat.json b/verigraph/tester/testcases/test_user_nat_vpn_fieldmod_webserver_unsat.json
new file mode 100644 (file)
index 0000000..252e3b5
--- /dev/null
@@ -0,0 +1,94 @@
+{
+       "id": 4,
+       "name": "nat_vpn_with_fieldmodifier_test_case",
+       "description": "This test case contains a graph with client, nat, vpn (with field mod in between) and server",
+       "policy_url_parameters": "?type=reachability&source=user1&destination=webserver",
+       "result": "UNSAT",
+       "graph": {
+          "nodes":[
+             {
+                "name":"user1",
+                "functional_type":"endhost",
+                "neighbours":[
+                   {
+                      "name":"nat"
+                   }
+                ],
+               "configuration": 
+                   [
+                                       {
+                                               "body": "cartoon",
+                                               "protocol": "HTTP_REQUEST",
+                                               "destination": "webserver"
+                                       }
+                   ]
+             },
+             {
+                "name":"nat",
+                "functional_type":"nat",
+                "neighbours":[
+                   {
+                      "name":"user1"
+                   },
+                   {
+                      "name":"vpnaccess"
+                   }
+                ],
+                "configuration":[
+                   "user1"
+                ]
+             },
+             {
+                "name":"vpnaccess",
+                "functional_type":"vpnaccess",
+                "neighbours":[
+                       {
+                      "name":"nat"
+                   },
+                   {
+                      "name":"fieldmodifier"
+                   }
+                ],
+                "configuration":[
+                   {"vpnexit": "vpnexit"}
+                ]
+             },
+             {
+                "name":"fieldmodifier",
+                "functional_type":"fieldmodifier",
+                "neighbours":[
+                       {
+                      "name":"vpnaccess"
+                   },
+                   {
+                      "name":"vpnexit"
+                   }
+                ]
+             },
+             {
+                "name":"vpnexit",
+                "functional_type":"vpnexit",
+                "neighbours":[
+                   {
+                      "name":"fieldmodifier"
+                   },
+                   {
+                      "name":"webserver"
+                   }
+                ],
+                "configuration":[
+                   {"vpnaccess": "vpnaccess"}
+                ]
+             },
+             {
+                "name":"webserver",
+                "functional_type":"webserver",
+                "neighbours":[
+                       {
+                               "name": "vpnexit"
+                       }
+                ]
+             }
+          ]
+       }
+}
\ No newline at end of file
diff --git a/verigraph/tester/testcases/test_user_nat_vpn_webserver_sat.json b/verigraph/tester/testcases/test_user_nat_vpn_webserver_sat.json
new file mode 100644 (file)
index 0000000..2ae31bc
--- /dev/null
@@ -0,0 +1,82 @@
+{
+       "id": 3,
+       "name": "nat_vpn_test_case",
+       "description": "This test case contains a graph with client, nat, vpn and server",
+       "policy_url_parameters": "?type=reachability&source=user1&destination=webserver",
+       "result": "SAT",
+       "graph": {
+          "nodes":[
+             {
+                "name":"user1",
+                "functional_type":"endhost",
+                "neighbours":[
+                   {
+                      "name":"nat"
+                   }
+                ],
+               "configuration":
+                   [
+                                       {
+                                               "body": "cartoon",
+                                               "protocol": "HTTP_REQUEST",
+                                               "destination": "webserver"
+                                       }
+                   ]
+             },
+             {
+                "name":"nat",
+                "functional_type":"nat",
+                "neighbours":[
+                   {
+                      "name":"user1"
+                   },
+                   {
+                      "name":"vpnaccess"
+                   }
+                ],
+                "configuration":[
+                   "user1"
+                ]
+             },
+             {
+                "name":"vpnaccess",
+                "functional_type":"vpnaccess",
+                "neighbours":[
+                       {
+                      "name":"nat"
+                   },
+                   {
+                      "name":"vpnexit"
+                   }
+                ],
+                "configuration":[
+                   {"vpnexit": "vpnexit"}
+                ]
+             },
+             {
+                "name":"vpnexit",
+                "functional_type":"vpnexit",
+                "neighbours":[
+                   {
+                      "name":"vpnaccess"
+                   },
+                   {
+                      "name":"webserver"
+                   }
+                ],
+                "configuration":[
+                   {"vpnaccess": "vpnaccess"}
+                ]
+             },
+             {
+                "name":"webserver",
+                "functional_type":"webserver",
+                "neighbours":[
+                       {
+                               "name": "vpnexit"
+                       }
+                ]
+             }
+          ]
+       }
+}
\ No newline at end of file
diff --git a/verigraph/tester/testcases/test_webserver_vpn_nat_user_unsat.json b/verigraph/tester/testcases/test_webserver_vpn_nat_user_unsat.json
new file mode 100644 (file)
index 0000000..60d09b3
--- /dev/null
@@ -0,0 +1,82 @@
+{
+       "id": 5,
+       "name": "nat_vpn_test_case_serv_to_user",
+       "description": "This test case contains a graph with client, nat, vpn and server. webserver -> client",
+       "policy_url_parameters": "?type=reachability&source=webserver&destination=user1",
+       "result": "UNSAT",
+       "graph": {
+          "nodes":[
+             {
+                "name":"user1",
+                "functional_type":"endhost",
+                "neighbours":[
+                   {
+                      "name":"nat"
+                   }
+                ],
+               "configuration":
+                   [
+                                       {
+                                               "body": "cartoon",
+                                               "protocol": "HTTP_REQUEST",
+                                               "destination": "webserver"
+                                       }
+                   ]
+             },
+             {
+                "name":"nat",
+                "functional_type":"nat",
+                "neighbours":[
+                   {
+                      "name":"user1"
+                   },
+                   {
+                      "name":"vpnaccess"
+                   }
+                ],
+                "configuration":[
+                   "user1"
+                ]
+             },
+             {
+                "name":"vpnaccess",
+                "functional_type":"vpnaccess",
+                "neighbours":[
+                       {
+                      "name":"nat"
+                   },
+                   {
+                      "name":"vpnexit"
+                   }
+                ],
+                "configuration":[
+                   {"vpnexit": "vpnexit"}
+                ]
+             },
+             {
+                "name":"vpnexit",
+                "functional_type":"vpnexit",
+                "neighbours":[
+                   {
+                      "name":"vpnaccess"
+                   },
+                   {
+                      "name":"webserver"
+                   }
+                ],
+                "configuration":[
+                   {"vpnaccess": "vpnaccess"}
+                ]
+             },
+             {
+                "name":"webserver",
+                "functional_type":"webserver",
+                "neighbours":[
+                       {
+                               "name": "vpnexit"
+                       }
+                ]
+             }
+          ]
+       }
+}
\ No newline at end of file