aboutsummaryrefslogtreecommitdiffstats
path: root/aai-resources/src/main/java/org/onap/aai/migration
diff options
context:
space:
mode:
Diffstat (limited to 'aai-resources/src/main/java/org/onap/aai/migration')
-rw-r--r--aai-resources/src/main/java/org/onap/aai/migration/EdgeMigrator.java21
-rw-r--r--aai-resources/src/main/java/org/onap/aai/migration/MigrationController.java21
-rw-r--r--aai-resources/src/main/java/org/onap/aai/migration/MigrationControllerInternal.java273
-rw-r--r--aai-resources/src/main/java/org/onap/aai/migration/MigrationDangerRating.java42
-rw-r--r--aai-resources/src/main/java/org/onap/aai/migration/MigrationPriority.java42
-rw-r--r--aai-resources/src/main/java/org/onap/aai/migration/Migrator.java68
-rw-r--r--aai-resources/src/main/java/org/onap/aai/migration/PropertyMigrator.java22
-rw-r--r--aai-resources/src/main/java/org/onap/aai/migration/v12/ContainmentDeleteOtherVPropertyMigration.java105
-rw-r--r--aai-resources/src/main/java/org/onap/aai/migration/v12/EdgeReportForToscaMigration.java142
-rw-r--r--aai-resources/src/main/java/org/onap/aai/migration/v12/MigrateDataFromASDCToConfiguration.java107
-rw-r--r--aai-resources/src/main/java/org/onap/aai/migration/v12/MigrateServiceInstanceToConfiguration.java171
-rw-r--r--aai-resources/src/main/java/org/onap/aai/migration/v12/ToscaMigration.java160
12 files changed, 999 insertions, 175 deletions
diff --git a/aai-resources/src/main/java/org/onap/aai/migration/EdgeMigrator.java b/aai-resources/src/main/java/org/onap/aai/migration/EdgeMigrator.java
index 4e2fde4..ed29c84 100644
--- a/aai-resources/src/main/java/org/onap/aai/migration/EdgeMigrator.java
+++ b/aai-resources/src/main/java/org/onap/aai/migration/EdgeMigrator.java
@@ -39,16 +39,13 @@ import org.onap.aai.serialization.db.EdgeRules;
* A migration template for migrating all edge properties between "from" and "to" node from the DbedgeRules.json
*
*/
+@MigrationPriority(0)
+@MigrationDangerRating(1)
public abstract class EdgeMigrator extends Migrator {
private boolean success = true;
private EdgeRules rules;
- public EdgeMigrator() {
- // used for not great reflection implementation
- super();
- }
-
public EdgeMigrator(TransactionalGraphEngine engine) {
super(engine);
rules = EdgeRules.getInstance();
@@ -140,20 +137,6 @@ public abstract class EdgeMigrator extends Migrator {
}
}
- @Override
- public int getPriority() {
- return 0;
- }
-
- /*
- * Higher danger rating of 10 only for all edge property changes
- * or when a quorum of edges change which can be overridden by inheritors
- */
- @Override
- public int getDangerRating() {
- return 1;
- }
-
/**
* List of node pairs("from" and "to"), you would like EdgeMigrator to migrate from json files
* @return
diff --git a/aai-resources/src/main/java/org/onap/aai/migration/MigrationController.java b/aai-resources/src/main/java/org/onap/aai/migration/MigrationController.java
index 93d58b3..6742c8a 100644
--- a/aai-resources/src/main/java/org/onap/aai/migration/MigrationController.java
+++ b/aai-resources/src/main/java/org/onap/aai/migration/MigrationController.java
@@ -21,10 +21,15 @@
*/
package org.onap.aai.migration;
+import java.util.UUID;
+
import org.onap.aai.dbmap.AAIGraph;
+import org.onap.aai.logging.LoggingContext;
+import org.onap.aai.logging.LoggingContext.StatusCode;
+import org.onap.aai.util.AAIConstants;
/**
- * Wrapper class to allow {@link com.openecomp.aai.migration.MigrationControllerInternal MigrationControllerInternal}
+ * Wrapper class to allow {@link org.onap.aai.migration.MigrationControllerInternal MigrationControllerInternal}
* to be run from a shell script
*/
public class MigrationController {
@@ -36,15 +41,23 @@ public class MigrationController {
* the arguments
*/
public static void main(String[] args) {
-
+ LoggingContext.init();
+ LoggingContext.partnerName("Migration");
+ LoggingContext.serviceName(AAIConstants.AAI_RESOURCES_MS);
+ LoggingContext.component("MigrationController");
+ LoggingContext.targetEntity(AAIConstants.AAI_RESOURCES_MS);
+ LoggingContext.targetServiceName("main");
+ LoggingContext.requestId(UUID.randomUUID().toString());
+ LoggingContext.statusCode(StatusCode.COMPLETE);
+ LoggingContext.responseCode(LoggingContext.SUCCESS);
MigrationControllerInternal internal = new MigrationControllerInternal();
try {
internal.run(args);
} catch (Exception e) {
- //ignore
+ e.printStackTrace();
}
- AAIGraph.getInstance().getGraph().close();
+ AAIGraph.getInstance().graphShutdown();
System.exit(0);
}
}
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 6da9321..fbc4e03 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
@@ -29,10 +29,10 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Comparator;
import java.util.List;
import java.util.Properties;
import java.util.Set;
+import java.util.stream.Collectors;
import org.apache.activemq.broker.BrokerService;
import org.apache.commons.configuration.ConfigurationException;
@@ -48,6 +48,8 @@ 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.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.TransactionalGraphEngine;
@@ -63,20 +65,20 @@ import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
/**
- * Runs a series of migrations from a defined directory based on the presence of
- * the {@link com.openecomp.aai.migration.Enabled Enabled} annotation
- *
+ * Runs a series of migrations from a defined directory based on the presence of
+ * the {@link org.onap.aai.migration.Enabled Enabled} annotation
+ *
* It will also write a record of the migrations run to the database.
*/
public class MigrationControllerInternal {
private EELFLogger logger;
private final int DANGER_ZONE = 10;
- private final String vertexType = "migration-list-1707";
+ private static final String VERTEX_TYPE = "migration-list-" + Version.getLatest().toString();
private final List<String> resultsSummary = new ArrayList<>();
private BrokerService broker;
private final List<NotificationHelper> notifications = new ArrayList<>();
- private final String snapshotLocation = AAIConstants.AAI_HOME + AAIConstants.AAI_FILESEP + "logs" + AAIConstants.AAI_FILESEP + "data" + AAIConstants.AAI_FILESEP + "migrationSnapshots";
+ private static final String SNAPSHOT_LOCATION = AAIConstants.AAI_HOME + AAIConstants.AAI_FILESEP + "logs" + AAIConstants.AAI_FILESEP + "data" + AAIConstants.AAI_FILESEP + "migrationSnapshots";
/**
* The main method.
*
@@ -85,6 +87,7 @@ public class MigrationControllerInternal {
*/
public void run(String[] args) {
// Set the logging file properties to be used by EELFManager
+ System.setProperty("aai.service.name", MigrationController.class.getSimpleName());
Properties props = System.getProperties();
props.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, "migration-logback.xml");
props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES);
@@ -98,6 +101,7 @@ public class MigrationControllerInternal {
JCommander jCommander = new JCommander(cArgs, args);
jCommander.setProgramName(MigrationController.class.getSimpleName());
+
// Set flag to load from snapshot based on the presence of snapshot and
// graph storage backend of inmemory
if (cArgs.dataSnapshot != null && !cArgs.dataSnapshot.isEmpty()) {
@@ -109,6 +113,8 @@ public class MigrationControllerInternal {
System.setProperty("snapshot.location", cArgs.dataSnapshot);
}
} catch (ConfigurationException e) {
+ LoggingContext.statusCode(StatusCode.ERROR);
+ LoggingContext.responseCode(LoggingContext.DATA_ERROR);
logAndPrint("ERROR: Could not load titan configuration.\n" + ExceptionUtils.getFullStackTrace(e));
return;
}
@@ -123,80 +129,76 @@ public class MigrationControllerInternal {
ModelType introspectorFactoryType = ModelType.MOXY;
Loader loader = LoaderFactory.createLoaderForVersion(introspectorFactoryType, version);
TransactionalGraphEngine engine = new TitanDBEngine(queryStyle, DBConnectionType.REALTIME, loader);
-
+
if (cArgs.help) {
jCommander.usage();
engine.rollback();
return;
- } else if (cArgs.list) {
- Reflections reflections = new Reflections("org.onap.aai.migration");
- Set<Class<? extends Migrator>> migratorClasses = findClasses(reflections);
- List<Migrator> migratorList = createMigratorList(cArgs, migratorClasses);
-
- sortList(migratorList);
- engine.startTransaction();
- System.out.println("---------- List of all migrations ----------");
- migratorList.forEach(migrator -> {
- boolean enabledAnnotation = migrator.getClass().isAnnotationPresent(Enabled.class);
- String enabled = enabledAnnotation ? "Enabled" : "Disabled";
- StringBuilder sb = new StringBuilder();
- sb.append(migrator.getClass().getSimpleName() + " " + enabled);
- sb.append(" ");
- sb.append("[" + getDbStatus(migrator.getClass().getSimpleName(), engine) + "]");
- System.out.println(sb.toString());
- });
- engine.rollback();
- System.out.println("---------- Done ----------");
- return;
}
-
Reflections reflections = new Reflections("org.onap.aai.migration");
+ List<Class<? extends Migrator>> migratorClasses = new ArrayList<>(findClasses(reflections));
+ //Displays list of migration classes which needs to be executed.Pass flag "-l" following by the class names
+ if (cArgs.list) {
+ listMigrationWithStatus(cArgs, migratorClasses, engine);
+ return;
+ }
logAndPrint("---------- Looking for migration scripts to be executed. ----------");
- Set<Class<? extends Migrator>> migratorClasses = findClasses(reflections);
- List<Migrator> migratorList = createMigratorList(cArgs, migratorClasses);
+ //Excluding any migration class when run migration from script.Pass flag "-e" following by the class names
+ if (!cArgs.excludeClasses.isEmpty()) {
+ migratorClasses = filterMigrationClasses(cArgs.excludeClasses, migratorClasses);
+ listMigrationWithStatus(cArgs, migratorClasses, engine);
+ }
+ List<Class<? extends Migrator>> migratorClassesToRun = createMigratorList(cArgs, migratorClasses);
- sortList(migratorList);
+ sortList(migratorClassesToRun);
- if (!cArgs.scripts.isEmpty() && migratorList.size() == 0) {
+ if (!cArgs.scripts.isEmpty() && migratorClassesToRun.isEmpty()) {
+ LoggingContext.statusCode(StatusCode.ERROR);
+ LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR);
logAndPrint("\tERROR: Failed to find migrations " + cArgs.scripts + ".");
logAndPrint("---------- Done ----------");
+ LoggingContext.successStatusFields();
}
- logAndPrint("\tFound " + migratorList.size() + " migration scripts.");
+ logAndPrint("\tFound " + migratorClassesToRun.size() + " migration scripts.");
logAndPrint("---------- Executing Migration Scripts ----------");
-
-
- takeSnapshotIfRequired(engine, cArgs, migratorList);
- for (Migrator migratorClass : migratorList) {
- String name = migratorClass.getClass().getSimpleName();
+ if (!cArgs.skipPreMigrationSnapShot) {
+ takePreSnapshotIfRequired(engine, cArgs, migratorClassesToRun);
+ }
+
+ for (Class<? extends Migrator> migratorClass : migratorClassesToRun) {
+ String name = migratorClass.getSimpleName();
Migrator migrator;
- if (migratorClass.getClass().isAnnotationPresent(Enabled.class)) {
-
+ if (migratorClass.isAnnotationPresent(Enabled.class)) {
+
try {
engine.startTransaction();
if (!cArgs.forced && hasAlreadyRun(name, engine)) {
logAndPrint("Migration " + name + " has already been run on this database and will not be executed again. Use -f to force execution");
continue;
}
- migrator = migratorClass.getClass().getConstructor(TransactionalGraphEngine.class).newInstance(engine);
+ migrator = migratorClass.getConstructor(TransactionalGraphEngine.class).newInstance(engine);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
- logAndPrint("EXCEPTION caught initalizing migration class " + migratorClass.getClass().getSimpleName() + ".\n" + ExceptionUtils.getFullStackTrace(e));
+ LoggingContext.statusCode(StatusCode.ERROR);
+ LoggingContext.responseCode(LoggingContext.DATA_ERROR);
+ logAndPrint("EXCEPTION caught initalizing migration class " + migratorClass.getSimpleName() + ".\n" + ExceptionUtils.getFullStackTrace(e));
+ LoggingContext.successStatusFields();
engine.rollback();
continue;
}
- logAndPrint("\tRunning " + migratorClass.getClass().getSimpleName() + " migration script.");
- logAndPrint("\t\t See " + System.getProperty("AJSC_HOME") + "/logs/migration/" + migratorClass.getClass().getSimpleName() + "/* for logs.");
- MDC.put("logFilenameAppender", migratorClass.getClass().getSimpleName() + "/" + migratorClass.getClass().getSimpleName());
-
+ logAndPrint("\tRunning " + migratorClass.getSimpleName() + " migration script.");
+ logAndPrint("\t\t See " + System.getProperty("AJSC_HOME") + "/logs/migration/" + migratorClass.getSimpleName() + "/* for logs.");
+ MDC.put("logFilenameAppender", migratorClass.getSimpleName() + "/" + migratorClass.getSimpleName());
+
migrator.run();
-
+
commitChanges(engine, migrator, cArgs);
} else {
- logAndPrint("\tSkipping " + migratorClass.getClass().getSimpleName() + " migration script because it has been disabled.");
+ logAndPrint("\tSkipping " + migratorClass.getSimpleName() + " migration script because it has been disabled.");
}
}
MDC.put("logFilenameAppender", MigrationController.class.getSimpleName());
@@ -204,27 +206,76 @@ public class MigrationControllerInternal {
try {
notificationHelper.triggerEvents();
} catch (AAIException e) {
+ LoggingContext.statusCode(StatusCode.ERROR);
+ LoggingContext.responseCode(LoggingContext.AVAILABILITY_TIMEOUT_ERROR);
logAndPrint("\tcould not event");
logger.error("could not event", e);
+ LoggingContext.successStatusFields();
}
}
logAndPrint("---------- Done ----------");
// Save post migration snapshot if snapshot was loaded
- generateSnapshot(engine, "post");
-
+ if (!cArgs.skipPostMigrationSnapShot) {
+ generateSnapshot(engine, "post");
+ }
+
outputResultsSummary();
}
+ /**
+ * This method is used to remove excluded classes from migration from the
+ * script command.
+ *
+ * @param excludeClasses
+ * : Classes to be removed from Migration
+ * @param migratorClasses
+ * : Classes to execute migration.
+ * @return
+ */
+ private List<Class<? extends Migrator>> filterMigrationClasses(
+ List<String> excludeClasses,
+ List<Class<? extends Migrator>> migratorClasses) {
+
+ List<Class<? extends Migrator>> filteredMigratorClasses = migratorClasses
+ .stream()
+ .filter(migratorClass -> !excludeClasses.contains(migratorClass
+ .getSimpleName())).collect(Collectors.toList());
+
+ return filteredMigratorClasses;
+ }
+
+ private void listMigrationWithStatus(CommandLineArgs cArgs,
+ List<Class<? extends Migrator>> migratorClasses, TransactionalGraphEngine engine) {
+ sortList(migratorClasses);
+ engine.startTransaction();
+ System.out.println("---------- List of all migrations ----------");
+ migratorClasses.forEach(migratorClass -> {
+ boolean enabledAnnotation = migratorClass.isAnnotationPresent(Enabled.class);
+ String enabled = enabledAnnotation ? "Enabled" : "Disabled";
+ StringBuilder sb = new StringBuilder();
+ sb.append(migratorClass.getSimpleName());
+ sb.append(" in package ");
+ sb.append(migratorClass.getPackage().getName().substring(migratorClass.getPackage().getName().lastIndexOf('.')+1));
+ sb.append(" is ");
+ sb.append(enabled);
+ sb.append(" ");
+ sb.append("[" + getDbStatus(migratorClass.getSimpleName(), engine) + "]");
+ System.out.println(sb.toString());
+ });
+ engine.rollback();
+ System.out.println("---------- Done ----------");
+ }
+
private String getDbStatus(String name, TransactionalGraphEngine engine) {
if (hasAlreadyRun(name, engine)) {
return "Already executed in this env";
}
- return "Will be run on next execution";
+ return "Will be run on next execution if Enabled";
}
private boolean hasAlreadyRun(String name, TransactionalGraphEngine engine) {
- return engine.asAdmin().getReadOnlyTraversalSource().V().has(AAIProperties.NODE_TYPE, vertexType).has(name, true).hasNext();
+ return engine.asAdmin().getReadOnlyTraversalSource().V().has(AAIProperties.NODE_TYPE, VERTEX_TYPE).has(name, true).hasNext();
}
private Set<Class<? extends Migrator>> findClasses(Reflections reflections) {
Set<Class<? extends Migrator>> migratorClasses = reflections.getSubTypesOf(Migrator.class);
@@ -232,85 +283,75 @@ public class MigrationControllerInternal {
* TODO- Change this to make sure only classes in the specific $release are added in the runList
* Or add a annotation like exclude which folks again need to remember to add ??
*/
-
+
migratorClasses.remove(PropertyMigrator.class);
migratorClasses.remove(EdgeMigrator.class);
return migratorClasses;
}
- private void takeSnapshotIfRequired(TransactionalGraphEngine engine, CommandLineArgs cArgs, List<Migrator> migratorList) {
+ private void takePreSnapshotIfRequired(TransactionalGraphEngine engine, CommandLineArgs cArgs, List<Class<? extends Migrator>> migratorClassesToRun) {
/*int sum = 0;
- for (Migrator migrator : migratorList) {
- if (migrator.getClass().isAnnotationPresent(Enabled.class)) {
- sum += migrator.getDangerRating();
+ for (Class<? extends Migrator> migratorClass : migratorClassesToRun) {
+ if (migratorClass.isAnnotationPresent(Enabled.class)) {
+ sum += migratorClass.getAnnotation(MigrationPriority.class).value();
}
}
-
+
if (sum >= DANGER_ZONE) {
-
+
logAndPrint("Entered Danger Zone. Taking snapshot.");
}*/
-
+
//always take snapshot for now
+
generateSnapshot(engine, "pre");
}
- private List<Migrator> createMigratorList(CommandLineArgs cArgs,
- Set<Class<? extends Migrator>> migratorClasses) {
- List<Migrator> migratorList = new ArrayList<>();
+ private List<Class<? extends Migrator>> createMigratorList(CommandLineArgs cArgs,
+ List<Class<? extends Migrator>> migratorClasses) {
+ List<Class<? extends Migrator>> migratorClassesToRun = new ArrayList<>();
for (Class<? extends Migrator> migratorClass : migratorClasses) {
if (!cArgs.scripts.isEmpty() && !cArgs.scripts.contains(migratorClass.getSimpleName())) {
continue;
} else {
- Migrator migrator;
- try {
-
- migrator = migratorClass.getConstructor().newInstance();
- } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
- logAndPrint("EXCEPTION caught initalizing migration class " + migratorClass.getSimpleName() + ".\n" + ExceptionUtils.getFullStackTrace(e));
- continue;
- }
- migratorList.add(migrator);
+ migratorClassesToRun.add(migratorClass);
}
}
- return migratorList;
+ return migratorClassesToRun;
}
- private void sortList(List<Migrator> migratorList) {
- Collections.sort(migratorList, new Comparator<Migrator>() {
- public int compare(Migrator m1, Migrator m2) {
- try {
-
- if (m1.getPriority() > m2.getPriority()) {
- return 1;
- } else if (m1.getPriority() < m2.getPriority()) {
- return -1;
- } else {
- return m1.getClass().getSimpleName().compareTo(m2.getClass().getSimpleName());
- }
- } catch (Exception e) {
- return 0;
+ private void sortList(List<Class<? extends Migrator>> migratorClasses) {
+ Collections.sort(migratorClasses, (m1, m2) -> {
+ try {
+ if (m1.getAnnotation(MigrationPriority.class).value() > m2.getAnnotation(MigrationPriority.class).value()) {
+ return 1;
+ } else if (m1.getAnnotation(MigrationPriority.class).value() < m2.getAnnotation(MigrationPriority.class).value()) {
+ return -1;
+ } else {
+ return m1.getSimpleName().compareTo(m2.getSimpleName());
}
+ } catch (Exception e) {
+ return 0;
}
});
}
-
+
private void generateSnapshot(TransactionalGraphEngine engine, String phase) {
-
+
FormatDate fd = new FormatDate("yyyyMMddHHmm", "GMT");
String dateStr= fd.getDateTime();
- String fileName = snapshotLocation + File.separator + phase + "Migration." + dateStr + ".graphson";
+ String fileName = SNAPSHOT_LOCATION + File.separator + phase + "Migration." + dateStr + ".graphson";
logAndPrint("Saving snapshot of inmemory graph " + phase + " migration to " + fileName);
Graph transaction = null;
try {
-
+
Path pathToFile = Paths.get(fileName);
if (!pathToFile.toFile().exists()) {
Files.createDirectories(pathToFile.getParent());
@@ -319,17 +360,18 @@ public class MigrationControllerInternal {
transaction.io(IoCore.graphson()).writeGraph(fileName);
engine.rollback();
} catch (IOException e) {
+ LoggingContext.statusCode(StatusCode.ERROR);
+ LoggingContext.responseCode(LoggingContext.AVAILABILITY_TIMEOUT_ERROR);
logAndPrint("ERROR: Could not write in memory graph to " + phase + "Migration file. \n" + ExceptionUtils.getFullStackTrace(e));
+ LoggingContext.successStatusFields();
engine.rollback();
- }
+ }
logAndPrint( phase + " migration snapshot saved to " + fileName);
}
/**
* Log and print.
*
- * @param logger
- * the logger
* @param msg
* the msg
*/
@@ -341,12 +383,11 @@ public class MigrationControllerInternal {
/**
* Commit changes.
*
- * @param g
- * the g
+ * @param engine
+ * the graph transaction
* @param migrator
* the migrator
- * @param logger
- * the logger
+ * @param cArgs
*/
protected void commitChanges(TransactionalGraphEngine engine, Migrator migrator, CommandLineArgs cArgs) {
@@ -354,20 +395,26 @@ public class MigrationControllerInternal {
String message;
if (migrator.getStatus().equals(Status.FAILURE)) {
message = "Migration " + simpleName + " Failed. Rolling back.";
+ LoggingContext.statusCode(StatusCode.ERROR);
+ LoggingContext.responseCode(LoggingContext.DATA_ERROR);
logAndPrint("\t" + message);
+ LoggingContext.successStatusFields();
migrator.rollback();
} else if (migrator.getStatus().equals(Status.CHECK_LOGS)) {
- message = "Migration " + simpleName + " encountered an anomily, check logs. Rolling back.";
+ message = "Migration " + simpleName + " encountered an anomaly, check logs. Rolling back.";
+ LoggingContext.statusCode(StatusCode.ERROR);
+ LoggingContext.responseCode(LoggingContext.DATA_ERROR);
logAndPrint("\t" + message);
+ LoggingContext.successStatusFields();
migrator.rollback();
} else {
- MDC.put("logFilenameAppender", simpleName + "/" + migrator.getClass().getSimpleName());
+ MDC.put("logFilenameAppender", simpleName + "/" + simpleName);
if (cArgs.commit) {
- if (!engine.asAdmin().getTraversalSource().V().has(AAIProperties.NODE_TYPE, vertexType).hasNext()) {
- engine.asAdmin().getTraversalSource().addV(AAIProperties.NODE_TYPE, vertexType).iterate();
+ if (!engine.asAdmin().getTraversalSource().V().has(AAIProperties.NODE_TYPE, VERTEX_TYPE).hasNext()) {
+ engine.asAdmin().getTraversalSource().addV(AAIProperties.NODE_TYPE, VERTEX_TYPE).iterate();
}
- engine.asAdmin().getTraversalSource().V().has(AAIProperties.NODE_TYPE, vertexType)
+ engine.asAdmin().getTraversalSource().V().has(AAIProperties.NODE_TYPE, VERTEX_TYPE)
.property(simpleName, true).iterate();
MDC.put("logFilenameAppender", MigrationController.class.getSimpleName());
notifications.add(migrator.getNotificationHelper());
@@ -381,11 +428,11 @@ public class MigrationControllerInternal {
}
}
-
+
resultsSummary.add(message);
}
-
+
private void outputResultsSummary() {
logAndPrint("---------------------------------");
logAndPrint("-------------Summary-------------");
@@ -395,7 +442,7 @@ public class MigrationControllerInternal {
logAndPrint("---------------------------------");
logAndPrint("---------------------------------");
}
-
+
}
class CommandLineArgs {
@@ -411,14 +458,22 @@ class CommandLineArgs {
@Parameter(names = "-l", description = "list the status of migrations")
public boolean list = false;
-
+
@Parameter(names = "-d", description = "location of data snapshot", hidden = true)
public String dataSnapshot;
-
+
@Parameter(names = "-f", description = "force migrations to be rerun")
public boolean forced = false;
-
+
@Parameter(names = "--commit", description = "commit changes to graph")
public boolean commit = false;
+ @Parameter(names = "-e", description = "exclude list of migrator classes")
+ public List<String> excludeClasses = new ArrayList<>();
+
+ @Parameter(names = "--skipPreMigrationSnapShot", description = "skips taking the PRE migration snapshot")
+ public boolean skipPreMigrationSnapShot = false;
+
+ @Parameter(names = "--skipPostMigrationSnapShot", description = "skips taking the POST migration snapshot")
+ public boolean skipPostMigrationSnapShot = false;
}
diff --git a/aai-resources/src/main/java/org/onap/aai/migration/MigrationDangerRating.java b/aai-resources/src/main/java/org/onap/aai/migration/MigrationDangerRating.java
new file mode 100644
index 0000000..a1d456c
--- /dev/null
+++ b/aai-resources/src/main/java/org/onap/aai/migration/MigrationDangerRating.java
@@ -0,0 +1,42 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.onap.aai.migration;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/**
+ * Used to enable a migration to be picked up by the {@link com.openecomp.aai.migration.MigrationControllerInternal MigrationController}
+ *
+ * The larger the number, the more danger
+ *
+ * Range is 0-10
+ */
+@Target(ElementType.TYPE)
+@Retention(value = RetentionPolicy.RUNTIME)
+public @interface MigrationDangerRating {
+
+ int value();
+
+}
diff --git a/aai-resources/src/main/java/org/onap/aai/migration/MigrationPriority.java b/aai-resources/src/main/java/org/onap/aai/migration/MigrationPriority.java
new file mode 100644
index 0000000..fb7b06f
--- /dev/null
+++ b/aai-resources/src/main/java/org/onap/aai/migration/MigrationPriority.java
@@ -0,0 +1,42 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.onap.aai.migration;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/**
+ * Used to enable a migration to be picked up by the {@link com.openecomp.aai.migration.MigrationControllerInternal MigrationController}
+ *
+ * The priority of the migration.
+ *
+ * Lower number has higher priority
+ */
+@Target(ElementType.TYPE)
+@Retention(value = RetentionPolicy.RUNTIME)
+public @interface MigrationPriority {
+
+ int value();
+
+}
diff --git a/aai-resources/src/main/java/org/onap/aai/migration/Migrator.java b/aai-resources/src/main/java/org/onap/aai/migration/Migrator.java
index 900c914..e5e4c52 100644
--- a/aai-resources/src/main/java/org/onap/aai/migration/Migrator.java
+++ b/aai-resources/src/main/java/org/onap/aai/migration/Migrator.java
@@ -21,6 +21,7 @@
*/
package org.onap.aai.migration;
+import java.util.Collections;
import java.util.Iterator;
import java.util.Optional;
@@ -50,6 +51,8 @@ import com.att.eelf.configuration.EELFManager;
/**
* This class defines an A&AI Migration
*/
+@MigrationPriority(0)
+@MigrationDangerRating(0)
public abstract class Migrator implements Runnable {
protected EELFLogger logger = null;
@@ -59,10 +62,7 @@ public abstract class Migrator implements Runnable {
protected TransactionalGraphEngine engine;
protected NotificationHelper notificationHelper;
-
- public Migrator() {
- //used for not great reflection implementation
- }
+
/**
* Instantiates a new migrator.
*
@@ -97,24 +97,8 @@ public abstract class Migrator implements Runnable {
engine.commit();
}
- /**
- * Gets the priority.
- *
- * Lower number has higher priority
- *
- * @return the priority
- */
- public abstract int getPriority();
/**
- * The larger the number, the more danger
- *
- * Range is 0-10
- *
- * @return danger rating
- */
- public abstract int getDangerRating();
- /**
* As string.
*
* @param v the v
@@ -157,12 +141,48 @@ public abstract class Migrator implements Runnable {
return result.toString();
}
+
+ /**
+ *
+ * @param v
+ * @param numLeadingTabs number of leading \t char's
+ * @return
+ */
+ protected String toStringForPrinting(Vertex v, int numLeadingTabs) {
+ String prefix = String.join("", Collections.nCopies(numLeadingTabs, "\t"));
+ if (v == null) {
+ return "";
+ }
+ final StringBuilder sb = new StringBuilder();
+ sb.append(prefix + v + "\n");
+ v.properties().forEachRemaining(prop -> sb.append(prefix + prop + "\n"));
+ return sb.toString();
+ }
+
+ /**
+ *
+ * @param e
+ * @param numLeadingTabs number of leading \t char's
+ * @return
+ */
+ protected String toStringForPrinting(Edge e, int numLeadingTabs) {
+ String prefix = String.join("", Collections.nCopies(numLeadingTabs, "\t"));
+ if (e == null) {
+ return "";
+ }
+ final StringBuilder sb = new StringBuilder();
+ sb.append(prefix + e + "\n");
+ sb.append(prefix + e.label() + "\n");
+ e.properties().forEachRemaining(prop -> sb.append(prefix + "\t" + prop + "\n"));
+ return sb.toString();
+ }
+
/**
* Checks for edge between.
*
- * @param vertex a
- * @param vertex b
- * @param direction d
+ * @param a a
+ * @param b b
+ * @param d d
* @param edgeLabel the edge label
* @return true, if successful
*/
@@ -179,7 +199,7 @@ public abstract class Migrator implements Runnable {
/**
* Creates the edge
*
- * @param edgeType the edge type - COUSIN or TREE
+ * @param type the edge type - COUSIN or TREE
* @param out the out
* @param in the in
* @return the edge
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 c42862a..28c78ea 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
@@ -36,6 +36,8 @@ import com.thinkaurelius.titan.core.schema.TitanManagement;
/**
* A migration template for migrating a property from one name to another
*/
+@MigrationPriority(0)
+@MigrationDangerRating(1)
public abstract class PropertyMigrator extends Migrator {
protected final String OLD_FIELD;
@@ -43,15 +45,7 @@ public abstract class PropertyMigrator extends Migrator {
protected final Class<?> fieldType;
protected final Cardinality cardinality;
protected final TitanManagement graphMgmt;
- public PropertyMigrator() {
- //used for not great reflection implementation
- super();
- this.OLD_FIELD = null;
- this.NEW_FIELD = null;
- this.fieldType = null;
- this.cardinality = null;
- this.graphMgmt = null;
- }
+
public PropertyMigrator(TransactionalGraphEngine engine, String oldName, String newName, Class<?> type, Cardinality cardinality) {
super(engine);
this.OLD_FIELD = oldName;
@@ -111,17 +105,7 @@ public abstract class PropertyMigrator extends Migrator {
return Status.FAILURE;
}
}
-
- @Override
- public int getPriority() {
- return 0;
- }
- @Override
- public int getDangerRating() {
- return 1;
- }
-
protected Optional<PropertyKey> addProperty() {
if (!graphMgmt.containsPropertyKey(this.NEW_FIELD)) {
diff --git a/aai-resources/src/main/java/org/onap/aai/migration/v12/ContainmentDeleteOtherVPropertyMigration.java b/aai-resources/src/main/java/org/onap/aai/migration/v12/ContainmentDeleteOtherVPropertyMigration.java
new file mode 100644
index 0000000..643517d
--- /dev/null
+++ b/aai-resources/src/main/java/org/onap/aai/migration/v12/ContainmentDeleteOtherVPropertyMigration.java
@@ -0,0 +1,105 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.onap.aai.migration.v12;
+
+import java.util.Optional;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.onap.aai.migration.MigrationDangerRating;
+import org.onap.aai.migration.Enabled;
+import org.onap.aai.migration.MigrationPriority;
+import org.onap.aai.migration.Migrator;
+import org.onap.aai.migration.Status;
+import org.onap.aai.serialization.db.AAIDirection;
+import org.onap.aai.serialization.db.EdgeProperty;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+
+
+
+@Enabled
+@MigrationPriority(-100)
+@MigrationDangerRating(10)
+public class ContainmentDeleteOtherVPropertyMigration extends Migrator {
+
+ private boolean success = true;
+
+ public ContainmentDeleteOtherVPropertyMigration(TransactionalGraphEngine engine) {
+ super(engine);
+ }
+
+ //just for testing using test edge rule files
+ public ContainmentDeleteOtherVPropertyMigration(TransactionalGraphEngine engine, String edgeRulesFile) {
+ super(engine);
+ }
+
+ @Override
+ public void run() {
+ try {
+ engine.asAdmin().getTraversalSource().E().sideEffect(t -> {
+ Edge e = t.get();
+ logger.info("out vertex: " + e.outVertex().property("aai-node-type").value() +
+ " in vertex: " + e.inVertex().property("aai-node-type").value() +
+ " label : " + e.label());
+ if (e.property(EdgeProperty.CONTAINS.toString()).isPresent() &&
+ e.property(EdgeProperty.DELETE_OTHER_V.toString()).isPresent()) {
+ //in case of orphans
+ if (!("constrained-element-set".equals(e.inVertex().property("aai-node-type").value())
+ && "model-element".equals(e.outVertex().property("aai-node-type").value()))) {
+ //skip the weird horrible problem child edge
+ String containment = (String) e.property(EdgeProperty.CONTAINS.toString()).value();
+ if (AAIDirection.OUT.toString().equalsIgnoreCase(containment) ||
+ AAIDirection.IN.toString().equalsIgnoreCase(containment) ||
+ AAIDirection.BOTH.toString().equalsIgnoreCase(containment)) {
+ logger.info("updating delete-other-v property");
+ e.property(EdgeProperty.DELETE_OTHER_V.toString(), containment);
+ }
+ }
+ }
+ }).iterate();
+ } catch (Exception e) {
+ logger.info("error encountered " + e.getClass() + " " + e.getMessage() + " " + ExceptionUtils.getFullStackTrace(e));
+ logger.error("error encountered " + e.getClass() + " " + e.getMessage() + " " + ExceptionUtils.getFullStackTrace(e));
+ success = false;
+ }
+
+ }
+
+ @Override
+ public Status getStatus() {
+ if (success) {
+ return Status.SUCCESS;
+ } else {
+ return Status.FAILURE;
+ }
+ }
+
+ @Override
+ public Optional<String[]> getAffectedNodeTypes() {
+ return Optional.empty();
+ }
+
+ @Override
+ public String getMigrationName() {
+ return "migrate-containment-delete-other-v";
+ }
+
+}
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
new file mode 100644
index 0000000..859e52f
--- /dev/null
+++ b/aai-resources/src/main/java/org/onap/aai/migration/v12/EdgeReportForToscaMigration.java
@@ -0,0 +1,142 @@
+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;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.onap.aai.migration.*;
+import org.onap.aai.serialization.db.EdgeRules;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+
+import java.util.*;
+
+@Enabled
+@MigrationPriority(0)
+@MigrationDangerRating(0)
+public class EdgeReportForToscaMigration extends Migrator {
+
+ private boolean success = true;
+ EdgeRules ers = EdgeRules.getInstance();
+
+ public EdgeReportForToscaMigration(TransactionalGraphEngine graphEngine){
+ super(graphEngine);
+ }
+
+ @Override
+ public Status getStatus() {
+ if (success) {
+ return Status.SUCCESS;
+ } else {
+ return Status.FAILURE;
+ }
+ }
+
+ @Override
+ public void run() {
+ Vertex out = null;
+ Vertex in = null;
+ String label = "";
+ String outURI = "";
+ String inURI = "";
+ String parentCousinIndicator = "NONE";
+ String oldEdgeString = null;
+ List<String> edgeMissingParentProperty = new ArrayList<>();
+ StringBuilder sb = new StringBuilder();
+ Set<String> noURI = new HashSet<>();
+ sb.append("----------EDGES----------\n");
+
+ GraphTraversalSource g = engine.asAdmin().getTraversalSource();
+
+ try {
+ Set<Edge> edges = g.E().toSet();
+ for (Edge edge : edges) {
+ out = edge.outVertex();
+ in = edge.inVertex();
+ label = edge.label();
+ outURI = this.getVertexURI(out);
+ inURI = this.getVertexURI(in);
+ parentCousinIndicator = "NONE";
+ oldEdgeString = this.toStringForPrinting(edge, 1);
+
+ if (!outURI.startsWith("/")) {
+ noURI.add(outURI);
+ }
+ if (!inURI.startsWith("/")) {
+ noURI.add(inURI);
+ }
+
+ if (out == null || in == null) {
+ logger.error(edge.id() + " invalid because one vertex was null: out=" + edge.outVertex() + " in=" + edge.inVertex());
+ } else {
+
+ if (edge.property("contains-other-v").isPresent()) {
+ parentCousinIndicator = edge.property("contains-other-v").value().toString();
+ } else if (edge.property("isParent").isPresent()) {
+ if ((Boolean)edge.property("isParent").value()) {
+ parentCousinIndicator = "OUT";
+ } else if (edge.property("isParent-REV").isPresent() && (Boolean)edge.property("isParent-REV").value()) {
+ parentCousinIndicator = "IN";
+ }
+ } else {
+ edgeMissingParentProperty.add(this.toStringForPrinting(edge, 1));
+ }
+
+ sb.append(outURI + "|" + label + "|" + inURI + "|" + parentCousinIndicator + "\n");
+ }
+ }
+ } catch(Exception ex){
+ logger.error("exception occurred during migration, failing: out=" + out + " in=" + in + "edge=" + oldEdgeString, ex);
+ success = false;
+ }
+ sb.append("--------EDGES END--------\n");
+
+ logger.info(sb.toString());
+ edgeMissingParentProperty.forEach(s -> logger.warn("Edge Missing Parent Property: " + s));
+ logger.info("Edge Missing Parent Property Count: " + edgeMissingParentProperty.size());
+ logger.info("Vertex Missing URI Property Count: " + noURI.size());
+
+ }
+
+ private String getVertexURI(Vertex v) {
+ if (v.property("aai-uri").isPresent()) {
+ return v.property("aai-uri").value().toString();
+ } else {
+ return v.id().toString() + "(" + v.property("aai-node-type").value().toString() + ")";
+ }
+ }
+
+ @Override
+ public Optional<String[]> getAffectedNodeTypes() {
+ return Optional.empty();
+ }
+
+ @Override
+ public String getMigrationName() {
+ return "edge-report-for-tosca-migration";
+ }
+
+ @Override
+ public void commit() {
+ engine.rollback();
+ }
+
+}
diff --git a/aai-resources/src/main/java/org/onap/aai/migration/v12/MigrateDataFromASDCToConfiguration.java b/aai-resources/src/main/java/org/onap/aai/migration/v12/MigrateDataFromASDCToConfiguration.java
new file mode 100644
index 0000000..5185db3
--- /dev/null
+++ b/aai-resources/src/main/java/org/onap/aai/migration/v12/MigrateDataFromASDCToConfiguration.java
@@ -0,0 +1,107 @@
+package org.onap.aai.migration.v12;
+
+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.migration.*;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import org.onap.aai.util.AAIConstants;
+
+import java.io.*;
+import java.util.Optional;
+
+@MigrationPriority(20)
+@MigrationDangerRating(2)
+@Enabled
+public class MigrateDataFromASDCToConfiguration extends Migrator {
+ private final String PARENT_NODE_TYPE = "generic-vnf";
+ private boolean success = true;
+ private String entitlementPoolUuid = "";
+ private String VNT = "";
+
+
+ public MigrateDataFromASDCToConfiguration(TransactionalGraphEngine engine) {
+ super(engine);
+ }
+
+
+ @Override
+ public void run() {
+ String csvFile = AAIConstants.AAI_HOME_ETC + "VNT-migration-data" + AAIConstants.AAI_FILESEP + "VNT-migration-input.csv";
+ logger.info("Reading Csv file: " + csvFile);
+ BufferedReader br = null;
+ String line = "";
+ String cvsSplitBy = "\t";
+ try {
+
+ br = new BufferedReader(new FileReader(new File(csvFile)));
+ while ((line = br.readLine()) != null) {
+ line = line.replaceAll("\"", "");
+ String[] temp = line.split(cvsSplitBy);
+ if ("entitlement-pool-uuid".equals(temp[0]) || "vendor-allowed-max-bandwidth (VNT)".equals(temp[1])) {
+ continue;
+ }
+ entitlementPoolUuid = temp[0];
+ VNT = temp[1];
+ GraphTraversal<Vertex, Vertex> f = this.engine.asAdmin().getTraversalSource().V().has(AAIProperties.NODE_TYPE, "entitlement").has("group-uuid", entitlementPoolUuid)
+ .out("org.onap.relationships.inventory.BelongsTo").has(AAIProperties.NODE_TYPE, "generic-vnf")
+ .has("vnf-type", "vHNF").in("org.onap.relationships.inventory.ComposedOf").has(AAIProperties.NODE_TYPE, "service-instance").out("org.onap.relationships.inventory.Uses").has(AAIProperties.NODE_TYPE, "configuration");
+
+ modify(f);
+ }
+
+ } catch (FileNotFoundException e) {
+ success = false;
+ logger.error("Found Exception" , e);
+ } catch (IOException e) {
+ success = false;
+ logger.error("Found Exception" , e);
+ } catch (Exception a) {
+ success= false;
+ logger.error("Found Exception" , a);
+ } finally {
+ try {
+ br.close();
+ } catch (IOException e) {
+ success = false;
+ logger.error("Found Exception" , e);
+ }
+ }
+
+ }
+
+ public void modify(GraphTraversal<Vertex, Vertex> g) {
+ int count = 0;
+ while (g.hasNext()) {
+ Vertex v = g.next();
+ logger.info("Found node type " + v.property("aai-node-type").value().toString() + " with configuration id: " + v.property("configuration-id").value().toString());
+ v.property("vendor-allowed-max-bandwidth", VNT);
+ logger.info("VNT val after migration: " + v.property("vendor-allowed-max-bandwidth").value().toString());
+ count++;
+ }
+
+ logger.info("modified " + count + " configuration nodes related to Entitlement UUID: " +entitlementPoolUuid);
+
+ }
+
+ @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 "MigrateDataFromASDCToConfiguration";
+ }
+
+
+}
diff --git a/aai-resources/src/main/java/org/onap/aai/migration/v12/MigrateServiceInstanceToConfiguration.java b/aai-resources/src/main/java/org/onap/aai/migration/v12/MigrateServiceInstanceToConfiguration.java
new file mode 100644
index 0000000..f36fb2d
--- /dev/null
+++ b/aai-resources/src/main/java/org/onap/aai/migration/v12/MigrateServiceInstanceToConfiguration.java
@@ -0,0 +1,171 @@
+package org.onap.aai.migration.v12;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Iterator;
+import java.util.Optional;
+import java.util.UUID;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
+import org.onap.aai.migration.Enabled;
+import org.onap.aai.migration.MigrationDangerRating;
+import org.onap.aai.migration.MigrationPriority;
+import org.onap.aai.migration.Migrator;
+import org.onap.aai.migration.Status;
+import org.onap.aai.serialization.db.EdgeType;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+
+@Enabled
+@MigrationPriority(10)
+@MigrationDangerRating(10)
+public class MigrateServiceInstanceToConfiguration extends Migrator {
+
+ private boolean success = true;
+ private final String CONFIGURATION_NODE_TYPE = "configuration";
+ private final String SERVICE_INSTANCE_NODE_TYPE = "service-instance";
+ private Introspector configObj;
+
+ public MigrateServiceInstanceToConfiguration(TransactionalGraphEngine engine) {
+ super(engine);
+ try {
+ this.configObj = this.loader.introspectorFromName(CONFIGURATION_NODE_TYPE);
+ } catch (AAIUnknownObjectException e) {
+ this.configObj = null;
+ }
+ }
+
+ @Override
+ public void run() {
+ Vertex serviceInstance = null;
+ Vertex configuration = null;
+ String serviceInstanceId = "", tunnelBandwidth = "";
+ String bandwidthTotal, configType, nodeType;
+ GraphTraversal<Vertex, Vertex> serviceInstanceItr;
+ Iterator<Vertex> configurationItr;
+
+ try {
+ serviceInstanceItr = this.engine.asAdmin().getTraversalSource().V()
+ .has(AAIProperties.NODE_TYPE, P.within(getAffectedNodeTypes().get()))
+ .where(this.engine.getQueryBuilder()
+ .createEdgeTraversal(EdgeType.TREE, "service-instance", "service-subscription")
+ .getVerticesByProperty("service-type", "DHV")
+ .<GraphTraversal<?, ?>>getQuery());
+
+ if (serviceInstanceItr == null || !serviceInstanceItr.hasNext()) {
+ logger.info("No servince-instance nodes found with service-type of DHV");
+ return;
+ }
+
+ // iterate through all service instances of service-type DHV
+ while (serviceInstanceItr.hasNext()) {
+ serviceInstance = serviceInstanceItr.next();
+
+ if (serviceInstance != null && serviceInstance.property("bandwidth-total").isPresent()) {
+ serviceInstanceId = serviceInstance.value("service-instance-id");
+ logger.info("Processing service instance with id=" + serviceInstanceId);
+ bandwidthTotal = serviceInstance.value("bandwidth-total");
+
+ if (bandwidthTotal != null && !bandwidthTotal.isEmpty()) {
+
+ // check for existing edges to configuration nodes
+ configurationItr = serviceInstance.vertices(Direction.OUT, "has");
+
+ // create new configuration node if service-instance does not have existing ones
+ if (!configurationItr.hasNext()) {
+ logger.info(serviceInstanceId + " has no existing configuration nodes, creating new node");
+ createConfigurationNode(serviceInstance, bandwidthTotal);
+ continue;
+ }
+
+ // in case if configuration nodes exist, but none are DHV
+ boolean hasDHVConfig = false;
+
+ // service-instance has existing configuration nodes
+ while (configurationItr.hasNext()) {
+ configuration = configurationItr.next();
+ nodeType = configuration.value("aai-node-type").toString();
+
+ if (configuration != null && "configuration".equalsIgnoreCase(nodeType)) {
+ logger.info("Processing configuration node with id=" + configuration.property("configuration-id").value());
+ configType = configuration.value("configuration-type");
+ logger.info("Configuration type: " + configType);
+
+ // if configuration-type is DHV, update tunnel-bandwidth to bandwidth-total value
+ if ("DHV".equalsIgnoreCase(configType)) {
+ if (configuration.property("tunnel-bandwidth").isPresent()) {
+ tunnelBandwidth = configuration.value("tunnel-bandwidth");
+ } else {
+ tunnelBandwidth = "";
+ }
+
+ logger.info("Existing tunnel-bandwidth: " + tunnelBandwidth);
+ configuration.property("tunnel-bandwidth", bandwidthTotal);
+ touchVertexProperties(configuration, false);
+ logger.info("Updated tunnel-bandwidth: " + configuration.value("tunnel-bandwidth"));
+ hasDHVConfig = true;
+ }
+ }
+ }
+
+ // create new configuration node if none of existing config nodes are of type DHV
+ if (!hasDHVConfig) {
+ logger.info(serviceInstanceId + " has existing configuration nodes, but none are DHV, create new node");
+ createConfigurationNode(serviceInstance, bandwidthTotal);
+ }
+ }
+ }
+ }
+ } catch (AAIException | UnsupportedEncodingException e) {
+ logger.error("Caught exception while processing service instance with id=" + serviceInstanceId + " | " + e.toString());
+ success = false;
+ }
+ }
+
+ private void createConfigurationNode(Vertex serviceInstance, String bandwidthTotal) throws UnsupportedEncodingException, AAIException {
+ // create new vertex
+ Vertex configurationNode = serializer.createNewVertex(configObj);
+
+ // configuration-id: UUID format
+ String configurationUUID = UUID.randomUUID().toString();
+ configObj.setValue("configuration-id", configurationUUID);
+
+ // configuration-type: DHV
+ configObj.setValue("configuration-type", "DHV");
+
+ // migrate the bandwidth-total property from the service-instance to the
+ // tunnel-bandwidth property of the related configuration object
+ configObj.setValue("tunnel-bandwidth", bandwidthTotal);
+
+ // create edge between service instance and configuration: cousinEdge(out, in)
+ createCousinEdge(serviceInstance, configurationNode);
+
+ // serialize edge & vertex, takes care of everything
+ serializer.serializeSingleVertex(configurationNode, configObj, "migrations");
+ logger.info("Created configuration node with uuid=" + configurationUUID + ", tunnel-bandwidth=" + bandwidthTotal);
+ }
+
+ @Override
+ public Status getStatus() {
+ if (success) {
+ return Status.SUCCESS;
+ } else {
+ return Status.FAILURE;
+ }
+ }
+
+ @Override
+ public Optional<String[]> getAffectedNodeTypes() {
+ return Optional.of(new String[] {SERVICE_INSTANCE_NODE_TYPE});
+ }
+
+ @Override
+ public String getMigrationName() {
+ return "service-instance-to-configuration";
+ }
+}
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
new file mode 100644
index 0000000..274f1b6
--- /dev/null
+++ b/aai-resources/src/main/java/org/onap/aai/migration/v12/ToscaMigration.java
@@ -0,0 +1,160 @@
+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.*;
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.migration.Enabled;
+import org.onap.aai.migration.MigrationDangerRating;
+import org.onap.aai.migration.MigrationPriority;
+import org.onap.aai.migration.Migrator;
+import org.onap.aai.migration.Status;
+import org.onap.aai.serialization.db.*;
+import org.onap.aai.serialization.db.exceptions.EdgeMultiplicityException;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+
+@Enabled
+
+@MigrationPriority(0)
+@MigrationDangerRating(1000)
+public class ToscaMigration extends Migrator {
+
+ private boolean success = true;
+ EdgeRules ers = EdgeRules.getInstance();
+
+ public ToscaMigration(TransactionalGraphEngine graphEngine){
+ super(graphEngine);
+ }
+
+ @Override
+ public Status getStatus() {
+ if (success) {
+ return Status.SUCCESS;
+ } else {
+ return Status.FAILURE;
+ }
+ }
+
+ @Override
+ public void run() {
+ Vertex out = null;
+ Vertex in = null;
+ boolean isCousin = false;
+ String oldEdgeString = null;
+ Map<String,Integer> edgeMultiplicityExceptionCtr = new HashMap<>();
+ List<String> edgeMissingParentProperty = new ArrayList<>();
+
+ GraphTraversalSource g = engine.asAdmin().getTraversalSource();
+
+ try {
+ Set<Edge> edges = g.E().toSet();
+ for (Edge edge : edges) {
+ // skip if this edge was migrated in a previous run
+ if (edge.label().contains("org.") || edge.label().contains("tosca.")) {
+ continue;
+ }
+ out = edge.outVertex();
+ in = edge.inVertex();
+ isCousin = false;
+
+ if (out == null || in == null) {
+ logger.error(edge.id() + " invalid because one vertex was null: out=" + edge.outVertex() + " in=" + edge.inVertex());
+ } else {
+
+ if (edge.property("contains-other-v").isPresent()) {
+ isCousin = "NONE".equals(edge.property("contains-other-v").value());
+ } else if (edge.property("isParent").isPresent()) {
+ isCousin = !(Boolean)edge.property("isParent").value();
+ } else {
+ edgeMissingParentProperty.add(this.toStringForPrinting(edge, 1));
+ }
+
+ String inVertexNodeType = in.value(AAIProperties.NODE_TYPE);
+ String outVertexNodeType = out.value(AAIProperties.NODE_TYPE);
+ String label = null;
+
+
+ Set<String> edgeLabels = ers.getEdgeRules(outVertexNodeType,inVertexNodeType).keySet();
+
+ if (edgeLabels.isEmpty()) {
+ logger.error(edge.id() + " did not migrate as no edge rule found for: out=" + outVertexNodeType + " in=" + inVertexNodeType);
+ continue;
+ } else if (edgeLabels.size() > 1) {
+ if (edgeLabels.contains("org.onap.relationships.inventory.Source")) {
+ if ("sourceLInterface".equals(edge.label())) {
+ label = "org.onap.relationships.inventory.Source";
+ } else if ("targetLInterface".equals(edge.label())) {
+ label = "org.onap.relationships.inventory.Destination";
+ } else {
+ label = "tosca.relationships.network.LinksTo";
+ }
+ }
+ }
+
+ try {
+ if (isCousin) {
+ ers.addEdgeIfPossible(g, in, out, label);
+ } else {
+ ers.addTreeEdge(g, out, in);
+ }
+ edge.remove();
+ } catch (EdgeMultiplicityException edgeMultiplicityException) {
+ logger.warn("Edge Multiplicity Exception: "
+ + "\nInV:\n" + this.toStringForPrinting(in, 1)
+ + "Edge:\n" + this.toStringForPrinting(edge, 1)
+ + "OutV:\n" + this.toStringForPrinting(out, 1)
+ );
+
+ final String mapKey = "OUT:" + outVertexNodeType + " " + (isCousin ? EdgeType.COUSIN.toString():EdgeType.TREE.toString()) + " " + "IN:" + inVertexNodeType;
+ if (edgeMultiplicityExceptionCtr.containsKey(mapKey)) {
+ edgeMultiplicityExceptionCtr.put(mapKey, edgeMultiplicityExceptionCtr.get(mapKey)+1);
+ } else {
+ edgeMultiplicityExceptionCtr.put(mapKey, 1);
+ }
+ }
+ }
+ }
+ } catch(Exception ex){
+ logger.error("exception occurred during migration, failing: out=" + out + " in=" + in + "edge=" + oldEdgeString, ex);
+ success = false;
+ }
+
+ logger.info("Edge Missing Parent Property Count: " + edgeMissingParentProperty.size());
+ logger.info("Edge Multiplicity Exception Count : " + edgeMultiplicityExceptionCtr.values().stream().mapToInt(Number::intValue).sum());
+ logger.info("Edge Multiplicity Exception Breakdown : " + edgeMultiplicityExceptionCtr);
+
+ }
+
+ @Override
+ public Optional<String[]> getAffectedNodeTypes() {
+ return Optional.empty();
+ }
+
+ @Override
+ public String getMigrationName() {
+ return "migrate-all-edges";
+ }
+
+}