optionally disable client auth in gizmo
[aai/gizmo.git] / src / main / java / org / onap / schema / validation / RelationshipSchemaValidator.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
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
11  *
12  *       http://www.apache.org/licenses/LICENSE-2.0
13  *
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=========================================================
20  */
21 package org.onap.schema.validation;
22
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27 import javax.ws.rs.core.Response.Status;
28 import org.onap.crud.entity.Edge;
29 import org.onap.crud.entity.Vertex;
30 import org.onap.crud.exception.CrudException;
31 import org.onap.crud.parser.EdgePayload;
32 import org.onap.crud.parser.util.EdgePayloadUtil;
33 import org.onap.crud.util.CrudServiceUtil;
34 import org.onap.schema.EdgeRulesLoader;
35 import org.onap.schema.RelationshipSchema;
36 import org.onap.schema.validation.OxmModelValidator.Metadata;
37 import org.radeox.util.logging.Logger;
38 import com.google.gson.JsonElement;
39 import com.google.gson.JsonNull;
40
41 public class RelationshipSchemaValidator {
42
43   private static final String SOURCE_LABEL = "Source";
44   private static final String TARGET_LABEL = "Target";
45
46   public static Map<String, Object> resolveCollectionfilter(String version, String type, Map<String, String> filter) throws CrudException {
47     RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
48     if (schema == null) {
49       throw new CrudException("", Status.NOT_FOUND);
50     }
51
52     Map<String, Class<?>> props = schema.lookupRelationType(type);
53     Map<String, Object> result = new HashMap<String, Object>();
54
55     for (String key : filter.keySet()) {
56
57       if (props.containsKey(key)) {
58         try {
59           Object value = CrudServiceUtil.validateFieldType(filter.get(key), props.get(key));
60           result.put(key, value);
61         } catch (Exception ex) {
62           // Skip any exceptions thrown while validating the filter key value
63           continue;
64         }
65       }
66     }
67     return result;
68   }
69
70   public static void validateType(String version, String type) throws CrudException {
71     RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
72     if (!schema.isValidType(type)) {
73       throw new CrudException("Invalid " + RelationshipSchema.SCHEMA_RELATIONSHIP_TYPE
74           + ": " + type,
75           Status.BAD_REQUEST);
76     }
77
78   }
79
80   public static Edge validateIncomingAddPayload(String version, String type, EdgePayload payload,
81     List<Edge> sourceVertexEdges, List<Edge> targetVertexEdges) throws CrudException {
82
83     //perform standard validation
84     Edge edge = validateIncomingAddPayload(version, type, payload);
85
86     // validate payload using multiplicity edge rules
87     MultiplicityValidator.validatePayloadMultiplicity(payload, sourceVertexEdges, targetVertexEdges, type, version);
88
89     return edge;
90   }
91
92   public static Edge validateIncomingAddPayload(String version, String type, EdgePayload payload)
93       throws CrudException {
94     RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
95
96     try {
97       if (payload.getSource() == null || payload.getTarget() == null) {
98         throw new CrudException("Source/Target not specified", Status.BAD_REQUEST);
99       }
100
101       String key = EdgePayloadUtil.generateEdgeKey(payload.getSource(), payload.getTarget(), type);
102
103       // find the validate the key from the schema
104       Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
105
106       if (schemaObject == null) {
107         throw new CrudException("Invalid source/target/relationship type: " + key, Status.BAD_REQUEST);
108       }
109
110       Edge.Builder modelEdgeBuilder = EdgePayloadUtil.getBuilderFromEdgePayload(payload.getSource(), payload.getTarget(), type);
111
112       // validate it properties
113       validateEdgeProps(modelEdgeBuilder, payload.getProperties(), schemaObject);
114
115       return modelEdgeBuilder.build();
116     } catch (Exception ex) {
117       throw new CrudException(ex.getMessage(), Status.BAD_REQUEST);
118     }
119   }
120
121   public static Edge validateIncomingPatchPayload(Edge edge, String version, EdgePayload payload)
122       throws CrudException {
123     RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
124
125     try {
126       validateEdgeVertexMatchesPayload(edge.getSource(), payload.getSource(), SOURCE_LABEL);
127       validateEdgeVertexMatchesPayload(edge.getTarget(), payload.getTarget(), TARGET_LABEL);
128
129       // Remove the timestamp properties from the existing edge, as these should be managed by Champ.
130       Map<String,Object> existingProps = edge.getProperties();
131
132       if (existingProps.containsKey(Metadata.CREATED_TS.propertyName())) {
133         existingProps.remove(Metadata.CREATED_TS.propertyName());
134       }
135       if (existingProps.containsKey(Metadata.UPDATED_TS.propertyName())) {
136         existingProps.remove(Metadata.UPDATED_TS.propertyName());
137       }
138
139       // create key based on source:target:relationshipType
140       String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
141           + ":" + edge.getType();
142
143       // find the validate the key from the schema
144       Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
145
146       if (schemaObject == null) {
147         Logger.warn("key :" + key
148             + " not found in relationship schema . Skipping the schema validation");
149         return edge;
150       }
151
152       validateEdgePropertiesFromPayload(edge, payload, schemaObject);
153
154       return edge;
155     } catch (Exception ex) {
156       throw new CrudException(ex.getMessage(), Status.BAD_REQUEST);
157     }
158   }
159
160   private static void validateEdgePropertiesFromPayload(Edge edge, EdgePayload payload, Map<String, Class<?>> schemaObject) throws CrudException {
161     Set<Map.Entry<String, JsonElement>> entries = payload.getProperties().getAsJsonObject().entrySet();
162     for (Map.Entry<String, JsonElement> entry : entries) {
163
164       if (!schemaObject.containsKey(entry.getKey())) {
165         throw new CrudException("Invalid property: " + entry.getKey(), Status.BAD_REQUEST);
166       } else if (entry.getValue() instanceof JsonNull && edge.getProperties().containsKey(entry.getKey())) {
167         edge.getProperties().remove(entry.getKey());
168       } else if (!(entry.getValue() instanceof JsonNull)) {
169         Object value = CrudServiceUtil.validateFieldType(entry.getValue().getAsString(), schemaObject.get(entry.getKey()));
170         edge.getProperties().put(entry.getKey(), value);
171       }
172     }
173   }
174
175
176   public static Edge validateIncomingUpdatePayload(Edge edge, String version, EdgePayload payload, String type,
177             List<Edge> sourceVertexEdges, List<Edge> targetVertexEdges) throws CrudException {
178
179     //perform standard validation
180     Edge validatedEdge = validateIncomingUpdatePayload(edge, version, payload);
181
182     // validate payload using multiplicity edge rules
183     MultiplicityValidator.validatePayloadMultiplicity(payload, sourceVertexEdges, targetVertexEdges, type, version);
184
185     return validatedEdge;
186   }
187
188   public static Edge validateIncomingUpdatePayload(Edge edge, String version, EdgePayload payload)
189       throws CrudException {
190     RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
191
192     try {
193       validateEdgeVertexMatchesPayload(edge.getSource(), payload.getSource(), SOURCE_LABEL);
194       validateEdgeVertexMatchesPayload(edge.getTarget(), payload.getTarget(), TARGET_LABEL);
195
196       // create key based on source:target:relationshipType
197       String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
198           + ":" + edge.getType();
199
200       // find the validate the key from the schema
201       Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
202
203       if (schemaObject == null) {
204         Logger.warn("key :" + key
205             + " not found in relationship schema . Skipping the schema validation");
206         return edge;
207       }
208
209       Edge.Builder updatedEdgeBuilder = EdgePayloadUtil.getBuilderFromEdge(edge);
210
211       validateEdgeProps(updatedEdgeBuilder, payload.getProperties(), schemaObject);
212
213       return updatedEdgeBuilder.build();
214     } catch (Exception ex) {
215       throw new CrudException(ex.getMessage(), Status.BAD_REQUEST);
216     }
217   }
218
219   private static void validateEdgeVertexMatchesPayload(Vertex edgeVertex, String payloadVertex, String vertexTypeLabel) throws CrudException {
220     if (payloadVertex != null) {
221       String sourceNodeId = EdgePayloadUtil.getVertexNodeId(payloadVertex);
222       if (!sourceNodeId.equals(edgeVertex.getId().get())) {
223         throw new CrudException(vertexTypeLabel + " can't be updated", Status.BAD_REQUEST);
224       }
225     }
226   }
227
228   private static void validateEdgeProps(Edge.Builder builder, JsonElement props, Map<String, Class<?>> schemaObject) throws CrudException {
229     Set<Map.Entry<String, JsonElement>> entries = props.getAsJsonObject().entrySet();
230
231     for (Map.Entry<String, JsonElement> entry : entries) {
232       if (!schemaObject.containsKey(entry.getKey())) {
233         throw new CrudException("Invalid property: " + entry.getKey(), Status.BAD_REQUEST);
234       } else {
235         Object value = CrudServiceUtil.validateFieldType(entry.getValue().getAsString(),
236             schemaObject.get(entry.getKey()));
237         builder.property(entry.getKey(), value);
238       }
239     }
240   }
241
242   public static Edge validateOutgoingPayload(String version, Edge edge) throws CrudException {
243     Edge.Builder modelEdgeBuilder = new Edge.Builder(edge.getType()).id(edge.getId()
244         .get()).source(edge.getSource())
245         .target(edge.getTarget());
246
247     RelationshipSchema schema = EdgeRulesLoader.getSchemaForVersion(version);
248
249     String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
250         + ":" + edge.getType();
251     Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
252
253     if (schemaObject == null || schemaObject.isEmpty()) {
254       return edge;
255     }
256
257     for (String prop : edge.getProperties().keySet()) {
258       if (schemaObject.containsKey(prop)) {
259         modelEdgeBuilder.property(prop, edge.getProperties().get(prop));
260       }
261
262     }
263     return modelEdgeBuilder.build();
264   }
265 }