2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.onap.aai.serialization.db;
22 import java.util.EnumMap;
24 import java.util.Optional;
25 import java.util.UUID;
26 import java.util.Map.Entry;
28 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
29 import org.apache.tinkerpop.gremlin.structure.Direction;
30 import org.apache.tinkerpop.gremlin.structure.Edge;
31 import org.apache.tinkerpop.gremlin.structure.Vertex;
32 import org.onap.aai.db.props.AAIProperties;
33 import org.onap.aai.edges.EdgeIngestor;
34 import org.onap.aai.edges.EdgeRule;
35 import org.onap.aai.edges.EdgeRuleQuery;
36 import org.onap.aai.edges.enums.EdgeField;
37 import org.onap.aai.edges.enums.EdgeProperty;
38 import org.onap.aai.edges.enums.EdgeType;
39 import org.onap.aai.edges.enums.MultiplicityRule;
40 import org.onap.aai.edges.exceptions.AmbiguousRuleChoiceException;
41 import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
42 import org.onap.aai.exceptions.AAIException;
43 import org.onap.aai.serialization.db.exceptions.EdgeMultiplicityException;
44 import org.onap.aai.serialization.db.exceptions.MultipleEdgeRuleFoundException;
45 import org.onap.aai.serialization.db.exceptions.NoEdgeRuleFoundException;
46 import org.springframework.beans.factory.annotation.Autowired;
47 import org.springframework.stereotype.Component;
50 public class EdgeSerializer {
53 private EdgeIngestor edgerules;
55 public EdgeSerializer(EdgeIngestor ei) {
62 * @param aVertex the out vertex
63 * @param bVertex the in vertex
65 * @throws AAIException the AAI exception
67 public Edge addTreeEdge(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex) throws AAIException {
68 return this.addEdge(EdgeType.TREE, traversalSource, aVertex, bVertex, false, null);
74 * @param aVertex the out vertex
75 * @param bVertex the in vertex
77 * @throws AAIException the AAI exception
79 public Edge addEdge(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex) throws AAIException {
80 return this.addEdge(traversalSource, aVertex, bVertex, null);
83 public Edge addEdge(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex, String label) throws AAIException {
84 return this.addEdge(EdgeType.COUSIN, traversalSource, aVertex, bVertex, false, label);
87 public Edge addPrivateEdge(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex, String label) throws AAIException, EdgeRuleNotFoundException, AmbiguousRuleChoiceException {
88 return this.addEdge(EdgeType.COUSIN, traversalSource, aVertex, bVertex, false, label, true);
91 private Edge addEdge(EdgeType type, GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex, boolean isBestEffort, String label, boolean isPrivateEdge) throws AAIException, EdgeRuleNotFoundException, AmbiguousRuleChoiceException {
95 String aType = aVertex.<String>property(AAIProperties.NODE_TYPE).orElse(null);
96 String bType = bVertex.<String>property(AAIProperties.NODE_TYPE).orElse(null);
97 EdgeRuleQuery edgeQuery = new EdgeRuleQuery.Builder(aType, bType).label(label).setPrivate(isPrivateEdge).build();
99 rule = edgerules.getRule(edgeQuery);
101 if(rule.isPrivateEdge() != isPrivateEdge){
107 Optional<String> message = this.validateMultiplicity(rule, traversalSource, aVertex, bVertex);
109 if (message.isPresent() && !isBestEffort) {
110 throw new EdgeMultiplicityException(message.get());
112 if (!message.isPresent()) {
113 if (rule.getDirection().equals(Direction.OUT)) {
114 e = aVertex.addEdge(rule.getLabel(), bVertex);
115 } else if (rule.getDirection().equals(Direction.IN)) {
116 e = bVertex.addEdge(rule.getLabel(), aVertex);
119 this.addProperties(e, rule);
125 * Adds the tree edge.
127 * @param aVertex the out vertex
128 * @param bVertex the in vertex
130 * @throws AAIException the AAI exception
132 public Edge addTreeEdgeIfPossible(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex) throws AAIException {
133 return this.addEdge(EdgeType.TREE, traversalSource, aVertex, bVertex, true, null);
139 * @param aVertex the out vertex
140 * @param bVertex the in vertex
142 * @throws AAIException the AAI exception
144 public Edge addEdgeIfPossible(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex) throws AAIException {
145 return this.addEdgeIfPossible(traversalSource, aVertex, bVertex, null);
148 public Edge addEdgeIfPossible(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex, String label) throws AAIException {
149 return this.addEdge(EdgeType.COUSIN, traversalSource, aVertex, bVertex, true, label);
155 * @param type the type
156 * @param aVertex the out vertex
157 * @param bVertex the in vertex
159 * @throws AAIException the AAI exception
161 private Edge addEdge(EdgeType type, GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex, boolean isBestEffort, String label) throws AAIException {
162 String aNodeType = (String)aVertex.property(AAIProperties.NODE_TYPE).value();
163 String bNodeType = (String)bVertex.property(AAIProperties.NODE_TYPE).value();
164 EdgeRuleQuery q = new EdgeRuleQuery.Builder(aNodeType, bNodeType).label(label).edgeType(type).build();
167 rule = edgerules.getRule(q);
168 } catch (EdgeRuleNotFoundException e1) {
169 throw new NoEdgeRuleFoundException(e1);
170 } catch (AmbiguousRuleChoiceException e1) {
171 throw new MultipleEdgeRuleFoundException(e1);
176 Optional<String> message = this.validateMultiplicity(rule, traversalSource, aVertex, bVertex);
178 if (message.isPresent() && !isBestEffort) {
179 throw new EdgeMultiplicityException(message.get());
181 if (!message.isPresent()) {
182 if (rule.getDirection().equals(Direction.OUT)) {
183 e = aVertex.addEdge(rule.getLabel(), bVertex);
184 } else if (rule.getDirection().equals(Direction.IN)) {
185 e = bVertex.addEdge(rule.getLabel(), aVertex);
188 this.addProperties(e, rule);
194 * Adds the properties.
196 * @param edge the edge
197 * @param rule the rule
199 public void addProperties(Edge edge, EdgeRule rule) {
200 Map<EdgeProperty, String> propMap = new EnumMap<>(EdgeProperty.class);
201 propMap.put(EdgeProperty.CONTAINS, rule.getContains());
202 propMap.put(EdgeProperty.DELETE_OTHER_V, rule.getDeleteOtherV());
203 propMap.put(EdgeProperty.PREVENT_DELETE, rule.getPreventDelete());
205 for (Entry<EdgeProperty, String> entry : propMap.entrySet()) {
206 edge.property(entry.getKey().toString(), entry.getValue());
209 edge.property(EdgeField.PRIVATE.toString(), rule.isPrivateEdge());
210 edge.property(AAIProperties.AAI_UUID, UUID.randomUUID().toString());
214 * Validate multiplicity.
216 * @param rule the rule
217 * @param aVertex the out vertex
218 * @param bVertex the in vertex
219 * @return true, if successful
220 * @throws AAIException the AAI exception
222 private Optional<String> validateMultiplicity(EdgeRule rule, GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex) {
227 if (rule.getDirection().equals(Direction.OUT)) {
230 } else if (rule.getDirection().equals(Direction.IN)) {
235 String aVertexType = a.<String>property(AAIProperties.NODE_TYPE).orElse(null);
236 String bVertexType = b.<String>property(AAIProperties.NODE_TYPE).orElse(null);
237 String label = rule.getLabel();
239 MultiplicityRule multiplicityRule = rule.getMultiplicityRule();
242 final String msg = "multiplicity rule violated: only one edge can exist with label: ";
244 if (multiplicityRule.equals(MultiplicityRule.ONE2ONE)) {
245 Long outEdgesCnt = traversalSource.V(a).out(label).has(AAIProperties.NODE_TYPE, bVertexType).count().next();
246 Long inEdgesCnt = traversalSource.V(b).in(label).has(AAIProperties.NODE_TYPE, aVertexType).count().next();
247 if (aVertexType.equals(bVertexType)) {
248 inEdgesCnt = inEdgesCnt + traversalSource.V(a).in(label).has(AAIProperties.NODE_TYPE, aVertexType).count().next();
249 outEdgesCnt = outEdgesCnt + traversalSource.V(b).out(label).has(AAIProperties.NODE_TYPE, bVertexType).count().next();
251 if ( (inEdgesCnt != 0) || (outEdgesCnt != 0) ) {
252 detail = msg + label + " between " + aVertexType + " and " + bVertexType;
254 } else if (multiplicityRule.equals(MultiplicityRule.ONE2MANY)) {
255 Long inEdgesCnt = traversalSource.V(b).in(label).has(AAIProperties.NODE_TYPE, aVertexType).count().next();
256 if (inEdgesCnt != 0) {
257 detail = msg + label + " between " + aVertexType + " and " + bVertexType;
259 } else if (multiplicityRule.equals(MultiplicityRule.MANY2ONE)) {
260 Long outEdgesCnt = traversalSource.V(a).out(label).has(AAIProperties.NODE_TYPE, bVertexType).count().next();
261 if (outEdgesCnt != 0) {
262 detail = msg + label + " between " + aVertexType + " and " + bVertexType;
266 if (!"".equals(detail)) {
267 return Optional.of(detail);
269 return Optional.empty();