2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 2017-2018 Amdocs
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
21 package org.onap.schema;
23 import com.google.gson.JsonElement;
24 import com.google.gson.JsonNull;
26 import org.onap.crud.entity.Edge;
27 import org.onap.crud.entity.Vertex;
28 import org.onap.crud.exception.CrudException;
29 import org.onap.crud.service.EdgePayload;
30 import org.onap.crud.util.CrudServiceUtil;
31 import org.onap.schema.OxmModelValidator.Metadata;
32 import org.radeox.util.logging.Logger;
34 import java.util.HashMap;
37 import java.util.regex.Matcher;
38 import java.util.regex.Pattern;
39 import javax.ws.rs.core.Response.Status;
41 public class RelationshipSchemaValidator {
43 public static final String SOURCE_NODE = "source";
44 public static final String TARGET_NODE = "target";
46 final static Pattern urlPattern = Pattern.compile("services/inventory/(.*)/(.*)/(.*)");
48 public static Map<String, Object> resolveCollectionfilter(String version, String type,
49 Map<String, String> filter)
50 throws CrudException {
52 RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
54 throw new CrudException("", Status.NOT_FOUND);
57 Map<String, Class<?>> props = schema.lookupRelationType(type);
58 Map<String, Object> result = new HashMap<String, Object>();
60 for (String key : filter.keySet()) {
62 if (props.containsKey(key)) {
64 Object value = CrudServiceUtil.validateFieldType(filter.get(key), props.get(key));
65 result.put(key, value);
66 } catch (Exception ex) {
67 // Skip any exceptions thrown while validating the filter
78 public static void validateType(String version, String type) throws CrudException {
80 RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
81 if (!schema.isValidType(type)) {
82 throw new CrudException("Invalid " + RelationshipSchema.SCHEMA_RELATIONSHIP_TYPE
89 public static Edge validateIncomingAddPayload(String version, String type, Vertex sourceNode,
90 Vertex targetNode, JsonElement properties)
91 throws CrudException {
92 EdgePayload payload = new EdgePayload();
93 payload.setSource("services/inventory/" + version + "/" + sourceNode.getType()
94 + "/" + sourceNode.getId().get());
95 payload.setTarget("services/inventory/" + version + "/" + targetNode.getType()
96 + "/" + targetNode.getId().get());
97 payload.setType(type);
98 payload.setProperties(properties);
99 return validateIncomingAddPayload(version, type, payload);
102 public static Edge validateIncomingAddPayload(String version, String type, EdgePayload payload)
103 throws CrudException {
104 RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
108 if (payload.getSource() == null || payload.getTarget() == null) {
109 throw new CrudException("Source/Target not specified", Status.BAD_REQUEST);
112 Matcher sourceMatcher = urlPattern.matcher(payload.getSource());
113 Matcher targetMatcher = urlPattern.matcher(payload.getTarget());
115 if (!sourceMatcher.matches() || !targetMatcher.matches()) {
116 throw new CrudException("Invalid Source/Target Urls", Status.BAD_REQUEST);
119 // create key based on source:target:relationshipType
120 String sourceNodeType = sourceMatcher.group(2);
121 String targetNodeType = targetMatcher.group(2);
123 String sourceNodeId = sourceMatcher.group(3);
124 String targetNodeId = targetMatcher.group(3);
126 String key = sourceNodeType + ":" + targetNodeType + ":" + type;
128 // find the validate the key from the schema
129 Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
131 if (schemaObject == null) {
132 throw new CrudException("Invalid source/target/relationship type: " + key,
136 Edge.Builder modelEdgeBuilder = new Edge.Builder(type);
138 modelEdgeBuilder.source(new Vertex.Builder(sourceNodeType).id(sourceNodeId).build());
139 modelEdgeBuilder.target(new Vertex.Builder(targetNodeType).id(targetNodeId).build());
141 // validate it properties
142 validateEdgeProps(modelEdgeBuilder, payload.getProperties(), schemaObject);
144 return modelEdgeBuilder.build();
145 } catch (Exception ex) {
147 throw new CrudException(ex.getMessage(), Status.BAD_REQUEST);
152 public static Edge validateIncomingPatchPayload(Edge edge, String version, EdgePayload payload)
153 throws CrudException {
154 RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
157 if (payload.getSource() != null) {
158 Matcher sourceMatcher = urlPattern.matcher(payload.getSource());
160 if (!sourceMatcher.matches()) {
161 throw new CrudException("Invalid Target Urls", Status.BAD_REQUEST);
163 String sourceNodeId = sourceMatcher.group(3);
164 if (!sourceNodeId.equals(edge.getSource().getId().get())) {
165 throw new CrudException("Source can't be updated", Status.BAD_REQUEST);
169 if (payload.getTarget() != null) {
170 Matcher targetMatcher = urlPattern.matcher(payload.getTarget());
172 if (!targetMatcher.matches()) {
173 throw new CrudException("Invalid Target Urls", Status.BAD_REQUEST);
175 String sourceNodeId = targetMatcher.group(3);
176 if (!sourceNodeId.equals(edge.getTarget().getId().get())) {
177 throw new CrudException("Target can't be updated", Status.BAD_REQUEST);
181 // Remove the timestamp properties from the existing edge, as these should be managed by Champ.
182 Map<String,Object> existingProps = edge.getProperties();
184 if (existingProps.containsKey(Metadata.CREATED_TS.propertyName())) {
185 existingProps.remove(Metadata.CREATED_TS.propertyName());
187 if (existingProps.containsKey(Metadata.UPDATED_TS.propertyName())) {
188 existingProps.remove(Metadata.UPDATED_TS.propertyName());
191 // create key based on source:target:relationshipType
193 String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
194 + ":" + edge.getType();
196 // find the validate the key from the schema
197 Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
199 if (schemaObject == null) {
200 Logger.warn("key :" + key
201 + " not found in relationship schema . Skipping the schema validation");
205 Set<Map.Entry<String, JsonElement>> entries = payload.getProperties()
206 .getAsJsonObject().entrySet();
208 for (Map.Entry<String, JsonElement> entry : entries) {
210 if (!schemaObject.containsKey(entry.getKey())) {
211 throw new CrudException("Invalid property: " + entry.getKey(), Status.BAD_REQUEST);
212 } else if (entry.getValue() instanceof JsonNull && edge.getProperties()
213 .containsKey(entry.getKey())) {
214 edge.getProperties().remove(entry.getKey());
215 } else if (!(entry.getValue() instanceof JsonNull)) {
216 Object value = CrudServiceUtil.validateFieldType(entry.getValue().getAsString(),
217 schemaObject.get(entry.getKey()));
218 edge.getProperties().put(entry.getKey(), value);
225 } catch (Exception ex) {
227 throw new CrudException(ex.getMessage(), Status.BAD_REQUEST);
231 public static Edge validateIncomingUpdatePayload(Edge edge, String version, Vertex sourceNode,
232 Vertex targetNode, JsonElement properties)
233 throws CrudException {
234 EdgePayload payload = new EdgePayload();
235 payload.setSource("services/inventory/" + version + "/" + sourceNode.getType()
236 + "/" + sourceNode.getId().get());
237 payload.setTarget("services/inventory/" + version + "/" + targetNode.getType()
238 + "/" + targetNode.getId().get());
239 payload.setType(edge.getType());
240 payload.setProperties(properties);
241 return validateIncomingUpdatePayload(edge, version, payload);
244 public static Edge validateIncomingUpdatePayload(Edge edge, String version, EdgePayload payload)
245 throws CrudException {
246 RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
250 if (payload.getSource() != null) {
251 Matcher sourceMatcher = urlPattern.matcher(payload.getSource());
253 if (!sourceMatcher.matches()) {
254 throw new CrudException("Invalid Target Urls", Status.BAD_REQUEST);
256 String sourceNodeId = sourceMatcher.group(3);
257 if (!sourceNodeId.equals(edge.getSource().getId().get())) {
258 throw new CrudException("Source can't be updated", Status.BAD_REQUEST);
262 if (payload.getTarget() != null) {
263 Matcher targetMatcher = urlPattern.matcher(payload.getTarget());
265 if (!targetMatcher.matches()) {
266 throw new CrudException("Invalid Target Urls", Status.BAD_REQUEST);
268 String sourceNodeId = targetMatcher.group(3);
269 if (!sourceNodeId.equals(edge.getTarget().getId().get())) {
270 throw new CrudException("Target can't be updated", Status.BAD_REQUEST);
273 // create key based on source:target:relationshipType
275 String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
276 + ":" + edge.getType();
278 // find the validate the key from the schema
279 Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
281 if (schemaObject == null) {
282 Logger.warn("key :" + key
283 + " not found in relationship schema . Skipping the schema validation");
287 Edge.Builder updatedEdgeBuilder = new Edge.Builder(edge.getType()).id(edge.getId().get());
290 .source(new Vertex.Builder(edge.getSource().getType()).id(edge.getSource().getId()
293 .target(new Vertex.Builder(edge.getTarget().getType()).id(edge.getTarget().getId()
296 validateEdgeProps(updatedEdgeBuilder, payload.getProperties(), schemaObject);
298 return updatedEdgeBuilder.build();
299 } catch (Exception ex) {
301 throw new CrudException(ex.getMessage(), Status.BAD_REQUEST);
306 private static void validateEdgeProps(Edge.Builder builder, JsonElement props,
307 Map<String, Class<?>> schemaObject)
308 throws CrudException {
309 Set<Map.Entry<String, JsonElement>> entries = props.getAsJsonObject().entrySet();
311 for (Map.Entry<String, JsonElement> entry : entries) {
313 if (!schemaObject.containsKey(entry.getKey())) {
314 throw new CrudException("Invalid property: " + entry.getKey(), Status.BAD_REQUEST);
316 Object value = CrudServiceUtil.validateFieldType(entry.getValue().getAsString(),
317 schemaObject.get(entry.getKey()));
318 builder.property(entry.getKey(), value);
325 public static Edge validateOutgoingPayload(String version, Edge edge) throws CrudException {
327 Edge.Builder modelEdgeBuilder = new Edge.Builder(edge.getType()).id(edge.getId()
328 .get()).source(edge.getSource())
329 .target(edge.getTarget());
331 RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
333 String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
334 + ":" + edge.getType();
335 Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
337 if (schemaObject == null || schemaObject.isEmpty()) {
341 for (String prop : edge.getProperties().keySet()) {
342 if (schemaObject.containsKey(prop)) {
343 modelEdgeBuilder.property(prop, edge.getProperties().get(prop));
347 return modelEdgeBuilder.build();
351 public static String vertexTypeFromUri(String uri) throws CrudException {
353 Matcher matcher = urlPattern.matcher(uri);
355 if (!matcher.matches()) {
356 throw new CrudException("Invalid Source/Target Urls", Status.BAD_REQUEST);
359 return matcher.group(2);