2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017 AT&T Intellectual Property.
6 * Copyright © 2017 Amdocs
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
22 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
24 package org.onap.schema;
26 import com.google.gson.JsonElement;
27 import com.google.gson.JsonNull;
29 import org.onap.crud.entity.Edge;
30 import org.onap.crud.entity.Vertex;
31 import org.onap.crud.exception.CrudException;
32 import org.onap.crud.service.EdgePayload;
33 import org.onap.crud.util.CrudServiceUtil;
34 import org.onap.schema.OxmModelValidator.Metadata;
35 import org.radeox.util.logging.Logger;
37 import java.util.HashMap;
40 import java.util.regex.Matcher;
41 import java.util.regex.Pattern;
42 import javax.ws.rs.core.Response.Status;
44 public class RelationshipSchemaValidator {
46 public static final String SOURCE_NODE = "source";
47 public static final String TARGET_NODE = "target";
49 final static Pattern urlPattern = Pattern.compile("services/inventory/(.*)/(.*)/(.*)");
51 public static Map<String, Object> resolveCollectionfilter(String version, String type,
52 Map<String, String> filter)
53 throws CrudException {
55 RelationshipSchema schema = RelationshipSchemaLoader.getSchemaForVersion(version);
57 throw new CrudException("", Status.NOT_FOUND);
60 Map<String, Class<?>> props = schema.lookupRelationType(type);
61 Map<String, Object> result = new HashMap<String, Object>();
63 for (String key : filter.keySet()) {
65 if (props.containsKey(key)) {
67 Object value = CrudServiceUtil.validateFieldType(filter.get(key), props.get(key));
68 result.put(key, value);
69 } catch (Exception ex) {
70 // Skip any exceptions thrown while validating the filter
81 public static void validateType(String version, String type) throws CrudException {
83 RelationshipSchema schema = RelationshipSchemaLoader.getSchemaForVersion(version);
84 if (!schema.isValidType(type)) {
85 throw new CrudException("Invalid " + RelationshipSchema.SCHEMA_RELATIONSHIP_TYPE
92 public static Edge validateIncomingAddPayload(String version, String type, Vertex sourceNode,
93 Vertex targetNode, JsonElement properties)
94 throws CrudException {
95 EdgePayload payload = new EdgePayload();
96 payload.setSource("services/inventory/" + version + "/" + sourceNode.getType()
97 + "/" + sourceNode.getId().get());
98 payload.setTarget("services/inventory/" + version + "/" + targetNode.getType()
99 + "/" + targetNode.getId().get());
100 payload.setType(type);
101 payload.setProperties(properties);
102 return validateIncomingAddPayload(version, type, payload);
105 public static Edge validateIncomingAddPayload(String version, String type, EdgePayload payload)
106 throws CrudException {
107 RelationshipSchema schema = RelationshipSchemaLoader.getSchemaForVersion(version);
111 if (payload.getSource() == null || payload.getTarget() == null) {
112 throw new CrudException("Source/Target not specified", Status.BAD_REQUEST);
115 Matcher sourceMatcher = urlPattern.matcher(payload.getSource());
116 Matcher targetMatcher = urlPattern.matcher(payload.getTarget());
118 if (!sourceMatcher.matches() || !targetMatcher.matches()) {
119 throw new CrudException("Invalid Source/Target Urls", Status.BAD_REQUEST);
122 // create key based on source:target:relationshipType
123 String sourceNodeType = sourceMatcher.group(2);
124 String targetNodeType = targetMatcher.group(2);
126 String sourceNodeId = sourceMatcher.group(3);
127 String targetNodeId = targetMatcher.group(3);
129 String key = sourceNodeType + ":" + targetNodeType + ":" + type;
131 // find the validate the key from the schema
132 Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
134 if (schemaObject == null) {
135 throw new CrudException("Invalid source/target/relationship type: " + key,
139 Edge.Builder modelEdgeBuilder = new Edge.Builder(type);
141 modelEdgeBuilder.source(new Vertex.Builder(sourceNodeType).id(sourceNodeId).build());
142 modelEdgeBuilder.target(new Vertex.Builder(targetNodeType).id(targetNodeId).build());
144 // validate it properties
145 validateEdgeProps(modelEdgeBuilder, payload.getProperties(), schemaObject);
147 return modelEdgeBuilder.build();
148 } catch (Exception ex) {
150 throw new CrudException(ex.getMessage(), Status.BAD_REQUEST);
155 public static Edge validateIncomingPatchPayload(Edge edge, String version, EdgePayload payload)
156 throws CrudException {
157 RelationshipSchema schema = RelationshipSchemaLoader.getSchemaForVersion(version);
160 if (payload.getSource() != null) {
161 Matcher sourceMatcher = urlPattern.matcher(payload.getSource());
163 if (!sourceMatcher.matches()) {
164 throw new CrudException("Invalid Target Urls", Status.BAD_REQUEST);
166 String sourceNodeId = sourceMatcher.group(3);
167 if (!sourceNodeId.equals(edge.getSource().getId().get())) {
168 throw new CrudException("Source can't be updated", Status.BAD_REQUEST);
172 if (payload.getTarget() != null) {
173 Matcher targetMatcher = urlPattern.matcher(payload.getTarget());
175 if (!targetMatcher.matches()) {
176 throw new CrudException("Invalid Target Urls", Status.BAD_REQUEST);
178 String sourceNodeId = targetMatcher.group(3);
179 if (!sourceNodeId.equals(edge.getTarget().getId().get())) {
180 throw new CrudException("Target can't be updated", Status.BAD_REQUEST);
184 // Remove the timestamp properties from the existing edge, as these should be managed by Champ.
185 Map<String,Object> existingProps = edge.getProperties();
187 if (existingProps.containsKey(Metadata.CREATED_TS.propertyName())) {
188 existingProps.remove(Metadata.CREATED_TS.propertyName());
190 if (existingProps.containsKey(Metadata.UPDATED_TS.propertyName())) {
191 existingProps.remove(Metadata.UPDATED_TS.propertyName());
194 // create key based on source:target:relationshipType
196 String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
197 + ":" + edge.getType();
199 // find the validate the key from the schema
200 Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
202 if (schemaObject == null) {
203 Logger.warn("key :" + key
204 + " not found in relationship schema . Skipping the schema validation");
208 Set<Map.Entry<String, JsonElement>> entries = payload.getProperties()
209 .getAsJsonObject().entrySet();
211 for (Map.Entry<String, JsonElement> entry : entries) {
213 if (!schemaObject.containsKey(entry.getKey())) {
214 throw new CrudException("Invalid property: " + entry.getKey(), Status.BAD_REQUEST);
215 } else if (entry.getValue() instanceof JsonNull && edge.getProperties()
216 .containsKey(entry.getKey())) {
217 edge.getProperties().remove(entry.getKey());
218 } else if (!(entry.getValue() instanceof JsonNull)) {
219 Object value = CrudServiceUtil.validateFieldType(entry.getValue().getAsString(),
220 schemaObject.get(entry.getKey()));
221 edge.getProperties().put(entry.getKey(), value);
228 } catch (Exception ex) {
230 throw new CrudException(ex.getMessage(), Status.BAD_REQUEST);
234 public static Edge validateIncomingUpdatePayload(Edge edge, String version, Vertex sourceNode,
235 Vertex targetNode, JsonElement properties)
236 throws CrudException {
237 EdgePayload payload = new EdgePayload();
238 payload.setSource("services/inventory/" + version + "/" + sourceNode.getType()
239 + "/" + sourceNode.getId().get());
240 payload.setTarget("services/inventory/" + version + "/" + targetNode.getType()
241 + "/" + targetNode.getId().get());
242 payload.setType(edge.getType());
243 payload.setProperties(properties);
244 return validateIncomingUpdatePayload(edge, version, payload);
247 public static Edge validateIncomingUpdatePayload(Edge edge, String version, EdgePayload payload)
248 throws CrudException {
249 RelationshipSchema schema = RelationshipSchemaLoader.getSchemaForVersion(version);
253 if (payload.getSource() != null) {
254 Matcher sourceMatcher = urlPattern.matcher(payload.getSource());
256 if (!sourceMatcher.matches()) {
257 throw new CrudException("Invalid Target Urls", Status.BAD_REQUEST);
259 String sourceNodeId = sourceMatcher.group(3);
260 if (!sourceNodeId.equals(edge.getSource().getId().get())) {
261 throw new CrudException("Source can't be updated", Status.BAD_REQUEST);
265 if (payload.getTarget() != null) {
266 Matcher targetMatcher = urlPattern.matcher(payload.getTarget());
268 if (!targetMatcher.matches()) {
269 throw new CrudException("Invalid Target Urls", Status.BAD_REQUEST);
271 String sourceNodeId = targetMatcher.group(3);
272 if (!sourceNodeId.equals(edge.getTarget().getId().get())) {
273 throw new CrudException("Target can't be updated", Status.BAD_REQUEST);
276 // create key based on source:target:relationshipType
278 String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
279 + ":" + edge.getType();
281 // find the validate the key from the schema
282 Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
284 if (schemaObject == null) {
285 Logger.warn("key :" + key
286 + " not found in relationship schema . Skipping the schema validation");
290 Edge.Builder updatedEdgeBuilder = new Edge.Builder(edge.getType()).id(edge.getId().get());
293 .source(new Vertex.Builder(edge.getSource().getType()).id(edge.getSource().getId()
296 .target(new Vertex.Builder(edge.getTarget().getType()).id(edge.getTarget().getId()
299 validateEdgeProps(updatedEdgeBuilder, payload.getProperties(), schemaObject);
301 return updatedEdgeBuilder.build();
302 } catch (Exception ex) {
304 throw new CrudException(ex.getMessage(), Status.BAD_REQUEST);
309 private static void validateEdgeProps(Edge.Builder builder, JsonElement props,
310 Map<String, Class<?>> schemaObject)
311 throws CrudException {
312 Set<Map.Entry<String, JsonElement>> entries = props.getAsJsonObject().entrySet();
314 for (Map.Entry<String, JsonElement> entry : entries) {
316 if (!schemaObject.containsKey(entry.getKey())) {
317 throw new CrudException("Invalid property: " + entry.getKey(), Status.BAD_REQUEST);
319 Object value = CrudServiceUtil.validateFieldType(entry.getValue().getAsString(),
320 schemaObject.get(entry.getKey()));
321 builder.property(entry.getKey(), value);
328 public static Edge validateOutgoingPayload(String version, Edge edge) throws CrudException {
330 Edge.Builder modelEdgeBuilder = new Edge.Builder(edge.getType()).id(edge.getId()
331 .get()).source(edge.getSource())
332 .target(edge.getTarget());
334 RelationshipSchema schema = RelationshipSchemaLoader.getSchemaForVersion(version);
336 String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
337 + ":" + edge.getType();
338 Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
340 if (schemaObject == null || schemaObject.isEmpty()) {
344 for (String prop : edge.getProperties().keySet()) {
345 if (schemaObject.containsKey(prop)) {
346 modelEdgeBuilder.property(prop, edge.getProperties().get(prop));
350 return modelEdgeBuilder.build();
354 public static String vertexTypeFromUri(String uri) throws CrudException {
356 Matcher matcher = urlPattern.matcher(uri);
358 if (!matcher.matches()) {
359 throw new CrudException("Invalid Source/Target Urls", Status.BAD_REQUEST);
362 return matcher.group(2);