2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.onap.aai.db.schema;
22 import org.apache.tinkerpop.gremlin.structure.Vertex;
23 import org.janusgraph.core.JanusGraph;
24 import org.janusgraph.core.PropertyKey;
25 import org.janusgraph.core.schema.JanusGraphIndex;
26 import org.janusgraph.core.schema.JanusGraphManagement;
27 import org.janusgraph.core.schema.JanusGraphManagement.IndexBuilder;
28 import org.janusgraph.core.schema.SchemaStatus;
29 import org.onap.aai.edges.EdgeIngestor;
30 import org.onap.aai.setup.SchemaVersions;
31 import org.onap.aai.setup.SchemaVersion;
33 import java.util.ArrayList;
34 import java.util.List;
37 public class ManageJanusGraphSchema {
40 private JanusGraphManagement graphMgmt;
41 private JanusGraph graph;
42 private List<DBProperty> aaiProperties;
43 private List<DBIndex> aaiIndexes;
44 private List<EdgeProperty> aaiEdgeProperties;
45 private Auditor oxmInfo = null;
46 private Auditor graphInfo = null;
49 * Instantiates a new manage JanusGraph schema.
51 * @param graph the graph
53 public ManageJanusGraphSchema(final JanusGraph graph, AuditorFactory auditorFactory, SchemaVersions schemaVersions, EdgeIngestor edgeIngestor) {
55 oxmInfo = auditorFactory.getOXMAuditor(schemaVersions.getDefaultVersion(), edgeIngestor);
56 graphInfo = auditorFactory.getGraphAuditor(graph);
63 public void buildSchema() {
65 this.graphMgmt = graph.openManagement();
66 aaiProperties = new ArrayList<>();
67 aaiEdgeProperties = new ArrayList<>();
68 aaiIndexes = new ArrayList<>();
69 aaiProperties.addAll(oxmInfo.getAuditDoc().getProperties());
70 aaiIndexes.addAll(oxmInfo.getAuditDoc().getIndexes());
71 aaiEdgeProperties.addAll(oxmInfo.getAuditDoc().getEdgeLabels());
76 } catch (Exception e) {
84 * Creates the property keys.
86 private void createPropertyKeys() {
89 for (DBProperty prop : aaiProperties) {
91 if (graphMgmt.containsPropertyKey(prop.getName())) {
92 PropertyKey key = graphMgmt.getPropertyKey(prop.getName());
93 boolean isChanged = false;
94 if (!prop.getCardinality().equals(key.cardinality())) {
97 if (!prop.getTypeClass().equals(key.dataType())) {
102 this.replaceProperty(prop);
105 //create a new property key
106 System.out.println("Key: " + prop.getName() + " not found - adding");
107 graphMgmt.makePropertyKey(prop.getName()).dataType(prop.getTypeClass()).cardinality(prop.getCardinality()).make();
114 * Creates the indexes.
116 private void createIndexes() {
118 for (DBIndex index : aaiIndexes) {
119 Set<DBProperty> props = index.getProperties();
120 boolean isChanged = false;
121 boolean isNew = false;
122 List<PropertyKey> keyList = new ArrayList<>();
123 for (DBProperty prop : props) {
124 keyList.add(graphMgmt.getPropertyKey(prop.getName()));
126 if (graphMgmt.containsGraphIndex(index.getName())) {
127 JanusGraphIndex JanusGraphIndex = graphMgmt.getGraphIndex(index.getName());
128 PropertyKey[] dbKeys = JanusGraphIndex.getFieldKeys();
129 if (dbKeys.length != keyList.size()) {
133 for (PropertyKey key : keyList) {
134 if (!dbKeys[i].equals(key)) {
144 if (keyList.size() > 0) {
145 this.createIndex(graphMgmt, index.getName(), keyList, index.isUnique(), isNew, isChanged);
150 // Use EdgeRules to make sure edgeLabels are defined in the db. NOTE: the multiplicty used here is
151 // always "MULTI". This is not the same as our internal "Many2Many", "One2One", "One2Many" or "Many2One"
152 // We use the same edge-label for edges between many different types of nodes and our internal
153 // multiplicty definitions depends on which two types of nodes are being connected.
155 * Creates the edge labels.
157 private void createEdgeLabels() {
160 for (EdgeProperty prop : aaiEdgeProperties) {
162 if (graphMgmt.containsEdgeLabel(prop.getName())) {
165 graphMgmt.makeEdgeLabel(prop.getName()).multiplicity(prop.getMultiplicity()).make();
174 * Creates the property.
176 * @param mgmt the mgmt
177 * @param prop the prop
179 private void createProperty(JanusGraphManagement mgmt, DBProperty prop) {
180 if (mgmt.containsPropertyKey(prop.getName())) {
181 PropertyKey key = mgmt.getPropertyKey(prop.getName());
182 boolean isChanged = false;
183 if (!prop.getCardinality().equals(key.cardinality())) {
186 if (!prop.getTypeClass().equals(key.dataType())) {
191 this.replaceProperty(prop);
194 //create a new property key
195 System.out.println("Key: " + prop.getName() + " not found - adding");
196 mgmt.makePropertyKey(prop.getName()).dataType(prop.getTypeClass()).cardinality(prop.getCardinality()).make();
203 * @param mgmt the mgmt
204 * @param indexName the index name
205 * @param keys the keys
206 * @param isUnique the is unique
207 * @param isNew the is new
208 * @param isChanged the is changed
210 private void createIndex(JanusGraphManagement mgmt, String indexName, List<PropertyKey> keys, boolean isUnique, boolean isNew, boolean isChanged) {
213 System.out.println("Changing index: " + indexName);
214 JanusGraphIndex oldIndex = mgmt.getGraphIndex(indexName);
215 mgmt.updateIndex(oldIndex, SchemaAction.DISABLE_INDEX);
217 //cannot remove indexes
218 //graphMgmt.updateIndex(oldIndex, SchemaAction.REMOVE_INDEX);
220 if (isNew || isChanged) {
223 IndexBuilder builder = mgmt.buildIndex(indexName,Vertex.class);
224 for (PropertyKey k : keys) {
230 builder.buildCompositeIndex();
231 System.out.println("Built index for " + indexName + " with keys: " + keys);
236 //mgmt = graph.asAdmin().getManagementSystem();
237 //mgmt.updateIndex(mgmt.getGraphIndex(indexName), SchemaAction.REGISTER_INDEX);
241 //waitForCompletion(indexName);
242 //JanusGraphIndexRepair.hbaseRepair(AAIConstants.AAI_CONFIG_FILENAME, indexName, "");
243 } catch (Exception e) {
244 // TODO Auto-generated catch block
245 graph.tx().rollback();
250 //mgmt = graph.asAdmin().getManagementSystem();
251 //mgmt.updateIndex(mgmt.getGraphIndex(indexName), SchemaAction.REINDEX);
253 //mgmt.updateIndex(mgmt.getGraphIndex(indexName), SchemaAction.ENABLE_INDEX);
261 * Wait for completion.
263 * @param name the name
264 * @throws InterruptedException the interrupted exception
266 private void waitForCompletion(String name) throws InterruptedException {
268 boolean registered = false;
269 long before = System.currentTimeMillis();
270 while (!registered) {
272 JanusGraphManagement mgmt = graph.openManagement();
273 JanusGraphIndex idx = mgmt.getGraphIndex(name);
275 for (PropertyKey k : idx.getFieldKeys()) {
276 SchemaStatus s = idx.getIndexStatus(k);
277 registered &= s.equals(SchemaStatus.REGISTERED);
281 System.out.println("Index REGISTERED in " + (System.currentTimeMillis() - before) + " ms");
289 private void replaceProperty(DBProperty key) {
299 * @param index the index
301 public void updateIndex(DBIndex index) {
303 JanusGraphManagement mgmt = graph.openManagement();
304 List<PropertyKey> keys = new ArrayList<>();
305 boolean isNew = false;
306 boolean isChanged = false;
307 for (DBProperty prop : index.getProperties()) {
308 createProperty(mgmt, prop);
309 keys.add(mgmt.getPropertyKey(prop.getName()));
311 if (mgmt.containsGraphIndex(index.getName())) {
312 System.out.println("index already exists");
319 this.createIndex(mgmt, index.getName(), keys, index.isUnique(), isNew, isChanged);