Update license files, sonar plugin and fix tests
[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 }