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.aai.champcore.graph.impl;
24 import java.util.Optional;
26 import org.onap.aai.champcore.ChampTransaction;
27 import org.onap.aai.champcore.event.AbstractLoggingChampGraph;
28 import org.onap.aai.champcore.exceptions.ChampMarshallingException;
29 import org.onap.aai.champcore.exceptions.ChampObjectNotExistsException;
30 import org.onap.aai.champcore.exceptions.ChampRelationshipNotExistsException;
31 import org.onap.aai.champcore.exceptions.ChampSchemaViolationException;
32 import org.onap.aai.champcore.exceptions.ChampTransactionException;
33 import org.onap.aai.champcore.exceptions.ChampUnmarshallingException;
34 import org.onap.aai.champcore.model.ChampObject;
35 import org.onap.aai.champcore.model.ChampObjectConstraint;
36 import org.onap.aai.champcore.model.ChampPartition;
37 import org.onap.aai.champcore.model.ChampRelationship;
38 import org.onap.aai.champcore.model.ChampRelationshipConstraint;
39 import org.onap.aai.champcore.model.ChampSchema;
40 import org.onap.aai.champcore.schema.ChampSchemaEnforcer;
42 public abstract class AbstractValidatingChampGraph extends AbstractLoggingChampGraph {
44 public static final String CANNOT_USE_CHAMP_API_AFTER_CALLING_SHUTDOWN = "Cannot use ChampAPI after calling shutdown()";
45 private ChampSchema schema = ChampSchema.emptySchema();
47 protected AbstractValidatingChampGraph(Map<String, Object> properties) {
50 protected abstract ChampSchemaEnforcer getSchemaEnforcer();
52 protected abstract boolean isShutdown();
55 * Updates an existing vertex in the graph data store.
57 * If a transaction context is not provided, then a transaction will be automatically
58 * created and committed for this operation only, otherwise, the supplied transaction
59 * will be used and it will be up to the caller to commit the transaction at its
63 * @param object - The vertex to be updated in the graph data store.
64 * @param transaction - Optional transaction context to perform the operation in.
66 * @return - The updated vertex, marshaled as a {@link ChampObject}
68 * @throws ChampMarshallingException - If the {@code relationship} is not able to be
69 * marshalled into the backend representation
70 * @throws ChampObjectNotExistsException - If {@link org.onap.aai.champcore.model.ChampObject#getKey}
71 * is not present or object not found in the graph
73 protected abstract ChampObject doReplaceObject(ChampObject object, Optional<ChampTransaction> transaction) throws ChampMarshallingException, ChampObjectNotExistsException, ChampTransactionException;
76 * Creates or updates a vertex in the graph data store.
78 * If a transaction context is not provided, then a transaction will be automatically
79 * created and committed for this operation only, otherwise, the supplied transaction
80 * will be used and it will be up to the caller to commit the transaction at its
83 * @param object - The vertex to be stored in the graph data store.
84 * @param transaction - Optional transaction context to perform the operation in.
86 * @return - The vertex which was created, marshaled as a {@link ChampObject}
88 * @throws ChampMarshallingException - If the {@code relationship} is not able to be
89 * marshaled into the back end representation
90 * @throws ChampObjectNotExistsException - If {@link org.onap.aai.champcore.model.ChampObject#getKey}
91 * is not present or object not found in the graph
93 protected abstract ChampObject doStoreObject(ChampObject object, Optional<ChampTransaction> transaction) throws ChampMarshallingException, ChampObjectNotExistsException, ChampTransactionException;
96 * Replaces an edge in the graph data store.
98 * If a transaction context is not provided, then a transaction will be automatically
99 * created and committed for this operation only, otherwise, the supplied transaction
100 * will be used and it will be up to the caller to commit the transaction at its
103 * @param relationship - The edge to be replaced in the graph data store.
104 * @param transaction - Optional transaction context to perform the operation in.
106 * @return - The edge as it was replaced, marshaled as a {@link ChampRelationship}
108 * @throws ChampUnmarshallingException - If the edge which was created could not be
109 * unmarshaled into a ChampObject
110 * @throws ChampRelationshipNotExistsException - If {@link org.onap.aai.champcore.model.ChampRelationship#getKey}.isPresent()
111 * but the object cannot be found in the graph
112 * @throws ChampMarshallingException - If the {@code relationship} is not able to be
113 * marshaled into the back end representation
115 protected abstract ChampRelationship doReplaceRelationship(ChampRelationship relationship, Optional<ChampTransaction> transaction) throws ChampUnmarshallingException, ChampRelationshipNotExistsException, ChampMarshallingException, ChampTransactionException;
118 * Creates or updates a relationship in the graph data store.
120 * If a transaction context is not provided, then a transaction will be automatically
121 * created and committed for this operation only, otherwise, the supplied transaction
122 * will be used and it will be up to the caller to commit the transaction at its
125 * @param relationship - The relationship to be stored in the graph data store.
126 * @param transaction - Optional transaction context to perform the operation in.
128 * @return - The relationship that was stored.
130 * @throws ChampUnmarshallingException - If the edge which was created could not be
131 * unmarshalled into a ChampObject
132 * @throws ChampObjectNotExistsException - If {@link org.onap.aai.champcore.model.ChampObject#getKey}
133 * is not present or object not found in the graph
134 * @throws ChampRelationshipNotExistsException - If {@link org.onap.aai.champcore.model.ChampRelationship#getKey}.isPresent()
135 * but the object cannot be found in the graph
136 * @throws ChampMarshallingException - If the {@code relationship} is not able to be
137 * marshalled into the backend representation
139 protected abstract ChampRelationship doStoreRelationship(ChampRelationship relationship, Optional<ChampTransaction> transaction) throws ChampUnmarshallingException, ChampObjectNotExistsException, ChampRelationshipNotExistsException, ChampMarshallingException, ChampTransactionException;
142 * Creates or updates a partition in the graph data store.
144 * @param partition - The partition to be stored in the graph data store.
145 * @param transaction - Optional transaction context to perform the operation in.
147 * @return - The partition that was stored.
149 * @throws ChampRelationshipNotExistsException - If {@link org.onap.aai.champcore.model.ChampRelationship#getKey}.isPresent()
150 * but the object cannot be found in the graph
151 * @throws ChampMarshallingException - If the {@code relationship} is not able to be
152 * marshalled into the backend representation
153 * @throws ChampObjectNotExistsException - If {@link org.onap.aai.champcore.model.ChampObject#getKey}
154 * is not present or object not found in the graph
156 protected abstract ChampPartition doStorePartition(ChampPartition partition, Optional<ChampTransaction> transaction) throws ChampRelationshipNotExistsException, ChampMarshallingException, ChampObjectNotExistsException, ChampTransactionException;
159 public ChampObject executeStoreObject(ChampObject object, Optional<ChampTransaction> transaction)
160 throws ChampMarshallingException, ChampSchemaViolationException, ChampObjectNotExistsException, ChampTransactionException {
163 throw new IllegalStateException(CANNOT_USE_CHAMP_API_AFTER_CALLING_SHUTDOWN);
168 return doStoreObject(object, transaction);
173 public ChampObject executeReplaceObject(ChampObject object, Optional<ChampTransaction> transaction)
174 throws ChampMarshallingException, ChampSchemaViolationException, ChampObjectNotExistsException, ChampTransactionException {
177 throw new IllegalStateException(CANNOT_USE_CHAMP_API_AFTER_CALLING_SHUTDOWN);
182 return doReplaceObject(object, transaction);
186 public ChampRelationship executeStoreRelationship(ChampRelationship relationship, Optional<ChampTransaction> transaction)
187 throws ChampUnmarshallingException, ChampMarshallingException, ChampObjectNotExistsException, ChampSchemaViolationException, ChampRelationshipNotExistsException, ChampTransactionException {
190 throw new IllegalStateException(CANNOT_USE_CHAMP_API_AFTER_CALLING_SHUTDOWN);
193 validate(relationship);
195 return doStoreRelationship(relationship, transaction);
199 public ChampRelationship executeReplaceRelationship(ChampRelationship relationship, Optional<ChampTransaction> transaction)
200 throws ChampUnmarshallingException, ChampMarshallingException, ChampSchemaViolationException, ChampRelationshipNotExistsException, ChampTransactionException {
203 throw new IllegalStateException(CANNOT_USE_CHAMP_API_AFTER_CALLING_SHUTDOWN);
206 validate(relationship);
208 return doReplaceRelationship(relationship, transaction);
212 public ChampPartition executeStorePartition(ChampPartition partition, Optional<ChampTransaction> transaction) throws ChampSchemaViolationException, ChampRelationshipNotExistsException, ChampMarshallingException, ChampObjectNotExistsException, ChampTransactionException {
215 throw new IllegalStateException(CANNOT_USE_CHAMP_API_AFTER_CALLING_SHUTDOWN);
220 return doStorePartition(partition, transaction);
223 protected void validate(ChampObject object) throws ChampSchemaViolationException {
224 final Optional<ChampObjectConstraint> objectConstraint = retrieveSchema().getObjectConstraint(object.getType());
226 if (objectConstraint.isPresent())
227 getSchemaEnforcer().validate(object, objectConstraint.get());
230 protected void validate(ChampRelationship relationship) throws ChampSchemaViolationException {
231 final ChampSchema graphSchema = retrieveSchema();
232 final Optional<ChampRelationshipConstraint> relationshipConstraint = graphSchema.getRelationshipConstraint(relationship.getType());
233 final Optional<ChampObjectConstraint> sourceObjConstraint = graphSchema.getObjectConstraint(relationship.getSource().getType());
234 final Optional<ChampObjectConstraint> targetObjConstraint = graphSchema.getObjectConstraint(relationship.getTarget().getType());
236 if (relationshipConstraint.isPresent())
237 getSchemaEnforcer().validate(relationship, relationshipConstraint.get());
238 if (sourceObjConstraint.isPresent())
239 getSchemaEnforcer().validate(relationship.getSource(), sourceObjConstraint.get());
240 if (targetObjConstraint.isPresent())
241 getSchemaEnforcer().validate(relationship.getTarget(), targetObjConstraint.get());
244 protected void validate(ChampPartition partition) throws ChampSchemaViolationException {
245 for (ChampObject object : partition.getChampObjects()) {
249 for (ChampRelationship relationship : partition.getChampRelationships()) {
250 validate(relationship);
255 public void storeSchema(ChampSchema schema) throws ChampSchemaViolationException {
257 throw new IllegalStateException("Cannot call storeSchema() after shutdown has been initiated");
259 this.schema = schema;
263 public ChampSchema retrieveSchema() {
265 throw new IllegalStateException("Cannot call retrieveSchema() after shutdown has been initiated");
271 public void updateSchema(ChampObjectConstraint objectConstraint) throws ChampSchemaViolationException {
273 throw new IllegalStateException("Cannot call updateSchema() after shutdown has been initiated");
275 final ChampSchema currentSchema = retrieveSchema();
276 final ChampSchema updatedSchema = new ChampSchema.Builder(currentSchema)
277 .constraint(objectConstraint)
280 storeSchema(updatedSchema);
284 public void updateSchema(ChampRelationshipConstraint relationshipConstraint) throws ChampSchemaViolationException {
286 throw new IllegalStateException("Cannot call updateSchema() after shutdown has been initiated");
288 final ChampSchema currentSchema = retrieveSchema();
289 final ChampSchema updatedSchema = new ChampSchema.Builder(currentSchema)
290 .constraint(relationshipConstraint)
293 storeSchema(updatedSchema);
297 public void deleteSchema() {
299 throw new IllegalStateException("Cannot call deleteSchema() after shutdown has been initiated");
300 this.schema = ChampSchema.emptySchema();