diff options
author | Kajur, Harish (vk250x) <vk250x@att.com> | 2018-03-21 19:08:46 -0400 |
---|---|---|
committer | Kajur, Harish (vk250x) <vk250x@att.com> | 2018-03-28 16:18:53 -0400 |
commit | c2b9f61673089a475a9749af8ec642d0ae5aa047 (patch) | |
tree | 09d31632b117f325aba7e60eeb18608281454fc4 /aai-resources/src/main/java | |
parent | d5d81567b37df4730a4326f6bba09bfe355700b0 (diff) |
Update titan code to janus graph code
Issue-ID: AAI-949
Change-Id: I841ac5e1734742af863c6bffd0cc3b1951dfa321
Signed-off-by: Kajur, Harish (vk250x) <vk250x@att.com>
Diffstat (limited to 'aai-resources/src/main/java')
19 files changed, 1547 insertions, 349 deletions
diff --git a/aai-resources/src/main/java/org/onap/aai/dbgen/DataSnapshot.java b/aai-resources/src/main/java/org/onap/aai/dbgen/DataSnapshot.java index aa1f9a6..d7271c9 100644 --- a/aai-resources/src/main/java/org/onap/aai/dbgen/DataSnapshot.java +++ b/aai-resources/src/main/java/org/onap/aai/dbgen/DataSnapshot.java @@ -39,8 +39,8 @@ import org.onap.aai.util.FormatDate; import com.att.eelf.configuration.Configuration; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; -import com.thinkaurelius.titan.core.TitanGraph; -import com.thinkaurelius.titan.core.util.TitanCleanup; +import org.janusgraph.core.JanusGraph; +import org.janusgraph.core.util.JanusGraphCleanup; public class DataSnapshot { @@ -63,7 +63,7 @@ public class DataSnapshot { props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES); Boolean dbClearFlag = false; - TitanGraph graph = null; + JanusGraph graph = null; String command = "JUST_TAKE_SNAPSHOT"; // This is the default String oldSnapshotFileName = ""; if (args.length == 1) { @@ -160,7 +160,7 @@ public class DataSnapshot { System.out.println(" Begin clearing out old data. "); graph.close(); - TitanCleanup.clear(graph); + JanusGraphCleanup.clear(graph); System.out.println(" Done clearing data. "); System.out.println(">>> IMPORTANT - NOTE >>> you need to run the SchemaGenerator (use GenTester) before "); System.out.println(" reloading data or the data will be put in without indexes. "); @@ -192,7 +192,7 @@ public class DataSnapshot { } System.out.println("We will load data IN from the file = " + oldSnapshotFullFname); - System.out.println(" Begin reloading Titan 0.5 data. "); + System.out.println(" Begin reloading JanusGraph 0.5 data. "); LegacyGraphSONReader lgr = LegacyGraphSONReader.build().create(); InputStream is = new FileInputStream(oldSnapshotFullFname); @@ -200,7 +200,7 @@ public class DataSnapshot { System.out.println("Completed the inputGraph command, now try to commit()... "); graph.tx().commit(); - System.out.println("Completed reloading Titan 0.5 data."); + System.out.println("Completed reloading JanusGraph 0.5 data."); long vCount = graph.traversal().V().count().next(); System.out.println("A little after repopulating from an old snapshot, we see: " + vCount + " vertices in the db."); diff --git a/aai-resources/src/main/java/org/onap/aai/dbgen/DupeTool.java b/aai-resources/src/main/java/org/onap/aai/dbgen/DupeTool.java index 87d68c3..3b9c56e 100644 --- a/aai-resources/src/main/java/org/onap/aai/dbgen/DupeTool.java +++ b/aai-resources/src/main/java/org/onap/aai/dbgen/DupeTool.java @@ -56,8 +56,8 @@ import org.slf4j.MDC; import com.att.eelf.configuration.Configuration; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; -import com.thinkaurelius.titan.core.TitanFactory; -import com.thinkaurelius.titan.core.TitanGraph; +import org.janusgraph.core.JanusGraphFactory; +import org.janusgraph.core.JanusGraph; @@ -132,8 +132,8 @@ public class DupeTool { logger.error("ERROR - Could not do the moxyMod.init() " + LogFormatTools.getStackTop(ex)); exit(1); } - TitanGraph graph1 = null; - TitanGraph graph2 = null; + JanusGraph graph1 = null; + JanusGraph graph2 = null; Graph gt1 = null; Graph gt2 = null; @@ -482,7 +482,7 @@ public class DupeTool { gt1.tx().rollback(); } catch (Exception ex) { - // Don't throw anything because Titan sometimes is just saying that the graph is already closed + // Don't throw anything because JanusGraph sometimes is just saying that the graph is already closed logger.warn("WARNING from final gt1.rollback() " + LogFormatTools.getStackTop(ex)); } } @@ -493,7 +493,7 @@ public class DupeTool { try { gt2.tx().rollback(); } catch (Exception ex) { - // Don't throw anything because Titan sometimes is just saying that the graph is already closed + // Don't throw anything because JanusGraph sometimes is just saying that the graph is already closed logger.warn("WARNING from final gt2.rollback() " + LogFormatTools.getStackTop(ex)); } } @@ -503,7 +503,7 @@ public class DupeTool { closeGraph(graph1, logger); } } catch (Exception ex) { - // Don't throw anything because Titan sometimes is just saying that the graph is already closed + // Don't throw anything because JanusGraph sometimes is just saying that the graph is already closed{ logger.warn("WARNING from final graph1.shutdown() " + LogFormatTools.getStackTop(ex)); } @@ -512,7 +512,7 @@ public class DupeTool { closeGraph(graph2, logger); } } catch (Exception ex) { - // Don't throw anything because Titan sometimes is just saying that the graph is already closed + // Don't throw anything because JanusGraph sometimes is just saying that the graph is already closed{ logger.warn("WARNING from final graph2.shutdown() " + LogFormatTools.getStackTop(ex)); } } @@ -756,7 +756,7 @@ public class DupeTool { }// End of getDupeSets4DependentNodes() - private static Graph getGraphTransaction(TitanGraph graph, EELFLogger logger){ + private static Graph getGraphTransaction(JanusGraph graph, EELFLogger logger){ Graph gt = null; try { @@ -829,7 +829,7 @@ public class DupeTool { } }// End of showNodeInfo() - + public static ArrayList <String> collectEdgeInfoForNode( EELFLogger logger, Vertex tVert, boolean displayAllVidsFlag ){ ArrayList <String> retArr = new ArrayList <String> (); Direction dir = Direction.OUT; @@ -1035,7 +1035,7 @@ public class DupeTool { } if(tgQ == null){ - msg = "Bad TitanGraphQuery object. "; + msg = "Bad JanusGraphQuery object. "; System.out.println(msg); LoggingContext.statusCode(StatusCode.ERROR); LoggingContext.responseCode(LoggingContext.AVAILABILITY_TIMEOUT_ERROR); @@ -1391,7 +1391,7 @@ public class DupeTool { String nType, ArrayList<Vertex> passedVertList, Loader loader) throws AAIException { - // Given a list of Titan Vertices, group them together by dependent + // Given a list of JanusGraph Vertices, group them together by dependent // nodes. Ie. if given a list of ip address nodes (assumed to all // have the same key info) they might sit under several different // parent vertices. @@ -1755,7 +1755,7 @@ public class DupeTool { // This is not the last entry, it is one of the dupes delIdArr.add(dupeArr[i]); continue; - } + } // This is the last entry which should tell us if we // have a preferred keeper and how many dupes we had @@ -1846,9 +1846,9 @@ public class DupeTool { private static int graphIndex = 1; - public static TitanGraph setupGraph(EELFLogger logger){ + public static JanusGraph setupGraph(EELFLogger logger){ - TitanGraph titanGraph = null; + JanusGraph janusGraph = null; try (InputStream inputStream = new FileInputStream(AAIConstants.REALTIME_DB_CONFIG);){ @@ -1857,20 +1857,20 @@ public class DupeTool { properties.load(inputStream); if(INMEMORY.equals(properties.get("storage.backend"))){ - titanGraph = AAIGraph.getInstance().getGraph(); + janusGraph = AAIGraph.getInstance().getGraph(); graphType = INMEMORY; } else { - titanGraph = TitanFactory.open(new AAIGraphConfig.Builder(AAIConstants.REALTIME_DB_CONFIG).forService(DupeTool.class.getSimpleName()).withGraphType("realtime" + graphIndex).buildConfiguration()); + janusGraph = JanusGraphFactory.open(new AAIGraphConfig.Builder(AAIConstants.REALTIME_DB_CONFIG).forService(DupeTool.class.getSimpleName()).withGraphType("realtime" + graphIndex).buildConfiguration()); graphIndex++; } } catch (Exception e) { logger.error("Unable to open the graph", LogFormatTools.getStackTop(e)); } - return titanGraph; + return janusGraph; } - public static void closeGraph(TitanGraph graph, EELFLogger logger){ + public static void closeGraph(JanusGraph graph, EELFLogger logger){ try { if(INMEMORY.equals(graphType)) { @@ -1881,7 +1881,7 @@ public class DupeTool { graph.close(); } } catch (Exception ex) { - // Don't throw anything because Titan sometimes is just saying that the graph is already closed + // Don't throw anything because JanusGraph sometimes is just saying that the graph is already closed{ logger.warn("WARNING from final graph.shutdown()", ex); } } diff --git a/aai-resources/src/main/java/org/onap/aai/dbgen/ForceDeleteTool.java b/aai-resources/src/main/java/org/onap/aai/dbgen/ForceDeleteTool.java index 060e659..96c5467 100644 --- a/aai-resources/src/main/java/org/onap/aai/dbgen/ForceDeleteTool.java +++ b/aai-resources/src/main/java/org/onap/aai/dbgen/ForceDeleteTool.java @@ -47,8 +47,8 @@ import org.slf4j.MDC; import com.att.eelf.configuration.Configuration; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; -import com.thinkaurelius.titan.core.TitanFactory; -import com.thinkaurelius.titan.core.TitanGraph; +import org.janusgraph.core.JanusGraphFactory; +import org.janusgraph.core.JanusGraph; @@ -235,7 +235,7 @@ public class ForceDeleteTool { } String msg = ""; - TitanGraph graph = null; + JanusGraph graph = null; try { AAIConfig.init(); System.out.println(" ---- NOTE --- about to open graph (takes a little while)--------\n"); @@ -321,7 +321,7 @@ public class ForceDeleteTool { } } else { - msg = "Bad TitanGraphQuery object. "; + msg = "Bad JanusGraphQuery object. "; System.out.println(msg); LoggingContext.statusCode(StatusCode.ERROR); LoggingContext.responseCode(LoggingContext.DATA_ERROR); @@ -411,9 +411,9 @@ public class ForceDeleteTool { public static class ForceDelete { - private static final int MAXDESCENDENTDEPTH = 15; - private final TitanGraph graph; - public ForceDelete(TitanGraph graph) { + private final int MAXDESCENDENTDEPTH = 15; + private final JanusGraph graph; + public ForceDelete(JanusGraph graph) { this.graph = graph; } public void showNodeInfo(EELFLogger logger, Vertex tVert, Boolean displayAllVidsFlag ){ @@ -814,9 +814,9 @@ public class ForceDeleteTool { } // End of getNodeDelConfirmation() } - public static TitanGraph setupGraph(EELFLogger logger){ + public static JanusGraph setupGraph(EELFLogger logger){ - TitanGraph titanGraph = null; + JanusGraph janusGraph = null; try (InputStream inputStream = new FileInputStream(AAIConstants.REALTIME_DB_CONFIG);){ @@ -824,10 +824,10 @@ public class ForceDeleteTool { properties.load(inputStream); if(INMEMORY.equals(properties.get("storage.backend"))){ - titanGraph = AAIGraph.getInstance().getGraph(); + janusGraph = AAIGraph.getInstance().getGraph(); graphType = INMEMORY; } else { - titanGraph = TitanFactory.open( + janusGraph = JanusGraphFactory.open( new AAIGraphConfig.Builder(AAIConstants.REALTIME_DB_CONFIG) .forService(ForceDeleteTool.class.getSimpleName()) .withGraphType("realtime1") @@ -838,10 +838,10 @@ public class ForceDeleteTool { logger.error("Unable to open the graph", LogFormatTools.getStackTop(e)); } - return titanGraph; + return janusGraph; } - public static void closeGraph(TitanGraph graph, EELFLogger logger){ + public static void closeGraph(JanusGraph graph, EELFLogger logger){ try { if(INMEMORY.equals(graphType)) { @@ -852,7 +852,7 @@ public class ForceDeleteTool { graph.close(); } } catch (Exception ex) { - // Don't throw anything because Titan sometimes is just saying that the graph is already closed + // Don't throw anything because JanusGraph sometimes is just saying that the graph is already closed{ logger.warn("WARNING from final graph.shutdown()", ex); } } diff --git a/aai-resources/src/main/java/org/onap/aai/dbgen/SchemaMod.java b/aai-resources/src/main/java/org/onap/aai/dbgen/SchemaMod.java new file mode 100644 index 0000000..146b729 --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/dbgen/SchemaMod.java @@ -0,0 +1,182 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.dbgen; + +import java.util.Properties; + +import org.onap.aai.dbmap.DBConnectionType; +import org.onap.aai.introspection.Loader; +import org.onap.aai.introspection.LoaderFactory; +import org.onap.aai.introspection.ModelType; +import org.onap.aai.introspection.Version; +import org.onap.aai.logging.ErrorLogHelper; +import org.onap.aai.serialization.engines.QueryStyle; +import org.onap.aai.serialization.engines.JanusGraphDBEngine; +import org.onap.aai.serialization.engines.TransactionalGraphEngine; +import org.onap.aai.util.AAIConfig; +import org.onap.aai.util.AAIConstants; +import org.onap.aai.util.UniquePropertyCheck; +import org.slf4j.MDC; + +import com.att.eelf.configuration.Configuration; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +public class SchemaMod { + + + + /** + * The main method. + * + * @param args the arguments + */ + public static void main(String[] args) { + + SchemaMod.execute(args); + System.exit(0); + + }// End of main() + + /** + * Execute. + * + * @param args the args + */ + public static void execute(String[] args) { + + // Set the logging file properties to be used by EELFManager + Properties props = System.getProperties(); + props.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, AAIConstants.AAI_SCHEMA_MOD_LOGBACK_PROPS); + props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES); + + EELFLogger logger = EELFManager.getInstance().getLogger(UniquePropertyCheck.class.getSimpleName()); + MDC.put("logFilenameAppender", SchemaMod.class.getSimpleName()); + + // NOTE -- We're just working with properties that are used for NODES + // for now. + String propName = ""; + String targetDataType = ""; + String targetIndexInfo = ""; + String preserveDataFlag = ""; + + String usageString = "Usage: SchemaMod propertyName targetDataType targetIndexInfo preserveDataFlag \n"; + if (args.length != 4) { + String emsg = "Four Parameters are required. \n" + usageString; + logAndPrint(logger, emsg); + System.exit(1); + } else { + propName = args[0]; + targetDataType = args[1]; + targetIndexInfo = args[2]; + preserveDataFlag = args[3]; + } + + if (propName.equals("")) { + String emsg = "Bad parameter - propertyName cannot be empty. \n" + usageString; + logAndPrint(logger, emsg); + System.exit(1); + } else if (!targetDataType.equals("String") && !targetDataType.equals("Set<String>") + && !targetDataType.equals("Integer") && !targetDataType.equals("Long") + && !targetDataType.equals("Boolean")) { + String emsg = "Unsupported targetDataType. We only support String, Set<String>, Integer, Long or Boolean for now.\n" + + usageString; + logAndPrint(logger, emsg); + System.exit(1); + } else if (!targetIndexInfo.equals("uniqueIndex") && !targetIndexInfo.equals("index") + && !targetIndexInfo.equals("noIndex")) { + String emsg = "Unsupported IndexInfo. We only support: 'uniqueIndex', 'index' or 'noIndex'.\n" + + usageString; + logAndPrint(logger, emsg); + System.exit(1); + } + + try { + AAIConfig.init(); + ErrorLogHelper.loadProperties(); + } catch (Exception ae) { + String emsg = "Problem with either AAIConfig.init() or ErrorLogHelper.LoadProperties(). "; + logAndPrint(logger, emsg + "[" + ae.getMessage() + "]"); + System.exit(1); + } + + + // Give a big warning if the DbMaps.PropertyDataTypeMap value does not + // agree with what we're doing + String warningMsg = ""; + /*if (!dbMaps.PropertyDataTypeMap.containsKey(propName)) { + String emsg = "Property Name = [" + propName + "] not found in PropertyDataTypeMap. "; + logAndPrint(logger, emsg); + System.exit(1); + } else { + String currentDataType = dbMaps.PropertyDataTypeMap.get(propName); + if (!currentDataType.equals(targetDataType)) { + warningMsg = "TargetDataType [" + targetDataType + "] does not match what is in DbRules.java (" + + currentDataType + ")."; + } + }*/ + + if (!warningMsg.equals("")) { + logAndPrint(logger, "\n>>> WARNING <<<< "); + logAndPrint(logger, ">>> " + warningMsg + " <<<"); + } + + logAndPrint(logger, ">>> Processing will begin in 5 seconds (unless interrupted). <<<"); + try { + // Give them a chance to back out of this + Thread.sleep(5000); + } catch (java.lang.InterruptedException ie) { + logAndPrint(logger, " DB Schema Update has been aborted. "); + System.exit(1); + } + + logAndPrint(logger, " ---- NOTE --- about to open graph (takes a little while)\n"); + + Version version = Version.getLatest(); + QueryStyle queryStyle = QueryStyle.TRAVERSAL; + ModelType introspectorFactoryType = ModelType.MOXY; + Loader loader = LoaderFactory.createLoaderForVersion(introspectorFactoryType, version); + TransactionalGraphEngine engine = null; + try { + engine = new JanusGraphDBEngine(queryStyle, DBConnectionType.REALTIME, loader); + SchemaModInternal internal = new SchemaModInternal(engine, logger, propName, targetDataType, targetIndexInfo, new Boolean(preserveDataFlag)); + internal.execute(); + engine.startTransaction(); + engine.tx().close(); + } catch (Exception e) { + String emsg = "Not able to get a graph object in SchemaMod.java\n"; + logAndPrint(logger, e.getMessage()); + logAndPrint(logger, emsg); + System.exit(1); + } + } + /** + * Log and print. + * + * @param logger the logger + * @param msg the msg + */ + protected static void logAndPrint(EELFLogger logger, String msg) { + System.out.println(msg); + logger.info(msg); + } + + +} diff --git a/aai-resources/src/main/java/org/onap/aai/dbgen/SchemaModInternal.java b/aai-resources/src/main/java/org/onap/aai/dbgen/SchemaModInternal.java new file mode 100644 index 0000000..1aa33ee --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/dbgen/SchemaModInternal.java @@ -0,0 +1,309 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aai.dbgen; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.UUID; + +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.VertexProperty; +import org.onap.aai.serialization.engines.TransactionalGraphEngine; +import org.onap.aai.util.FormatDate; +import org.onap.aai.util.UniquePropertyCheck; + +import com.att.eelf.configuration.EELFLogger; +import org.janusgraph.core.Cardinality; +import org.janusgraph.core.PropertyKey; +import org.janusgraph.core.schema.JanusGraphManagement; + +public class SchemaModInternal { + private static final String FROMAPPID = "AAI-UTILS"; + private final String TRANSID = UUID.randomUUID().toString(); + private final TransactionalGraphEngine engine; + private final String propName; + private final Class<?> type; + private final String indexType; + private final boolean preserveData; + private final Cardinality cardinality; + private final EELFLogger logger; + + public SchemaModInternal(TransactionalGraphEngine engine, EELFLogger logger, String propName, String type, String indexType, boolean preserveData) { + this.engine = engine; + this.propName = propName; + this.type = determineClass(type); + this.indexType = indexType; + this.preserveData = preserveData; + this.cardinality = determineCardinality(type); + this.logger = logger; + } + + + private Class<?> determineClass(String type) { + final Class<?> result; + if (type.equals("String")) { + result = String.class; + } else if (type.equals("Set<String>")) { + result = String.class; + } else if (type.equals("Integer")) { + result = Integer.class; + } else if (type.equals("Boolean")) { + result = Boolean.class; + } else if (type.equals("Character")) { + result = Character.class; + } else if (type.equals("Long")) { + result = Long.class; + } else if (type.equals("Float")) { + result = Float.class; + } else if (type.equals("Double")) { + result = Double.class; + } else { + String emsg = "Not able translate the targetDataType [" + type + "] to a Class variable.\n"; + logAndPrint(logger, emsg); + throw new RuntimeException(emsg); + } + + return result; + } + private Cardinality determineCardinality(String type) { + if (type.equals("Set<String>")) { + return Cardinality.SET; + } else { + return Cardinality.SINGLE; + } + } + public void execute() { + JanusGraphManagement graphMgt = null; + boolean success = false; + try { + // Make sure this property is in the DB. + graphMgt = engine.asAdmin().getManagementSystem(); + if (graphMgt == null) { + String emsg = "Not able to get a graph Management object in SchemaMod.java\n"; + logAndPrint(logger, emsg); + System.exit(1); + } + PropertyKey origPropKey = graphMgt.getPropertyKey(propName); + if (origPropKey == null) { + String emsg = "The propName = [" + propName + "] is not defined in our graph. "; + logAndPrint(logger, emsg); + System.exit(1); + } + + if (indexType.equals("uniqueIndex")) { + // Make sure the data in the property being changed can have a + // unique-index put on it. + // Ie. if there are duplicate values, we will not be able to + // migrate the data back into the property. + Boolean foundDupesFlag = UniquePropertyCheck.runTheCheckForUniqueness(TRANSID, FROMAPPID, + engine.tx(), propName, logger); + if (foundDupesFlag) { + logAndPrint(logger, + "\n\n!!!!!! >> Cannot add a uniqueIndex for the property: [" + propName + + "] because duplicate values were found. See the log for details on which" + + " nodes have this value. \nThey will need to be resolved (by updating those values to new" + + " values or deleting unneeded nodes) using the standard REST-API \n"); + System.exit(1); + } + } + + // -------------- If we made it to here - we must be OK with making + // this change ------------ + + // Rename this property to a backup name (old name with "retired_" + // appended plus a dateStr) + + FormatDate fd = new FormatDate("MMddHHmm", "GMT"); + String dteStr= fd.getDateTime(); + + String retiredName = propName + "-" + dteStr + "-RETIRED"; + graphMgt.changeName(origPropKey, retiredName); + + // Create a new property using the original property name and the + // targetDataType + PropertyKey freshPropKey = graphMgt.makePropertyKey(propName).dataType(type) + .cardinality(cardinality).make(); + + // Create the appropriate index (if any) + if (indexType.equals("uniqueIndex")) { + String freshIndexName = propName + dteStr; + graphMgt.buildIndex(freshIndexName, Vertex.class).addKey(freshPropKey).unique().buildCompositeIndex(); + } else if (indexType.equals("index")) { + String freshIndexName = propName + dteStr; + graphMgt.buildIndex(freshIndexName, Vertex.class).addKey(freshPropKey).buildCompositeIndex(); + } + + logAndPrint(logger, "Committing schema changes with graphMgt.commit()"); + graphMgt.commit(); + engine.startTransaction(); + // Get A new graph object + logAndPrint(logger, " ---- NOTE --- about to open a second graph object (takes a little while)\n"); + + // For each node that has this property, update the new from the old + // and then remove the + // old property from that node + Iterator<Vertex> verts = engine.asAdmin().getTraversalSource().V().has(retiredName); + int vtxCount = 0; + ArrayList<String> alreadySeenVals = new ArrayList<String>(); + while (verts.hasNext()) { + vtxCount++; + Vertex tmpVtx = verts.next(); + String tmpVid = tmpVtx.id().toString(); + + Object origVal = tmpVtx.<Object> property(retiredName).orElse(null); + if (preserveData) { + tmpVtx.property(propName, origVal); + if (indexType.equals("uniqueIndex")) { + // We're working on a property that is being used as a + // unique index + String origValStr = ""; + if (origVal != null) { + origValStr = origVal.toString(); + } + if (alreadySeenVals.contains(origValStr)) { + // This property is supposed to be unique, but we've + // already seen this value in this loop + // This should have been caught up in the first part + // of SchemaMod, but since it wasn't, we + // will just log the problem. + logAndPrint(logger, + "\n\n ---------- ERROR - could not migrate the old data [" + origValStr + + "] for propertyName [" + propName + + "] because this property is having a unique index put on it."); + showPropertiesAndEdges(TRANSID, FROMAPPID, tmpVtx, logger); + logAndPrint(logger, "-----------------------------------\n"); + } else { + // Ok to add this prop in as a unique value + tmpVtx.property(propName, origVal); + logAndPrint(logger, + "INFO -- just did the add of the freshPropertyKey and updated it with the orig value (" + + origValStr + ")"); + } + alreadySeenVals.add(origValStr); + } else { + // We are not working with a unique index + tmpVtx.property(propName, origVal); + logAndPrint(logger, + "INFO -- just did the add of the freshPropertyKey and updated it with the orig value (" + + origVal.toString() + ")"); + } + } else { + // existing nodes just won't have that property anymore + // Not sure if we'd ever actually want to do this -- maybe + // we'd do this if the new + // data type was not compatible with the old? + } + tmpVtx.property(retiredName).remove(); + + logAndPrint(logger, "INFO -- just did the remove of the " + retiredName + " from this vertex. (vid=" + + tmpVid + ")"); + } + + success = true; + } catch (Exception ex) { + logAndPrint(logger, "Threw a regular Exception: "); + logAndPrint(logger, ex.getMessage()); + } finally { + if (graphMgt != null && graphMgt.isOpen()) { + // Any changes that worked correctly should have already done + // their commits. + graphMgt.rollback(); + } + if (engine != null) { + if (success) { + engine.commit(); + } else { + engine.rollback(); + } + } + } + } + + /** + * Show properties and edges. + * + * @param transId the trans id + * @param fromAppId the from app id + * @param tVert the t vert + * @param logger the logger + */ + private static void showPropertiesAndEdges(String transId, String fromAppId, Vertex tVert, EELFLogger logger) { + + if (tVert == null) { + logAndPrint(logger, "Null node passed to showPropertiesAndEdges."); + } else { + String nodeType = ""; + Object ob = tVert.<String> property("aai-node-type"); + if (ob == null) { + nodeType = "null"; + } else { + nodeType = ob.toString(); + } + + logAndPrint(logger, " AAINodeType/VtxID for this Node = [" + nodeType + "/" + tVert.id() + "]"); + logAndPrint(logger, " Property Detail: "); + Iterator<VertexProperty<Object>> pI = tVert.properties(); + while (pI.hasNext()) { + VertexProperty<Object> tp = pI.next(); + Object val = tp.value(); + logAndPrint(logger, "Prop: [" + tp.key() + "], val = [" + val + "] "); + } + + Iterator<Edge> eI = tVert.edges(Direction.BOTH); + if (!eI.hasNext()) { + logAndPrint(logger, "No edges were found for this vertex. "); + } + while (eI.hasNext()) { + Edge ed = eI.next(); + String lab = ed.label(); + Vertex vtx; + if (tVert.equals(ed.inVertex())) { + vtx = ed.outVertex(); + } else { + vtx = ed.inVertex(); + } + if (vtx == null) { + logAndPrint(logger, + " >>> COULD NOT FIND VERTEX on the other side of this edge edgeId = " + ed.id() + " <<< "); + } else { + String nType = vtx.<String> property("aai-node-type").orElse(null); + String vid = vtx.id().toString(); + logAndPrint(logger, "Found an edge (" + lab + ") from this vertex to a [" + nType + + "] node with VtxId = " + vid); + } + } + } + } // End of showPropertiesAndEdges() + + /** + * Log and print. + * + * @param logger the logger + * @param msg the msg + */ + protected static void logAndPrint(EELFLogger logger, String msg) { + System.out.println(msg); + logger.info(msg); + } + +} diff --git a/aai-resources/src/main/java/org/onap/aai/dbgen/UpdateEdgeTags.java b/aai-resources/src/main/java/org/onap/aai/dbgen/UpdateEdgeTags.java index 8be40de..aebc456 100644 --- a/aai-resources/src/main/java/org/onap/aai/dbgen/UpdateEdgeTags.java +++ b/aai-resources/src/main/java/org/onap/aai/dbgen/UpdateEdgeTags.java @@ -19,23 +19,14 @@ */ package org.onap.aai.dbgen; -import com.google.common.collect.Multimap; -import com.thinkaurelius.titan.core.TitanGraph; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Graph; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.onap.aai.dbmap.AAIGraph; +import org.onap.aai.dbgen.tags.UpdateEdgeTagsCmd; import org.onap.aai.exceptions.AAIException; -import org.onap.aai.logging.ErrorLogHelper; import org.onap.aai.logging.LoggingContext; import org.onap.aai.logging.LoggingContext.StatusCode; -import org.onap.aai.serialization.db.EdgeRule; -import org.onap.aai.serialization.db.EdgeRules; -import org.onap.aai.util.AAIConfig; -import org.onap.aai.util.AAISystemExitUtil; import org.onap.aai.util.AAIConstants; +import org.onap.aai.util.AAISystemExitUtil; -import java.util.*; +import java.util.UUID; public class UpdateEdgeTags { @@ -52,10 +43,10 @@ public class UpdateEdgeTags { System.setProperty("aai.service.name", UpdateEdgeTags.class.getSimpleName()); - if( args == null || args.length != 1 ){ + if( args == null || args.length != 1 ){ String msg = "usage: UpdateEdgeTags edgeRuleKey (edgeRuleKey can be either, all, or a rule key like 'nodeTypeA|nodeTypeB') \n"; System.out.println(msg); - AAISystemExitUtil.systemExitCloseAAIGraph(1); + System.exit(1); } LoggingContext.init(); LoggingContext.partnerName(FROMAPPID); @@ -66,257 +57,19 @@ public class UpdateEdgeTags { LoggingContext.requestId(TRANSID); LoggingContext.statusCode(StatusCode.COMPLETE); LoggingContext.responseCode("0"); - - String edgeRuleKeyVal = args[0]; - - TitanGraph graph = null; - EdgeRules edgeRulesInstance = EdgeRules.getInstance(); - Multimap<String, EdgeRule> edgeRuleMultimap = edgeRulesInstance.getAllRules(); - - HashMap <String,Object> edgeRuleHash = new HashMap <String,Object>(); - HashMap <String,Object> edgeRulesFullHash = new HashMap <String,Object>(); - HashMap <String,Object> edgeRuleLabelToKeyHash = new HashMap <String,Object>(); - ArrayList <String> labelMapsToMultipleKeys = new <String> ArrayList (); - - // Loop through all the edge-rules make sure they look right and - // collect info about which labels support duplicate ruleKeys. - Iterator<String> edgeRulesIterator = edgeRuleMultimap.keySet().iterator(); - - while( edgeRulesIterator.hasNext() ){ - String ruleKey = edgeRulesIterator.next(); - Collection <EdgeRule> edRuleColl = edgeRuleMultimap.get(ruleKey); - Iterator <EdgeRule> ruleItr = edRuleColl.iterator(); - if( ruleItr.hasNext() ){ - // For now, we only look for one type of edge between two nodes. - EdgeRule edgeRule = ruleItr.next(); - String edgeRuleString = String.format("%s,%s,%s,%s,%s,%s", - edgeRule.getLabel(), - edgeRule.getDirection(), - edgeRule.getMultiplicityRule(), - edgeRule.getContains(), - edgeRule.getDeleteOtherV(), - edgeRule.getServiceInfrastructure()); - edgeRulesFullHash.put(ruleKey,edgeRuleString); - String edgeLabel = edgeRule.getLabel(); - if( edgeRuleLabelToKeyHash.containsKey(edgeLabel) ){ - // This label maps to more than one edge rule - we'll have to figure out - // which rule applies when we look at each edge that uses this label. - // So we take it out of mapping hash and add it to the list of ones that - // we'll need to look up later. - edgeRuleLabelToKeyHash.remove(edgeLabel); - labelMapsToMultipleKeys.add(edgeLabel); - } - else { - edgeRuleLabelToKeyHash.put(edgeLabel, ruleKey); - } - } - } - - if( ! edgeRuleKeyVal.equals( "all" ) ){ - // If they passed in a (non-"all") argument, that is the single edgeRule that they want to update. - // Note - the key looks like "nodeA|nodeB" as it appears in DbEdgeRules.EdgeRules - Collection <EdgeRule> edRuleColl = edgeRuleMultimap.get(edgeRuleKeyVal); - Iterator <EdgeRule> ruleItr = edRuleColl.iterator(); - if( ruleItr.hasNext() ){ - // For now, we only look for one type of edge between two nodes (Ie. for one key). - EdgeRule edRule = ruleItr.next(); - edgeRuleHash.put(edgeRuleKeyVal, edRule); - System.out.println("Adding this rule to list of rules to do: key = " + edgeRuleKeyVal + ", rule = [" + edRule + "]"); - } - else { - String msg = " Error - Unrecognized edgeRuleKey: [" + edgeRuleKeyVal + "]. "; - System.out.println(msg); - AAISystemExitUtil.systemExitCloseAAIGraph(0); - } - } - else { - // They didn't pass a target ruleKey in, so we'll work on all types of edges - edgeRuleHash.putAll(edgeRulesFullHash); - } - try { - AAIConfig.init(); - System.out.println(" ---- NOTE --- about to open graph (takes a little while)--------\n"); - ErrorLogHelper.loadProperties(); - - graph = AAIGraph.getInstance().getGraph(); - - if( graph == null ){ - String emsg = "null graph object in updateEdgeTags() \n"; - System.out.println(emsg); - AAISystemExitUtil.systemExitCloseAAIGraph(0); - } - } - catch (AAIException e1) { - String msg = e1.getErrorObject().toString(); - System.out.println(msg); - AAISystemExitUtil.systemExitCloseAAIGraph(0); - } - catch (Exception e2) { - String msg = e2.toString(); - System.out.println(msg); - e2.printStackTrace(); - AAISystemExitUtil.systemExitCloseAAIGraph(0); - } - - Graph g = graph.newTransaction(); - try { - Iterator<Edge> edgeItr = graph.traversal().E(); - - // Loop through all edges and update their tags if they are a type we are interested in. - // Sorry about looping over everything, but for now, I can't find a way to just select one type of edge at a time...!? - StringBuffer sb; - boolean missingEdge = false; - while( edgeItr != null && edgeItr.hasNext() ){ - Edge tmpEd = edgeItr.next(); - String edLab = tmpEd.label().toString(); - - // Since we have edgeLabels that can be used for different pairs of node-types, we have to - // look to see what nodeTypes this edge is connecting (if it is a label that could do this). - String derivedEdgeKey = ""; - if( labelMapsToMultipleKeys.contains(edLab) ){ - // need to figure out which key is right for this edge - derivedEdgeKey = deriveEdgeRuleKeyForThisEdge( TRANSID, FROMAPPID, g, tmpEd ); - } - else { - // This kind of label only maps to one key -- so we can just look it up. - if ( edgeRuleLabelToKeyHash.get(edLab) == null ) { - if ( !missingEdge ) { - System.out.print("DEBUG - missing edge(s) in edgeRuleLabelToKeyHash " + edgeRuleLabelToKeyHash.toString()); - missingEdge = true; - } - sb = new StringBuffer(); - Vertex vIn = null; - Vertex vOut = null; - Object obj = null; - vIn = tmpEd.inVertex(); - if ( vIn != null ){ - obj = vIn.<String>property("aai-node-type").orElse(null); - if ( obj != null ) { - sb.append("from node-type " + obj.toString()); - - obj = vIn.id(); - sb.append(" id " + obj.toString()); - } else { - sb.append(" missing from node-type "); - } - } else { - sb.append(" missing inbound vertex "); - } - vOut = tmpEd.outVertex(); - if ( vOut != null ) { - obj = vOut.<String>property("aai-node-type").orElse(null); - if ( obj != null ) { - sb.append(" to node-type " + obj.toString()); - obj = vOut.id(); - sb.append(" id " + obj.toString()); - } else { - sb.append(" missing to node-type "); - } - } else { - sb.append(" missing to vertex "); - } - System.out.println("DEBUG - null entry for [" + edLab + "] between " + sb.toString()); - continue; - } - derivedEdgeKey = edgeRuleLabelToKeyHash.get(edLab).toString(); - } - - if( edgeRuleHash.containsKey(derivedEdgeKey) ){ - // this is an edge that we want to update - System.out.print("DEBUG - key = " + derivedEdgeKey + ", label = " + edLab - + ", for id = " + tmpEd.id().toString() + ", set: "); - Map<String,EdgeRule> edgeRules = getEdgeTagPropPutHash(TRANSID, FROMAPPID, derivedEdgeKey); - for (String key : edgeRules.keySet()) { - if (tmpEd.label().equals(key)) { - EdgeRules.getInstance().addProperties(tmpEd, edgeRules.get(key)); - } - } - System.out.print("\n"); - } - } // End of looping over all edges - graph.tx().commit(); - System.out.println("DEBUG - committed updates for listed edges " ); - } - catch (Exception e2) { - String msg = e2.toString(); - System.out.println(msg); - e2.printStackTrace(); - if( graph != null ){ - graph.tx().rollback(); - } + String edgeRuleKeyVal = args[0]; + + try { + UpdateEdgeTagsCmd edgeOp = new UpdateEdgeTagsCmd(edgeRuleKeyVal); + edgeOp.execute(); + } catch (AAIException e) { + e.printStackTrace(); + } finally { AAISystemExitUtil.systemExitCloseAAIGraph(0); } - - AAISystemExitUtil.systemExitCloseAAIGraph(0); }// end of main() - - - /** - * Derive edge rule key for this edge. - * - * @param transId the trans id - * @param fromAppId the from app id - * @param graph the graph - * @param tEdge the t edge - * @return String - key to look up edgeRule (fromNodeType|toNodeType) - * @throws AAIException the AAI exception - */ - public static String deriveEdgeRuleKeyForThisEdge( String transId, String fromAppId, Graph graph, - Edge tEdge ) throws AAIException { - - Vertex fromVtx = tEdge.outVertex(); - Vertex toVtx = tEdge.inVertex(); - String startNodeType = fromVtx.<String>property("aai-node-type").orElse(null); - String targetNodeType = toVtx.<String>property("aai-node-type").orElse(null); - String key = startNodeType + "|" + targetNodeType; - if( EdgeRules.getInstance().hasEdgeRule(startNodeType, targetNodeType) ){ - // We can use the node info in the order they were given - return( key ); - } - else { - key = targetNodeType + "|" + startNodeType; - if( EdgeRules.getInstance().hasEdgeRule(targetNodeType, startNodeType) ){ - return( key ); - } - else { - // Couldn't find a rule for this edge - throw new AAIException("AAI_6120", "No EdgeRule found for passed nodeTypes: " + startNodeType + ", " - + targetNodeType); - } - } - }// end of deriveEdgeRuleKeyForThisEdge() - - - /** - * Gets the edge tag prop put hash. - * - * @param transId the trans id - * @param fromAppId the from app id - * @param edgeRuleKey the edge rule key - * @return the edge tag prop put hash - * @throws AAIException the AAI exception - */ - public static Map<String, EdgeRule> getEdgeTagPropPutHash(String transId, String fromAppId, String edgeRuleKey ) - throws AAIException { - // For a given edgeRuleKey (nodeTypeA|nodeTypeB), look up the rule that goes with it in - // DbEdgeRules.EdgeRules and parse out the "tags" that need to be set on each edge. - // These are the Boolean properties like, "isParent", "usesResource" etc. - // Note - this code is also used by the updateEdgeTags.java code - - String[] edgeRuleKeys = edgeRuleKey.split("\\|"); - - if (edgeRuleKeys.length < 2 || ! EdgeRules.getInstance().hasEdgeRule(edgeRuleKeys[0], edgeRuleKeys[1])) { - throw new AAIException("AAI_6120", "Could not find an DbEdgeRule entry for passed edgeRuleKey (nodeTypeA|nodeTypeB): " + edgeRuleKey + "."); - } - - Map<String, EdgeRule> edgeRules = EdgeRules.getInstance().getEdgeRules(edgeRuleKeys[0], edgeRuleKeys[1]); - - return edgeRules; - - } // End of getEdgeTagPropPutHash() - } diff --git a/aai-resources/src/main/java/org/onap/aai/dbgen/tags/Command.java b/aai-resources/src/main/java/org/onap/aai/dbgen/tags/Command.java new file mode 100644 index 0000000..bc18047 --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/dbgen/tags/Command.java @@ -0,0 +1,25 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.dbgen.tags; + +@FunctionalInterface +interface Command { + public abstract void execute() throws Exception; +} diff --git a/aai-resources/src/main/java/org/onap/aai/dbgen/tags/UpdateEdgeTagsCmd.java b/aai-resources/src/main/java/org/onap/aai/dbgen/tags/UpdateEdgeTagsCmd.java new file mode 100644 index 0000000..d1ee6c4 --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/dbgen/tags/UpdateEdgeTagsCmd.java @@ -0,0 +1,212 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.dbgen.tags; + +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Graph; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.janusgraph.core.JanusGraph; +import org.onap.aai.dbmap.AAIGraph; +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.logging.ErrorLogHelper; +import org.onap.aai.serialization.db.EdgeRule; +import org.onap.aai.serialization.db.EdgeRules; +import org.onap.aai.util.AAIConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +public class UpdateEdgeTagsCmd implements Command { + private JanusGraph graph; + private String rulesFilename; + private EdgeRules edgeRulesInstance = null; + private String[] edgeRuleKeys = null; + + private String filter = "all"; + private static final String FROMAPPID = "AAI-DB"; + private static final String TRANSID = UUID.randomUUID().toString(); + + + static final Logger logger = LoggerFactory.getLogger(UpdateEdgeTagsCmd.class); + + /** + * @param filter + */ + public UpdateEdgeTagsCmd(String filter) throws AAIException { + super(); + this.filter = filter; + createEdgeRuleSet(); + } + + /** + * @param filter + * @param rulesFilename + */ + public UpdateEdgeTagsCmd(String filter, String rulesFilename) { + super(); + this.rulesFilename = rulesFilename; + this.filter = filter; + this.createEdgeRuleSet(); + } + + @Override + public void execute() throws AAIException { + try { + ErrorLogHelper.loadProperties(); + if(graph == null) { + AAIConfig.init(); + logger.info(" ---- NOTE --- about to open graph (takes a little while)--------\n"); + graph = AAIGraph.getInstance().getGraph(); + } + if( graph == null ){ + String emsg = "null graph object in updateEdgeTags() \n"; + logger.info(emsg); + return; + } + } + catch (AAIException e1) { + String msg = e1.getErrorObject().toString(); + System.out.println(msg); + return; + } + catch (Exception e2) { + String msg = e2.toString(); + System.out.println(msg); + e2.printStackTrace(); + return; + } + + Graph g = graph.newTransaction(); + try { + Iterator<Edge> edgeItr = graph.traversal().E(); +/* + if("all".equalsIgnoreCase(filter)) { + edgeItr = graph.traversal().E(); + } else { + edgeItr = graph.traversal().E()..inV().property("aai-node-type",this.edgeRuleKeys[0]); + edgeItr = graph.traversal().E().inV().has("aai-node-type").values(this.edgeRuleKeys[0]).outV().has("aai-node-type").values(this.edgeRuleKeys[1]); + } +*/ + //Iterate over all the edges of the in memory graph + while( edgeItr != null && edgeItr.hasNext() ){ + + Edge thisEdge = edgeItr.next(); + //The filter can limit the application of changes to edges between vertices of one pair of node-types + //Other node type pairs found in in-memory graph are skipped + if(! passesFilter(thisEdge) ) { + continue; + } + + //Find the rules in the file between the node-type pair for the current in-memory edge + if( edgeRulesInstance.hasEdgeRule(thisEdge.inVertex().<String>property("aai-node-type").orElse(null),thisEdge.outVertex().<String>property("aai-node-type").orElse(null))) { + logger.info("key = " + thisEdge.inVertex().<String>property("aai-node-type").orElse(null)+"|"+ thisEdge.outVertex().<String>property("aai-node-type").orElse(null)+ ", label = " + thisEdge.label() + + ", for id = " + thisEdge.id().toString() + ", set: "+thisEdge.keys()+"\n"); + //Get the rule map from the FILE for the node-type pair, filtered by label found on the in-memory Edge; expecting one rule + //Note: the filter label does not work -- adding equals/contains(thisEdge.label() tests below + Map<String, EdgeRule> edgeRules =edgeRulesInstance.getEdgeRules(thisEdge.inVertex().<String>property("aai-node-type").orElse(null),thisEdge.outVertex().<String>property("aai-node-type").orElse(null), thisEdge.label()); +// Collection<EdgeRule> edgeRules = edgeRuleMultimap.get(derivedEdgeKey); + //Apply the Edge properties from the FILE rule to the in-memory Edge + for(EdgeRule e : edgeRules.values()) { + if(e.getLabel().equals(thisEdge.label())) { + logger.info("EdgeRule e: " + String.join("|",thisEdge.outVertex().<String>property("aai-node-type").orElse(null),thisEdge.inVertex().<String>property("aai-node-type").orElse(null),e.getLabel())); + edgeRulesInstance.addProperties(thisEdge, e); + } + } + //The FILE ruleset is broken? -- run away; discard all changes! + if(! edgeRules.containsKey(thisEdge.label())) { + // Couldn't find a rule for this edge + logger.error("Broken EdgeSet in edgeRuleFile: " + thisEdge.bothVertices()); + throw new AAIException("AAI_6120", "No EdgeRule found for nodeTypes: " + String.join("|",thisEdge.outVertex().<String>property("aai-node-type").orElse(null),thisEdge.inVertex().<String>property("aai-node-type").orElse(null),thisEdge.label())); + } + } else { + //The expected FILE ruleset could not be found -- run away; discard all changes! + logger.error("Missing EdgeSet in edgeRuleFile: " + thisEdge.bothVertices()); + throw new AAIException("AAI_6120", "No EdgeRule found for nodeTypes: " + String.join("|",thisEdge.outVertex().<String>property("aai-node-type").orElse(null),thisEdge.inVertex().<String>property("aai-node-type").orElse(null),thisEdge.label())); + } + + } // End of looping over all in-memory edges + graph.tx().commit(); + logger.info("- committed updates for listed edges " ); + } + catch (Exception e2) { + String msg = e2.toString(); + logger.error(msg); + e2.printStackTrace(); + if( g != null ){ + graph.tx().rollback(); + } + if(e2 instanceof AAIException) { + throw e2; + } + return; + } + } + + + /** + * @return the rulesFilename + */ + public String getRulesFilename() { + return this.rulesFilename; + } + + /** + * @return the graph + */ + public JanusGraph getGraph() { + return this.graph; + } + + /** + * @param graph the graph to set + */ + public void setGraph(JanusGraph graph) { + this.graph = graph; + } + + private void createEdgeRuleSet() { + if(this.filter != null) this.edgeRuleKeys = filter.split("\\|"); + edgeRulesInstance = (this.rulesFilename == null) ? EdgeRules.getInstance() : EdgeRules.getInstance(rulesFilename); + return; + } + + private boolean passesFilter(Edge tEdge) { + if("all".equalsIgnoreCase(filter) ) { + logger.debug("EdgeRule PROCESSALL: " + String.join("|",tEdge.outVertex().<String>property("aai-node-type").orElse(null),tEdge.inVertex().<String>property("aai-node-type").orElse(null),tEdge.label())); + return true; + } + Iterator<Vertex> vItr = tEdge.bothVertices(); + + ArrayList<String> l = new ArrayList<String>(Arrays.asList(edgeRuleKeys)); + while( vItr != null && vItr.hasNext() ) { + Vertex v = vItr.next(); + int i = l.indexOf(v.property("aai-node-type").value()); + if (i >= 0) l.remove(i); + } + if(l.isEmpty()) { + logger.debug("EdgeRule filterPROCESS: " + String.join("|",tEdge.outVertex().<String>property("aai-node-type").orElse(null),tEdge.inVertex().<String>property("aai-node-type").orElse(null),tEdge.label())); + } + else { + logger.debug("EdgeRule filterSKIP: " + String.join("|",tEdge.outVertex().<String>property("aai-node-type").orElse(null),tEdge.inVertex().<String>property("aai-node-type").orElse(null),tEdge.label())); + } + return l.isEmpty(); + } +} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/EdgeSwingMigrator.java b/aai-resources/src/main/java/org/onap/aai/migration/EdgeSwingMigrator.java new file mode 100644 index 0000000..3ce5669 --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/migration/EdgeSwingMigrator.java @@ -0,0 +1,285 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.migration; + + +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Property; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.javatuples.Pair; +import org.onap.aai.db.props.AAIProperties; +import org.onap.aai.serialization.engines.TransactionalGraphEngine; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * A migration template for "swinging" edges that terminate on an old-node to a new target node. + * That is, given an oldNode and a newNode we will swing edges that terminate on the + * oldNode and terminate them on the newNode (actually we drop the old edges and add new ones). + * + * + * We allow the passing of some parameters to restrict what edges get swung over: + * > otherEndNodeTypeRestriction: only swing edges that terminate on the oldNode if the + * node at the other end of the edge is of this nodeType. + * > edgeLabelRestriction: Only swing edges that have this edgeLabel + * > edgeDirectionRestriction: Only swing edges that go this direction (from the oldNode) + * this is a required parameter. valid values are: BOTH, IN, OUT + * + */ +@MigrationPriority(0) +@MigrationDangerRating(1) +public abstract class EdgeSwingMigrator extends Migrator { + + private boolean success = true; + private String nodeTypeRestriction = null; + private String edgeLabelRestriction = null; + private String edgeDirRestriction = null; + private List<Pair<Vertex, Vertex>> nodePairList; + + + public EdgeSwingMigrator(TransactionalGraphEngine engine ) { + super(engine); + } + + + /** + * Do not override this method as an inheritor of this class + */ + @Override + public void run() { + executeModifyOperation(); + cleanupAsAppropriate(this.nodePairList); + } + + /** + * This is where inheritors should add their logic + */ + protected void executeModifyOperation() { + + try { + this.nodeTypeRestriction = this.getNodeTypeRestriction(); + this.edgeLabelRestriction = this.getEdgeLabelRestriction(); + this.edgeDirRestriction = this.getEdgeDirRestriction(); + nodePairList = this.getAffectedNodePairs(); + for (Pair<Vertex, Vertex> nodePair : nodePairList) { + Vertex fromNode = nodePair.getValue0(); + Vertex toNode = nodePair.getValue1(); + this.swingEdges(fromNode, toNode, + this.nodeTypeRestriction,this.edgeLabelRestriction,this.edgeDirRestriction); + } + } catch (Exception e) { + logger.error("error encountered", e); + success = false; + } + } + + + protected void swingEdges(Vertex oldNode, Vertex newNode, String nodeTypeRestr, String edgeLabelRestr, String edgeDirRestr) { + try { + // If the old and new Vertices aren't populated, throw an exception + if( oldNode == null ){ + logger.info ( "null oldNode passed to swingEdges() "); + success = false; + return; + } + else if( newNode == null ){ + logger.info ( "null newNode passed to swingEdges() "); + success = false; + return; + } + else if( edgeDirRestr == null || + (!edgeDirRestr.equals("BOTH") + && !edgeDirRestr.equals("IN") + && !edgeDirRestr.equals("OUT") ) + ){ + logger.info ( "invalid direction passed to swingEdges(). valid values are BOTH/IN/OUT "); + success = false; + return; + } + else if( edgeLabelRestr != null + && (edgeLabelRestr.trim().equals("none") || edgeLabelRestr.trim().equals("")) ){ + edgeLabelRestr = null; + } + else if( nodeTypeRestr == null || nodeTypeRestr.trim().equals("") ){ + nodeTypeRestr = "none"; + } + + String oldNodeType = oldNode.value(AAIProperties.NODE_TYPE); + String oldUri = oldNode.<String> property("aai-uri").isPresent() ? oldNode.<String> property("aai-uri").value() : "URI Not present"; + + String newNodeType = newNode.value(AAIProperties.NODE_TYPE); + String newUri = newNode.<String> property("aai-uri").isPresent() ? newNode.<String> property("aai-uri").value() : "URI Not present"; + + // If the nodeTypes don't match, throw an error + if( !oldNodeType.equals(newNodeType) ){ + logger.info ( "Can not swing edge from a [" + oldNodeType + "] node to a [" + + newNodeType + "] node. "); + success = false; + return; + } + + // Find and migrate any applicable OUT edges. + if( edgeDirRestr.equals("BOTH") || edgeDirRestr.equals("OUT") ){ + Iterator <Edge> edgeOutIter = null; + if( edgeLabelRestr == null ) { + edgeOutIter = oldNode.edges(Direction.OUT); + } + else { + edgeOutIter = oldNode.edges(Direction.OUT, edgeLabelRestr); + } + + while( edgeOutIter.hasNext() ){ + Edge oldOutE = edgeOutIter.next(); + String eLabel = oldOutE.label(); + Vertex otherSideNode4ThisEdge = oldOutE.inVertex(); + String otherSideNodeType = otherSideNode4ThisEdge.value(AAIProperties.NODE_TYPE); + if( nodeTypeRestr.equals("none") || nodeTypeRestr.toLowerCase().equals(otherSideNodeType) ){ + Iterator <Property<Object>> propsIter = oldOutE.properties(); + HashMap<String, String> propMap = new HashMap<String,String>(); + while( propsIter.hasNext() ){ + Property<Object> ep = propsIter.next(); + propMap.put(ep.key(), ep.value().toString()); + } + + String otherSideUri = otherSideNode4ThisEdge.<String> property("aai-uri").isPresent() ? otherSideNode4ThisEdge.<String> property("aai-uri").value() : "URI Not present"; + logger.info ( "\nSwinging [" + eLabel + "] OUT edge. \n >> Unchanged side is [" + + otherSideNodeType + "][" + otherSideUri + "] \n >> Edge used to go to [" + oldNodeType + + "][" + oldUri + "],\n >> now swung to [" + newNodeType + "][" + newUri + "]. "); + // remove the old edge + oldOutE.remove(); + + // add the new edge with properties that match the edge that was deleted. We don't want to + // change any edge properties - just swinging one end of the edge to a new node. + // NOTE - addEdge adds an OUT edge to the vertex passed as a parameter, so we are + // adding from the newNode side. + Edge newOutE = newNode.addEdge(eLabel, otherSideNode4ThisEdge); + + Iterator it = propMap.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry pair = (Map.Entry)it.next(); + newOutE.property(pair.getKey().toString(), pair.getValue().toString() ); + } + + } + } + } + + // Find and migrate any applicable IN edges. + if( edgeDirRestr.equals("BOTH") || edgeDirRestr.equals("IN") ){ + Iterator <Edge> edgeInIter = null; + if( edgeLabelRestr == null ) { + edgeInIter = oldNode.edges(Direction.IN); + } + else { + edgeInIter = oldNode.edges(Direction.IN, edgeLabelRestr); + } + + while( edgeInIter.hasNext() ){ + Edge oldInE = edgeInIter.next(); + String eLabel = oldInE.label(); + Vertex otherSideNode4ThisEdge = oldInE.outVertex(); + String otherSideNodeType = otherSideNode4ThisEdge.value(AAIProperties.NODE_TYPE); + if( nodeTypeRestr.equals("none") || nodeTypeRestr.toLowerCase().equals(otherSideNodeType) ){ + Iterator <Property<Object>> propsIter = oldInE.properties(); + HashMap<String, String> propMap = new HashMap<String,String>(); + while( propsIter.hasNext() ){ + Property<Object> ep = propsIter.next(); + propMap.put(ep.key(), ep.value().toString()); + } + + String otherSideUri = otherSideNode4ThisEdge.<String> property("aai-uri").isPresent() ? otherSideNode4ThisEdge.<String> property("aai-uri").value() : "URI Not present"; + logger.info ( "\nSwinging [" + eLabel + "] IN edge. \n >> Unchanged side is [" + + otherSideNodeType + "][" + otherSideUri + "] \n >> Edge used to go to [" + oldNodeType + + "][" + oldUri + "],\n >> now swung to [" + newNodeType + "][" + newUri + "]. "); + + // remove the old edge + oldInE.remove(); + + // add the new edge with properties that match the edge that was deleted. We don't want to + // change any edge properties - just swinging one end of the edge to a new node. + // NOTE - addEdge adds an OUT edge to the vertex passed as a parameter, so we are + // adding from the node on the other-end of the original edge so we'll get + // an IN-edge to the newNode. + Edge newInE = otherSideNode4ThisEdge.addEdge(eLabel, newNode); + + Iterator it = propMap.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry pair = (Map.Entry)it.next(); + newInE.property(pair.getKey().toString(), pair.getValue().toString() ); + } + } + } + } + + } catch (Exception e) { + logger.error("error encountered", e); + success = false; + } + } + + @Override + public Status getStatus() { + if (success) { + return Status.SUCCESS; + } else { + return Status.FAILURE; + } + } + + + /** + * Get the List of node pairs("from" and "to"), you would like EdgeSwingMigrator to migrate from json files + * @return + */ + public abstract List<Pair<Vertex, Vertex>> getAffectedNodePairs() ; + + + /** + * Get the nodeTypeRestriction that you want EdgeSwingMigrator to use + * @return + */ + public abstract String getNodeTypeRestriction() ; + + + /** + * Get the nodeTypeRestriction that you want EdgeSwingMigrator to use + * @return + */ + public abstract String getEdgeLabelRestriction() ; + + /** + * Get the nodeTypeRestriction that you want EdgeSwingMigrator to use + * @return + */ + public abstract String getEdgeDirRestriction() ; + + + + /** + * Cleanup (remove) the nodes that edges were moved off of if appropriate + * @return + */ + public abstract void cleanupAsAppropriate(List<Pair<Vertex, Vertex>> nodePairL); + +}
\ No newline at end of file diff --git a/aai-resources/src/main/java/org/onap/aai/migration/MigrationControllerInternal.java b/aai-resources/src/main/java/org/onap/aai/migration/MigrationControllerInternal.java index a2baa5a..62007c4 100644 --- a/aai-resources/src/main/java/org/onap/aai/migration/MigrationControllerInternal.java +++ b/aai-resources/src/main/java/org/onap/aai/migration/MigrationControllerInternal.java @@ -49,7 +49,7 @@ import org.onap.aai.introspection.Version; import org.onap.aai.logging.LoggingContext; import org.onap.aai.logging.LoggingContext.StatusCode; import org.onap.aai.serialization.engines.QueryStyle; -import org.onap.aai.serialization.engines.TitanDBEngine; +import org.onap.aai.serialization.engines.JanusGraphDBEngine; import org.onap.aai.serialization.engines.TransactionalGraphEngine; import org.onap.aai.util.AAIConstants; import org.onap.aai.util.FormatDate; @@ -113,7 +113,7 @@ public class MigrationControllerInternal { } catch (ConfigurationException e) { LoggingContext.statusCode(StatusCode.ERROR); LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logAndPrint("ERROR: Could not load titan configuration.\n" + ExceptionUtils.getFullStackTrace(e)); + logAndPrint("ERROR: Could not load janusgraph configuration.\n" + ExceptionUtils.getFullStackTrace(e)); return; } } @@ -126,7 +126,7 @@ public class MigrationControllerInternal { QueryStyle queryStyle = QueryStyle.TRAVERSAL; ModelType introspectorFactoryType = ModelType.MOXY; Loader loader = LoaderFactory.createLoaderForVersion(introspectorFactoryType, version); - TransactionalGraphEngine engine = new TitanDBEngine(queryStyle, DBConnectionType.REALTIME, loader); + TransactionalGraphEngine engine = new JanusGraphDBEngine(queryStyle, DBConnectionType.REALTIME, loader); if (cArgs.help) { jCommander.usage(); diff --git a/aai-resources/src/main/java/org/onap/aai/migration/PropertyMigrator.java b/aai-resources/src/main/java/org/onap/aai/migration/PropertyMigrator.java index d5c3ca4..ed43724 100644 --- a/aai-resources/src/main/java/org/onap/aai/migration/PropertyMigrator.java +++ b/aai-resources/src/main/java/org/onap/aai/migration/PropertyMigrator.java @@ -27,9 +27,9 @@ import org.apache.tinkerpop.gremlin.structure.Vertex; import org.onap.aai.db.props.AAIProperties; import org.onap.aai.serialization.engines.TransactionalGraphEngine; -import com.thinkaurelius.titan.core.Cardinality; -import com.thinkaurelius.titan.core.PropertyKey; -import com.thinkaurelius.titan.core.schema.TitanManagement; +import org.janusgraph.core.Cardinality; +import org.janusgraph.core.PropertyKey; +import org.janusgraph.core.schema.JanusGraphManagement; /** * A migration template for migrating a property from one name to another @@ -42,7 +42,7 @@ public abstract class PropertyMigrator extends Migrator { protected final String NEW_FIELD; protected final Class<?> fieldType; protected final Cardinality cardinality; - protected final TitanManagement graphMgmt; + protected final JanusGraphManagement graphMgmt; public PropertyMigrator(TransactionalGraphEngine engine, String oldName, String newName, Class<?> type, Cardinality cardinality) { super(engine); diff --git a/aai-resources/src/main/java/org/onap/aai/migration/ValueMigrator.java b/aai-resources/src/main/java/org/onap/aai/migration/ValueMigrator.java new file mode 100644 index 0000000..eb562a2 --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/migration/ValueMigrator.java @@ -0,0 +1,100 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.migration; + +import java.util.Map; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.onap.aai.db.props.AAIProperties; +import org.onap.aai.serialization.engines.TransactionalGraphEngine; +import org.janusgraph.core.schema.JanusGraphManagement; + +/** + * A migration template for filling in default values that are missing or are empty + */ +@MigrationPriority(0) +@MigrationDangerRating(1) +public abstract class ValueMigrator extends Migrator { + + protected final Map<String, Map<String, ?>> propertyValuePairByNodeType; + protected final Boolean updateExistingValues; + protected final JanusGraphManagement graphMgmt; + + /** + * + * @param engine + * @param propertyValuePairByNodeType - format {nodeType: { property: newValue}} + * @param updateExistingValues - if true, updates the value regardless if it already exists + */ + public ValueMigrator(TransactionalGraphEngine engine, Map propertyValuePairByNodeType, Boolean updateExistingValues) { + super(engine); + this.propertyValuePairByNodeType = propertyValuePairByNodeType; + this.updateExistingValues = updateExistingValues; + this.graphMgmt = engine.asAdmin().getManagementSystem(); + } + + /** + * Do not override this method as an inheritor of this class + */ + @Override + public void run() { + updateValues(); + } + + protected void updateValues() { + for (Map.Entry<String, Map<String, ?>> entry: propertyValuePairByNodeType.entrySet()) { + String nodeType = entry.getKey(); + Map<String, ?> propertyValuePair = entry.getValue(); + for (Map.Entry<String, ?> pair : propertyValuePair.entrySet()) { + String property = pair.getKey(); + Object newValue = pair.getValue(); + try { + GraphTraversal<Vertex, Vertex> g = this.engine.asAdmin().getTraversalSource().V() + .has(AAIProperties.NODE_TYPE, nodeType); + while (g.hasNext()) { + Vertex v = g.next(); + if (v.property(property).isPresent() && !updateExistingValues) { + String propertyValue = v.property(property).value().toString(); + if (propertyValue.isEmpty()) { + v.property(property, newValue); + logger.info(String.format("Node Type %s: Property %s is empty, adding value %s", + nodeType, property, newValue.toString())); + this.touchVertexProperties(v, false); + } else { + logger.info(String.format("Node Type %s: Property %s value already exists - skipping", + nodeType, property)); + } + } else { + logger.info(String.format("Node Type %s: Property %s does not exist or " + + "updateExistingValues flag is set to True - adding the property with value %s", + nodeType, property, newValue.toString())); + v.property(property, newValue); + this.touchVertexProperties(v, false); + } + } + } catch (Exception e) { + logger.error(String.format("caught exception updating aai-node-type %s's property %s's value to " + + "%s: %s", nodeType, property, newValue.toString(), e.getMessage())); + logger.error(e.getMessage()); + } + } + } + } +} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/v12/EdgeReportForToscaMigration.java b/aai-resources/src/main/java/org/onap/aai/migration/v12/EdgeReportForToscaMigration.java index d3d0564..2ff916c 100644 --- a/aai-resources/src/main/java/org/onap/aai/migration/v12/EdgeReportForToscaMigration.java +++ b/aai-resources/src/main/java/org/onap/aai/migration/v12/EdgeReportForToscaMigration.java @@ -18,26 +18,6 @@ * ============LICENSE_END========================================================= */ package org.onap.aai.migration.v12; -/*- - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; import org.apache.tinkerpop.gremlin.structure.Edge; diff --git a/aai-resources/src/main/java/org/onap/aai/migration/v12/SDWANSpeedChangeMigration.java b/aai-resources/src/main/java/org/onap/aai/migration/v12/SDWANSpeedChangeMigration.java new file mode 100644 index 0000000..57e3e5e --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/migration/v12/SDWANSpeedChangeMigration.java @@ -0,0 +1,254 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.migration.v12; + +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.migration.*; +import org.onap.aai.serialization.db.EdgeType; +import org.onap.aai.serialization.engines.TransactionalGraphEngine; + +import java.util.*; + +@MigrationPriority(1) +@MigrationDangerRating(1) +@Enabled +public class SDWANSpeedChangeMigration extends Migrator { + + private final String PARENT_NODE_TYPE = "alloted-resource"; + private boolean success = true; + + Vertex allottedRsrcVertex; + + Map<String, String> bandwidthMap = new HashMap<>(); + Set<String> bandWidthSet = new HashSet<>(); + + GraphTraversal<Vertex, Vertex> allottedRsrcTraversal; + GraphTraversal<Vertex, Vertex> tunnelXConnectTraversal; + GraphTraversal<Vertex, Vertex> pinterfaceTraversal; + GraphTraversal<Vertex, Vertex> plinkTraversal; + + public SDWANSpeedChangeMigration(TransactionalGraphEngine engine) { + super(engine); + bandWidthSet.add("bandwidth-up-wan1"); + bandWidthSet.add("bandwidth-down-wan1"); + bandWidthSet.add("bandwidth-up-wan2"); + bandWidthSet.add("bandwidth-down-wan2"); + } + + + @Override + public void run() { + + logger.info("Started the migration "+ getMigrationName()); + + try { + + allottedRsrcTraversal = this.engine.asAdmin().getTraversalSource().V() + .has("aai-node-type", "service-subscription") + .has("service-type", "DHV") + .in("org.onap.relationships.inventory.BelongsTo") + .has("aai-node-type", "service-instance") + .out("org.onap.relationships.inventory.Uses") + .has("aai-node-type", "allotted-resource") + .where( + this.engine.getQueryBuilder() + .createEdgeTraversal(EdgeType.TREE, "allotted-resource", "service-instance") + .createEdgeTraversal(EdgeType.TREE, "service-instance", "service-subscription") + .<GraphTraversal<Vertex, Vertex>>getQuery() + .has("service-type", "VVIG") + ); + + if(!(allottedRsrcTraversal.hasNext())){ + + logger.info("unable to find allotted resource to DHV as cousin and child of VVIG"); + } + + while (allottedRsrcTraversal.hasNext()) { + bandwidthMap.clear(); + + allottedRsrcVertex = allottedRsrcTraversal.next(); + String allottedResourceId = allottedRsrcVertex.property("id").value().toString(); + logger.info("Found an allotted resource with id " + allottedResourceId); + + tunnelXConnectTraversal = this.engine.asAdmin().getTraversalSource() + .V(allottedRsrcVertex) + .in("org.onap.relationships.inventory.BelongsTo") + .has("aai-node-type", "tunnel-xconnect"); + + if (tunnelXConnectTraversal != null && tunnelXConnectTraversal.hasNext()) { + Vertex xConnect = tunnelXConnectTraversal.next(); + String tunnelId = xConnect.property("id").value().toString(); + logger.info("Found an tunnelxconnect object with id " + tunnelId); + extractBandwidthProps(xConnect); + modifyPlink(allottedRsrcVertex); + } else { + logger.info("Unable to find the tunnel connect for the current allotted resource traversal"); + } + + } + } catch (AAIException e) { + e.printStackTrace(); + success = false; + } + + logger.info("Successfully finished the " + getMigrationName()); + } + + public void extractBandwidthProps(Vertex vertex) { + logger.info("Trying to extract bandwith props"); + bandWidthSet.stream().forEach((key) -> { + if (vertex.property(key).isPresent()) { + bandwidthMap.put(key, vertex.property(key).value().toString()); + } + }); + logger.info("Extracted bandwith props for tunnelXConnect " +vertex.value("id")); + } + + public void modifyPlink(Vertex v) { + + try { + pinterfaceTraversal = this.engine.asAdmin().getTraversalSource().V(v) + .in("org.onap.relationships.inventory.Uses").has("aai-node-type", "service-instance") + .where( + __.out("org.onap.relationships.inventory.BelongsTo") + .has("aai-node-type", "service-subscription") + .has("service-type", "DHV") + ) + .out("org.onap.relationships.inventory.ComposedOf").has("aai-node-type", "generic-vnf") + .out("tosca.relationships.HostedOn").has("aai-node-type", "vserver") + .out("tosca.relationships.HostedOn").has("aai-node-type", "pserver") + .in("tosca.relationships.network.BindsTo").has("aai-node-type", "p-interface"); + } catch (Exception e) { + logger.info("error trying to find p interfaces"); + } + + + while (pinterfaceTraversal.hasNext()) { + + Vertex pInterfaceVertex = pinterfaceTraversal.next(); + + String pinterfaceName = pInterfaceVertex.property("interface-name").value().toString(); + logger.info("p-interface "+ pinterfaceName + " found from traversal from allotted-resource " +v.value("id")); + String[] parts = pinterfaceName.split("/"); + + if (parts[parts.length - 1].equals("10")) { + + logger.info("Found the pinterface with the interface name ending with /10"); + + try { + plinkTraversal = this.engine.asAdmin().getTraversalSource() + .V(pInterfaceVertex) + .out("tosca.relationships.network.LinksTo") + .has("aai-node-type", "physical-link"); + } catch (Exception e) { + logger.info("error trying to find the p Link for /10"); + } + if (plinkTraversal != null && plinkTraversal.hasNext()) { + Vertex pLink = plinkTraversal.next(); + + + if ( bandwidthMap.containsKey("bandwidth-up-wan1") + && bandwidthMap.containsKey("bandwidth-down-wan1") + && !(("").equals(bandwidthMap.get("bandwidth-up-wan1").replaceAll("[^0-9]", "").trim())) + && !(("").equals(bandwidthMap.get("bandwidth-down-wan1").replaceAll("[^0-9]", "").trim()))) + { + + pLink.property("service-provider-bandwidth-up-value", Integer.valueOf(bandwidthMap.get("bandwidth-up-wan1").replaceAll("[^0-9]", "").trim())); + pLink.property("service-provider-bandwidth-up-units", "Mbps"); + pLink.property("service-provider-bandwidth-down-value", Integer.valueOf(bandwidthMap.get("bandwidth-down-wan1").replaceAll("[^0-9]", "").trim())); + pLink.property("service-provider-bandwidth-down-units", "Mbps"); + logger.info("Successfully modified the plink with link name ", pLink.property("link-name").value().toString()); + this.touchVertexProperties(pLink, false); + } else { + logger.info("missing up and down vals for the plink with link name ", pLink.property("link-name").value().toString()); + } + + + } else { + logger.info("missing plink for p interface" + pinterfaceName); + } + + } + + if (parts[parts.length - 1].equals("11")) { + + logger.info("Found the pinterface with the interface name ending with /11"); + try { + plinkTraversal = this.engine.asAdmin() + .getTraversalSource() + .V(pInterfaceVertex) + .out("tosca.relationships.network.LinksTo") + .has("aai-node-type", "physical-link"); + } catch (Exception e) { + logger.info("error trying to find the p Link for /11"); + } + + if (plinkTraversal != null && plinkTraversal.hasNext()) { + Vertex pLink = plinkTraversal.next(); + + + if ( bandwidthMap.containsKey("bandwidth-up-wan2") + && bandwidthMap.containsKey("bandwidth-down-wan2") + && !(("").equals(bandwidthMap.get("bandwidth-up-wan2").replaceAll("[^0-9]", "").trim())) + && !(("").equals(bandwidthMap.get("bandwidth-down-wan2").replaceAll("[^0-9]", "").trim()))) + { + pLink.property("service-provider-bandwidth-up-value", Integer.valueOf(bandwidthMap.get("bandwidth-up-wan2").replaceAll("[^0-9]", "").trim())); + pLink.property("service-provider-bandwidth-up-units", "Mbps"); + pLink.property("service-provider-bandwidth-down-value", Integer.valueOf(bandwidthMap.get("bandwidth-down-wan2").replaceAll("[^0-9]", "").trim())); + pLink.property("service-provider-bandwidth-down-units", "Mbps"); + logger.info("Successfully modified the plink with link name ", pLink.property("link-name").value().toString()); + this.touchVertexProperties(pLink, false); + } else { + logger.error("missing up and down vals for the plink with link name ", pLink.property("link-name").value().toString()); + } + + } else { + logger.info("missing plink for p interface" + pinterfaceName); + } + } + } + } + + + @Override + public Status getStatus() { + if (success) { + return Status.SUCCESS; + } else { + return Status.FAILURE; + } + } + + @Override + public Optional<String[]> getAffectedNodeTypes() { + + return Optional.of(new String[]{PARENT_NODE_TYPE}); + } + + @Override + public String getMigrationName() { + return "SDWANSpeedChangeMigration"; + } + + +} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/v12/ToscaMigration.java b/aai-resources/src/main/java/org/onap/aai/migration/v12/ToscaMigration.java index a409710..91ca4d7 100644 --- a/aai-resources/src/main/java/org/onap/aai/migration/v12/ToscaMigration.java +++ b/aai-resources/src/main/java/org/onap/aai/migration/v12/ToscaMigration.java @@ -18,26 +18,6 @@ * ============LICENSE_END========================================================= */ package org.onap.aai.migration.v12; -/*- - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - import java.util.*; diff --git a/aai-resources/src/main/java/org/onap/aai/migration/v13/MigrateInstanceGroupSubType.java b/aai-resources/src/main/java/org/onap/aai/migration/v13/MigrateInstanceGroupSubType.java new file mode 100644 index 0000000..feb8a6a --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/migration/v13/MigrateInstanceGroupSubType.java @@ -0,0 +1,59 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.migration.v13; +import java.util.Optional; + +import org.onap.aai.migration.Enabled; +import org.onap.aai.migration.MigrationDangerRating; +import org.onap.aai.migration.MigrationPriority; +import org.onap.aai.migration.PropertyMigrator; +import org.onap.aai.serialization.engines.TransactionalGraphEngine; + +import org.janusgraph.core.Cardinality; + +@MigrationPriority(20) +@MigrationDangerRating(2) +@Enabled +public class MigrateInstanceGroupSubType extends PropertyMigrator{ + + protected static final String SUB_TYPE_PROPERTY = "sub-type"; + protected static final String INSTANCE_GROUP_ROLE_PROPERTY = "instance-group-role"; + protected static final String INSTANCE_GROUP_NODE_TYPE = "instance-group"; + + public MigrateInstanceGroupSubType(TransactionalGraphEngine engine) { + super(engine,SUB_TYPE_PROPERTY , INSTANCE_GROUP_ROLE_PROPERTY, String.class,Cardinality.SINGLE); + } + + @Override + public Optional<String[]> getAffectedNodeTypes() { + return Optional.of(new String[]{INSTANCE_GROUP_NODE_TYPE}); + } + + @Override + public String getMigrationName() { + return "MigrateInstanceGroupSubType"; + } + + @Override + public boolean isIndexed() { + return true; + } + +} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/v13/MigrateInstanceGroupType.java b/aai-resources/src/main/java/org/onap/aai/migration/v13/MigrateInstanceGroupType.java new file mode 100644 index 0000000..dc55b40 --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/migration/v13/MigrateInstanceGroupType.java @@ -0,0 +1,59 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.migration.v13; +import java.util.Optional; + +import org.onap.aai.migration.Enabled; +import org.onap.aai.migration.MigrationDangerRating; +import org.onap.aai.migration.MigrationPriority; +import org.onap.aai.migration.PropertyMigrator; +import org.onap.aai.serialization.engines.TransactionalGraphEngine; + +import org.janusgraph.core.Cardinality; + +@MigrationPriority(20) +@MigrationDangerRating(2) +@Enabled +public class MigrateInstanceGroupType extends PropertyMigrator{ + + protected static final String TYPE_PROPERTY = "type"; + protected static final String INSTANCE_GROUP_TYPE_PROPERTY = "instance-group-type"; + protected static final String INSTANCE_GROUP_NODE_TYPE = "instance-group"; + + public MigrateInstanceGroupType(TransactionalGraphEngine engine) { + super(engine,TYPE_PROPERTY , INSTANCE_GROUP_TYPE_PROPERTY, String.class,Cardinality.SINGLE); + } + + @Override + public Optional<String[]> getAffectedNodeTypes() { + return Optional.of(new String[]{INSTANCE_GROUP_NODE_TYPE}); + } + + @Override + public String getMigrationName() { + return "MigrateInstanceGroupType"; + } + + @Override + public boolean isIndexed() { + return true; + } + +} diff --git a/aai-resources/src/main/java/org/onap/aai/rest/URLFromVertexIdConsumer.java b/aai-resources/src/main/java/org/onap/aai/rest/URLFromVertexIdConsumer.java index 072a602..f423eba 100644 --- a/aai-resources/src/main/java/org/onap/aai/rest/URLFromVertexIdConsumer.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/URLFromVertexIdConsumer.java @@ -115,7 +115,7 @@ public class URLFromVertexIdConsumer extends RESTAPI { } catch (Exception e) { AAIException ex = new AAIException("AAI_4000", e); response = consumerExceptionResponseGenerator(headers, info, HttpMethod.GET, ex); - } finally { //to close the titan transaction (I think) + } finally { //to close the janusgraph transaction (I think) if (dbEngine != null) { dbEngine.rollback(); } diff --git a/aai-resources/src/main/java/org/onap/aai/rest/VertexIdConsumer.java b/aai-resources/src/main/java/org/onap/aai/rest/VertexIdConsumer.java index fc54bca..3d90b64 100644 --- a/aai-resources/src/main/java/org/onap/aai/rest/VertexIdConsumer.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/VertexIdConsumer.java @@ -134,7 +134,7 @@ public class VertexIdConsumer extends RESTAPI { } catch (Exception e) { AAIException ex = new AAIException("AAI_4000", e); response = consumerExceptionResponseGenerator(headers, info, HttpMethod.GET, ex); - } finally { //to close the titan transaction (I think) + } finally { //to close the janusgraph transaction (I think) if (dbEngine != null) { dbEngine.rollback(); } |