[AAI-2175] Change aai champ container processes to run as non-root on the host
[aai/champ.git] / champ-lib / champ-core / src / main / java / org / onap / aai / champcore / graph / impl / AbstractValidatingChampGraph.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.aai.champcore.graph.impl;
22
23 import java.util.Map;
24 import java.util.Optional;
25
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;
41
42 public abstract class AbstractValidatingChampGraph extends AbstractLoggingChampGraph {
43
44         public static final String CANNOT_USE_CHAMP_API_AFTER_CALLING_SHUTDOWN = "Cannot use ChampAPI after calling shutdown()";
45         private ChampSchema schema = ChampSchema.emptySchema();
46
47         protected AbstractValidatingChampGraph(Map<String, Object> properties) {
48                 super(properties);
49         }
50         protected abstract ChampSchemaEnforcer getSchemaEnforcer();
51
52         protected abstract boolean isShutdown();
53
54         /**
55          * Updates an existing vertex in the graph data store.
56          * <p>
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
60      * discretion.
61      * <p>
62      *
63          * @param object      - The vertex to be updated in the graph data store.
64          * @param transaction - Optional transaction context to perform the operation in.
65          *
66          * @return - The updated vertex, marshaled as a {@link ChampObject}
67          *
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
72          */
73         protected abstract ChampObject doReplaceObject(ChampObject object, Optional<ChampTransaction> transaction) throws ChampMarshallingException, ChampObjectNotExistsException, ChampTransactionException;
74
75     /**
76      * Creates or updates a vertex in the graph data store.
77      * <p>
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
81      * discretion.
82      *
83          * @param object      - The vertex to be stored in the graph data store.
84          * @param transaction - Optional transaction context to perform the operation in.
85          *
86          * @return - The vertex which was created, marshaled as a {@link ChampObject}
87          *
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
92          */
93         protected abstract ChampObject doStoreObject(ChampObject object, Optional<ChampTransaction> transaction) throws ChampMarshallingException, ChampObjectNotExistsException, ChampTransactionException;
94
95         /**
96          * Replaces an edge in the graph data store.
97      * <p>
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
101      * discretion.
102      *
103          * @param relationship - The edge to be replaced in the graph data store.
104          * @param transaction  - Optional transaction context to perform the operation in.
105          *
106          * @return - The edge as it was replaced, marshaled as a {@link ChampRelationship}
107          *
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
114          */
115         protected abstract ChampRelationship doReplaceRelationship(ChampRelationship relationship, Optional<ChampTransaction> transaction) throws ChampUnmarshallingException, ChampRelationshipNotExistsException, ChampMarshallingException, ChampTransactionException;
116
117         /**
118          * Creates or updates a relationship in the graph data store.
119      * <p>
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
123      * discretion.
124      *
125          * @param relationship - The relationship to be stored in the graph data store.
126          * @param transaction  - Optional transaction context to perform the operation in.
127          *
128          * @return - The relationship that was stored.
129          *
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
138          */
139         protected abstract ChampRelationship doStoreRelationship(ChampRelationship relationship, Optional<ChampTransaction> transaction) throws ChampUnmarshallingException, ChampObjectNotExistsException, ChampRelationshipNotExistsException, ChampMarshallingException, ChampTransactionException;
140
141         /**
142          * Creates or updates a partition in the graph data store.
143          *
144          * @param partition   - The partition to be stored in the graph data store.
145          * @param transaction - Optional transaction context to perform the operation in.
146          *
147          * @return - The partition that was stored.
148          *
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
155          */
156         protected abstract ChampPartition doStorePartition(ChampPartition partition, Optional<ChampTransaction> transaction) throws ChampRelationshipNotExistsException, ChampMarshallingException, ChampObjectNotExistsException, ChampTransactionException;
157
158         @Override
159         public ChampObject executeStoreObject(ChampObject object, Optional<ChampTransaction> transaction)
160                         throws ChampMarshallingException, ChampSchemaViolationException, ChampObjectNotExistsException, ChampTransactionException {
161           
162           if (isShutdown()) {
163             throw new IllegalStateException(CANNOT_USE_CHAMP_API_AFTER_CALLING_SHUTDOWN);
164           }
165
166       validate(object);
167
168       return doStoreObject(object, transaction);
169         }
170           
171
172         @Override
173         public ChampObject executeReplaceObject(ChampObject object, Optional<ChampTransaction> transaction)
174                         throws ChampMarshallingException, ChampSchemaViolationException, ChampObjectNotExistsException, ChampTransactionException {
175           
176                 if (isShutdown()) {
177                   throw new IllegalStateException(CANNOT_USE_CHAMP_API_AFTER_CALLING_SHUTDOWN);
178                 }
179
180                 validate(object);
181
182                 return doReplaceObject(object, transaction);
183         }
184
185         @Override
186         public ChampRelationship executeStoreRelationship(ChampRelationship relationship, Optional<ChampTransaction> transaction)
187                         throws ChampUnmarshallingException, ChampMarshallingException, ChampObjectNotExistsException, ChampSchemaViolationException, ChampRelationshipNotExistsException, ChampTransactionException {   
188                 
189           if (isShutdown()) {
190             throw new IllegalStateException(CANNOT_USE_CHAMP_API_AFTER_CALLING_SHUTDOWN);
191           }
192
193           validate(relationship);
194
195           return doStoreRelationship(relationship, transaction);
196         }
197         
198         @Override
199         public ChampRelationship executeReplaceRelationship(ChampRelationship relationship, Optional<ChampTransaction> transaction)
200                         throws ChampUnmarshallingException, ChampMarshallingException, ChampSchemaViolationException, ChampRelationshipNotExistsException, ChampTransactionException {  
201                 
202           if (isShutdown()) {
203             throw new IllegalStateException(CANNOT_USE_CHAMP_API_AFTER_CALLING_SHUTDOWN);
204           }
205
206           validate(relationship);
207
208           return doReplaceRelationship(relationship, transaction);
209         }
210
211         @Override
212         public ChampPartition executeStorePartition(ChampPartition partition, Optional<ChampTransaction> transaction) throws ChampSchemaViolationException, ChampRelationshipNotExistsException, ChampMarshallingException, ChampObjectNotExistsException, ChampTransactionException {
213
214           if (isShutdown()) {
215             throw new IllegalStateException(CANNOT_USE_CHAMP_API_AFTER_CALLING_SHUTDOWN);
216           }
217
218           validate(partition);
219
220           return doStorePartition(partition, transaction);
221         }
222
223         protected void validate(ChampObject object) throws ChampSchemaViolationException {
224                 final Optional<ChampObjectConstraint> objectConstraint = retrieveSchema().getObjectConstraint(object.getType());
225
226                 if (objectConstraint.isPresent())
227                         getSchemaEnforcer().validate(object, objectConstraint.get());
228         }
229
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());
235
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());
242         }
243
244         protected void validate(ChampPartition partition) throws ChampSchemaViolationException {
245                 for (ChampObject object : partition.getChampObjects()) {
246                         validate(object);
247                 }
248
249                 for (ChampRelationship relationship : partition.getChampRelationships()) {
250                         validate(relationship);
251                 }
252         }
253
254         @Override
255         public void storeSchema(ChampSchema schema) throws ChampSchemaViolationException {
256                 if (isShutdown())
257                         throw new IllegalStateException("Cannot call storeSchema() after shutdown has been initiated");
258
259                 this.schema = schema;
260         }
261
262         @Override
263         public ChampSchema retrieveSchema() {
264                 if (isShutdown())
265                         throw new IllegalStateException("Cannot call retrieveSchema() after shutdown has been initiated");
266
267                 return schema;
268         }
269
270         @Override
271         public void updateSchema(ChampObjectConstraint objectConstraint) throws ChampSchemaViolationException {
272                 if (isShutdown())
273                         throw new IllegalStateException("Cannot call updateSchema() after shutdown has been initiated");
274
275                 final ChampSchema currentSchema = retrieveSchema();
276                 final ChampSchema updatedSchema = new ChampSchema.Builder(currentSchema)
277                                                                                                 .constraint(objectConstraint)
278                                                                                                 .build();
279                 
280                 storeSchema(updatedSchema);
281         }
282
283         @Override
284         public void updateSchema(ChampRelationshipConstraint relationshipConstraint) throws ChampSchemaViolationException {
285                 if (isShutdown())
286                         throw new IllegalStateException("Cannot call updateSchema() after shutdown has been initiated");
287
288                 final ChampSchema currentSchema = retrieveSchema();
289                 final ChampSchema updatedSchema = new ChampSchema.Builder(currentSchema)
290                                                                                                 .constraint(relationshipConstraint)
291                                                                                                 .build();
292                 
293                 storeSchema(updatedSchema);
294         }
295
296         @Override
297         public void deleteSchema() {
298                 if (isShutdown())
299                         throw new IllegalStateException("Cannot call deleteSchema() after shutdown has been initiated");
300                 this.schema = ChampSchema.emptySchema();
301         }
302 }