Update aai-common to 1.14.0 in graphadmin
[aai/graphadmin.git] / src / main / java / org / onap / aai / dbgen / schemamod / SchemaModInternal4Hist.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.dbgen.schemamod;
21
22 import java.util.Iterator;
23
24 import org.apache.tinkerpop.gremlin.structure.Graph;
25 import org.apache.tinkerpop.gremlin.structure.Vertex;
26 import org.onap.aai.dbmap.AAIGraph;
27 import org.onap.aai.serialization.engines.TransactionalGraphEngine;
28 import org.onap.aai.util.FormatDate;
29 import org.slf4j.Logger;
30 import org.janusgraph.core.Cardinality;
31 import org.janusgraph.core.PropertyKey;
32 import org.janusgraph.core.schema.JanusGraphManagement;
33 import org.janusgraph.graphdb.database.management.ManagementSystem;
34
35 public class SchemaModInternal4Hist {
36         private final TransactionalGraphEngine engine;
37         private final String propName;
38         private final Class<?> type;
39         private final String indexType;
40         private final boolean preserveData;
41         private final Cardinality cardinality;
42         private final Logger logger;
43
44         public SchemaModInternal4Hist(TransactionalGraphEngine engine, Logger logger, String propName, String type, String indexType, boolean preserveData) {
45                 this.engine = engine;
46                 this.propName = propName;
47                 this.type = determineClass(type);
48                 this.indexType = indexType;
49                 this.preserveData = preserveData;
50                 this.cardinality = Cardinality.LIST; // Always use this for History
51                 this.logger = logger;
52         }
53
54         private Class<?> determineClass(String type) {
55                 final Class<?> result;
56                 if (type.equals("String")) {
57                         result = String.class;
58                 } else if (type.equals("Set<String>")) {
59                         result = String.class;
60                 } else if (type.equals("Integer")) {
61                         result = Integer.class;
62                 } else if (type.equals("Boolean")) {
63                         result = Boolean.class;
64                 } else if (type.equals("Character")) {
65                         result = Character.class;
66                 } else if (type.equals("Long")) {
67                         result = Long.class;
68                 } else if (type.equals("Float")) {
69                         result = Float.class;
70                 } else if (type.equals("Double")) {
71                         result = Double.class;
72                 } else {
73                         String emsg = "Not able translate the targetDataType [" + type + "] to a Class variable.\n";
74                         logAndPrint(logger, emsg);
75                         throw new RuntimeException(emsg);
76                 }
77
78                 return result;
79         }
80
81         public void execute() {
82                 JanusGraphManagement graphMgt = null;
83                 boolean success = false;
84                 try {
85                         // Make sure this property is in the DB.
86                         graphMgt = engine.asAdmin().getManagementSystem();
87                         if (graphMgt == null) {
88                                 String emsg = "Not able to get a graph Management object in SchemaModInternal4Hist.java\n";
89                                 logAndPrint(logger, emsg);
90                                 System.exit(1);
91                         }
92                         PropertyKey origPropKey = graphMgt.getPropertyKey(propName);
93                         if (origPropKey == null) {
94                                 String emsg = "The propName = [" + propName + "] is not defined in our graph. ";
95                                 logAndPrint(logger, emsg);
96                                 System.exit(1);
97                         }
98
99                         // Rename this property to a backup name (old name with "retired_"
100                         // appended plus a dateStr)
101                         FormatDate fd = new FormatDate("MMddHHmm", "GMT");
102                         String dteStr= fd.getDateTime();
103
104                         String retiredName = propName + "-" + dteStr + "-RETIRED";
105                         graphMgt.changeName(origPropKey, retiredName);
106
107                         // Create a new property using the original property name and the
108                         // targetDataType
109                         PropertyKey freshPropKey = graphMgt.makePropertyKey(propName).dataType(type)
110                                         .cardinality(cardinality).make();
111
112                         // Create an index if needed (regular index will be used instead of unique for history)
113                         boolean needsIndex = indexType.equals("index") || indexType.equals("uniqueIndex");
114                         String freshIndexName = propName + dteStr;
115                         if (needsIndex) {
116                                 graphMgt.buildIndex(freshIndexName, Vertex.class).addKey(freshPropKey).buildCompositeIndex();
117                         }
118
119                         logAndPrint(logger, "Committing schema changes with graphMgt.commit()");
120                         graphMgt.commit();
121                         engine.commit();
122                         if (needsIndex) {
123                                 ManagementSystem.awaitGraphIndexStatus(AAIGraph.getInstance().getGraph(), freshIndexName).call();
124                         }
125                         Graph grTmp2 = engine.startTransaction();
126
127                         // For each node that has this property, update the new from the old
128                         // and then remove the
129                         // old property from that node
130                         Iterator<Vertex> verts = grTmp2.traversal().V().has(retiredName);
131                         int vtxCount = 0;
132                         while (verts.hasNext()) {
133                                 vtxCount++;
134                                 Vertex tmpVtx =  verts.next();
135                                 String tmpVid = tmpVtx.id().toString();
136                                 Object origVal = tmpVtx.<Object> property(retiredName).orElse(null);
137                                 if (preserveData) {
138                                         tmpVtx.property(propName, origVal);
139                                         logAndPrint(logger,
140                                                                 "INFO -- just did the add of the freshPropertyKey and updated it with the orig value ("
141                                                                                 + origVal.toString() + ")");
142                                 } else {
143                                         // existing nodes just won't have that property anymore
144                                         // Not sure if we'd ever actually want to do this -- maybe
145                                         // we'd do this if the new
146                                         // data type was not compatible with the old?
147                                 }
148                                 tmpVtx.property(retiredName).remove();
149                                 logAndPrint(logger, "INFO -- just did the remove of the " + retiredName + " from this vertex. (vid="
150                                                 + tmpVid + ")");
151                         }
152
153                         success = true;
154                 } catch (Exception ex) {
155                         logAndPrint(logger, "Threw a regular Exception: ");
156                         logAndPrint(logger, ex.getMessage());
157                 } finally {
158                         if (graphMgt != null && graphMgt.isOpen()) {
159                                 // Any changes that worked correctly should have already done
160                                 // their commits.
161                                 graphMgt.rollback();
162                         }
163                         if (engine != null) {
164                                 if (success) {
165                                         engine.commit();
166                                 } else {
167                                         engine.rollback();
168                                 }
169                         }
170                 }
171         }
172
173         /**
174          * Log and print.
175          *
176          * @param logger the logger
177          * @param msg the msg
178          */
179         protected static void logAndPrint(Logger logger, String msg) {
180                 System.out.println(msg);
181                 logger.debug(msg);
182         }
183
184 }