2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 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=========================================================
21 package org.openecomp.aai.db.schema;
23 import java.util.ArrayList;
24 import java.util.List;
27 import org.apache.tinkerpop.gremlin.structure.Vertex;
29 import org.openecomp.aai.introspection.Version;
30 import com.thinkaurelius.titan.core.PropertyKey;
31 import com.thinkaurelius.titan.core.TitanGraph;
32 import com.thinkaurelius.titan.core.schema.SchemaStatus;
33 import com.thinkaurelius.titan.core.schema.TitanGraphIndex;
34 import com.thinkaurelius.titan.core.schema.TitanManagement;
35 import com.thinkaurelius.titan.core.schema.TitanManagement.IndexBuilder;
37 public class ManageTitanSchema {
40 private TitanManagement graphMgmt;
41 private TitanGraph 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 titan schema.
51 * @param graph the graph
53 public ManageTitanSchema(final TitanGraph graph) {
55 oxmInfo = AuditorFactory.getOXMAuditor(Version.v8);
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 TitanGraphIndex titanIndex = graphMgmt.getGraphIndex(index.getName());
128 PropertyKey[] dbKeys = titanIndex.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(TitanManagement 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(TitanManagement mgmt, String indexName, List<PropertyKey> keys, boolean isUnique, boolean isNew, boolean isChanged) {
213 System.out.println("Changing index: " + indexName);
214 TitanGraphIndex 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 //TitanIndexRepair.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 TitanManagement mgmt = graph.openManagement();
273 TitanGraphIndex 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 TitanManagement 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);