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