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=========================================================
21 package org.onap.aai.serialization.db;
23 import java.util.EnumMap;
25 import java.util.Map.Entry;
26 import java.util.Optional;
27 import java.util.UUID;
29 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
30 import org.apache.tinkerpop.gremlin.structure.Direction;
31 import org.apache.tinkerpop.gremlin.structure.Edge;
32 import org.apache.tinkerpop.gremlin.structure.Vertex;
33 import org.onap.aai.db.props.AAIProperties;
34 import org.onap.aai.edges.EdgeIngestor;
35 import org.onap.aai.edges.EdgeRule;
36 import org.onap.aai.edges.EdgeRuleQuery;
37 import org.onap.aai.edges.enums.EdgeField;
38 import org.onap.aai.edges.enums.EdgeProperty;
39 import org.onap.aai.edges.enums.EdgeType;
40 import org.onap.aai.edges.enums.MultiplicityRule;
41 import org.onap.aai.edges.exceptions.AmbiguousRuleChoiceException;
42 import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
43 import org.onap.aai.exceptions.AAIException;
44 import org.onap.aai.serialization.db.exceptions.EdgeMultiplicityException;
45 import org.onap.aai.serialization.db.exceptions.MultipleEdgeRuleFoundException;
46 import org.onap.aai.serialization.db.exceptions.NoEdgeRuleFoundException;
47 import org.springframework.beans.factory.annotation.Autowired;
48 import org.springframework.stereotype.Component;
51 public class EdgeSerializer {
54 private EdgeIngestor edgerules;
56 public EdgeSerializer(EdgeIngestor ei) {
63 * @param aVertex the out vertex
64 * @param bVertex the in vertex
66 * @throws AAIException the AAI exception
68 public Edge addTreeEdge(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex) throws AAIException {
69 return this.addEdge(EdgeType.TREE, traversalSource, aVertex, bVertex, false, null);
75 * @param aVertex the out vertex
76 * @param bVertex the in vertex
78 * @throws AAIException the AAI exception
80 public Edge addEdge(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex) throws AAIException {
81 return this.addEdge(traversalSource, aVertex, bVertex, null);
84 public Edge addEdge(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex, String label)
86 return this.addEdge(EdgeType.COUSIN, traversalSource, aVertex, bVertex, false, label);
89 public Edge addPrivateEdge(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex, String label)
90 throws AAIException, EdgeRuleNotFoundException, AmbiguousRuleChoiceException {
91 return this.addEdge(EdgeType.COUSIN, traversalSource, aVertex, bVertex, false, label, true);
94 private Edge addEdge(EdgeType type, GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex,
95 boolean isBestEffort, String label, boolean isPrivateEdge)
96 throws AAIException, EdgeRuleNotFoundException, AmbiguousRuleChoiceException {
100 String aType = aVertex.<String>property(AAIProperties.NODE_TYPE).orElse(null);
101 String bType = bVertex.<String>property(AAIProperties.NODE_TYPE).orElse(null);
102 EdgeRuleQuery edgeQuery =
103 new EdgeRuleQuery.Builder(aType, bType).label(label).setPrivate(isPrivateEdge).build();
105 rule = edgerules.getRule(edgeQuery);
107 if (rule.isPrivateEdge() != isPrivateEdge) {
113 Optional<String> message = this.validateMultiplicity(rule, traversalSource, aVertex, bVertex);
115 if (message.isPresent() && !isBestEffort) {
116 throw new EdgeMultiplicityException(message.get());
118 if (!message.isPresent()) {
119 if (rule.getDirection().equals(Direction.OUT)) {
120 e = aVertex.addEdge(rule.getLabel(), bVertex);
121 } else if (rule.getDirection().equals(Direction.IN)) {
122 e = bVertex.addEdge(rule.getLabel(), aVertex);
125 this.addProperties(e, rule);
131 * Adds the tree edge.
133 * @param aVertex the out vertex
134 * @param bVertex the in vertex
136 * @throws AAIException the AAI exception
138 public Edge addTreeEdgeIfPossible(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex)
139 throws AAIException {
140 return this.addEdge(EdgeType.TREE, traversalSource, aVertex, bVertex, true, null);
146 * @param aVertex the out vertex
147 * @param bVertex the in vertex
149 * @throws AAIException the AAI exception
151 public Edge addEdgeIfPossible(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex)
152 throws AAIException {
153 return this.addEdgeIfPossible(traversalSource, aVertex, bVertex, null);
156 public Edge addEdgeIfPossible(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex, String label)
157 throws AAIException {
158 return this.addEdge(EdgeType.COUSIN, traversalSource, aVertex, bVertex, true, label);
164 * @param type the type
165 * @param aVertex the out vertex
166 * @param bVertex the in vertex
168 * @throws AAIException the AAI exception
170 private Edge addEdge(EdgeType type, GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex,
171 boolean isBestEffort, String label) throws AAIException {
172 String aNodeType = (String) aVertex.property(AAIProperties.NODE_TYPE).value();
173 String bNodeType = (String) bVertex.property(AAIProperties.NODE_TYPE).value();
174 EdgeRuleQuery q = new EdgeRuleQuery.Builder(aNodeType, bNodeType).label(label).edgeType(type).build();
177 rule = edgerules.getRule(q);
178 } catch (EdgeRuleNotFoundException e1) {
179 throw new NoEdgeRuleFoundException(e1);
180 } catch (AmbiguousRuleChoiceException e1) {
181 throw new MultipleEdgeRuleFoundException(e1);
186 Optional<String> message = this.validateMultiplicity(rule, traversalSource, aVertex, bVertex);
188 if (message.isPresent() && !isBestEffort) {
189 throw new EdgeMultiplicityException(message.get());
191 if (!message.isPresent()) {
192 if (rule.getDirection().equals(Direction.OUT)) {
193 e = aVertex.addEdge(rule.getLabel(), bVertex);
194 } else if (rule.getDirection().equals(Direction.IN)) {
195 e = bVertex.addEdge(rule.getLabel(), aVertex);
198 this.addProperties(e, rule);
204 * Adds the properties.
206 * @param edge the edge
207 * @param rule the rule
209 public void addProperties(Edge edge, EdgeRule rule) {
210 Map<EdgeProperty, String> propMap = new EnumMap<>(EdgeProperty.class);
211 propMap.put(EdgeProperty.CONTAINS, rule.getContains());
212 propMap.put(EdgeProperty.DELETE_OTHER_V, rule.getDeleteOtherV());
213 propMap.put(EdgeProperty.PREVENT_DELETE, rule.getPreventDelete());
215 for (Entry<EdgeProperty, String> entry : propMap.entrySet()) {
216 edge.property(entry.getKey().toString(), entry.getValue());
219 edge.property(EdgeField.PRIVATE.toString(), rule.isPrivateEdge());
220 edge.property(AAIProperties.AAI_UUID, UUID.randomUUID().toString());
224 * Validate multiplicity.
226 * @param rule the rule
227 * @param aVertex the out vertex
228 * @param bVertex the in vertex
229 * @return true, if successful
230 * @throws AAIException the AAI exception
232 private Optional<String> validateMultiplicity(EdgeRule rule, GraphTraversalSource traversalSource, Vertex aVertex,
238 if (rule.getDirection().equals(Direction.OUT)) {
241 } else if (rule.getDirection().equals(Direction.IN)) {
246 String aVertexType = a.<String>property(AAIProperties.NODE_TYPE).orElse(null);
247 String bVertexType = b.<String>property(AAIProperties.NODE_TYPE).orElse(null);
248 String label = rule.getLabel();
250 MultiplicityRule multiplicityRule = rule.getMultiplicityRule();
253 final String msg = "multiplicity rule violated: only one edge can exist with label: ";
255 if (multiplicityRule.equals(MultiplicityRule.ONE2ONE)) {
256 Long outEdgesCnt = traversalSource.V(a).out(label).has(AAIProperties.NODE_TYPE, bVertexType).count().next();
257 Long inEdgesCnt = traversalSource.V(b).in(label).has(AAIProperties.NODE_TYPE, aVertexType).count().next();
258 if (aVertexType.equals(bVertexType)) {
259 inEdgesCnt = inEdgesCnt
260 + traversalSource.V(a).in(label).has(AAIProperties.NODE_TYPE, aVertexType).count().next();
261 outEdgesCnt = outEdgesCnt
262 + traversalSource.V(b).out(label).has(AAIProperties.NODE_TYPE, bVertexType).count().next();
264 if ((inEdgesCnt != 0) || (outEdgesCnt != 0)) {
265 detail = msg + label + " between " + aVertexType + " and " + bVertexType;
267 } else if (multiplicityRule.equals(MultiplicityRule.ONE2MANY)) {
268 Long inEdgesCnt = traversalSource.V(b).in(label).has(AAIProperties.NODE_TYPE, aVertexType).count().next();
269 if (inEdgesCnt != 0) {
270 detail = msg + label + " between " + aVertexType + " and " + bVertexType;
272 } else if (multiplicityRule.equals(MultiplicityRule.MANY2ONE)) {
273 Long outEdgesCnt = traversalSource.V(a).out(label).has(AAIProperties.NODE_TYPE, bVertexType).count().next();
274 if (outEdgesCnt != 0) {
275 detail = msg + label + " between " + aVertexType + " and " + bVertexType;
279 if (!"".equals(detail)) {
280 return Optional.of(detail);
282 return Optional.empty();