2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 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=========================================================
20 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 package org.onap.aai.db.schema;
24 import java.util.ArrayList;
25 import java.util.List;
28 import org.apache.tinkerpop.gremlin.structure.Vertex;
30 import org.onap.aai.introspection.Version;
31 import com.thinkaurelius.titan.core.PropertyKey;
32 import com.thinkaurelius.titan.core.TitanGraph;
33 import com.thinkaurelius.titan.core.schema.SchemaStatus;
34 import com.thinkaurelius.titan.core.schema.TitanGraphIndex;
35 import com.thinkaurelius.titan.core.schema.TitanManagement;
36 import com.thinkaurelius.titan.core.schema.TitanManagement.IndexBuilder;
38 public class ManageTitanSchema {
41 private TitanManagement graphMgmt;
42 private TitanGraph graph;
43 private List<DBProperty> aaiProperties;
44 private List<DBIndex> aaiIndexes;
45 private List<EdgeProperty> aaiEdgeProperties;
46 private Auditor oxmInfo = null;
47 private Auditor graphInfo = null;
50 * Instantiates a new manage titan schema.
52 * @param graph the graph
54 public ManageTitanSchema(final TitanGraph graph) {
56 oxmInfo = AuditorFactory.getOXMAuditor(Version.v8);
57 graphInfo = AuditorFactory.getGraphAuditor(graph);
64 public void buildSchema() {
66 this.graphMgmt = graph.openManagement();
67 aaiProperties = new ArrayList<>();
68 aaiEdgeProperties = new ArrayList<>();
69 aaiIndexes = new ArrayList<>();
70 aaiProperties.addAll(oxmInfo.getAuditDoc().getProperties());
71 aaiIndexes.addAll(oxmInfo.getAuditDoc().getIndexes());
72 aaiEdgeProperties.addAll(oxmInfo.getAuditDoc().getEdgeLabels());
77 } catch (Exception e) {
85 * Creates the property keys.
87 private void createPropertyKeys() {
90 for (DBProperty prop : aaiProperties) {
92 if (graphMgmt.containsPropertyKey(prop.getName())) {
93 PropertyKey key = graphMgmt.getPropertyKey(prop.getName());
94 boolean isChanged = false;
95 if (!prop.getCardinality().equals(key.cardinality())) {
98 if (!prop.getTypeClass().equals(key.dataType())) {
103 this.replaceProperty(prop);
106 //create a new property key
107 System.out.println("Key: " + prop.getName() + " not found - adding");
108 graphMgmt.makePropertyKey(prop.getName()).dataType(prop.getTypeClass()).cardinality(prop.getCardinality()).make();
115 * Creates the indexes.
117 private void createIndexes() {
119 for (DBIndex index : aaiIndexes) {
120 Set<DBProperty> props = index.getProperties();
121 boolean isChanged = false;
122 boolean isNew = false;
123 List<PropertyKey> keyList = new ArrayList<>();
124 for (DBProperty prop : props) {
125 keyList.add(graphMgmt.getPropertyKey(prop.getName()));
127 if (graphMgmt.containsGraphIndex(index.getName())) {
128 TitanGraphIndex titanIndex = graphMgmt.getGraphIndex(index.getName());
129 PropertyKey[] dbKeys = titanIndex.getFieldKeys();
130 if (dbKeys.length != keyList.size()) {
134 for (PropertyKey key : keyList) {
135 if (!dbKeys[i].equals(key)) {
145 if (keyList.size() > 0) {
146 this.createIndex(graphMgmt, index.getName(), keyList, index.isUnique(), isNew, isChanged);
151 // Use EdgeRules to make sure edgeLabels are defined in the db. NOTE: the multiplicty used here is
152 // always "MULTI". This is not the same as our internal "Many2Many", "One2One", "One2Many" or "Many2One"
153 // We use the same edge-label for edges between many different types of nodes and our internal
154 // multiplicty definitions depends on which two types of nodes are being connected.
156 * Creates the edge labels.
158 private void createEdgeLabels() {
161 for (EdgeProperty prop : aaiEdgeProperties) {
163 if (graphMgmt.containsEdgeLabel(prop.getName())) {
166 graphMgmt.makeEdgeLabel(prop.getName()).multiplicity(prop.getMultiplicity()).make();
175 * Creates the property.
177 * @param mgmt the mgmt
178 * @param prop the prop
180 private void createProperty(TitanManagement mgmt, DBProperty prop) {
181 if (mgmt.containsPropertyKey(prop.getName())) {
182 PropertyKey key = mgmt.getPropertyKey(prop.getName());
183 boolean isChanged = false;
184 if (!prop.getCardinality().equals(key.cardinality())) {
187 if (!prop.getTypeClass().equals(key.dataType())) {
192 this.replaceProperty(prop);
195 //create a new property key
196 System.out.println("Key: " + prop.getName() + " not found - adding");
197 mgmt.makePropertyKey(prop.getName()).dataType(prop.getTypeClass()).cardinality(prop.getCardinality()).make();
204 * @param mgmt the mgmt
205 * @param indexName the index name
206 * @param keys the keys
207 * @param isUnique the is unique
208 * @param isNew the is new
209 * @param isChanged the is changed
211 private void createIndex(TitanManagement mgmt, String indexName, List<PropertyKey> keys, boolean isUnique, boolean isNew, boolean isChanged) {
214 System.out.println("Changing index: " + indexName);
215 TitanGraphIndex oldIndex = mgmt.getGraphIndex(indexName);
216 mgmt.updateIndex(oldIndex, SchemaAction.DISABLE_INDEX);
218 //cannot remove indexes
219 //graphMgmt.updateIndex(oldIndex, SchemaAction.REMOVE_INDEX);
221 if (isNew || isChanged) {
224 IndexBuilder builder = mgmt.buildIndex(indexName,Vertex.class);
225 for (PropertyKey k : keys) {
231 builder.buildCompositeIndex();
232 System.out.println("Built index for " + indexName + " with keys: " + keys);
237 //mgmt = graph.asAdmin().getManagementSystem();
238 //mgmt.updateIndex(mgmt.getGraphIndex(indexName), SchemaAction.REGISTER_INDEX);
242 //waitForCompletion(indexName);
243 //TitanIndexRepair.hbaseRepair(AAIConstants.AAI_CONFIG_FILENAME, indexName, "");
244 } catch (Exception e) {
245 // TODO Auto-generated catch block
246 graph.tx().rollback();
251 //mgmt = graph.asAdmin().getManagementSystem();
252 //mgmt.updateIndex(mgmt.getGraphIndex(indexName), SchemaAction.REINDEX);
254 //mgmt.updateIndex(mgmt.getGraphIndex(indexName), SchemaAction.ENABLE_INDEX);
262 * Wait for completion.
264 * @param name the name
265 * @throws InterruptedException the interrupted exception
267 private void waitForCompletion(String name) throws InterruptedException {
269 boolean registered = false;
270 long before = System.currentTimeMillis();
271 while (!registered) {
273 TitanManagement mgmt = graph.openManagement();
274 TitanGraphIndex idx = mgmt.getGraphIndex(name);
276 for (PropertyKey k : idx.getFieldKeys()) {
277 SchemaStatus s = idx.getIndexStatus(k);
278 registered &= s.equals(SchemaStatus.REGISTERED);
282 System.out.println("Index REGISTERED in " + (System.currentTimeMillis() - before) + " ms");
290 private void replaceProperty(DBProperty key) {
300 * @param index the index
302 public void updateIndex(DBIndex index) {
304 TitanManagement mgmt = graph.openManagement();
305 List<PropertyKey> keys = new ArrayList<>();
306 boolean isNew = false;
307 boolean isChanged = false;
308 for (DBProperty prop : index.getProperties()) {
309 createProperty(mgmt, prop);
310 keys.add(mgmt.getPropertyKey(prop.getName()));
312 if (mgmt.containsGraphIndex(index.getName())) {
313 System.out.println("index already exists");
320 this.createIndex(mgmt, index.getName(), keys, index.isUnique(), isNew, isChanged);