Updated champ-lib to use the correct logger
[aai/champ.git] / champ-lib / champ-janus / src / main / java / org / onap / aai / champjanus / graph / impl / JanusChampGraphImpl.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.champjanus.graph.impl;
22
23 import java.security.SecureRandom;
24 import java.time.temporal.ChronoUnit;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.NoSuchElementException;
31 import java.util.Optional;
32 import java.util.Spliterator;
33 import java.util.Spliterators;
34 import java.util.concurrent.ExecutionException;
35 import java.util.stream.Stream;
36 import java.util.stream.StreamSupport;
37
38 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
39 import org.apache.tinkerpop.gremlin.structure.Edge;
40 import org.apache.tinkerpop.gremlin.structure.Vertex;
41 import org.janusgraph.core.Cardinality;
42 import org.janusgraph.core.EdgeLabel;
43 import org.janusgraph.core.JanusGraph;
44 import org.janusgraph.core.JanusGraphEdge;
45 import org.janusgraph.core.JanusGraphFactory;
46 import org.janusgraph.core.JanusGraphVertex;
47 import org.janusgraph.core.PropertyKey;
48 import org.janusgraph.core.SchemaViolationException;
49 import org.janusgraph.core.schema.JanusGraphIndex;
50 import org.janusgraph.core.schema.JanusGraphManagement;
51 import org.janusgraph.core.schema.JanusGraphManagement.IndexBuilder;
52 import org.janusgraph.core.schema.SchemaAction;
53 import org.janusgraph.core.schema.SchemaStatus;
54 import org.janusgraph.graphdb.database.management.ManagementSystem;
55 import org.onap.aai.champcore.ChampCapabilities;
56 import org.onap.aai.champcore.exceptions.ChampIndexNotExistsException;
57 import org.onap.aai.champcore.exceptions.ChampSchemaViolationException;
58 import org.onap.aai.champcore.graph.impl.AbstractTinkerpopChampGraph;
59 import org.onap.aai.champcore.model.ChampCardinality;
60 import org.onap.aai.champcore.model.ChampField;
61 import org.onap.aai.champcore.model.ChampObject;
62 import org.onap.aai.champcore.model.ChampObjectConstraint;
63 import org.onap.aai.champcore.model.ChampObjectIndex;
64 import org.onap.aai.champcore.model.ChampPropertyConstraint;
65 import org.onap.aai.champcore.model.ChampRelationship;
66 import org.onap.aai.champcore.model.ChampRelationshipConstraint;
67 import org.onap.aai.champcore.model.ChampRelationshipIndex;
68 import org.onap.aai.champcore.model.ChampSchema;
69 import org.onap.aai.champcore.schema.ChampSchemaEnforcer;
70 import org.onap.aai.champcore.schema.DefaultChampSchemaEnforcer;
71 import org.onap.aai.cl.api.Logger;
72 import org.onap.aai.cl.eelf.LoggerFactory;
73
74 public final class JanusChampGraphImpl extends AbstractTinkerpopChampGraph {
75   private static final Logger LOGGER = LoggerFactory.getInstance().getLogger(JanusChampGraphImpl.class);
76   private static final String JANUS_CASSANDRA_KEYSPACE = "storage.cassandra.keyspace";
77   private static final String JANUS_CQL_KEYSPACE = "storage.cql.keyspace";
78   private static final String JANUS_HBASE_TABLE = "storage.hbase.table";
79   private static final String JANUS_UNIQUE_SUFFIX = "graph.unique-instance-id-suffix";
80   private static final ChampSchemaEnforcer SCHEMA_ENFORCER = new DefaultChampSchemaEnforcer();
81   private static final int REGISTER_OBJECT_INDEX_TIMEOUT_SECS = 45;
82
83   private static final ChampCapabilities CAPABILITIES = new ChampCapabilities() {
84
85     @Override
86     public boolean canDeleteObjectIndices() {
87       return false;
88     }
89
90     @Override
91     public boolean canDeleteRelationshipIndices() {
92       return false;
93     }
94   };
95
96   private JanusGraph graph;
97   private final JanusGraphFactory.Builder janusGraphBuilder;
98
99   public JanusChampGraphImpl(Builder builder) {
100     super(builder.graphConfiguration);
101     janusGraphBuilder = JanusGraphFactory.build();
102
103     for (Map.Entry<String, Object> janusGraphProperty : builder.graphConfiguration.entrySet()) {
104       janusGraphBuilder.set(janusGraphProperty.getKey(), janusGraphProperty.getValue());
105     }
106     
107     janusGraphBuilder.set(JANUS_UNIQUE_SUFFIX, ((short) new SecureRandom().nextInt(Short.MAX_VALUE)+""));
108
109     final Object storageBackend = builder.graphConfiguration.get("storage.backend");
110
111     if ("cassandra".equals(storageBackend) ||
112         "cassandrathrift".equals(storageBackend) ||
113         "astyanax".equals(storageBackend) ||
114         "embeddedcassandra".equals(storageBackend)) {
115
116       janusGraphBuilder.set(JANUS_CASSANDRA_KEYSPACE, builder.graphName);
117     } else if("cql".equals(storageBackend)){
118       janusGraphBuilder.set(JANUS_CQL_KEYSPACE, builder.graphName);
119     } else if ("hbase".equals(storageBackend)) {
120       janusGraphBuilder.set(JANUS_HBASE_TABLE, builder.graphName);
121     } else if ("berkleyje".equals(storageBackend)) {
122       throw new RuntimeException("storage.backend=berkleyje cannot handle multiple graphs on a single DB, not usable");
123     } else if ("inmemory".equals(storageBackend)) {
124     } else {
125       throw new RuntimeException("Unknown storage.backend=" + storageBackend);
126     }
127     
128     try {
129       openGraph();
130     }
131     catch (Exception ex) {
132       // Swallow exception.  Cassandra may not be reachable.  Will retry next time we need to use the graph.
133       LOGGER.error(ChampJanusMsgs.JANUS_CHAMP_GRAPH_IMPL_ERROR,
134           "Error opening graph: " + ex.getMessage());
135       return;
136     }
137     
138     LOGGER.info(ChampJanusMsgs.JANUS_CHAMP_GRAPH_IMPL_INFO,
139         "Instantiated data access layer for Janus graph data store with backend: " + storageBackend);
140   }
141
142   public static class Builder {
143     private final String graphName;
144
145     private final Map<String, Object> graphConfiguration = new HashMap<String, Object>();
146
147     public Builder(String graphName) {
148       this.graphName = graphName;
149     }
150     
151     public Builder(String graphName, Map<String, Object> properties) {
152         this.graphName = graphName;
153         properties(properties);
154     }
155
156     public Builder properties(Map<String, Object> properties) {
157       if (properties.containsKey(JANUS_CASSANDRA_KEYSPACE)) {
158         throw new IllegalArgumentException("Cannot use path " + JANUS_CASSANDRA_KEYSPACE
159             + " in initial configuration - this path is used"
160             + " to specify graph names");
161       }
162
163       this.graphConfiguration.putAll(properties);
164       return this;
165     }
166
167     public Builder property(String path, Object value) {
168       if (path.equals(JANUS_CASSANDRA_KEYSPACE)) {
169         throw new IllegalArgumentException("Cannot use path " + JANUS_CASSANDRA_KEYSPACE
170             + " in initial configuration - this path is used"
171             + " to specify graph names");
172       }
173       graphConfiguration.put(path, value);
174       return this;
175     }
176
177     public JanusChampGraphImpl build() {
178       return new JanusChampGraphImpl(this);
179     }
180   }
181
182   @Override
183   protected JanusGraph getGraph() {
184     if (graph == null) {
185       openGraph();
186     }
187     return graph;
188   }
189
190  
191   @Override
192   protected ChampSchemaEnforcer getSchemaEnforcer() {
193     return SCHEMA_ENFORCER;
194   }
195
196   @Override
197   public void executeStoreObjectIndex(ChampObjectIndex index) {
198     if (isShutdown()) {
199       throw new IllegalStateException("Cannot call storeObjectIndex() after shutdown has been initiated");
200     }
201
202     final JanusGraph graph = getGraph();
203     final JanusGraphManagement createIndexMgmt = graph.openManagement();
204
205     if (createIndexMgmt.getGraphIndex(index.getName()) != null) {
206       createIndexMgmt.rollback();
207       LOGGER.info(ChampJanusMsgs.JANUS_CHAMP_GRAPH_IMPL_INFO,
208           "Index " + index.getName() + " already exists");
209       return; //Ignore, index already exists
210     }
211
212     LOGGER.info(ChampJanusMsgs.JANUS_CHAMP_GRAPH_IMPL_INFO,
213         "Create index " + index.getName());
214     IndexBuilder ib = createIndexMgmt.buildIndex(index.getName(), Vertex.class);
215     for (ChampField field : index.getFields()) {
216       PropertyKey pk = createIndexMgmt.getOrCreatePropertyKey(field.getName());
217       ib = ib.addKey(pk);
218     }
219     ib.buildCompositeIndex();
220
221     createIndexMgmt.commit();
222     graph.tx().commit();
223
224     awaitIndexCreation(index.getName());
225   }
226
227   @Override
228   public Optional<ChampObjectIndex> retrieveObjectIndex(String indexName) {
229     if (isShutdown()) {
230       throw new IllegalStateException("Cannot call retrieveObjectIndex() after shutdown has been initiated");
231     }
232
233     final JanusGraphManagement retrieveIndexMgmt = getGraph().openManagement();
234     final JanusGraphIndex index = retrieveIndexMgmt.getGraphIndex(indexName);
235
236     if (index == null) {
237       return Optional.empty();
238     }
239     if (index.getIndexedElement() != JanusGraphVertex.class) {
240       return Optional.empty();
241     }
242
243     List<String> fieldNames = new ArrayList<String>();
244     for (int i = 0; i < index.getFieldKeys().length; i++) {
245       fieldNames.add(index.getFieldKeys()[i].name());
246     }
247     
248     return Optional.of(ChampObjectIndex.create()
249         .ofName(indexName)
250         .onType(ChampObject.ReservedTypes.ANY.toString())
251         .forFields(fieldNames)
252         .build());
253   }
254
255   @Override
256   public Stream<ChampObjectIndex> retrieveObjectIndices() {
257     if (isShutdown()) {
258       throw new IllegalStateException("Cannot call retrieveObjectIndices() after shutdown has been initiated");
259     }
260
261     final JanusGraphManagement createIndexMgmt = getGraph().openManagement();
262     final Iterator<JanusGraphIndex> indices = createIndexMgmt.getGraphIndexes(Vertex.class).iterator();
263
264     final Iterator<ChampObjectIndex> objIter = new Iterator<ChampObjectIndex>() {
265
266       private ChampObjectIndex next;
267
268       @Override
269       public boolean hasNext() {
270         if (indices.hasNext()) {
271           final JanusGraphIndex index = indices.next();
272
273           List<String> fieldNames = new ArrayList<String>();
274           for (int i = 0; i < index.getFieldKeys().length; i++) {
275             fieldNames.add(index.getFieldKeys()[i].name());
276           }
277           
278           next = ChampObjectIndex.create()
279               .ofName(index.name())
280               .onType(ChampObject.ReservedTypes.ANY.toString())
281               .forFields(fieldNames)
282               .build();
283           return true;
284         }
285
286         next = null;
287         return false;
288       }
289
290       @Override
291       public ChampObjectIndex next() {
292         if (next == null) {
293           throw new NoSuchElementException();
294         }
295
296         return next;
297       }
298     };
299
300     return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
301         objIter, Spliterator.ORDERED | Spliterator.NONNULL), false);
302   }
303
304   @Override
305   public void executeDeleteObjectIndex(String indexName) throws ChampIndexNotExistsException {
306     if (isShutdown()) {
307       throw new IllegalStateException("Cannot call deleteObjectIndex() after shutdown has been initiated");
308     }
309
310     throw new UnsupportedOperationException("Cannot delete indices using the JanusChampImpl");
311   }
312
313   @Override
314   public void executeStoreRelationshipIndex(ChampRelationshipIndex index) {
315     if (isShutdown()) {
316       throw new IllegalStateException("Cannot call storeRelationshipIndex() after shutdown has been initiated");
317     }
318
319     final JanusGraph graph = getGraph();
320     final JanusGraphManagement createIndexMgmt = graph.openManagement();
321     final PropertyKey pk = createIndexMgmt.getOrCreatePropertyKey(index.getField().getName());
322
323     if (createIndexMgmt.getGraphIndex(index.getName()) != null) {
324       return; //Ignore, index already exists
325     }
326     
327     LOGGER.info(ChampJanusMsgs.JANUS_CHAMP_GRAPH_IMPL_INFO,
328         "Create edge index " + index.getName());
329     createIndexMgmt.buildIndex(index.getName(), Edge.class).addKey(pk).buildCompositeIndex();
330
331     createIndexMgmt.commit();
332     graph.tx().commit();
333
334     awaitIndexCreation(index.getName());
335   }
336
337   @Override
338   public Optional<ChampRelationshipIndex> retrieveRelationshipIndex(String indexName) {
339     if (isShutdown()) {
340       throw new IllegalStateException("Cannot call retrieveRelationshipIndex() after shutdown has been initiated");
341     }
342
343     final JanusGraphManagement retrieveIndexMgmt = getGraph().openManagement();
344     final JanusGraphIndex index = retrieveIndexMgmt.getGraphIndex(indexName);
345
346     if (index == null) {
347       return Optional.empty();
348     }
349     if (index.getIndexedElement() != JanusGraphEdge.class) {
350       return Optional.empty();
351     }
352
353     return Optional.of(ChampRelationshipIndex.create()
354         .ofName(indexName)
355         .onType(ChampObject.ReservedTypes.ANY.toString())
356         .forField(index.getFieldKeys()[0].name())
357         .build());
358   }
359
360   @Override
361   public Stream<ChampRelationshipIndex> retrieveRelationshipIndices() {
362     if (isShutdown()) {
363       throw new IllegalStateException("Cannot call retrieveRelationshipIndices() after shutdown has been initiated");
364     }
365
366     final JanusGraphManagement createIndexMgmt = getGraph().openManagement();
367     final Iterator<JanusGraphIndex> indices = createIndexMgmt.getGraphIndexes(Edge.class).iterator();
368
369     final Iterator<ChampRelationshipIndex> objIter = new Iterator<ChampRelationshipIndex>() {
370
371       private ChampRelationshipIndex next;
372
373       @Override
374       public boolean hasNext() {
375         if (indices.hasNext()) {
376           final JanusGraphIndex index = indices.next();
377
378           next = ChampRelationshipIndex.create()
379               .ofName(index.name())
380               .onType(ChampRelationship.ReservedTypes.ANY.toString())
381               .forField(index.getFieldKeys()[0].name())
382               .build();
383           return true;
384         }
385
386         next = null;
387         return false;
388       }
389
390       @Override
391       public ChampRelationshipIndex next() {
392         if (next == null) {
393           throw new NoSuchElementException();
394         }
395
396         return next;
397       }
398     };
399
400     return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
401         objIter, Spliterator.ORDERED | Spliterator.NONNULL), false);
402   }
403
404   @Override
405   public void executeDeleteRelationshipIndex(String indexName) throws ChampIndexNotExistsException {
406     if (isShutdown()) {
407       throw new IllegalStateException("Cannot call deleteRelationshipIndex() after shutdown has been initiated");
408     }
409
410     throw new UnsupportedOperationException("Cannot delete indices using the JanusChampImpl");
411   }
412
413   private Cardinality getJanusCardinality(ChampCardinality cardinality) {
414     switch (cardinality) {
415       case LIST:
416         return Cardinality.LIST;
417       case SET:
418         return Cardinality.SET;
419       case SINGLE:
420         return Cardinality.SINGLE;
421       default:
422         throw new RuntimeException("Unknown ChampCardinality " + cardinality);
423     }
424   }
425
426   private void awaitIndexCreation(String indexName) {
427     //Wait for the index to become available
428     try {
429       if (ManagementSystem.awaitGraphIndexStatus(graph, indexName)
430           .status(SchemaStatus.ENABLED)
431           .timeout(1, ChronoUnit.SECONDS)
432           .call()
433           .getSucceeded()) {
434         return; //Empty graphs immediately ENABLE indices
435       }
436
437       if (!ManagementSystem.awaitGraphIndexStatus(graph, indexName)
438           .status(SchemaStatus.REGISTERED)
439           .timeout(REGISTER_OBJECT_INDEX_TIMEOUT_SECS, ChronoUnit.SECONDS)
440           .call()
441           .getSucceeded()) {
442         LOGGER.warn(ChampJanusMsgs.JANUS_CHAMP_GRAPH_IMPL_WARN,
443             "Object index was created, but timed out while waiting for it to be registered");
444         return;
445       }
446     } catch (InterruptedException e) {
447       LOGGER.warn(ChampJanusMsgs.JANUS_CHAMP_GRAPH_IMPL_WARN,
448           "Interrupted while waiting for object index creation status");
449       Thread.currentThread().interrupt();
450       return;
451     }
452
453     //Reindex the existing data
454
455     try {
456       final JanusGraphManagement updateIndexMgmt = graph.openManagement();
457       updateIndexMgmt.updateIndex(updateIndexMgmt.getGraphIndex(indexName), SchemaAction.REINDEX).get();
458       updateIndexMgmt.commit();
459     } catch (InterruptedException e) {
460       LOGGER.warn(ChampJanusMsgs.JANUS_CHAMP_GRAPH_IMPL_WARN,
461           "Interrupted while reindexing for object index");
462       Thread.currentThread().interrupt();
463       return;
464     } catch (ExecutionException e) {
465       LOGGER.warn(ChampJanusMsgs.JANUS_CHAMP_GRAPH_IMPL_WARN,
466           "Exception occurred during reindexing procedure for creating object index " + indexName + ". " + e.getMessage());
467     }
468
469     try {
470       ManagementSystem.awaitGraphIndexStatus(graph, indexName)
471           .status(SchemaStatus.ENABLED)
472           .timeout(2, ChronoUnit.MINUTES)
473           .call();
474     } catch (InterruptedException e) {
475       LOGGER.warn(ChampJanusMsgs.JANUS_CHAMP_GRAPH_IMPL_WARN,
476           "Interrupted while waiting for index to transition to ENABLED state");
477       Thread.currentThread().interrupt();
478       return;
479     }
480   }
481
482   @Override
483   public ChampCapabilities capabilities() {
484     return CAPABILITIES;
485   }
486
487   public void storeSchema(ChampSchema schema) throws ChampSchemaViolationException {
488     if (isShutdown()) throw new IllegalStateException("Cannot call storeSchema() after shutdown has been initiated");
489
490     final ChampSchema currentSchema = retrieveSchema();
491     final JanusGraphManagement mgmt = getGraph().openManagement();
492
493     try {
494       for (ChampObjectConstraint objConstraint : schema.getObjectConstraints().values()) {
495         for (ChampPropertyConstraint propConstraint : objConstraint.getPropertyConstraints()) {
496           final Optional<ChampObjectConstraint> currentObjConstraint = currentSchema.getObjectConstraint(objConstraint.getType());
497
498           if (currentObjConstraint.isPresent()) {
499             final Optional<ChampPropertyConstraint> currentPropConstraint = currentObjConstraint.get().getPropertyConstraint(propConstraint.getField().getName());
500
501             if (currentPropConstraint.isPresent() && currentPropConstraint.get().compareTo(propConstraint) != 0) {
502               throw new ChampSchemaViolationException("Cannot update already existing property on object type " + objConstraint.getType() + ": " + propConstraint);
503             }
504           }
505
506           final String newPropertyKeyName = propConstraint.getField().getName();
507
508           if (mgmt.getPropertyKey(newPropertyKeyName) != null) continue; //Check Janus to see if another node created this property key
509
510           mgmt.makePropertyKey(newPropertyKeyName)
511               .dataType(propConstraint.getField().getJavaType())
512               .cardinality(getJanusCardinality(propConstraint.getCardinality()))
513               .make();
514         }
515       }
516
517       for (ChampRelationshipConstraint relConstraint : schema.getRelationshipConstraints().values()) {
518
519         final Optional<ChampRelationshipConstraint> currentRelConstraint = currentSchema.getRelationshipConstraint(relConstraint.getType());
520
521         for (ChampPropertyConstraint propConstraint : relConstraint.getPropertyConstraints()) {
522
523           if (currentRelConstraint.isPresent()) {
524             final Optional<ChampPropertyConstraint> currentPropConstraint = currentRelConstraint.get().getPropertyConstraint(propConstraint.getField().getName());
525
526             if (currentPropConstraint.isPresent() && currentPropConstraint.get().compareTo(propConstraint) != 0) {
527               throw new ChampSchemaViolationException("Cannot update already existing property on relationship type " + relConstraint.getType());
528             }
529           }
530
531           final String newPropertyKeyName = propConstraint.getField().getName();
532
533           if (mgmt.getPropertyKey(newPropertyKeyName) != null) continue; //Check Janus to see if another node created this property key
534
535           mgmt.makePropertyKey(newPropertyKeyName)
536               .dataType(propConstraint.getField().getJavaType())
537               .cardinality(getJanusCardinality(propConstraint.getCardinality()))
538               .make();
539         }
540
541         final EdgeLabel edgeLabel = mgmt.getEdgeLabel(relConstraint.getType());
542
543         if (edgeLabel != null) {
544           mgmt.makeEdgeLabel(relConstraint.getType())
545               .directed()
546               .make();
547         }
548       }
549
550       mgmt.commit();
551
552       super.storeSchema(schema);
553     } catch (SchemaViolationException | ChampSchemaViolationException e) {
554       mgmt.rollback();
555       throw new ChampSchemaViolationException(e);
556     }
557   }
558   
559   private synchronized void openGraph() {
560     if (graph == null) {
561       graph = janusGraphBuilder.open();
562     }
563   }
564   
565   public GraphTraversal<?, ?> hasLabel(GraphTraversal<?, ?> query, Object type) {
566     return query.hasLabel(type);
567   }
568
569
570   @Override
571   public void createDefaultIndexes() {
572     if (isShutdown()) {
573       throw new IllegalStateException("Cannot call storeObjectIndex() after shutdown has been initiated");
574     }
575
576     final String EDGE_IX_NAME = "rel-key-uuid";
577     
578     final JanusGraph graph = getGraph();
579     JanusGraphManagement createIndexMgmt = graph.openManagement();
580     
581     boolean vertexIndexExists = (createIndexMgmt.getGraphIndex(KEY_PROPERTY_NAME) != null);
582     boolean edgeIndexExists = (createIndexMgmt.getGraphIndex(EDGE_IX_NAME) != null);
583     boolean nodeTypeIndexExists = (createIndexMgmt.getGraphIndex(NODE_TYPE_PROPERTY_NAME) != null);
584     
585     if (!vertexIndexExists || !edgeIndexExists) {
586       PropertyKey pk = createIndexMgmt.getOrCreatePropertyKey(KEY_PROPERTY_NAME);
587       
588       if (!vertexIndexExists) {
589         LOGGER.info(ChampJanusMsgs.JANUS_CHAMP_GRAPH_IMPL_INFO,
590             "Create Index " + KEY_PROPERTY_NAME);
591         createIndexMgmt.buildIndex(KEY_PROPERTY_NAME, Vertex.class).addKey(pk).buildCompositeIndex();
592       }
593       if (!edgeIndexExists) {
594         LOGGER.info(ChampJanusMsgs.JANUS_CHAMP_GRAPH_IMPL_INFO,
595             "Create Index " + EDGE_IX_NAME);
596         createIndexMgmt.buildIndex(EDGE_IX_NAME, Edge.class).addKey(pk).buildCompositeIndex();
597       }
598       createIndexMgmt.commit();
599
600       if (!vertexIndexExists) {
601         awaitIndexCreation(KEY_PROPERTY_NAME);
602       }
603       if (!edgeIndexExists) {
604         awaitIndexCreation(EDGE_IX_NAME);
605       }
606     }
607     else {
608       createIndexMgmt.rollback();
609       LOGGER.info(ChampJanusMsgs.JANUS_CHAMP_GRAPH_IMPL_INFO,
610           "Index " + KEY_PROPERTY_NAME + " and " + EDGE_IX_NAME + " already exist");
611     }
612     
613     
614     
615     if (!nodeTypeIndexExists) {
616       LOGGER.info(ChampJanusMsgs.JANUS_CHAMP_GRAPH_IMPL_INFO,
617           "Create Index " + NODE_TYPE_PROPERTY_NAME);
618       createIndexMgmt = graph.openManagement();
619       PropertyKey pk = createIndexMgmt.getOrCreatePropertyKey(NODE_TYPE_PROPERTY_NAME);
620       createIndexMgmt.buildIndex(NODE_TYPE_PROPERTY_NAME, Vertex.class).addKey(pk).buildCompositeIndex();
621       createIndexMgmt.commit();
622       awaitIndexCreation(NODE_TYPE_PROPERTY_NAME);
623     }    
624   }
625 }