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 java.util.HashMap;
26 import java.util.regex.Matcher;
27 import java.util.regex.Pattern;
29 import javax.ws.rs.core.Response.Status;
31 import org.onap.crud.entity.Edge;
32 import org.onap.crud.entity.Vertex;
33 import org.onap.crud.exception.CrudException;
34 import org.onap.crud.service.EdgePayload;
35 import org.onap.crud.util.CrudServiceUtil;
36 import org.onap.schema.OxmModelValidator.Metadata;
37 import org.radeox.util.logging.Logger;
39 import com.google.gson.JsonElement;
40 import com.google.gson.JsonNull;
42 public class RelationshipSchemaValidator {
44 public static final String SOURCE_NODE = "source";
45 public static final String TARGET_NODE = "target";
47 final static Pattern urlPattern = Pattern.compile("services/inventory/(.*)/(.*)/(.*)");
49 public static Map<String, Object> resolveCollectionfilter(String version, String type,Map<String, String> filter) throws CrudException {
50 RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
52 throw new CrudException("", Status.NOT_FOUND);
55 Map<String, Class<?>> props = schema.lookupRelationType(type);
56 Map<String, Object> result = new HashMap<String, Object>();
58 for (String key : filter.keySet()) {
60 if (props.containsKey(key)) {
62 Object value = CrudServiceUtil.validateFieldType(filter.get(key), props.get(key));
63 result.put(key, value);
64 } catch (Exception ex) {
65 // Skip any exceptions thrown while validating the filter key value
73 public static void validateType(String version, String type) throws CrudException {
74 RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
75 if (!schema.isValidType(type)) {
76 throw new CrudException("Invalid " + RelationshipSchema.SCHEMA_RELATIONSHIP_TYPE
83 public static Edge validateIncomingAddPayload(String version, String type, Vertex sourceNode, Vertex targetNode, JsonElement properties) throws CrudException {
84 EdgePayload payload = new EdgePayload();
85 payload.setSource("services/inventory/" + version + "/" + sourceNode.getType() + "/" + sourceNode.getId().get());
86 payload.setTarget("services/inventory/" + version + "/" + targetNode.getType() + "/" + targetNode.getId().get());
87 payload.setType(type);
88 payload.setProperties(properties);
90 return validateIncomingAddPayload(version, type, payload);
93 public static Edge validateIncomingAddPayload(String version, String type, EdgePayload payload)
94 throws CrudException {
95 RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
98 if (payload.getSource() == null || payload.getTarget() == null) {
99 throw new CrudException("Source/Target not specified", Status.BAD_REQUEST);
102 Matcher sourceMatcher = urlPattern.matcher(payload.getSource());
103 Matcher targetMatcher = urlPattern.matcher(payload.getTarget());
105 if (!sourceMatcher.matches() || !targetMatcher.matches()) {
106 throw new CrudException("Invalid Source/Target Urls", Status.BAD_REQUEST);
109 // create key based on source:target:relationshipType
110 String sourceNodeType = sourceMatcher.group(2);
111 String targetNodeType = targetMatcher.group(2);
113 String sourceNodeId = sourceMatcher.group(3);
114 String targetNodeId = targetMatcher.group(3);
116 String key = sourceNodeType + ":" + targetNodeType + ":" + type;
118 // find the validate the key from the schema
119 Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
121 if (schemaObject == null) {
122 throw new CrudException("Invalid source/target/relationship type: " + key, Status.BAD_REQUEST);
125 Edge.Builder modelEdgeBuilder = new Edge.Builder(type);
127 modelEdgeBuilder.source(new Vertex.Builder(sourceNodeType).id(sourceNodeId).build());
128 modelEdgeBuilder.target(new Vertex.Builder(targetNodeType).id(targetNodeId).build());
130 // validate it properties
131 validateEdgeProps(modelEdgeBuilder, payload.getProperties(), schemaObject);
133 return modelEdgeBuilder.build();
134 } catch (Exception ex) {
135 throw new CrudException(ex.getMessage(), Status.BAD_REQUEST);
139 public static Edge validateIncomingPatchPayload(Edge edge, String version, EdgePayload payload)
140 throws CrudException {
141 RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
144 if (payload.getSource() != null) {
145 Matcher sourceMatcher = urlPattern.matcher(payload.getSource());
147 if (!sourceMatcher.matches()) {
148 throw new CrudException("Invalid Source Urls", Status.BAD_REQUEST);
150 String sourceNodeId = sourceMatcher.group(3);
151 if (!sourceNodeId.equals(edge.getSource().getId().get())) {
152 throw new CrudException("Source can't be updated", Status.BAD_REQUEST);
156 if (payload.getTarget() != null) {
157 Matcher targetMatcher = urlPattern.matcher(payload.getTarget());
159 if (!targetMatcher.matches()) {
160 throw new CrudException("Invalid Target Urls", Status.BAD_REQUEST);
162 String sourceNodeId = targetMatcher.group(3);
163 if (!sourceNodeId.equals(edge.getTarget().getId().get())) {
164 throw new CrudException("Target can't be updated", Status.BAD_REQUEST);
168 // Remove the timestamp properties from the existing edge, as these should be managed by Champ.
169 Map<String,Object> existingProps = edge.getProperties();
171 if (existingProps.containsKey(Metadata.CREATED_TS.propertyName())) {
172 existingProps.remove(Metadata.CREATED_TS.propertyName());
174 if (existingProps.containsKey(Metadata.UPDATED_TS.propertyName())) {
175 existingProps.remove(Metadata.UPDATED_TS.propertyName());
178 // create key based on source:target:relationshipType
179 String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
180 + ":" + edge.getType();
182 // find the validate the key from the schema
183 Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
185 if (schemaObject == null) {
186 Logger.warn("key :" + key
187 + " not found in relationship schema . Skipping the schema validation");
191 Set<Map.Entry<String, JsonElement>> entries = payload.getProperties().getAsJsonObject().entrySet();
193 for (Map.Entry<String, JsonElement> entry : entries) {
194 if (!schemaObject.containsKey(entry.getKey())) {
195 throw new CrudException("Invalid property: " + entry.getKey(), Status.BAD_REQUEST);
196 } else if (entry.getValue() instanceof JsonNull && edge.getProperties().containsKey(entry.getKey())) {
197 edge.getProperties().remove(entry.getKey());
198 } else if (!(entry.getValue() instanceof JsonNull)) {
199 Object value = CrudServiceUtil.validateFieldType(entry.getValue().getAsString(), schemaObject.get(entry.getKey()));
200 edge.getProperties().put(entry.getKey(), value);
205 } catch (Exception ex) {
206 throw new CrudException(ex.getMessage(), Status.BAD_REQUEST);
211 public static Edge validateIncomingUpdatePayload(Edge edge, String version, Vertex sourceNode, Vertex targetNode, JsonElement properties)
212 throws CrudException {
213 EdgePayload payload = new EdgePayload();
214 payload.setSource("services/inventory/" + version + "/" + sourceNode.getType() + "/" + sourceNode.getId().get());
215 payload.setTarget("services/inventory/" + version + "/" + targetNode.getType() + "/" + targetNode.getId().get());
216 payload.setType(edge.getType());
217 payload.setProperties(properties);
218 return validateIncomingUpdatePayload(edge, version, payload);
221 public static Edge validateIncomingUpdatePayload(Edge edge, String version, EdgePayload payload)
222 throws CrudException {
223 RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
226 if (payload.getSource() != null) {
227 Matcher sourceMatcher = urlPattern.matcher(payload.getSource());
229 if (!sourceMatcher.matches()) {
230 throw new CrudException("Invalid Source Urls", Status.BAD_REQUEST);
232 String sourceNodeId = sourceMatcher.group(3);
233 if (!sourceNodeId.equals(edge.getSource().getId().get())) {
234 throw new CrudException("Source can't be updated", Status.BAD_REQUEST);
238 if (payload.getTarget() != null) {
239 Matcher targetMatcher = urlPattern.matcher(payload.getTarget());
241 if (!targetMatcher.matches()) {
242 throw new CrudException("Invalid Target Urls", Status.BAD_REQUEST);
244 String sourceNodeId = targetMatcher.group(3);
245 if (!sourceNodeId.equals(edge.getTarget().getId().get())) {
246 throw new CrudException("Target can't be updated", Status.BAD_REQUEST);
250 // create key based on source:target:relationshipType
251 String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
252 + ":" + edge.getType();
254 // find the validate the key from the schema
255 Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
257 if (schemaObject == null) {
258 Logger.warn("key :" + key
259 + " not found in relationship schema . Skipping the schema validation");
263 Edge.Builder updatedEdgeBuilder = new Edge.Builder(edge.getType()).id(edge.getId().get());
265 updatedEdgeBuilder.source(new Vertex.Builder(edge.getSource().getType()).id(edge.getSource().getId().get()).build());
266 updatedEdgeBuilder.target(new Vertex.Builder(edge.getTarget().getType()).id(edge.getTarget().getId().get()).build());
268 validateEdgeProps(updatedEdgeBuilder, payload.getProperties(), schemaObject);
270 return updatedEdgeBuilder.build();
271 } catch (Exception ex) {
272 throw new CrudException(ex.getMessage(), Status.BAD_REQUEST);
277 private static void validateEdgeProps(Edge.Builder builder, JsonElement props, Map<String, Class<?>> schemaObject) throws CrudException {
278 Set<Map.Entry<String, JsonElement>> entries = props.getAsJsonObject().entrySet();
280 for (Map.Entry<String, JsonElement> entry : entries) {
281 if (!schemaObject.containsKey(entry.getKey())) {
282 throw new CrudException("Invalid property: " + entry.getKey(), Status.BAD_REQUEST);
284 Object value = CrudServiceUtil.validateFieldType(entry.getValue().getAsString(),
285 schemaObject.get(entry.getKey()));
286 builder.property(entry.getKey(), value);
291 public static Edge validateOutgoingPayload(String version, Edge edge) throws CrudException {
292 Edge.Builder modelEdgeBuilder = new Edge.Builder(edge.getType()).id(edge.getId()
293 .get()).source(edge.getSource())
294 .target(edge.getTarget());
296 RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
298 String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
299 + ":" + edge.getType();
300 Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
302 if (schemaObject == null || schemaObject.isEmpty()) {
306 for (String prop : edge.getProperties().keySet()) {
307 if (schemaObject.containsKey(prop)) {
308 modelEdgeBuilder.property(prop, edge.getProperties().get(prop));
312 return modelEdgeBuilder.build();
315 public static String vertexTypeFromUri(String uri) throws CrudException {
317 Matcher matcher = urlPattern.matcher(uri);
319 if (!matcher.matches()) {
320 throw new CrudException("Invalid Source/Target Urls", Status.BAD_REQUEST);
323 return matcher.group(2);