5b719e33c323f3670d6fd4142bda2d98cacfc916
[aai/aai-common.git] / aai-core / src / main / java / org / onap / aai / introspection / sideeffect / PrivateEdge.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
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
10  *
11  *    http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20 package org.onap.aai.introspection.sideeffect;
21
22 import com.google.common.collect.Multimap;
23 import org.apache.tinkerpop.gremlin.structure.Edge;
24 import org.apache.tinkerpop.gremlin.structure.Vertex;
25 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
26 import org.onap.aai.config.SpringContextAware;
27 import org.onap.aai.db.props.AAIProperties;
28 import org.onap.aai.edges.EdgeIngestor;
29 import org.onap.aai.edges.EdgeRuleQuery;
30 import org.onap.aai.edges.exceptions.AmbiguousRuleChoiceException;
31 import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
32 import org.onap.aai.exceptions.AAIException;
33 import org.onap.aai.introspection.*;
34 import org.onap.aai.introspection.sideeffect.exceptions.AAIMultiplePropertiesException;
35 import org.onap.aai.parsers.query.QueryParser;
36 import org.onap.aai.restcore.util.URITools;
37 import org.onap.aai.schema.enums.PropertyMetadata;
38 import org.onap.aai.serialization.db.DBSerializer;
39 import org.onap.aai.edges.EdgeRule;
40 import org.onap.aai.edges.enums.EdgeType;
41 import org.onap.aai.serialization.db.EdgeSerializer;
42 import org.onap.aai.serialization.db.exceptions.EdgeMultiplicityException;
43 import org.onap.aai.serialization.engines.TransactionalGraphEngine;
44
45 import javax.ws.rs.core.MultivaluedMap;
46 import java.io.UnsupportedEncodingException;
47 import java.net.URI;
48 import java.net.URISyntaxException;
49 import java.util.*;
50 import java.util.Map.Entry;
51
52
53 public class PrivateEdge extends SideEffect {
54
55     public PrivateEdge(Introspector obj, Vertex self, TransactionalGraphEngine dbEngine, DBSerializer serializer) {
56         super(obj, self, dbEngine, serializer);
57     }
58
59     @Override
60     protected void processURI(Optional<String> completeUri, Entry<String, String> entry) throws URISyntaxException, UnsupportedEncodingException, AAIException, EdgeRuleNotFoundException, AmbiguousRuleChoiceException {
61         if (completeUri.isPresent()) {
62             process(completeUri, entry);
63         } else {
64             // Check if the vertex self has the template keys or the db aliased keys
65             // If it does check if the self vertex has a edge to that model
66             // If it does, then remove the edge since the update happened and doesn't have required props anymore
67                         // "service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}"
68             // If the vertex does have
69                 Loader loader = SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(ModelType.MOXY, obj.getVersion());
70             Introspector introspector = loader.introspectorFromName(obj.getDbName());
71             List<Vertex> vertices = new ArrayList<>();
72             vertices.add(self);
73             Introspector curObj = serializer.dbToObject(vertices, introspector, 0, true, "false");
74             Optional<String> populatedUri = this.replaceTemplates(curObj, entry.getValue());
75             process(populatedUri, entry);
76         }
77     }
78
79     private void process(Optional<String> completeUri, Entry<String, String> entry) throws URISyntaxException, UnsupportedEncodingException, AAIException, EdgeRuleNotFoundException, AmbiguousRuleChoiceException {
80         if(completeUri.isPresent()){
81             URI uri = new URI(completeUri.get());
82             MultivaluedMap<String, String> map = URITools.getQueryMap(uri);
83             QueryParser uriQuery = dbEngine.getQueryBuilder(this.latestLoader).createQueryFromURI(uri, map);
84             List<Vertex> results = uriQuery.getQueryBuilder().toList();
85             if (results.size() == 1) {
86                 Vertex otherVertex = results.get(0);
87                 VertexProperty otherVProperty = otherVertex.property("aai-node-type");
88
89                 if (otherVProperty.isPresent()) {
90
91                     EdgeRuleQuery edgeQuery = new EdgeRuleQuery.Builder(obj.getName(), otherVProperty.value().toString()).edgeType(EdgeType.COUSIN).setPrivate(true).build();
92                     EdgeIngestor edgeIngestor = serializer.getEdgeIngestor();
93                     EdgeSerializer edgeSerializer = serializer.getEdgeSeriailizer();
94
95                     Multimap<String, EdgeRule> edgeRulesMap = edgeIngestor.getRules(edgeQuery);
96
97                     if (edgeRulesMap.isEmpty()) {
98                         String message = String.format("Unable to find edge between %s and %s", obj.getName(), otherVProperty.value().toString());
99                         throw new AAIException("AAI_6127", message);
100                     } else if (edgeRulesMap.size() > 1) {
101                         String message = String.format("Found multiple edges between %s and %s", obj.getName(), otherVProperty.value().toString());
102                         throw new EdgeMultiplicityException(message);
103                     }
104
105
106                     for (Entry<String, EdgeRule> edgeEntry : edgeRulesMap.entries()) {
107                         EdgeRule edgeRule = edgeIngestor.getRule(edgeQuery);
108                         Iterator<Edge> edges = self.edges(edgeRule.getDirection(), edgeRule.getLabel().toString());
109                         if(edges.hasNext()){
110                             Edge edge = edges.next();
111                             EdgeStatus status = checkStatus(obj, self);
112                             switch(status){
113                                 case CREATED:
114                                     edgeSerializer.addPrivateEdge(this.dbEngine.asAdmin().getTraversalSource(), self, otherVertex, edgeRule.getLabel());
115                                     break;
116                                 case MODIFIED:
117                                     edge.remove();
118                                     edgeSerializer.addPrivateEdge(this.dbEngine.asAdmin().getTraversalSource(), self, otherVertex, edgeRule.getLabel());
119                                     break;
120                                 case REMOVED:
121                                     edge.remove();
122                                     break;
123                                 case UNCHANGED:
124                                     break;
125                             }
126                         } else {
127                             edgeSerializer.addPrivateEdge(this.dbEngine.asAdmin().getTraversalSource(), self, otherVertex, edgeRule.getLabel());
128                         }
129                     }
130                 }
131             } else {
132                 if (results.isEmpty()) {
133                     throw new AAIException("AAI_6114", "object located at " + uri + " not found");
134                 } else if (results.size() > 1) {
135                     throw new AAIMultiplePropertiesException("multiple values of " + entry.getKey() + " found when searching " + uri);
136                 }
137             }
138         }
139     }
140
141     public enum EdgeStatus {
142         CREATED,
143         REMOVED,
144         MODIFIED,
145         UNCHANGED
146     }
147
148     private EdgeStatus checkStatus(Introspector obj, Vertex self) {
149
150         for(String key : templateKeys){
151             String currentObjValue = obj.getValue(key);
152             Map<PropertyMetadata, String> map = obj.getPropertyMetadata(key);
153             String oldVertexValue = null;
154
155             if(map.containsKey(PropertyMetadata.DB_ALIAS)){
156                 oldVertexValue = self.<String>property(key + AAIProperties.DB_ALIAS_SUFFIX).orElse(null);
157             } else {
158                 oldVertexValue = self.<String>property(key).orElse(null);
159             }
160
161             if(currentObjValue == null && oldVertexValue == null){
162                 continue;
163             }
164
165             if(currentObjValue == null){
166                 if(oldVertexValue != null){
167                     return EdgeStatus.REMOVED;
168                 }
169             }
170
171             if(oldVertexValue == null){
172                 if(currentObjValue != null){
173                     return EdgeStatus.CREATED;
174                 }
175             }
176
177             if(!oldVertexValue.equals(currentObjValue)){
178                 return EdgeStatus.MODIFIED;
179             }
180         }
181
182         return EdgeStatus.UNCHANGED;
183     }
184
185     @Override
186     protected PropertyMetadata getPropertyMetadata() {
187         return PropertyMetadata.PRIVATE_EDGE;
188     }
189
190     @Override
191     protected boolean replaceWithWildcard() {
192         return false;
193     }
194
195 }