From a42de79292d9541db7865b54e93be2d0b6e6a094 Mon Sep 17 00:00:00 2001 From: "serena.spinoso" Date: Thu, 7 Sep 2017 10:22:39 +0200 Subject: update verigraph JIRA: PARSER-154 code optimizations about graph manipulation and formula generation. Change-Id: Idebef19b128281aa2bc40d1aeab6e208c7ddd93d Signed-off-by: serena.spinoso --- .../it/polito/verigraph/service/NodeService.java | 223 +++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 verigraph/src/it/polito/verigraph/service/NodeService.java (limited to 'verigraph/src/it/polito/verigraph/service/NodeService.java') diff --git a/verigraph/src/it/polito/verigraph/service/NodeService.java b/verigraph/src/it/polito/verigraph/service/NodeService.java new file mode 100644 index 0000000..ffd6751 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/service/NodeService.java @@ -0,0 +1,223 @@ +/******************************************************************************* + * 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.verigraph.service; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.ws.rs.InternalServerErrorException; +import javax.xml.bind.JAXBException; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.github.fge.jsonschema.core.exceptions.ProcessingException; +import com.github.fge.jsonschema.main.JsonSchema; +import it.polito.neo4j.exceptions.MyInvalidIdException; +import it.polito.neo4j.exceptions.MyNotFoundException; +import it.polito.neo4j.manager.Neo4jDBManager; +import it.polito.verigraph.exception.BadRequestException; +import it.polito.verigraph.exception.DataNotFoundException; +import it.polito.verigraph.exception.ForbiddenException; +import it.polito.verigraph.model.Configuration; +import it.polito.verigraph.model.Graph; +import it.polito.verigraph.model.Neighbour; +import it.polito.verigraph.model.Node; + +public class NodeService { + + private Neo4jDBManager manager=new Neo4jDBManager(); + + public NodeService() {} + + public List getAllNodes(long graphId) throws JsonParseException, JsonMappingException, JAXBException, IOException, MyNotFoundException { + if (graphId < 0) { + throw new ForbiddenException("Illegal graph id: " + graphId); + } + + /*il controllo sull'esistenza del grafo viene fatto all'interno della getNodes + + */ + + Map nodes =manager.getNodes(graphId); + return new ArrayList(nodes.values()); + } + + public Node getNode(long graphId, long nodeId) throws JsonParseException, JsonMappingException, JAXBException, IOException, MyNotFoundException { + if (graphId < 0) { + throw new ForbiddenException("Illegal graph id: " + graphId); + } + if (nodeId < 0) { + throw new ForbiddenException("Illegal node id: " + nodeId); + } + + Node node=manager.getNodeById(nodeId, graphId); + 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) throws JAXBException, IOException, MyInvalidIdException { + if (graphId < 0) { + throw new ForbiddenException("Illegal graph id: " + graphId); + } + if (node.getId() < 0) { + throw new ForbiddenException("Illegal node id: " + node.getId()); + } + + Graph graph=manager.getGraph(graphId); + validateNode(graph, node); + + Node n=manager.updateNode(graphId, node, node.getId()); + validateNode(graph, n); + + return n; + } + + public Node removeNode(long graphId, long nodeId) throws JsonParseException, JsonMappingException, JAXBException, IOException { + if (graphId < 0) { + throw new ForbiddenException("Illegal graph id: " + graphId); + } + if (nodeId < 0) { + throw new ForbiddenException("Illegal node id: " + nodeId); + } + + Graph graph=manager.getGraph(graphId); + if (graph == null) + throw new DataNotFoundException("Graph with id " + graphId + " not found"); + Node n=manager.deleteNode(graphId, nodeId); + return n; + } + + public Node addNode(long graphId, Node node) throws JsonParseException, JsonMappingException, JAXBException, IOException, MyInvalidIdException { + if (graphId < 0) { + throw new ForbiddenException("Illegal graph id: " + graphId); + } + + Graph graph=manager.getGraph(graphId); + validateNode(graph, node); + Node n=manager.addNode(graphId, node); + validateNode(graph, n); + return n; + } + + public Node searchByName(long graphId, String nodeName) throws JsonParseException, JsonMappingException, JAXBException, IOException { + if (graphId < 0) { + throw new ForbiddenException("Illegal graph id: " + graphId); + } + Graph graph = manager.getGraph(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) throws JsonProcessingException { + 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/verigraph/jsonschema/" + schemaFileName); + + if (!schemaFile.exists()) { + //if no REST client, try gRPC application + schemaFile = new File(System.getProperty("user.dir") + "/jsonschema/" + 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()); + } + + } + + public Configuration addNodeConfiguration(long graphId, long nodeId, Configuration nodeConfiguration) throws IOException, MyInvalidIdException { + if (graphId < 0) { + throw new ForbiddenException("Illegal graph id: " + graphId); + } + if (nodeId < 0) { + throw new ForbiddenException("Illegal node id: " + nodeId); + } + + Node node=manager.getNodeById(nodeId, graphId); + validateNodeConfigurationAgainstSchemaFile(node, nodeConfiguration.getConfiguration()); + Configuration newConf=manager.updateConfiguration(nodeId, graphId, nodeConfiguration, node); + return newConf; + } +} \ No newline at end of file -- cgit 1.2.3-korg