[AAI-26] Adding gizmo data to the repository.
[aai/gizmo.git] / src / main / java / org / openecomp / schema / RelationshipSchemaValidator.java
1 /**
2  * ============LICENSE_START=======================================================
3  * Gizmo
4  * ================================================================================
5  * Copyright © 2017 AT&T Intellectual Property.
6  * Copyright © 2017 Amdocs
7  * All rights reserved.
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *    http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  *
22  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
23  */
24 package org.openecomp.schema;
25
26 import com.google.gson.JsonElement;
27 import com.google.gson.JsonNull;
28
29 import org.openecomp.crud.entity.Edge;
30 import org.openecomp.crud.entity.Vertex;
31 import org.openecomp.crud.exception.CrudException;
32 import org.openecomp.crud.service.EdgePayload;
33 import org.openecomp.crud.util.CrudServiceUtil;
34 import org.radeox.util.logging.Logger;
35
36 import java.util.HashMap;
37 import java.util.Map;
38 import java.util.Set;
39 import java.util.regex.Matcher;
40 import java.util.regex.Pattern;
41 import javax.ws.rs.core.Response.Status;
42
43 public class RelationshipSchemaValidator {
44
45   public static final String SOURCE_NODE = "source";
46   public static final String TARGET_NODE = "target";
47
48   final static Pattern urlPattern = Pattern.compile("services/inventory/(.*)/(.*)/(.*)");
49
50   public static Map<String, Object> resolveCollectionfilter(String version, String type,
51                                                             Map<String, String> filter)
52       throws CrudException {
53
54     RelationshipSchema schema = RelationshipSchemaLoader.getSchemaForVersion(version);
55     if (schema == null) {
56       throw new CrudException("", Status.NOT_FOUND);
57     }
58
59     HashMap<String, Class<?>> props = schema.lookupRelationType(type);
60     Map<String, Object> result = new HashMap<String, Object>();
61
62     for (String key : filter.keySet()) {
63
64       if (props.containsKey(key)) {
65         try {
66           Object value = CrudServiceUtil.validateFieldType(filter.get(key), props.get(key));
67           result.put(key, value);
68         } catch (Exception ex) {
69           // Skip any exceptions thrown while validating the filter
70           // key value
71           continue;
72         }
73       }
74     }
75
76     return result;
77
78   }
79
80   public static void validateType(String version, String type) throws CrudException {
81
82     RelationshipSchema schema = RelationshipSchemaLoader.getSchemaForVersion(version);
83     if (!schema.isValidType(type)) {
84       throw new CrudException("Invalid " + RelationshipSchema.SCHEMA_RELATIONSHIP_TYPE
85           + ": " + type,
86           Status.BAD_REQUEST);
87     }
88
89   }
90
91   public static Edge validateIncomingAddPayload(String version, String type, Vertex sourceNode,
92                                                 Vertex targetNode, JsonElement properties)
93       throws CrudException {
94     EdgePayload payload = new EdgePayload();
95     payload.setSource("services/inventory/" + version + "/" + sourceNode.getType()
96         + "/" + sourceNode.getId().get());
97     payload.setTarget("services/inventory/" + version + "/" + targetNode.getType()
98         + "/" + targetNode.getId().get());
99     payload.setType(type);
100     payload.setProperties(properties);
101     return validateIncomingAddPayload(version, type, payload);
102   }
103
104   public static Edge validateIncomingAddPayload(String version, String type, EdgePayload payload)
105       throws CrudException {
106     RelationshipSchema schema = RelationshipSchemaLoader.getSchemaForVersion(version);
107
108     try {
109
110       if (payload.getSource() == null || payload.getTarget() == null) {
111         throw new CrudException("Source/Target not specified", Status.BAD_REQUEST);
112       }
113
114       Matcher sourceMatcher = urlPattern.matcher(payload.getSource());
115       Matcher targetMatcher = urlPattern.matcher(payload.getTarget());
116
117       if (!sourceMatcher.matches() || !targetMatcher.matches()) {
118         throw new CrudException("Invalid Source/Target Urls", Status.BAD_REQUEST);
119       }
120
121       // create key based on source:target:relationshipType
122       String sourceNodeType = sourceMatcher.group(2);
123       String targetNodeType = targetMatcher.group(2);
124
125       String sourceNodeId = sourceMatcher.group(3);
126       String targetNodeId = targetMatcher.group(3);
127
128       String key = sourceNodeType + ":" + targetNodeType + ":" + type;
129
130       // find the validate the key from the schema
131       HashMap<String, Class<?>> schemaObject = schema.lookupRelation(key);
132
133       if (schemaObject == null) {
134         throw new CrudException("Invalid source/target/relationship type: " + key,
135             Status.BAD_REQUEST);
136       }
137
138       Edge.Builder modelEdgeBuilder = new Edge.Builder(type);
139
140       modelEdgeBuilder.source(new Vertex.Builder(sourceNodeType).id(sourceNodeId).build());
141       modelEdgeBuilder.target(new Vertex.Builder(targetNodeType).id(targetNodeId).build());
142
143       // validate it properties
144       validateEdgeProps(modelEdgeBuilder, payload.getProperties(), schemaObject);
145
146       return modelEdgeBuilder.build();
147     } catch (Exception ex) {
148
149       throw new CrudException(ex.getMessage(), Status.BAD_REQUEST);
150     }
151
152   }
153
154   public static Edge validateIncomingPatchPayload(Edge edge, String version, EdgePayload payload)
155       throws CrudException {
156     RelationshipSchema schema = RelationshipSchemaLoader.getSchemaForVersion(version);
157
158     try {
159       if (payload.getSource() != null) {
160         Matcher sourceMatcher = urlPattern.matcher(payload.getSource());
161
162         if (!sourceMatcher.matches()) {
163           throw new CrudException("Invalid Target Urls", Status.BAD_REQUEST);
164         }
165         String sourceNodeId = sourceMatcher.group(3);
166         if (!sourceNodeId.equals(edge.getSource().getId().get())) {
167           throw new CrudException("Source can't be updated", Status.BAD_REQUEST);
168         }
169       }
170
171       if (payload.getTarget() != null) {
172         Matcher targetMatcher = urlPattern.matcher(payload.getTarget());
173
174         if (!targetMatcher.matches()) {
175           throw new CrudException("Invalid Target Urls", Status.BAD_REQUEST);
176         }
177         String sourceNodeId = targetMatcher.group(3);
178         if (!sourceNodeId.equals(edge.getTarget().getId().get())) {
179           throw new CrudException("Target can't be updated", Status.BAD_REQUEST);
180         }
181       }
182       // create key based on source:target:relationshipType
183
184       String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
185           + ":" + edge.getType();
186
187       // find the validate the key from the schema
188       HashMap<String, Class<?>> schemaObject = schema.lookupRelation(key);
189
190       if (schemaObject == null) {
191         Logger.warn("key :" + key
192             + " not found in relationship schema . Skipping the schema validation");
193         return edge;
194       }
195
196       Set<Map.Entry<String, JsonElement>> entries = payload.getProperties()
197           .getAsJsonObject().entrySet();
198
199       for (Map.Entry<String, JsonElement> entry : entries) {
200
201         if (!schemaObject.containsKey(entry.getKey())) {
202           throw new CrudException("Invalid property: " + entry.getKey(), Status.BAD_REQUEST);
203         } else if (entry.getValue() instanceof JsonNull && edge.getProperties()
204             .containsKey(entry.getKey())) {
205           edge.getProperties().remove(entry.getKey());
206         } else if (!(entry.getValue() instanceof JsonNull)) {
207           Object value = CrudServiceUtil.validateFieldType(entry.getValue().getAsString(),
208               schemaObject.get(entry.getKey()));
209           edge.getProperties().put(entry.getKey(), value);
210         }
211
212       }
213
214       return edge;
215
216     } catch (Exception ex) {
217
218       throw new CrudException(ex.getMessage(), Status.BAD_REQUEST);
219     }
220   }
221
222   public static Edge validateIncomingUpdatePayload(Edge edge, String version, Vertex sourceNode,
223                                                    Vertex targetNode, JsonElement properties)
224       throws CrudException {
225     EdgePayload payload = new EdgePayload();
226     payload.setSource("services/inventory/" + version + "/" + sourceNode.getType()
227         + "/" + sourceNode.getId().get());
228     payload.setTarget("services/inventory/" + version + "/" + targetNode.getType()
229         + "/" + targetNode.getId().get());
230     payload.setType(edge.getType());
231     payload.setProperties(properties);
232     return validateIncomingUpdatePayload(edge, version, payload);
233   }
234
235   public static Edge validateIncomingUpdatePayload(Edge edge, String version, EdgePayload payload)
236       throws CrudException {
237     RelationshipSchema schema = RelationshipSchemaLoader.getSchemaForVersion(version);
238
239     try {
240
241       if (payload.getSource() != null) {
242         Matcher sourceMatcher = urlPattern.matcher(payload.getSource());
243
244         if (!sourceMatcher.matches()) {
245           throw new CrudException("Invalid Target Urls", Status.BAD_REQUEST);
246         }
247         String sourceNodeId = sourceMatcher.group(3);
248         if (!sourceNodeId.equals(edge.getSource().getId().get())) {
249           throw new CrudException("Source can't be updated", Status.BAD_REQUEST);
250         }
251       }
252
253       if (payload.getTarget() != null) {
254         Matcher targetMatcher = urlPattern.matcher(payload.getTarget());
255
256         if (!targetMatcher.matches()) {
257           throw new CrudException("Invalid Target Urls", Status.BAD_REQUEST);
258         }
259         String sourceNodeId = targetMatcher.group(3);
260         if (!sourceNodeId.equals(edge.getTarget().getId().get())) {
261           throw new CrudException("Target can't be updated", Status.BAD_REQUEST);
262         }
263       }
264       // create key based on source:target:relationshipType
265
266       String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
267           + ":" + edge.getType();
268
269       // find the validate the key from the schema
270       HashMap<String, Class<?>> schemaObject = schema.lookupRelation(key);
271
272       if (schemaObject == null) {
273         Logger.warn("key :" + key
274             + " not found in relationship schema . Skipping the schema validation");
275         return edge;
276       }
277
278       Edge.Builder updatedEdgeBuilder = new Edge.Builder(edge.getType()).id(edge.getId().get());
279
280       updatedEdgeBuilder
281           .source(new Vertex.Builder(edge.getSource().getType()).id(edge.getSource().getId()
282               .get()).build());
283       updatedEdgeBuilder
284           .target(new Vertex.Builder(edge.getTarget().getType()).id(edge.getTarget().getId()
285               .get()).build());
286
287       validateEdgeProps(updatedEdgeBuilder, payload.getProperties(), schemaObject);
288
289       return updatedEdgeBuilder.build();
290     } catch (Exception ex) {
291
292       throw new CrudException(ex.getMessage(), Status.BAD_REQUEST);
293     }
294   }
295
296
297   private static void validateEdgeProps(Edge.Builder builder, JsonElement props,
298                                         HashMap<String, Class<?>> schemaObject)
299       throws CrudException {
300     Set<Map.Entry<String, JsonElement>> entries = props.getAsJsonObject().entrySet();
301
302     for (Map.Entry<String, JsonElement> entry : entries) {
303
304       if (!schemaObject.containsKey(entry.getKey())) {
305         throw new CrudException("Invalid property: " + entry.getKey(), Status.BAD_REQUEST);
306       } else {
307         Object value = CrudServiceUtil.validateFieldType(entry.getValue().getAsString(),
308             schemaObject.get(entry.getKey()));
309         builder.property(entry.getKey(), value);
310       }
311
312     }
313
314   }
315
316   public static Edge validateOutgoingPayload(String version, Edge edge) throws CrudException {
317
318     Edge.Builder modelEdgeBuilder = new Edge.Builder(edge.getType()).id(edge.getId()
319         .get()).source(edge.getSource())
320         .target(edge.getTarget());
321
322     RelationshipSchema schema = RelationshipSchemaLoader.getSchemaForVersion(version);
323
324     String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
325         + ":" + edge.getType();
326     HashMap<String, Class<?>> schemaObject = schema.lookupRelation(key);
327
328     if (schemaObject == null || schemaObject.isEmpty()) {
329       return edge;
330     }
331
332     for (String prop : edge.getProperties().keySet()) {
333       if (schemaObject.containsKey(prop)) {
334         modelEdgeBuilder.property(prop, edge.getProperties().get(prop));
335       }
336
337     }
338     return modelEdgeBuilder.build();
339   }
340
341 }