Either log or rethrow this exception
[aai/champ.git] / champ-lib / champ-core / src / main / java / org / onap / aai / champcore / graph / impl / InMemoryChampGraphImpl.java
1 /**
2  * ============LICENSE_START==========================================
3  * org.onap.aai
4  * ===================================================================
5  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2017 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  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  */
22 package org.onap.aai.champcore.graph.impl;
23
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Optional;
28 import java.util.concurrent.ConcurrentHashMap;
29 import java.util.stream.Stream;
30
31 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
32 import org.apache.tinkerpop.gremlin.structure.Edge;
33 import org.apache.tinkerpop.gremlin.structure.Vertex;
34 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
35 import org.onap.aai.champcore.ChampCapabilities;
36 import org.onap.aai.champcore.ChampTransaction;
37 import org.onap.aai.champcore.NoOpTinkerPopTransaction;
38 import org.onap.aai.champcore.exceptions.ChampIndexNotExistsException;
39 import org.onap.aai.champcore.model.ChampObject;
40 import org.onap.aai.champcore.model.ChampObjectIndex;
41 import org.onap.aai.champcore.model.ChampRelationshipIndex;
42 import org.onap.aai.champcore.schema.ChampSchemaEnforcer;
43 import org.onap.aai.champcore.schema.DefaultChampSchemaEnforcer;
44
45 public final class InMemoryChampGraphImpl extends AbstractTinkerpopChampGraph {
46
47         private static final ChampCapabilities CAPABILITIES = new ChampCapabilities() {
48
49                 @Override
50                 public boolean canDeleteObjectIndices() {
51                         return true;
52                 }
53
54                 @Override
55                 public boolean canDeleteRelationshipIndices() {
56                         return true;
57                 }
58         };
59
60         private final ConcurrentHashMap<String, ChampObjectIndex> objectIndices;
61         private final ConcurrentHashMap<String, ChampRelationshipIndex> relationshipIndices;
62
63         private final ChampSchemaEnforcer schemaEnforcer;
64         private final TinkerGraph graph;
65
66         private InMemoryChampGraphImpl(Builder builder) {
67             super(builder.graphConfiguration);
68                 this.graph = TinkerGraph.open();
69         
70                 this.objectIndices = new ConcurrentHashMap<String, ChampObjectIndex> ();
71                 this.relationshipIndices = new ConcurrentHashMap<String, ChampRelationshipIndex> ();
72
73                 this.schemaEnforcer = builder.schemaEnforcer;
74         }
75
76         @Override
77     public ChampTransaction getOrCreateTransactionInstance(Optional<ChampTransaction> transaction) {
78
79           return new NoOpTinkerPopTransaction(getGraph());
80
81         }
82            
83         public static class Builder {
84             private final Map<String, Object> graphConfiguration = new HashMap<String, Object> ();
85                 private ChampSchemaEnforcer schemaEnforcer = new DefaultChampSchemaEnforcer();
86
87                 public Builder() {}
88
89                 public Builder schemaEnforcer(ChampSchemaEnforcer schemaEnforcer) {
90                         this.schemaEnforcer = schemaEnforcer;
91                         return this;
92                 }
93
94               public Builder properties(Map<String, Object> properties) {
95             
96             this.graphConfiguration.putAll(properties);
97             return this;
98         }
99
100         public Builder property(String path, Object value) {
101            
102             graphConfiguration.put(path, value);
103             return this;
104         }
105         
106                 public InMemoryChampGraphImpl build() {
107                         return new InMemoryChampGraphImpl(this);
108                 }
109         }
110
111         protected ChampSchemaEnforcer getSchemaEnforcer() {
112                 return schemaEnforcer;
113         }
114
115         @Override
116         protected TinkerGraph getGraph() {
117                 return graph;
118         }
119
120         
121         private ConcurrentHashMap<String, ChampObjectIndex> getObjectIndices() {
122                 return objectIndices;
123         }
124
125         private ConcurrentHashMap<String, ChampRelationshipIndex> getRelationshipIndices() {
126                 return relationshipIndices;
127         }
128
129         @Override
130         public void executeStoreObjectIndex(ChampObjectIndex index) {
131           
132                 if (isShutdown()) throw new IllegalStateException("Cannot call storeObjectIndex() after shutdown has been initiated");
133
134                 getGraph().createIndex(index.getField().getName(), Vertex.class);
135                 getObjectIndices().put(index.getName(), index);
136         }
137
138         @Override
139         public Optional<ChampObjectIndex> retrieveObjectIndex(String indexName) {
140                 if (isShutdown()) throw new IllegalStateException("Cannot call retrieveObjectIndex() after shutdown has been initiated");
141
142                 if (getObjectIndices().containsKey(indexName))
143                         return Optional.of(getObjectIndices().get(indexName));
144                         
145                 return Optional.empty();
146         }
147
148         @Override
149         public Stream<ChampObjectIndex> retrieveObjectIndices() {
150                 if (isShutdown()) throw new IllegalStateException("Cannot call retrieveObjectIndices() after shutdown has been initiated");
151
152                 return getObjectIndices().values().stream();
153         }
154
155         public void executeDeleteObjectIndex(String indexName) throws ChampIndexNotExistsException {
156                 if (isShutdown()) throw new IllegalStateException("Cannot call deleteObjectIndex() after shutdown has been initiated");
157
158                 final ChampObjectIndex objectIndex = getObjectIndices().remove(indexName);
159
160                 if (objectIndex == null) throw new ChampIndexNotExistsException();
161
162                 getGraph().dropIndex(objectIndex.getField().getName(), Vertex.class);
163         }
164
165         public void executeStoreRelationshipIndex(ChampRelationshipIndex index) {
166                 if (isShutdown()) throw new IllegalStateException("Cannot call storeRelationshipIndex() after shutdown has been initiated");
167
168                 getGraph().createIndex(index.getField().getName(), Edge.class);
169                 getRelationshipIndices().put(index.getName(), index);
170         }
171
172         @Override
173         public Optional<ChampRelationshipIndex> retrieveRelationshipIndex(String indexName) {
174                 if (isShutdown()) throw new IllegalStateException("Cannot call retrieveRelationshipIndex() after shutdown has been initiated");
175
176                 if (getRelationshipIndices().containsKey(indexName)) {
177                         return Optional.of(getRelationshipIndices().get(indexName));
178                 }
179                 
180                 return Optional.empty();
181         }
182
183         @Override
184         public Stream<ChampRelationshipIndex> retrieveRelationshipIndices() {
185                 if (isShutdown()) throw new IllegalStateException("Cannot call retrieveRelationshipIndices() after shutdown has been initiated");
186
187                 return getRelationshipIndices().values().stream();
188         }
189
190         public void executeDeleteRelationshipIndex(String indexName) throws ChampIndexNotExistsException {
191                 if (isShutdown()) throw new IllegalStateException("Cannot call deleteRelationshipIndex() after shutdown has been initiated");
192
193                 final ChampRelationshipIndex relationshipIndex = getRelationshipIndices().remove(indexName);
194
195                 if (relationshipIndex == null) throw new ChampIndexNotExistsException();
196                 
197                 getGraph().dropIndex(relationshipIndex.getField().getName(), Edge.class);
198         }
199
200         @Override
201         public ChampCapabilities capabilities() {
202                 return CAPABILITIES;
203         }
204
205         @Override
206         public GraphTraversal<?, ?> hasLabel(GraphTraversal<?, ?> query, Object type) {
207                 return query.hasLabel((String)type, (String)type);
208         }
209 }