From 53d83244c1bf36af86e90ce5fe758a369f73563e Mon Sep 17 00:00:00 2001 From: "serena.spinoso" Date: Sat, 25 Feb 2017 12:00:55 +0100 Subject: Add verigraph code base JIRA: PARSER-111 Change-Id: Ie76e14fabbb6c388ebc89d9a15dd3021b25fa892 Signed-off-by: serena.spinoso --- .../polito/escape/verify/service/NodeService.java | 258 +++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 verigraph/src/main/java/it/polito/escape/verify/service/NodeService.java (limited to 'verigraph/src/main/java/it/polito/escape/verify/service/NodeService.java') 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 graphs = DatabaseClass.getInstance().getGraphs(); + + public NodeService() { + + } + + public List 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 nodes = graph.getNodes(); + return new ArrayList(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 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 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(graph.getNodes())); + graphCopy.getNodes().remove(node.getId()); + + // int numberOfNeighbours = 0; + // for(Neighbour neighbour : node.getNeighbours().values()){ + // neighbour.setId(++numberOfNeighbours); + // } + + for (Map.Entry 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 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 nodes = graph.getNodes(); + + validateNode(graph, node); + + synchronized (this) { + node.setId(DatabaseClass.getInstance().getGraphNumberOfNodes(graphId) + 1); + } + + // int numberOfNeighbours = 0; + + for (Map.Entry 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 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 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()); + + } + + } +} -- cgit 1.2.3-korg