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