Initial commit with all the necessary files
[aai/aai-common.git] / aai-core / src / main / java / org / openecomp / aai / db / schema / ManageTitanSchema.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * org.openecomp.aai
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
10
11      http://www.apache.org/licenses/LICENSE-2.0
12
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=========================================================
19  */
20
21 package org.openecomp.aai.db.schema;
22
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Set;
26
27 import org.apache.tinkerpop.gremlin.structure.Vertex;
28
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;
36
37 public class ManageTitanSchema {
38
39         
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;
47         
48         /**
49          * Instantiates a new manage titan schema.
50          *
51          * @param graph the graph
52          */
53         public ManageTitanSchema(final TitanGraph graph) {
54                 this.graph = graph;
55                 oxmInfo = AuditorFactory.getOXMAuditor(Version.v8);
56                 graphInfo = AuditorFactory.getGraphAuditor(graph);
57         }
58         
59         
60         /**
61          * Builds the schema.
62          */
63         public void buildSchema() {
64                 
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());
72                 try {
73                         createPropertyKeys();
74                         createIndexes();
75                         createEdgeLabels();
76                 } catch (Exception e) {
77                         e.printStackTrace();
78                         graphMgmt.rollback();
79                 }
80                 graphMgmt.commit();
81         }
82         
83         /**
84          * Creates the property keys.
85          */
86         private void createPropertyKeys() {
87                 
88                 
89                 for (DBProperty prop : aaiProperties) {
90                         
91                         if (graphMgmt.containsPropertyKey(prop.getName())) {
92                                 PropertyKey key = graphMgmt.getPropertyKey(prop.getName());
93                                 boolean isChanged = false;
94                                 if (!prop.getCardinality().equals(key.cardinality())) {
95                                         isChanged = true;
96                                 }
97                                 if (!prop.getTypeClass().equals(key.dataType())) {
98                                         isChanged = true;
99                                 }
100                                 if (isChanged) {
101                                         //must modify!
102                                         this.replaceProperty(prop);
103                                 }
104                         } else {
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();
108                         }
109                 }
110                 
111         }
112         
113         /**
114          * Creates the indexes.
115          */
116         private void createIndexes() {
117                 
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()));
125                         }
126                         if (graphMgmt.containsGraphIndex(index.getName())) {
127                                 TitanGraphIndex titanIndex = graphMgmt.getGraphIndex(index.getName());
128                                 PropertyKey[] dbKeys = titanIndex.getFieldKeys();
129                                 if (dbKeys.length != keyList.size()) {
130                                         isChanged = true;
131                                 } else {
132                                         int i = 0;
133                                         for (PropertyKey key : keyList) {
134                                                 if (!dbKeys[i].equals(key)) {
135                                                         isChanged = true;
136                                                         break;
137                                                 }
138                                                 i++;
139                                         }
140                                 }
141                         } else {
142                                 isNew = true;
143                         }
144                         if (keyList.size() > 0) {
145                                 this.createIndex(graphMgmt, index.getName(), keyList, index.isUnique(), isNew, isChanged);
146                         }
147                 }
148         }
149         
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.
154         /**
155          * Creates the edge labels.
156          */
157         private void createEdgeLabels() {
158                 
159                 
160                 for (EdgeProperty prop : aaiEdgeProperties) {
161                 
162                         if (graphMgmt.containsEdgeLabel(prop.getName())) {
163                                 // see what changed
164                         } else {
165                                 graphMgmt.makeEdgeLabel(prop.getName()).multiplicity(prop.getMultiplicity()).make();
166                         }
167                         
168                 }
169                 
170                 
171         }
172         
173         /**
174          * Creates the property.
175          *
176          * @param mgmt the mgmt
177          * @param prop the prop
178          */
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())) {
184                                 isChanged = true;
185                         }
186                         if (!prop.getTypeClass().equals(key.dataType())) {
187                                 isChanged = true;
188                         }
189                         if (isChanged) {
190                                 //must modify!
191                                 this.replaceProperty(prop);
192                         }
193                 } else {
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();
197                 }
198         }
199         
200         /**
201          * Creates the index.
202          *
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
209          */
210         private void createIndex(TitanManagement mgmt, String indexName, List<PropertyKey> keys, boolean isUnique, boolean isNew, boolean isChanged) {
211                 
212                 /*if (isChanged) {
213                         System.out.println("Changing index: " + indexName);
214                         TitanGraphIndex oldIndex = mgmt.getGraphIndex(indexName);
215                         mgmt.updateIndex(oldIndex, SchemaAction.DISABLE_INDEX);
216                         mgmt.commit();
217                         //cannot remove indexes
218                         //graphMgmt.updateIndex(oldIndex, SchemaAction.REMOVE_INDEX);
219                 }*/
220                 if (isNew || isChanged) {
221                         
222                         if (isNew) {
223                                 IndexBuilder builder = mgmt.buildIndex(indexName,Vertex.class);
224                                 for (PropertyKey k : keys) {
225                                         builder.addKey(k);
226                                 }
227                                 if (isUnique) {
228                                         builder.unique();
229                                 }
230                                 builder.buildCompositeIndex();
231                                 System.out.println("Built index for " + indexName + " with keys: " + keys);
232
233                                 //mgmt.commit();
234                         }
235
236                         //mgmt = graph.asAdmin().getManagementSystem();
237                         //mgmt.updateIndex(mgmt.getGraphIndex(indexName), SchemaAction.REGISTER_INDEX);
238                         //mgmt.commit();
239                         
240                         try {
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();
246                                 graph.close();
247                                 e.printStackTrace();
248                         }
249                         
250                         //mgmt = graph.asAdmin().getManagementSystem();
251                         //mgmt.updateIndex(mgmt.getGraphIndex(indexName), SchemaAction.REINDEX);
252                         
253                         //mgmt.updateIndex(mgmt.getGraphIndex(indexName), SchemaAction.ENABLE_INDEX);
254                         
255                         //mgmt.commit();
256                         
257                 }
258         }
259         
260         /**
261          * Wait for completion.
262          *
263          * @param name the name
264          * @throws InterruptedException the interrupted exception
265          */
266         private void waitForCompletion(String name) throws InterruptedException {
267                 
268                 boolean registered = false;
269                 long before = System.currentTimeMillis();
270                 while (!registered) {
271                     Thread.sleep(500L);
272                     TitanManagement mgmt = graph.openManagement();
273                     TitanGraphIndex idx  = mgmt.getGraphIndex(name);
274                     registered = true;
275                     for (PropertyKey k : idx.getFieldKeys()) {
276                         SchemaStatus s = idx.getIndexStatus(k);  
277                         registered &= s.equals(SchemaStatus.REGISTERED);
278                     }
279                     mgmt.rollback();
280                 }
281                 System.out.println("Index REGISTERED in " + (System.currentTimeMillis() - before) + " ms");
282         }
283         
284         /**
285          * Replace property.
286          *
287          * @param key the key
288          */
289         private void replaceProperty(DBProperty key) {
290                 
291                 
292                 
293                 
294         }
295
296         /**
297          * Update index.
298          *
299          * @param index the index
300          */
301         public void updateIndex(DBIndex index) {
302
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()));
310                 }
311                 if (mgmt.containsGraphIndex(index.getName())) {
312                         System.out.println("index already exists");
313                         isNew = false;
314                         isChanged = true;
315                 } else {
316                         isNew = true;
317                         isChanged = false;
318                 }
319                 this.createIndex(mgmt, index.getName(), keys, index.isUnique(), isNew, isChanged);
320
321                 mgmt.commit();
322                 
323         }
324         
325         
326         
327         
328         
329 }