summaryrefslogtreecommitdiffstats
path: root/verigraph/src
diff options
context:
space:
mode:
authorserena.spinoso <serena.spinoso@polito.it>2017-02-25 12:00:55 +0100
committerserena.spinoso <serena.spinoso@polito.it>2017-02-27 13:39:18 +0100
commit53d83244c1bf36af86e90ce5fe758a369f73563e (patch)
treef5780b3033763d6b3cd62c40f5d4a63dfac35f7a /verigraph/src
parentf0108f26fb1f62fefbbc4d5484b87241d563737b (diff)
Add verigraph code base
JIRA: PARSER-111 Change-Id: Ie76e14fabbb6c388ebc89d9a15dd3021b25fa892 Signed-off-by: serena.spinoso <serena.spinoso@polito.it>
Diffstat (limited to 'verigraph/src')
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/client/Neo4jManagerClient.java339
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/client/VerifyClient.java444
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/client/VerifyClientException.java24
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/database/DatabaseClass.java175
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/deserializer/ConfigurationCustomDeserializer.java42
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/deserializer/GraphCustomDeserializer.java87
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/deserializer/NodeCustomDeserializer.java92
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/deserializer/PathsMessageBodyReader.java52
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/exception/BadRequestException.java23
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/exception/BadRequestExceptionMapper.java30
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/exception/DataNotFoundException.java23
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/exception/DataNotFoundExceptionMapper.java30
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/exception/ForbiddenException.java23
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/exception/ForbiddenExceptionMapper.java30
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/exception/GenericExceptionMapper.java29
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/exception/InternalServerErrorException.java23
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/exception/InternalServerErrorExceptionMapper.java30
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/model/Configuration.java75
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/model/Entry.java37
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/model/ErrorMessage.java62
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/model/Graph.java105
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/model/Link.java71
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/model/Neighbour.java70
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/model/Node.java152
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/model/Test.java62
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/model/Verification.java69
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/model/jaxb.properties1
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/resources/GraphResource.java167
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/resources/NeighbourResource.java141
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/resources/NodeResource.java230
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/resources/beans/VerificationBean.java67
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/serializer/CustomConfigurationSerializer.java35
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/serializer/CustomMapSerializer.java30
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/service/GraphService.java129
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/service/JsonValidationService.java136
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/service/NeighbourService.java182
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/service/NodeService.java258
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/service/ValidationUtils.java132
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/service/VerificationService.java1185
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/test/MultiThreadedTestCase.java201
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/test/Scalability.java409
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/test/TestCase.java161
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/test/TestExecutionException.java24
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/test/Tester.java220
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/validation/DpiValidator.java45
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/validation/EndhostValidator.java25
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/validation/ValidationInterface.java21
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/validation/VpnaccessValidator.java51
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/validation/VpnexitValidator.java51
-rw-r--r--verigraph/src/main/java/it/polito/escape/verify/validation/exception/ValidationException.java31
-rw-r--r--verigraph/src/main/java/it/polito/grpc/Client.java550
-rw-r--r--verigraph/src/main/java/it/polito/grpc/GrpcUtils.java156
-rw-r--r--verigraph/src/main/java/it/polito/grpc/README.rst442
-rw-r--r--verigraph/src/main/java/it/polito/grpc/Service.java462
-rw-r--r--verigraph/src/main/java/it/polito/grpc/test/GrpcServerTest.java292
-rw-r--r--verigraph/src/main/java/it/polito/grpc/test/GrpcTest.java349
-rw-r--r--verigraph/src/main/java/it/polito/grpc/test/MultiThreadTest.java220
-rw-r--r--verigraph/src/main/java/it/polito/grpc/test/ReachabilityTest.java252
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ActionEnumType.java59
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ActionType.java81
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ActionsType.java67
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CiType.java206
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CpType.java86
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CpointsType.java67
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CtrlInterfacesType.java67
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpCpType.java89
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpType.java260
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpointsType.java65
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpsCpsType.java67
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/FlowrulesType.java619
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/HttpMessage.java108
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/MonParamsType.java122
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NeType.java133
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NelementsType.java67
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NfType.java181
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/Nffg.java183
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NffgSet.java69
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NfunctionsType.java67
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ObjectFactory.java319
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/Paths.java163
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/PortDirEnumType.java60
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/PortType.java104
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/Property.java152
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/SpecType.java577
-rw-r--r--verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/package-info.java11
-rw-r--r--verigraph/src/main/proto/verigraph.proto154
-rw-r--r--verigraph/src/main/schema/net_types.xsd62
-rw-r--r--verigraph/src/main/schema/nffg.xsd363
-rw-r--r--verigraph/src/main/webapp/json/antispam.json11
-rw-r--r--verigraph/src/main/webapp/json/cache.json11
-rw-r--r--verigraph/src/main/webapp/json/database.json5
-rw-r--r--verigraph/src/main/webapp/json/dpi.json11
-rw-r--r--verigraph/src/main/webapp/json/endhost.json42
-rw-r--r--verigraph/src/main/webapp/json/endpoint.json9
-rw-r--r--verigraph/src/main/webapp/json/fieldmodifier.json12
-rw-r--r--verigraph/src/main/webapp/json/firewall.json11
-rw-r--r--verigraph/src/main/webapp/json/mailclient.json22
-rw-r--r--verigraph/src/main/webapp/json/mailserver.json12
-rw-r--r--verigraph/src/main/webapp/json/nat.json11
-rw-r--r--verigraph/src/main/webapp/json/vpnaccess.json22
-rw-r--r--verigraph/src/main/webapp/json/vpnexit.json22
-rw-r--r--verigraph/src/main/webapp/json/webclient.json22
-rw-r--r--verigraph/src/main/webapp/json/webserver.json12
103 files changed, 13717 insertions, 0 deletions
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
index 0000000..044c136
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/client/Neo4jManagerClient.java
@@ -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
index 0000000..1997553
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/client/VerifyClient.java
@@ -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
index 0000000..d91d31e
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/client/VerifyClientException.java
@@ -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
index 0000000..7837e51
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/database/DatabaseClass.java
@@ -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
index 0000000..5cdd084
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/deserializer/ConfigurationCustomDeserializer.java
@@ -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
index 0000000..f71c996
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/deserializer/GraphCustomDeserializer.java
@@ -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
index 0000000..fb451db
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/deserializer/NodeCustomDeserializer.java
@@ -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
index 0000000..3b54503
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/deserializer/PathsMessageBodyReader.java
@@ -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
index 0000000..abbdbf0
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/exception/BadRequestException.java
@@ -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
index 0000000..8f1ba9c
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/exception/BadRequestExceptionMapper.java
@@ -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
index 0000000..5cd1806
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/exception/DataNotFoundException.java
@@ -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
index 0000000..62e3556
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/exception/DataNotFoundExceptionMapper.java
@@ -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
index 0000000..dc79e97
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/exception/ForbiddenException.java
@@ -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
index 0000000..d060b8b
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/exception/ForbiddenExceptionMapper.java
@@ -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
index 0000000..96f7caa
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/exception/GenericExceptionMapper.java
@@ -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
index 0000000..877edb5
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/exception/InternalServerErrorException.java
@@ -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
index 0000000..02b6765
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/exception/InternalServerErrorExceptionMapper.java
@@ -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
index 0000000..3498a10
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/model/Configuration.java
@@ -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
index 0000000..f2fdf14
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/model/Entry.java
@@ -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
index 0000000..e0e79d3
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/model/ErrorMessage.java
@@ -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
index 0000000..44a2273
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/model/Graph.java
@@ -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
index 0000000..dc2b4c5
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/model/Link.java
@@ -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
index 0000000..4b1206c
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/model/Neighbour.java
@@ -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
index 0000000..9f667ce
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/model/Node.java
@@ -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
index 0000000..1127abc
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/model/Test.java
@@ -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
index 0000000..60b4ddb
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/model/Verification.java
@@ -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
index 0000000..5837a4c
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/model/jaxb.properties
@@ -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
index 0000000..e610f1d
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/resources/GraphResource.java
@@ -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
index 0000000..63376da
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/resources/NeighbourResource.java
@@ -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
index 0000000..58d4064
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/resources/NodeResource.java
@@ -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
index 0000000..d6f9ca6
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/resources/beans/VerificationBean.java
@@ -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
index 0000000..e28273f
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/serializer/CustomConfigurationSerializer.java
@@ -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
index 0000000..e811365
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/serializer/CustomMapSerializer.java
@@ -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
index 0000000..b34eb08
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/service/GraphService.java
@@ -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
index 0000000..1ac6c1f
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/service/JsonValidationService.java
@@ -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
index 0000000..ecf4e69
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/service/NeighbourService.java
@@ -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
index 0000000..e6ad672
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/service/NodeService.java
@@ -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
index 0000000..77ef4f7
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/service/ValidationUtils.java
@@ -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
index 0000000..1d31ae9
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/service/VerificationService.java
@@ -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
index 0000000..7989b37
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/test/MultiThreadedTestCase.java
@@ -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
index 0000000..3039ca0
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/test/Scalability.java
@@ -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
index 0000000..a4c85ab
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/test/TestCase.java
@@ -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
index 0000000..8babe7b
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/test/TestExecutionException.java
@@ -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
index 0000000..4b85e1e
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/test/Tester.java
@@ -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
index 0000000..2666755
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/validation/DpiValidator.java
@@ -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
index 0000000..3d9eb75
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/validation/EndhostValidator.java
@@ -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
index 0000000..25608dd
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/validation/ValidationInterface.java
@@ -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
index 0000000..6abd603
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/validation/VpnaccessValidator.java
@@ -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
index 0000000..782e124
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/validation/VpnexitValidator.java
@@ -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
index 0000000..8b94748
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/escape/verify/validation/exception/ValidationException.java
@@ -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
index 0000000..adc16da
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/grpc/Client.java
@@ -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
index 0000000..0ed002c
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/grpc/GrpcUtils.java
@@ -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
index 0000000..d089908
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/grpc/README.rst
@@ -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’s 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
index 0000000..8a77d05
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/grpc/Service.java
@@ -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
index 0000000..7344447
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/grpc/test/GrpcServerTest.java
@@ -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
index 0000000..41f9cad
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/grpc/test/GrpcTest.java
@@ -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
index 0000000..5b76bea
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/grpc/test/MultiThreadTest.java
@@ -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
index 0000000..a120aff
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/grpc/test/ReachabilityTest.java
@@ -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
index 0000000..e7504b5
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ActionEnumType.java
@@ -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
index 0000000..db86975
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ActionType.java
@@ -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
index 0000000..5b81ae7
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ActionsType.java
@@ -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
index 0000000..9a82728
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CiType.java
@@ -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
index 0000000..4a67b79
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CpType.java
@@ -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
index 0000000..4c820ed
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CpointsType.java
@@ -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
index 0000000..02ad675
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/CtrlInterfacesType.java
@@ -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
index 0000000..a9448c1
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpCpType.java
@@ -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
index 0000000..2ae875d
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpType.java
@@ -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
index 0000000..850d8b6
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpointsType.java
@@ -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
index 0000000..181085e
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/EpsCpsType.java
@@ -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
index 0000000..53c8f79
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/FlowrulesType.java
@@ -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
index 0000000..5dc7c29
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/HttpMessage.java
@@ -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
index 0000000..8651966
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/MonParamsType.java
@@ -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
index 0000000..9cdecdd
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NeType.java
@@ -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
index 0000000..0ccef60
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NelementsType.java
@@ -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
index 0000000..f2b50ea
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NfType.java
@@ -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
index 0000000..54e6daf
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/Nffg.java
@@ -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
index 0000000..8fdc137
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NffgSet.java
@@ -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
index 0000000..7b26ac3
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/NfunctionsType.java
@@ -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
index 0000000..1c7c7f5
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/ObjectFactory.java
@@ -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
index 0000000..f097b30
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/Paths.java
@@ -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
index 0000000..f98907d
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/PortDirEnumType.java
@@ -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
index 0000000..4d44cf5
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/PortType.java
@@ -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
index 0000000..973eaf8
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/Property.java
@@ -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
index 0000000..e4d434b
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/SpecType.java
@@ -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
index 0000000..3d3c7b4
--- /dev/null
+++ b/verigraph/src/main/java/it/polito/nffg/neo4j/jaxb/package-info.java
@@ -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
index 0000000..5f77c78
--- /dev/null
+++ b/verigraph/src/main/proto/verigraph.proto
@@ -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
index 0000000..c99c7a6
--- /dev/null
+++ b/verigraph/src/main/schema/net_types.xsd
@@ -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
index 0000000..77e6f40
--- /dev/null
+++ b/verigraph/src/main/schema/nffg.xsd
@@ -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
index 0000000..dae3db9
--- /dev/null
+++ b/verigraph/src/main/webapp/json/antispam.json
@@ -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
index 0000000..0511e7b
--- /dev/null
+++ b/verigraph/src/main/webapp/json/cache.json
@@ -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
index 0000000..5b02a50
--- /dev/null
+++ b/verigraph/src/main/webapp/json/database.json
@@ -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
index 0000000..6e4dd6f
--- /dev/null
+++ b/verigraph/src/main/webapp/json/dpi.json
@@ -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
index 0000000..37c8881
--- /dev/null
+++ b/verigraph/src/main/webapp/json/endhost.json
@@ -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
index 0000000..1e6a521
--- /dev/null
+++ b/verigraph/src/main/webapp/json/endpoint.json
@@ -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
index 0000000..8be9419
--- /dev/null
+++ b/verigraph/src/main/webapp/json/fieldmodifier.json
@@ -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
index 0000000..01ec63f
--- /dev/null
+++ b/verigraph/src/main/webapp/json/firewall.json
@@ -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
index 0000000..cacfd5f
--- /dev/null
+++ b/verigraph/src/main/webapp/json/mailclient.json
@@ -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
index 0000000..974b560
--- /dev/null
+++ b/verigraph/src/main/webapp/json/mailserver.json
@@ -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
index 0000000..f2b973a
--- /dev/null
+++ b/verigraph/src/main/webapp/json/nat.json
@@ -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
index 0000000..907118d
--- /dev/null
+++ b/verigraph/src/main/webapp/json/vpnaccess.json
@@ -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
index 0000000..c80a138
--- /dev/null
+++ b/verigraph/src/main/webapp/json/vpnexit.json
@@ -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
index 0000000..dfbc55e
--- /dev/null
+++ b/verigraph/src/main/webapp/json/webclient.json
@@ -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
index 0000000..5d7a1c4
--- /dev/null
+++ b/verigraph/src/main/webapp/json/webserver.json
@@ -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