9af65c70c1fa3650eb9ec477abd087182bd77f54
[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 com.att.eelf.configuration.EELFLogger;
29 import com.att.eelf.configuration.EELFManager;
30 import org.apache.tinkerpop.gremlin.structure.Vertex;
31
32 import org.onap.aai.introspection.Version;
33 import com.thinkaurelius.titan.core.PropertyKey;
34 import com.thinkaurelius.titan.core.TitanGraph;
35 import com.thinkaurelius.titan.core.schema.SchemaStatus;
36 import com.thinkaurelius.titan.core.schema.TitanGraphIndex;
37 import com.thinkaurelius.titan.core.schema.TitanManagement;
38 import com.thinkaurelius.titan.core.schema.TitanManagement.IndexBuilder;
39
40 public class ManageTitanSchema {
41
42         private static final EELFLogger logger = EELFManager.getInstance().getLogger(AuditOXM.class);
43
44         private TitanManagement graphMgmt;
45         private TitanGraph graph;
46         private List<DBProperty> aaiProperties;
47         private List<DBIndex> aaiIndexes;
48         private List<EdgeProperty> aaiEdgeProperties;
49         private Auditor oxmInfo = null;
50         private Auditor graphInfo = null;
51         
52         /**
53          * Instantiates a new manage titan schema.
54          *
55          * @param graph the graph
56          */
57         public ManageTitanSchema(final TitanGraph graph) {
58                 this.graph = graph;
59                 oxmInfo = AuditorFactory.getOXMAuditor(Version.v8);
60                 graphInfo = AuditorFactory.getGraphAuditor(graph);
61         }
62         
63         
64         /**
65          * Builds the schema.
66          */
67         public void buildSchema() {
68                 
69                 this.graphMgmt = graph.openManagement();
70                 aaiProperties = new ArrayList<>();
71                 aaiEdgeProperties = new ArrayList<>();
72                 aaiIndexes = new ArrayList<>();
73                 aaiProperties.addAll(oxmInfo.getAuditDoc().getProperties());
74                 aaiIndexes.addAll(oxmInfo.getAuditDoc().getIndexes());
75                 aaiEdgeProperties.addAll(oxmInfo.getAuditDoc().getEdgeLabels());
76                 try {
77                         createPropertyKeys();
78                         createIndexes();
79                         createEdgeLabels();
80                 } catch (Exception e) {
81                         logger.error(e.getMessage(),e);
82                         graphMgmt.rollback();
83                 }
84                 graphMgmt.commit();
85         }
86         
87         /**
88          * Creates the property keys.
89          */
90         private void createPropertyKeys() {
91                 
92                 
93                 for (DBProperty prop : aaiProperties) {
94                         
95                         if (graphMgmt.containsPropertyKey(prop.getName())) {
96                                 PropertyKey key = graphMgmt.getPropertyKey(prop.getName());
97                                 boolean isChanged = false;
98                                 if (!prop.getCardinality().equals(key.cardinality())) {
99                                         isChanged = true;
100                                 }
101                                 if (!prop.getTypeClass().equals(key.dataType())) {
102                                         isChanged = true;
103                                 }
104                                 if (isChanged) {
105                                         //must modify!
106                                         this.replaceProperty(prop);
107                                 }
108                         } else {
109                                 //create a new property key
110                                 System.out.println("Key: " + prop.getName() + " not found - adding");
111                                 graphMgmt.makePropertyKey(prop.getName()).dataType(prop.getTypeClass()).cardinality(prop.getCardinality()).make();
112                         }
113                 }
114                 
115         }
116         
117         /**
118          * Creates the indexes.
119          */
120         private void createIndexes() {
121                 
122                 for (DBIndex index : aaiIndexes) {
123                         Set<DBProperty> props = index.getProperties();
124                         boolean isChanged = false;
125                         boolean isNew = false;
126                         List<PropertyKey> keyList = new ArrayList<>();
127                         for (DBProperty prop : props) {
128                                 keyList.add(graphMgmt.getPropertyKey(prop.getName()));
129                         }
130                         if (graphMgmt.containsGraphIndex(index.getName())) {
131                                 TitanGraphIndex titanIndex = graphMgmt.getGraphIndex(index.getName());
132                                 PropertyKey[] dbKeys = titanIndex.getFieldKeys();
133                                 if (dbKeys.length != keyList.size()) {
134                                         isChanged = true;
135                                 } else {
136                                         int i = 0;
137                                         for (PropertyKey key : keyList) {
138                                                 if (!dbKeys[i].equals(key)) {
139                                                         isChanged = true;
140                                                         break;
141                                                 }
142                                                 i++;
143                                         }
144                                 }
145                         } else {
146                                 isNew = true;
147                         }
148                         if (keyList.size() > 0) {
149                                 this.createIndex(graphMgmt, index.getName(), keyList, index.isUnique(), isNew, isChanged);
150                         }
151                 }
152         }
153         
154         // Use EdgeRules to make sure edgeLabels are defined in the db.  NOTE: the multiplicty used here is 
155         // always "MULTI".  This is not the same as our internal "Many2Many", "One2One", "One2Many" or "Many2One"
156         // We use the same edge-label for edges between many different types of nodes and our internal
157         // multiplicty definitions depends on which two types of nodes are being connected.
158         /**
159          * Creates the edge labels.
160          */
161         private void createEdgeLabels() {
162                 
163                 
164                 for (EdgeProperty prop : aaiEdgeProperties) {
165                 
166                         if (graphMgmt.containsEdgeLabel(prop.getName())) {
167                                 // see what changed
168                         } else {
169                                 graphMgmt.makeEdgeLabel(prop.getName()).multiplicity(prop.getMultiplicity()).make();
170                         }
171                         
172                 }
173                 
174                 
175         }
176         
177         /**
178          * Creates the property.
179          *
180          * @param mgmt the mgmt
181          * @param prop the prop
182          */
183         private void createProperty(TitanManagement mgmt, DBProperty prop) {
184                 if (mgmt.containsPropertyKey(prop.getName())) {
185                         PropertyKey key = mgmt.getPropertyKey(prop.getName());
186                         boolean isChanged = false;
187                         if (!prop.getCardinality().equals(key.cardinality())) {
188                                 isChanged = true;
189                         }
190                         if (!prop.getTypeClass().equals(key.dataType())) {
191                                 isChanged = true;
192                         }
193                         if (isChanged) {
194                                 //must modify!
195                                 this.replaceProperty(prop);
196                         }
197                 } else {
198                         //create a new property key
199                         System.out.println("Key: " + prop.getName() + " not found - adding");
200                         mgmt.makePropertyKey(prop.getName()).dataType(prop.getTypeClass()).cardinality(prop.getCardinality()).make();
201                 }
202         }
203         
204         /**
205          * Creates the index.
206          *
207          * @param mgmt the mgmt
208          * @param indexName the index name
209          * @param keys the keys
210          * @param isUnique the is unique
211          * @param isNew the is new
212          * @param isChanged the is changed
213          */
214         private void createIndex(TitanManagement mgmt, String indexName, List<PropertyKey> keys, boolean isUnique, boolean isNew, boolean isChanged) {
215                 
216                 /*if (isChanged) {
217                         System.out.println("Changing index: " + indexName);
218                         TitanGraphIndex oldIndex = mgmt.getGraphIndex(indexName);
219                         mgmt.updateIndex(oldIndex, SchemaAction.DISABLE_INDEX);
220                         mgmt.commit();
221                         //cannot remove indexes
222                         //graphMgmt.updateIndex(oldIndex, SchemaAction.REMOVE_INDEX);
223                 }*/
224                 if (isNew || isChanged) {
225                         
226                         if (isNew) {
227                                 IndexBuilder builder = mgmt.buildIndex(indexName,Vertex.class);
228                                 for (PropertyKey k : keys) {
229                                         builder.addKey(k);
230                                 }
231                                 if (isUnique) {
232                                         builder.unique();
233                                 }
234                                 builder.buildCompositeIndex();
235                                 System.out.println("Built index for " + indexName + " with keys: " + keys);
236
237                                 //mgmt.commit();
238                         }
239
240                         //mgmt = graph.asAdmin().getManagementSystem();
241                         //mgmt.updateIndex(mgmt.getGraphIndex(indexName), SchemaAction.REGISTER_INDEX);
242                         //mgmt.commit();
243                         
244                         try {
245                                 //waitForCompletion(indexName);
246                                 //TitanIndexRepair.hbaseRepair(AAIConstants.AAI_CONFIG_FILENAME, indexName, "");
247                         } catch (Exception e) {
248                                 graph.tx().rollback();
249                                 graph.close();
250                                 logger.error(e.getMessage(),e);
251                         }
252                         
253                         //mgmt = graph.asAdmin().getManagementSystem();
254                         //mgmt.updateIndex(mgmt.getGraphIndex(indexName), SchemaAction.REINDEX);
255                         
256                         //mgmt.updateIndex(mgmt.getGraphIndex(indexName), SchemaAction.ENABLE_INDEX);
257                         
258                         //mgmt.commit();
259                         
260                 }
261         }
262         
263         /**
264          * Wait for completion.
265          *
266          * @param name the name
267          * @throws InterruptedException the interrupted exception
268          */
269         private void waitForCompletion(String name) throws InterruptedException {
270                 
271                 boolean registered = false;
272                 long before = System.currentTimeMillis();
273                 while (!registered) {
274                     Thread.sleep(500L);
275                     TitanManagement mgmt = graph.openManagement();
276                     TitanGraphIndex idx  = mgmt.getGraphIndex(name);
277                     registered = true;
278                     for (PropertyKey k : idx.getFieldKeys()) {
279                         SchemaStatus s = idx.getIndexStatus(k);  
280                         registered &= s.equals(SchemaStatus.REGISTERED);
281                     }
282                     mgmt.rollback();
283                 }
284                 System.out.println("Index REGISTERED in " + (System.currentTimeMillis() - before) + " ms");
285         }
286         
287         /**
288          * Replace property.
289          *
290          * @param key the key
291          */
292         private void replaceProperty(DBProperty key) {
293                 
294                 
295                 
296                 
297         }
298
299         /**
300          * Update index.
301          *
302          * @param index the index
303          */
304         public void updateIndex(DBIndex index) {
305
306                 TitanManagement mgmt = graph.openManagement();
307                 List<PropertyKey> keys = new ArrayList<>();
308                 boolean isNew = false;
309                 boolean isChanged = false;
310                 for (DBProperty prop : index.getProperties()) {
311                         createProperty(mgmt, prop);
312                         keys.add(mgmt.getPropertyKey(prop.getName()));
313                 }
314                 if (mgmt.containsGraphIndex(index.getName())) {
315                         System.out.println("index already exists");
316                         isNew = false;
317                         isChanged = true;
318                 } else {
319                         isNew = true;
320                         isChanged = false;
321                 }
322                 this.createIndex(mgmt, index.getName(), keys, index.isUnique(), isNew, isChanged);
323
324                 mgmt.commit();
325                 
326         }
327         
328         
329         
330         
331         
332 }