Update the license for 2017-2018 license
[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-2018 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 package org.onap.aai.db.schema;
21
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Set;
25
26 import com.att.eelf.configuration.EELFLogger;
27 import com.att.eelf.configuration.EELFManager;
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         private static final EELFLogger logger = EELFManager.getInstance().getLogger(AuditOXM.class);
41
42         private TitanManagement graphMgmt;
43         private TitanGraph graph;
44         private List<DBProperty> aaiProperties;
45         private List<DBIndex> aaiIndexes;
46         private List<EdgeProperty> aaiEdgeProperties;
47         private Auditor oxmInfo = null;
48         private Auditor graphInfo = null;
49         
50         /**
51          * Instantiates a new manage titan schema.
52          *
53          * @param graph the graph
54          */
55         public ManageTitanSchema(final TitanGraph graph) {
56                 this.graph = graph;
57                 oxmInfo = AuditorFactory.getOXMAuditor(Version.v8);
58                 graphInfo = AuditorFactory.getGraphAuditor(graph);
59         }
60         
61         
62         /**
63          * Builds the schema.
64          */
65         public void buildSchema() {
66                 
67                 this.graphMgmt = graph.openManagement();
68                 aaiProperties = new ArrayList<>();
69                 aaiEdgeProperties = new ArrayList<>();
70                 aaiIndexes = new ArrayList<>();
71                 aaiProperties.addAll(oxmInfo.getAuditDoc().getProperties());
72                 aaiIndexes.addAll(oxmInfo.getAuditDoc().getIndexes());
73                 aaiEdgeProperties.addAll(oxmInfo.getAuditDoc().getEdgeLabels());
74                 try {
75                         createPropertyKeys();
76                         createIndexes();
77                         createEdgeLabels();
78                 } catch (Exception e) {
79                         logger.error(e.getMessage(),e);
80                         graphMgmt.rollback();
81                 }
82                 graphMgmt.commit();
83         }
84         
85         /**
86          * Creates the property keys.
87          */
88         private void createPropertyKeys() {
89                 
90                 
91                 for (DBProperty prop : aaiProperties) {
92                         
93                         if (graphMgmt.containsPropertyKey(prop.getName())) {
94                                 PropertyKey key = graphMgmt.getPropertyKey(prop.getName());
95                                 boolean isChanged = false;
96                                 if (!prop.getCardinality().equals(key.cardinality())) {
97                                         isChanged = true;
98                                 }
99                                 if (!prop.getTypeClass().equals(key.dataType())) {
100                                         isChanged = true;
101                                 }
102                                 if (isChanged) {
103                                         //must modify!
104                                         this.replaceProperty(prop);
105                                 }
106                         } else {
107                                 //create a new property key
108                                 System.out.println("Key: " + prop.getName() + " not found - adding");
109                                 graphMgmt.makePropertyKey(prop.getName()).dataType(prop.getTypeClass()).cardinality(prop.getCardinality()).make();
110                         }
111                 }
112                 
113         }
114         
115         /**
116          * Creates the indexes.
117          */
118         private void createIndexes() {
119                 
120                 for (DBIndex index : aaiIndexes) {
121                         Set<DBProperty> props = index.getProperties();
122                         boolean isChanged = false;
123                         boolean isNew = false;
124                         List<PropertyKey> keyList = new ArrayList<>();
125                         for (DBProperty prop : props) {
126                                 keyList.add(graphMgmt.getPropertyKey(prop.getName()));
127                         }
128                         if (graphMgmt.containsGraphIndex(index.getName())) {
129                                 TitanGraphIndex titanIndex = graphMgmt.getGraphIndex(index.getName());
130                                 PropertyKey[] dbKeys = titanIndex.getFieldKeys();
131                                 if (dbKeys.length != keyList.size()) {
132                                         isChanged = true;
133                                 } else {
134                                         int i = 0;
135                                         for (PropertyKey key : keyList) {
136                                                 if (!dbKeys[i].equals(key)) {
137                                                         isChanged = true;
138                                                         break;
139                                                 }
140                                                 i++;
141                                         }
142                                 }
143                         } else {
144                                 isNew = true;
145                         }
146                         if (keyList.size() > 0) {
147                                 this.createIndex(graphMgmt, index.getName(), keyList, index.isUnique(), isNew, isChanged);
148                         }
149                 }
150         }
151         
152         // Use EdgeRules to make sure edgeLabels are defined in the db.  NOTE: the multiplicty used here is 
153         // always "MULTI".  This is not the same as our internal "Many2Many", "One2One", "One2Many" or "Many2One"
154         // We use the same edge-label for edges between many different types of nodes and our internal
155         // multiplicty definitions depends on which two types of nodes are being connected.
156         /**
157          * Creates the edge labels.
158          */
159         private void createEdgeLabels() {
160                 
161                 
162                 for (EdgeProperty prop : aaiEdgeProperties) {
163                 
164                         if (graphMgmt.containsEdgeLabel(prop.getName())) {
165                                 // see what changed
166                         } else {
167                                 graphMgmt.makeEdgeLabel(prop.getName()).multiplicity(prop.getMultiplicity()).make();
168                         }
169                         
170                 }
171                 
172                 
173         }
174         
175         /**
176          * Creates the property.
177          *
178          * @param mgmt the mgmt
179          * @param prop the prop
180          */
181         private void createProperty(TitanManagement mgmt, DBProperty prop) {
182                 if (mgmt.containsPropertyKey(prop.getName())) {
183                         PropertyKey key = mgmt.getPropertyKey(prop.getName());
184                         boolean isChanged = false;
185                         if (!prop.getCardinality().equals(key.cardinality())) {
186                                 isChanged = true;
187                         }
188                         if (!prop.getTypeClass().equals(key.dataType())) {
189                                 isChanged = true;
190                         }
191                         if (isChanged) {
192                                 //must modify!
193                                 this.replaceProperty(prop);
194                         }
195                 } else {
196                         //create a new property key
197                         System.out.println("Key: " + prop.getName() + " not found - adding");
198                         mgmt.makePropertyKey(prop.getName()).dataType(prop.getTypeClass()).cardinality(prop.getCardinality()).make();
199                 }
200         }
201         
202         /**
203          * Creates the index.
204          *
205          * @param mgmt the mgmt
206          * @param indexName the index name
207          * @param keys the keys
208          * @param isUnique the is unique
209          * @param isNew the is new
210          * @param isChanged the is changed
211          */
212         private void createIndex(TitanManagement mgmt, String indexName, List<PropertyKey> keys, boolean isUnique, boolean isNew, boolean isChanged) {
213                 
214                 /*if (isChanged) {
215                         System.out.println("Changing index: " + indexName);
216                         TitanGraphIndex oldIndex = mgmt.getGraphIndex(indexName);
217                         mgmt.updateIndex(oldIndex, SchemaAction.DISABLE_INDEX);
218                         mgmt.commit();
219                         //cannot remove indexes
220                         //graphMgmt.updateIndex(oldIndex, SchemaAction.REMOVE_INDEX);
221                 }*/
222                 if (isNew || isChanged) {
223                         
224                         if (isNew) {
225                                 IndexBuilder builder = mgmt.buildIndex(indexName,Vertex.class);
226                                 for (PropertyKey k : keys) {
227                                         builder.addKey(k);
228                                 }
229                                 if (isUnique) {
230                                         builder.unique();
231                                 }
232                                 builder.buildCompositeIndex();
233                                 System.out.println("Built index for " + indexName + " with keys: " + keys);
234
235                                 //mgmt.commit();
236                         }
237
238                         //mgmt = graph.asAdmin().getManagementSystem();
239                         //mgmt.updateIndex(mgmt.getGraphIndex(indexName), SchemaAction.REGISTER_INDEX);
240                         //mgmt.commit();
241                         
242                         try {
243                                 //waitForCompletion(indexName);
244                                 //TitanIndexRepair.hbaseRepair(AAIConstants.AAI_CONFIG_FILENAME, indexName, "");
245                         } catch (Exception e) {
246                                 graph.tx().rollback();
247                                 graph.close();
248                                 logger.error(e.getMessage(),e);
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 }