Merge "Fix sonar issues in SchemaGenerator"
[aai/aai-common.git] / aai-core / src / main / java / org / onap / aai / db / schema / ManageJanusGraphSchema.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 org.janusgraph.core.PropertyKey;
32 import org.janusgraph.core.JanusGraph;
33 import org.janusgraph.core.schema.SchemaStatus;
34 import org.janusgraph.core.schema.JanusGraphIndex;
35 import org.janusgraph.core.schema.JanusGraphManagement;
36 import org.janusgraph.core.schema.JanusGraphManagement.IndexBuilder;
37
38 public class ManageJanusGraphSchema {
39
40         private static final EELFLogger logger = EELFManager.getInstance().getLogger(ManageJanusGraphSchema.class);
41
42         private JanusGraphManagement graphMgmt;
43         private JanusGraph 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 JanusGraph schema.
52          *
53          * @param graph the graph
54          */
55         public ManageJanusGraphSchema(final JanusGraph 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                 for (DBProperty prop : aaiProperties) {
91                         this.createProperty(graphMgmt, prop);
92                 }
93                 
94         }
95         
96         /**
97          * Creates the indexes.
98          */
99         private void createIndexes() {
100                 
101                 for (DBIndex index : aaiIndexes) {
102                         Set<DBProperty> props = index.getProperties();
103                         boolean isChanged = false;
104                         boolean isNew = false;
105                         List<PropertyKey> keyList = new ArrayList<>();
106                         for (DBProperty prop : props) {
107                                 keyList.add(graphMgmt.getPropertyKey(prop.getName()));
108                         }
109                         if (graphMgmt.containsGraphIndex(index.getName())) {
110                                 JanusGraphIndex janusGraphIndex = graphMgmt.getGraphIndex(index.getName());
111                                 PropertyKey[] dbKeys = janusGraphIndex.getFieldKeys();
112                                 if (dbKeys.length != keyList.size()) {
113                                         isChanged = true;
114                                 } else {
115                                         int i = 0;
116                                         for (PropertyKey key : keyList) {
117                                                 if (!dbKeys[i].equals(key)) {
118                                                         isChanged = true;
119                                                         break;
120                                                 }
121                                                 i++;
122                                         }
123                                 }
124                         } else {
125                                 isNew = true;
126                         }
127                         if (!keyList.isEmpty()) {
128                                 this.createIndex(graphMgmt, index.getName(), keyList, index.isUnique(), isNew, isChanged);
129                         }
130                 }
131         }
132         
133         // Use EdgeRules to make sure edgeLabels are defined in the db.  NOTE: the multiplicty used here is 
134         // always "MULTI".  This is not the same as our internal "Many2Many", "One2One", "One2Many" or "Many2One"
135         // We use the same edge-label for edges between many different types of nodes and our internal
136         // multiplicty definitions depends on which two types of nodes are being connected.
137         /**
138          * Creates the edge labels.
139          */
140         private void createEdgeLabels() {
141                 
142                 
143                 for (EdgeProperty prop : aaiEdgeProperties) {
144                 
145                         if (graphMgmt.containsEdgeLabel(prop.getName())) {
146                                 // see what changed
147                         } else {
148                                 graphMgmt.makeEdgeLabel(prop.getName()).multiplicity(prop.getMultiplicity()).make();
149                         }
150                         
151                 }
152                 
153                 
154         }
155         
156         /**
157          * Creates the property.
158          *
159          * @param mgmt the mgmt
160          * @param prop the prop
161          */
162         private void createProperty(JanusGraphManagement mgmt, DBProperty prop) {
163                 if (mgmt.containsPropertyKey(prop.getName())) {
164                         PropertyKey key = mgmt.getPropertyKey(prop.getName());
165                         boolean isChanged = false;
166                         if (!prop.getCardinality().equals(key.cardinality())) {
167                                 isChanged = true;
168                         }
169                         if (!prop.getTypeClass().equals(key.dataType())) {
170                                 isChanged = true;
171                         }
172                         if (isChanged) {
173                                 //must modify!
174                                 this.replaceProperty(prop);
175                         }
176                 } else {
177                         //create a new property key
178                         logger.info("Key: " + prop.getName() + " not found - adding");
179                         mgmt.makePropertyKey(prop.getName()).dataType(prop.getTypeClass()).cardinality(prop.getCardinality()).make();
180                 }
181         }
182         
183         /**
184          * Creates the index.
185          *
186          * @param mgmt the mgmt
187          * @param indexName the index name
188          * @param keys the keys
189          * @param isUnique the is unique
190          * @param isNew the is new
191          * @param isChanged the is changed
192          */
193         private void createIndex(JanusGraphManagement mgmt, String indexName, List<PropertyKey> keys, boolean isUnique, boolean isNew, boolean isChanged) {
194
195                 if (isNew || isChanged) {
196                         
197                         if (isNew) {
198                                 IndexBuilder builder = mgmt.buildIndex(indexName,Vertex.class);
199                                 for (PropertyKey k : keys) {
200                                         builder.addKey(k);
201                                 }
202                                 if (isUnique) {
203                                         builder.unique();
204                                 }
205                                 builder.buildCompositeIndex();
206                                 logger.info("Built index for " + indexName + " with keys: " + keys);
207                         }
208                 }
209         }
210         
211         /**
212          * Wait for completion.
213          *
214          * @param name the name
215          * @throws InterruptedException the interrupted exception
216          */
217         private void waitForCompletion(String name) throws InterruptedException {
218                 
219                 boolean registered = false;
220                 long before = System.currentTimeMillis();
221                 while (!registered) {
222                     Thread.sleep(500L);
223                     JanusGraphManagement mgmt = graph.openManagement();
224                     JanusGraphIndex idx  = mgmt.getGraphIndex(name);
225                     registered = true;
226                     for (PropertyKey k : idx.getFieldKeys()) {
227                         SchemaStatus s = idx.getIndexStatus(k);  
228                         registered &= s.equals(SchemaStatus.REGISTERED);
229                     }
230                     mgmt.rollback();
231                 }
232                 logger.info("Index REGISTERED in " + (System.currentTimeMillis() - before) + " ms");
233         }
234
235         /**
236          * Replace property.
237          *
238          * @param key the key
239          */
240         private void replaceProperty(DBProperty key) {
241
242         }
243
244         /**
245          * Update index.
246          *
247          * @param index the index
248          */
249         public void updateIndex(DBIndex index) {
250
251                 JanusGraphManagement mgmt = graph.openManagement();
252                 List<PropertyKey> keys = new ArrayList<>();
253                 boolean isNew = false;
254                 boolean isChanged = false;
255                 for (DBProperty prop : index.getProperties()) {
256                         createProperty(mgmt, prop);
257                         keys.add(mgmt.getPropertyKey(prop.getName()));
258                 }
259                 if (mgmt.containsGraphIndex(index.getName())) {
260                         logger.info("index already exists");
261                         isNew = false;
262                         isChanged = true;
263                 } else {
264                         isNew = true;
265                         isChanged = false;
266                 }
267                 this.createIndex(mgmt, index.getName(), keys, index.isUnique(), isNew, isChanged);
268
269                 mgmt.commit();
270                 
271         }
272         
273         
274         
275         
276         
277 }