aboutsummaryrefslogtreecommitdiffstats
path: root/aai-resources/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'aai-resources/src/main/java')
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/dbgen/AddResourceVersionProp.java126
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/dbgen/ChangePropertyCardinality.java307
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/dbgen/DataSnapshot.java2
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/dbgen/ForceDeleteTool.java722
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/dbgen/GraphMLReaderNew.java353
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/dbgen/GraphMLTokens.java57
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/dbgen/GraphMLWriterNew.java358
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/dbgen/PropertyNameChange.java317
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/dbgen/SchemaMod.java441
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/dbgen/UpdateEdgeTags.java380
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/dmaap/AAIDmaapEventJMSConsumer.java2
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/migration/EventAction.java27
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/migration/NotificationHelper.java103
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/migration/VertexMerge.java245
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/rest/LegacyMoxyConsumer.java17
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/rest/RestTokens.java36
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/rest/retired/V7V8Models.java28
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/rest/retired/V7V8NamedQueries.java28
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/rest/ueb/NotificationEvent.java15
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/rest/ueb/UEBNotification.java10
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/util/DataConversionHelper.java63
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/util/DeleteResource.java22
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/util/GetResource.java30
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/util/HttpsAuthClient.java58
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/util/JettyObfuscationConversionCommandLineUtil.java99
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/util/PostResource.java27
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/util/PutResource.java84
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/util/RelationshipPutDel.java211
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/util/StoreNotificationEvent.java102
-rw-r--r--aai-resources/src/main/java/org/openecomp/aai/util/UpdateResource.java18
30 files changed, 4193 insertions, 95 deletions
diff --git a/aai-resources/src/main/java/org/openecomp/aai/dbgen/AddResourceVersionProp.java b/aai-resources/src/main/java/org/openecomp/aai/dbgen/AddResourceVersionProp.java
new file mode 100644
index 0000000..15c9b1e
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/dbgen/AddResourceVersionProp.java
@@ -0,0 +1,126 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.dbgen;
+
+
+import java.util.Iterator;
+import java.util.Properties;
+
+import org.openecomp.aai.dbmap.AAIGraph;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.logging.ErrorLogHelper;
+import org.openecomp.aai.util.AAIConfig;
+import org.openecomp.aai.util.AAIConstants;
+import com.att.eelf.configuration.Configuration;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanVertex;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+
+
+public class AddResourceVersionProp {
+
+
+ /**
+ * The main method.
+ *
+ * @param args the arguments
+ */
+ public static void main(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);
+
+ // NOTE -- This is a one-time migration for adding the new property "resource-version" to ALL of our nodes.
+ // Also -- since it's a one-time thing, we just re-use AAI_SCHEMA_MOD_LOG4J_PROPS
+
+ TitanGraph graph = null;
+
+ System.out.println(">>> WARNING: this script affects all nodes in the database. <<<< " );
+ System.out.println(">>> 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) {
+ System.out.println( " AddResourceVersionProp script has been aborted. ");
+ System.exit(1);
+ }
+
+ try {
+ AAIConfig.init();
+ ErrorLogHelper.loadProperties();
+
+ System.out.println(" ---- NOTE --- about to open graph (takes a little while)\n");
+
+ graph = AAIGraph.getInstance().getGraph();
+ if( graph == null ){
+ String emsg = "Not able to get a graph object in AddResourceVersionProp.java\n";
+ System.out.println( emsg );
+ System.exit(1);
+ }
+
+
+ // For each node in the db -- update the "resource-version" and the last mod timestamp.
+ Iterable<TitanVertex> verts = null;
+ verts= graph.query().vertices();
+ Iterator<TitanVertex> it = verts.iterator();
+ int vtxCount = 0;
+ long unixTimeNow = System.currentTimeMillis() / 1000L;
+ String timeNowInSec = "" + unixTimeNow;
+
+ while( it.hasNext() ){
+ vtxCount++;
+ TitanVertex tmpVtx = (TitanVertex)it.next();
+ tmpVtx.property( "aai-last-mod-ts", timeNowInSec );
+ tmpVtx.property( "resource-version", timeNowInSec );
+ }
+
+ System.out.println("Updated data for " + vtxCount + " vertexes. Now call graph.tx().commit(). ");
+ graph.tx().commit();
+
+ }
+ catch (AAIException e) {
+ System.out.print("Threw a AAIException: \n");
+ System.out.println(e.getErrorObject().toString());
+ }
+ catch (Exception ex) {
+ System.out.print("Threw a regular Exception:\n");
+ System.out.println(ex.getMessage());
+ }
+ finally {
+ if( graph != null ){
+ // Any changes that worked correctly should have already done their commits.
+ graph.tx().rollback();
+ graph.close();
+ }
+
+ }
+
+
+ System.exit(0);
+
+ }// End of main()
+
+
+}
+
+
diff --git a/aai-resources/src/main/java/org/openecomp/aai/dbgen/ChangePropertyCardinality.java b/aai-resources/src/main/java/org/openecomp/aai/dbgen/ChangePropertyCardinality.java
new file mode 100644
index 0000000..f92cfbc
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/dbgen/ChangePropertyCardinality.java
@@ -0,0 +1,307 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.dbgen;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.TimeZone;
+
+import org.openecomp.aai.dbmap.AAIGraph;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.ingestModel.DbMaps;
+import org.openecomp.aai.ingestModel.IngestModelMoxyOxm;
+import org.openecomp.aai.logging.ErrorLogHelper;
+import org.openecomp.aai.util.AAIConfig;
+import org.openecomp.aai.util.AAIConstants;
+import com.att.eelf.configuration.Configuration;
+import com.thinkaurelius.titan.core.Cardinality;
+import com.thinkaurelius.titan.core.PropertyKey;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanVertex;
+import com.thinkaurelius.titan.core.schema.TitanManagement;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+
+
+public class ChangePropertyCardinality {
+
+
+ /**
+ * The main method.
+ *
+ * @param args the arguments
+ */
+ public static void main(String[] args) {
+
+ //public static void ChangePropertyCardinality( 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);
+
+ // NOTE -- We're just working with properties that are used for NODES
+ String propName = "";
+ String targetDataType = "String";
+ String targetCardinality = "SET";
+ String preserveDataFlag = "false";
+ boolean preserveData = false;
+
+
+ String usageString = "Usage: ChangePropertyCardinality propertyName targetDataType targetCardinality preserveDataFlag \n";
+ if( args.length != 4 ){
+ String emsg = "Four Parameters are required. \n" + usageString;
+ System.out.println( emsg );
+ System.exit(1);
+ }
+ else {
+ propName = args[0];
+ targetDataType = args[1];
+ targetCardinality = args[2];
+ preserveDataFlag = args[3];
+ }
+
+ if( propName.equals("") ){
+ String emsg = "Bad parameter - propertyName cannot be empty. \n" + usageString;
+ System.out.println( emsg );
+ System.exit(1);
+ }
+ else if( !targetDataType.equals("String") ){
+ // && !targetDataType.equals("Integer")
+ // && !targetDataType.equals("Long")
+ // && !targetDataType.equals("Boolean") ){
+ // String emsg = "Unsupported targetDataType. We only support String, Integer, Long or Boolean for now.\n" + usageString;
+ String emsg = "Unsupported targetDataType. We only support String for now.\n" + usageString;
+ System.out.println( emsg );
+ System.exit(1);
+ }
+ else if( !targetCardinality.equals("SET") ){
+ // && !targetCardinality.equals("LIST")
+ // && !targetCardinality.equals("SINGLE") ){
+ String emsg = "Unsupported targetCardinality. We only support SET for now.\n" + usageString;
+ System.out.println( emsg );
+ System.exit(1);
+ }
+ else {
+ if( preserveDataFlag.equals("true") ){
+ preserveData = true;
+ String emsg = "Unsupported preserveDataFlag. For now, we only support: 'false'.\n" + usageString;
+ System.out.println( emsg );
+ System.exit(1);
+ }
+ else if (preserveDataFlag.equals("false") ){
+ preserveData = false;
+ }
+ else {
+ String emsg = "Unsupported preserveDataFlag. We only support: 'true' or 'false'.\n" + usageString;
+ System.out.println( emsg );
+ System.exit(1);
+ }
+ }
+
+ String targetDataTypeStr = "";
+ if( targetCardinality.equals("SINGLE") ){
+ targetDataTypeStr = targetDataType;
+ }
+ else if( targetCardinality.equals("SET") ){
+ targetDataTypeStr = "Set<" + targetDataType + ">";
+ }
+ else if( targetCardinality.equals("LIST") ){
+ targetDataTypeStr = "List<" + targetDataType + ">";
+ }
+
+ Class dType = null;
+ if(targetDataType.equals("String")){ dType = String.class; }
+ else if(targetDataType.equals("Integer")){ dType = Integer.class; }
+ else if(targetDataType.equals("Boolean")){ dType = Boolean.class; }
+ else if(targetDataType.equals("Character")){ dType = Character.class; }
+ else if(targetDataType.equals("Long")){ dType = Long.class; }
+ else if(targetDataType.equals("Float")){ dType = Float.class; }
+ else if(targetDataType.equals("Double")){ dType = Double.class; }
+
+ System.out.println("\n>> WARNING/NOTE - If the passed cardinality is not in synch with what is in the ex5.json file, ");
+ System.out.println("\n>> then this will cause problems when new environments are created.");
+
+ // Give a big warning if the DbMaps.PropertyDataTypeMap value does not agree with what we're doing
+ DbMaps dbMaps = null;
+ try {
+ dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+ }
+ catch( AAIException ae ){
+ String emsg = "Could not instantiate a copy of dbMaps. ";
+ System.out.println( emsg );
+ System.exit(1);
+ }
+
+ String warningMsg = "";
+ if( !dbMaps.PropertyDataTypeMap.containsKey(propName) ){
+ String emsg = "Property Name = [" + propName + "] not found in PropertyDataTypeMap. ";
+ System.out.println( emsg );
+ System.exit(1);
+ }
+ else {
+ String currentDataType = dbMaps.PropertyDataTypeMap.get(propName);
+ if( !currentDataType.equals(targetDataTypeStr) ){
+ warningMsg = "TargetDataType [" + targetDataTypeStr + "] does not match what is in DbMaps (" + currentDataType + ").";
+ }
+ }
+
+ if( !warningMsg.equals("") ){
+ System.out.println("\n>>> WARNING <<<< " );
+ System.out.println(">>> " + warningMsg + " <<<");
+ System.out.println(">>> !!! WARNING -- this change may be overwritten in some environments if <<<");
+ System.out.println(">>> !!! entries are out of synch with what is done with this script. <<<");
+ System.out.println(">>> WARNING <<<< " );
+ }
+
+ System.out.println(">>> 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) {
+ System.out.println( " DB Schema Update has been aborted. ");
+ System.exit(1);
+ }
+
+ TitanManagement graphMgt = null;
+ TitanGraph graph = null;
+ try {
+ AAIConfig.init();
+ ErrorLogHelper.loadProperties();
+
+ System.out.println(" ---- NOTE --- about to open graph (takes a little while)\n");
+
+ graph = AAIGraph.getInstance().getGraph();
+ if( graph == null ){
+ String emsg = "Not able to get a graph object in ChangePropertyCardinality.java\n";
+ System.out.println( emsg );
+ System.exit(1);
+ }
+
+ // Make sure this property is in the DB.
+ graphMgt = graph.openManagement();
+ if( graphMgt == null ){
+ String emsg = "Not able to get a graph Management object in ChangePropertyCardinality.java\n";
+ System.out.println( emsg );
+ System.exit(1);
+ }
+
+ PropertyKey origPropKey = graphMgt.getPropertyKey(propName);
+ if( origPropKey == null ){
+ // The old one wasn't there, so there's nothing to do
+ String emsg = "The propName = [" + propName + "] is not defined in our graph. ";
+ System.out.println( emsg );
+ System.exit(1);
+ }
+
+ if( origPropKey.cardinality().equals(Cardinality.valueOf(targetCardinality)) ){
+ // The existing one already has cardinality of what they're asking for.
+ String emsg = "The propName = [" + propName + "] already has Cardinality of [" + targetCardinality + "]. ";
+ System.out.println( emsg );
+ System.exit(0);
+ }
+
+ // Rename this property to a backup name (old name with "retired_" appended plus a dateStr)
+ SimpleDateFormat d = new SimpleDateFormat("MMddHHmm");
+ d.setTimeZone(TimeZone.getTimeZone("GMT"));
+ String dteStr = d.format(new Date()).toString();
+ 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(dType).cardinality(Cardinality.valueOf(targetCardinality)).make();
+
+ System.out.println("Committing schema changes with graphMgt.tx().commit()");
+ graphMgt.commit();
+ graph.tx().commit();
+ graph.close();
+
+
+ // Get A new graph object
+ System.out.println(" ---- NOTE --- about to open a second graph object (takes a little while)\n");
+
+ graph = AAIGraph.getInstance().getGraph();
+ if( graph == null ){
+ String emsg = "Not able to get a graph object in SchemaMod.java\n";
+ System.out.println( emsg );
+ System.exit(1);
+ }
+
+ // For each node that has this property, update the new from the old and then remove the
+ // old property from that node
+ // ---- NOTE ---- We're not preserving data at this point
+ Iterable<TitanVertex> verts = null;
+ verts= graph.query().has(retiredName).vertices();
+ Iterator<TitanVertex> it = verts.iterator();
+ int vtxCount = 0;
+ while( it.hasNext() ){
+ vtxCount++;
+ TitanVertex tmpVtx = (TitanVertex)it.next();
+ String tmpVid = tmpVtx.id().toString();
+
+ Object origVal = tmpVtx.property(retiredName).orElse(null);
+ if( preserveData ){
+ tmpVtx.property(propName,origVal);
+ System.out.println("INFO -- just did the add of the freshPropertyKey and updated it with the orig value (" +
+ origVal.toString() + ")");
+ }
+ else {
+ // existing nodes just won't have this property anymore
+ //
+ }
+ tmpVtx.property(retiredName).remove();
+ System.out.println("INFO -- just did the remove of the " + retiredName + " from this vertex. (vid=" + tmpVid + ")");
+ }
+
+ System.out.println("Updated data for " + vtxCount + " vertexes. Now call graph.tx().commit(). ");
+ graph.tx().commit();
+
+ }
+ catch (AAIException e) {
+ System.out.print("Threw a AAIException: \n");
+ System.out.println(e.getErrorObject().toString());
+ }
+ catch (Exception ex) {
+ System.out.print("Threw a regular Exception:\n");
+ System.out.println(ex.getMessage());
+ }
+ finally {
+ if( graphMgt != null && graphMgt.isOpen() ){
+ // Any changes that worked correctly should have already done their commits.
+ graphMgt.rollback();
+ }
+ if( graph != null ){
+ // Any changes that worked correctly should have already done their commits.
+ graph.tx().rollback();
+ graph.close();
+ }
+
+ }
+
+ System.exit(0);
+
+ }// End of main()
+
+
+}
+
+
diff --git a/aai-resources/src/main/java/org/openecomp/aai/dbgen/DataSnapshot.java b/aai-resources/src/main/java/org/openecomp/aai/dbgen/DataSnapshot.java
index 68bebc2..d03a5e3 100644
--- a/aai-resources/src/main/java/org/openecomp/aai/dbgen/DataSnapshot.java
+++ b/aai-resources/src/main/java/org/openecomp/aai/dbgen/DataSnapshot.java
@@ -277,4 +277,4 @@ public class DataSnapshot {
}// End of main()
-}
+}
diff --git a/aai-resources/src/main/java/org/openecomp/aai/dbgen/ForceDeleteTool.java b/aai-resources/src/main/java/org/openecomp/aai/dbgen/ForceDeleteTool.java
new file mode 100644
index 0000000..20d5c9f
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/dbgen/ForceDeleteTool.java
@@ -0,0 +1,722 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.dbgen;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Scanner;
+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.slf4j.MDC;
+
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.util.AAIConfig;
+import org.openecomp.aai.util.AAIConstants;
+import com.att.eelf.configuration.Configuration;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.thinkaurelius.titan.core.TitanEdge;
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanGraphQuery;
+import com.thinkaurelius.titan.core.TitanVertex;
+
+
+
+public class ForceDeleteTool {
+
+
+ private static final int MAXDESCENDENTDEPTH = 15;
+
+ /**
+ * The main method.
+ *
+ * @param args the arguments
+ */
+ public static void main(String[] args) {
+
+ //SWGK 01/21/2016 - To suppress the warning message when the tool is run from the Terminal.
+
+ // Set the logging file properties to be used by EELFManager
+ Properties props = System.getProperties();
+ props.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, "forceDelete-logback.xml");
+ props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES);
+ EELFLogger logger = EELFManager.getInstance().getLogger(ForceDeleteTool.class.getSimpleName());
+ MDC.put("logFilenameAppender", ForceDeleteTool.class.getSimpleName());
+
+ String actionVal = "";
+ String userIdVal = "";
+ String dataString = "";
+ Boolean displayAllVidsFlag = false; // Note - This should rarely be needed
+ Boolean overRideProtection = false; // This should rarely be used - it overrides all our new checking
+ long vertexIdLong = 0;
+ String edgeIdStr = "";
+ String argStr4Msg = "";
+
+ if (args != null && args.length > 0) {
+ // They passed some arguments in that will affect processing
+ for (int i = 0; i < args.length; i++) {
+ String thisArg = args[i];
+ argStr4Msg = argStr4Msg + " " + thisArg;
+
+ if (thisArg.equals("-action")) {
+ i++;
+ if (i >= args.length) {
+ logger.error(" No value passed with -action option. ");
+ System.exit(0);
+ }
+ actionVal = args[i];
+ argStr4Msg = argStr4Msg + " " + actionVal;
+ }
+ else if (thisArg.equals("-userId")) {
+ i++;
+ if (i >= args.length) {
+ logger.error(" No value passed with -userId option. ");
+ System.exit(0);
+ }
+ userIdVal = args[i];
+ argStr4Msg = argStr4Msg + " " + userIdVal;
+ }
+ else if (thisArg.equals("-overRideProtection")) {
+ overRideProtection = true;
+ }
+ else if (thisArg.equals("-DISPLAY_ALL_VIDS")) {
+ displayAllVidsFlag = true;
+ }
+ else if (thisArg.equals("-vertexId")) {
+ i++;
+ if (i >= args.length) {
+ logger.error(" No value passed with -vertexId option. ");
+ System.exit(0);
+ }
+ String nextArg = args[i];
+ argStr4Msg = argStr4Msg + " " + nextArg;
+ try {
+ vertexIdLong = Long.parseLong(nextArg);
+ } catch (Exception e) {
+ logger.error("Bad value passed with -vertexId option: ["
+ + nextArg + "]");
+ System.exit(0);
+ }
+ }
+ else if (thisArg.equals("-params4Collect")) {
+ i++;
+ if (i >= args.length) {
+ logger.error(" No value passed with -params4Collect option. ");
+ System.exit(0);
+ }
+ dataString = args[i];
+ argStr4Msg = argStr4Msg + " " + dataString;
+ }
+ else if (thisArg.equals("-edgeId")) {
+ i++;
+ if (i >= args.length) {
+ logger.error(" No value passed with -edgeId option. ");
+ System.exit(0);
+ }
+ String nextArg = args[i];
+ argStr4Msg = argStr4Msg + " " + nextArg;
+ edgeIdStr = nextArg;
+ }
+ else {
+ logger.error(" Unrecognized argument passed to ForceDeleteTool: ["
+ + thisArg + "]. ");
+ logger.error(" Valid values are: -action -userId -vertexId -edgeId -overRideProtection -params4Collect -DISPLAY_ALL_VIDS");
+ System.exit(0);
+ }
+ }
+ }
+
+ if( !actionVal.equals("COLLECT_DATA") && !actionVal.equals("DELETE_NODE") && !actionVal.equals("DELETE_EDGE")){
+ String emsg = "Bad action parameter [" + actionVal + "] passed to ForceDeleteTool(). Valid values = COLLECT_DATA or DELETE_NODE or DELETE_EDGE\n";
+ System.out.println(emsg);
+ logger.error(emsg);
+ System.exit(0);
+ }
+
+ if( actionVal.equals("DELETE_NODE") && vertexIdLong == 0 ){
+ String emsg = "ERROR: No vertex ID passed on DELETE_NODE request. \n";
+ System.out.println(emsg);
+ logger.error(emsg);
+ System.exit(0);
+ }
+ else if( actionVal.equals("DELETE_EDGE") && edgeIdStr.equals("")){
+ String emsg = "ERROR: No edge ID passed on DELETE_EDGE request. \n";
+ System.out.println(emsg);
+ logger.error(emsg);
+ System.exit(0);
+ }
+
+
+ userIdVal = userIdVal.trim();
+ if( (userIdVal.length() < 6) || userIdVal.toUpperCase().equals("AAIADMIN") ){
+ String emsg = "Bad userId parameter [" + userIdVal + "] passed to ForceDeleteTool(). must be not empty and not aaiadmin \n";
+ System.out.println(emsg);
+ logger.error(emsg);
+ System.exit(0);
+ }
+
+ String msg = "";
+ TitanGraph graph = null;
+ try {
+ AAIConfig.init();
+ System.out.println(" ---- NOTE --- about to open graph (takes a little while)--------\n");
+ graph = TitanFactory.open(AAIConstants.REALTIME_DB_CONFIG);
+ if( graph == null ){
+ String emsg = "could not get graph object in ForceDeleteTool() \n";
+ System.out.println(emsg);
+ logger.error(emsg);
+ System.exit(0);
+ }
+ }
+ catch (AAIException e1) {
+ msg = e1.getErrorObject().toString();
+ System.out.println(msg);
+ logger.error(msg);
+ System.exit(0);
+ }
+ catch (Exception e2) {
+ msg = e2.toString();
+ System.out.println(msg);
+ logger.error(msg);
+ System.exit(0);
+ }
+
+ msg = "ForceDelete called by: userId [" + userIdVal + "] with these params: [" + argStr4Msg + "]";
+ System.out.println(msg);
+ logger.info(msg);
+
+
+ if( actionVal.equals("COLLECT_DATA") ){
+ // When doing COLLECT_DATA, we expect the dataString string to be comma separated
+ // name value pairs like this:
+ // "propName1|propVal1,propName2|propVal2" etc. We will look for a node or nodes
+ // that have properties that ALL match what was passed in.
+
+ int resCount = 0;
+ int firstPipeLoc = dataString.indexOf("|");
+ if( firstPipeLoc <= 0 ){
+ msg = "Must use the -params4Collect option when collecting data with data string in a format like: 'propName1|propVal1,propName2|propVal2'";
+ System.out.println(msg);
+ logger.error(msg);
+ System.exit(0);
+ }
+ TitanGraphQuery tgQ = graph.query();
+ String qStringForMsg = " graph.query()";
+ // Note - if they're only passing on parameter, there won't be any commas
+ String [] paramArr = dataString.split(",");
+ for( int i = 0; i < paramArr.length; i++ ){
+ int pipeLoc = paramArr[i].indexOf("|");
+ if( pipeLoc <= 0 ){
+ msg = "Must use the -params4Collect option when collecting data with data string in a format like: 'propName1|propVal1,propName2|propVal2'";
+ System.out.println(msg);
+ logger.error(msg);
+ System.exit(0);
+ }
+ else {
+ String propName = paramArr[i].substring(0,pipeLoc);
+ String propVal = paramArr[i].substring(pipeLoc + 1);
+ tgQ = tgQ.has(propName,propVal);
+ qStringForMsg = qStringForMsg + ".has(" + propName + "," + propVal + ")";
+ }
+ }
+ if( (tgQ != null) && (tgQ instanceof TitanGraphQuery) ){
+ Iterable <TitanVertex> verts = (Iterable<TitanVertex>) tgQ.vertices();
+ Iterator <TitanVertex> vertItor = verts.iterator();
+ while( vertItor.hasNext() ){
+ resCount++;
+ TitanVertex v = (TitanVertex)vertItor.next();
+ showNodeInfo( logger, v, displayAllVidsFlag );
+ int descendantCount = countDescendants( logger, v, 0 );
+ String infMsg = " Found " + descendantCount + " descendant nodes \n";
+ System.out.println( infMsg );
+ logger.info( infMsg );
+ }
+ }
+ else {
+ msg = "Bad TitanGraphQuery object. ";
+ System.out.println(msg);
+ logger.error(msg);
+ System.exit(0);
+ }
+
+ String infMsg = "\n\n Found: " + resCount + " nodes for this query: [" + qStringForMsg + "]\n";
+ System.out.println( infMsg );
+ logger.info( infMsg );
+ }
+ else if( actionVal.equals("DELETE_NODE") ){
+ Iterator <Vertex> vtxItr = graph.vertices( vertexIdLong );
+ if( vtxItr != null && vtxItr.hasNext() ) {
+ Vertex vtx = vtxItr.next();
+ showNodeInfo( logger, vtx, displayAllVidsFlag );
+ int descendantCount = countDescendants( logger, (TitanVertex)vtx, 0 );
+ String infMsg = " Found " + descendantCount + " descendant nodes. Note - forceDelete does not cascade to " +
+ " child nodes, but they may become unreachable after the delete. \n";
+ System.out.println( infMsg );
+ logger.info( infMsg );
+
+ int edgeCount = countEdges( logger, vtx );
+
+ infMsg = " Found total of " + edgeCount + " edges incident on this node. \n";
+ System.out.println( infMsg );
+ logger.info( infMsg );
+
+ if( getNodeDelConfirmation(logger, userIdVal, vtx, descendantCount, edgeCount, overRideProtection) ){
+ vtx.remove();
+ graph.tx().commit();
+ infMsg = ">>>>>>>>>> Removed node with vertexId = " + vertexIdLong;
+ logger.info( infMsg );
+ System.out.println(infMsg);
+ }
+ else {
+ infMsg = " Delete Cancelled. ";
+ System.out.println(infMsg);
+ logger.info( infMsg );
+ }
+ }
+ else {
+ String infMsg = ">>>>>>>>>> Vertex with vertexId = " + vertexIdLong + " not found.";
+ System.out.println( infMsg );
+ logger.info( infMsg );
+ }
+ }
+ else if( actionVal.equals("DELETE_EDGE") ){
+ TitanEdge thisEdge = null;
+ Iterator <Edge> edItr = graph.edges( edgeIdStr );
+ if( edItr != null && edItr.hasNext() ) {
+ thisEdge = (TitanEdge)edItr.next();
+ }
+
+ if( thisEdge == null ){
+ String infMsg = ">>>>>>>>>> Edge with edgeId = " + edgeIdStr + " not found.";
+ logger.info( infMsg );
+ System.out.println(infMsg);
+ System.exit(0);
+ }
+
+ if( getEdgeDelConfirmation(logger, userIdVal, thisEdge, overRideProtection) ){
+ thisEdge.remove();
+ graph.tx().commit();
+ String infMsg = ">>>>>>>>>> Removed edge with edgeId = " + edgeIdStr;
+ logger.info( infMsg );
+ System.out.println(infMsg);
+ }
+ else {
+ String infMsg = " Delete Cancelled. ";
+ System.out.println(infMsg);
+ logger.info( infMsg );
+ }
+ System.exit(0);
+ }
+ else {
+ String emsg = "Unknown action parameter [" + actionVal + "] passed to ForceDeleteTool(). Valid values = COLLECT_DATA, DELETE_NODE or DELETE_EDGE \n";
+ System.out.println(emsg);
+ logger.info( emsg );
+ System.exit(0);
+ }
+
+ System.exit(0);
+
+ }// end of main()
+
+
+ public static void showNodeInfo(EELFLogger logger, Vertex tVert, Boolean displayAllVidsFlag ){
+
+ try {
+ Iterator<VertexProperty<Object>> pI = tVert.properties();
+ String infStr = ">>> Found Vertex with VertexId = " + tVert.id() + ", properties: ";
+ System.out.println( infStr );
+ logger.info(infStr);
+ while( pI.hasNext() ){
+ VertexProperty<Object> tp = pI.next();
+ infStr = " [" + tp.key() + "|" + tp.value() + "] ";
+ System.out.println( infStr );
+ logger.info(infStr);
+ }
+
+ ArrayList <String> retArr = collectEdgeInfoForNode( logger, tVert, displayAllVidsFlag );
+ for( String infoStr : retArr ){
+ System.out.println( infoStr );
+ logger.info(infoStr);
+ }
+ }
+ catch (Exception e){
+ String warnMsg = " -- Error -- trying to display edge info. [" + e.getMessage() + "]";
+ System.out.println( warnMsg );
+ logger.warn(warnMsg);
+ }
+
+ }// End of showNodeInfo()
+
+
+ public static void showPropertiesForEdge( EELFLogger logger, TitanEdge tEd ){
+ String infMsg = "";
+ if( tEd == null ){
+ infMsg = "null Edge object passed to showPropertiesForEdge()";
+ System.out.print(infMsg);
+ logger.info(infMsg);
+ return;
+ }
+
+ // Try to show the edge properties
+ try {
+ infMsg =" Label for this Edge = [" + tEd.label() + "] ";
+ System.out.print(infMsg);
+ logger.info(infMsg);
+
+ infMsg =" EDGE Properties for edgeId = " + tEd.id() + ": ";
+ System.out.print(infMsg);
+ logger.info(infMsg);
+ Iterator <String> pI = tEd.keys().iterator();
+ while( pI.hasNext() ){
+ String propKey = pI.next();
+ infMsg = "Prop: [" + propKey + "], val = ["
+ + tEd.property(propKey) + "] ";
+ System.out.print(infMsg);
+ logger.info(infMsg);
+ }
+ }
+ catch( Exception ex ){
+ infMsg = " Could not retrieve properties for this edge. exMsg = ["
+ + ex.getMessage() + "] ";
+ System.out.println( infMsg );
+ logger.info(infMsg);
+ }
+
+ // Try to show what's connected to the IN side of this Edge
+ try {
+ infMsg = " Looking for the Vertex on the IN side of the edge: ";
+ System.out.print(infMsg);
+ logger.info(infMsg);
+ TitanVertex inVtx = tEd.inVertex();
+ Iterator<VertexProperty<Object>> pI = inVtx.properties();
+ String infStr = ">>> Found Vertex with VertexId = " + inVtx.id()
+ + ", properties: ";
+ System.out.println( infStr );
+ logger.info(infStr);
+ while( pI.hasNext() ){
+ VertexProperty<Object> tp = pI.next();
+ infStr = " [" + tp.key() + "|" + tp.value() + "] ";
+ System.out.println( infStr );
+ logger.info(infStr);
+ }
+ }
+ catch( Exception ex ){
+ infMsg = " Could not retrieve vertex data for the IN side of "
+ + "the edge. exMsg = [" + ex.getMessage() + "] ";
+ System.out.println( infMsg );
+ logger.info(infMsg);
+ }
+
+ // Try to show what's connected to the OUT side of this Edge
+ try {
+ infMsg = " Looking for the Vertex on the OUT side of the edge: ";
+ System.out.print(infMsg);
+ logger.info(infMsg);
+ TitanVertex outVtx = tEd.outVertex();
+ Iterator<VertexProperty<Object>> pI = outVtx.properties();
+ String infStr = ">>> Found Vertex with VertexId = " + outVtx.id()
+ + ", properties: ";
+ System.out.println( infStr );
+ logger.info(infStr);
+ while( pI.hasNext() ){
+ VertexProperty<Object> tp = pI.next();
+ infStr = " [" + tp.key() + "|" + tp.value() + "] ";
+ System.out.println( infStr );
+ logger.info(infStr);
+ }
+ }
+ catch( Exception ex ){
+ infMsg = " Could not retrieve vertex data for the OUT side of "
+ + "the edge. exMsg = [" + ex.getMessage() + "] ";
+ System.out.println( infMsg );
+ logger.info(infMsg);
+ }
+
+ }// end showPropertiesForEdge()
+
+
+
+ public static ArrayList <String> collectEdgeInfoForNode( EELFLogger logger, Vertex tVert, boolean displayAllVidsFlag ){
+ ArrayList <String> retArr = new ArrayList <String> ();
+ Direction dir = Direction.OUT;
+ for ( int i = 0; i <= 1; i++ ){
+ if( i == 1 ){
+ // Second time through we'll look at the IN edges.
+ dir = Direction.IN;
+ }
+ Iterator <Edge> eI = tVert.edges(dir);
+ if( ! eI.hasNext() ){
+ retArr.add("No " + dir + " edges were found for this vertex. ");
+ }
+ while( eI.hasNext() ){
+ Edge ed = eI.next();
+ String lab = ed.label();
+ Vertex vtx = null;
+ if( dir == Direction.OUT ){
+ // get the vtx on the "other" side
+ vtx = ed.inVertex();
+ }
+ else {
+ // get the vtx on the "other" side
+ vtx = ed.outVertex();
+ }
+ if( vtx == null ){
+ retArr.add(" >>> 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);
+ if( displayAllVidsFlag ){
+ // This should rarely be needed
+ String vid = vtx.id().toString();
+ retArr.add("Found an " + dir + " edge (" + lab + ") between this vertex and a [" + nType + "] node with VtxId = " + vid );
+ }
+ else {
+ // This is the normal case
+ retArr.add("Found an " + dir + " edge (" + lab + ") between this vertex and a [" + nType + "] node. ");
+ }
+ }
+ }
+ }
+ return retArr;
+
+ }// end of collectEdgeInfoForNode()
+
+
+ public static int countEdges( EELFLogger logger, Vertex vtx ){
+ int edgeCount = 0;
+ try {
+ Iterator<Edge> edgesItr = vtx.edges(Direction.BOTH);
+ while( edgesItr.hasNext() ){
+ edgesItr.next();
+ edgeCount++;
+ }
+ }
+ catch (Exception e) {
+ String wMsg = "-- ERROR -- Stopping the counting of edges because of Exception [" + e.getMessage() + "]";
+ System.out.println( wMsg );
+ logger.warn( wMsg );
+ }
+ return edgeCount;
+
+ }// end of countEdges()
+
+
+ public static int countDescendants(EELFLogger logger, TitanVertex vtx, int levelVal ){
+ int totalCount = 0;
+ int thisLevel = levelVal + 1;
+
+ if( thisLevel > MAXDESCENDENTDEPTH ){
+ String wMsg = "Warning -- Stopping the counting of descendents because we reached the max depth of " + MAXDESCENDENTDEPTH;
+ System.out.println( wMsg );
+ logger.warn( wMsg );
+ return totalCount;
+ }
+
+ try {
+ Iterable <?> verts = vtx.query().direction(Direction.OUT).has("isParent",true).vertices();
+ Iterator <?> vertI = verts.iterator();
+ while( vertI != null && vertI.hasNext() ){
+ totalCount++;
+ TitanVertex childVtx = (TitanVertex) vertI.next();
+ totalCount = totalCount + countDescendants( logger, childVtx, thisLevel );
+ }
+ }
+ catch (Exception e) {
+ String wMsg = "Error -- Stopping the counting of descendents because of Exception [" + e.getMessage() + "]";
+ System.out.println( wMsg );
+ logger.warn( wMsg );
+ }
+
+ return totalCount;
+ }// end of countDescendants()
+
+
+ public static boolean getEdgeDelConfirmation( EELFLogger logger, String uid, TitanEdge ed,
+ Boolean overRideProtection ) {
+
+ showPropertiesForEdge( logger, ed );
+ System.out.print("\n Are you sure you want to delete this EDGE? (y/n): ");
+ Scanner s = new Scanner(System.in);
+ s.useDelimiter("");
+ String confirm = s.next();
+ s.close();
+
+ if (!confirm.equalsIgnoreCase("y")) {
+ String infMsg = " User [" + uid + "] has chosen to abandon this delete request. ";
+ System.out.println("\n" + infMsg);
+ logger.info(infMsg);
+ return false;
+ }
+ else {
+ String infMsg = " User [" + uid + "] has confirmed this delete request. ";
+ System.out.println("\n" + infMsg);
+ logger.info(infMsg);
+ return true;
+ }
+
+ } // End of getEdgeDelConfirmation()
+
+
+ public static boolean getNodeDelConfirmation( EELFLogger logger, String uid, Vertex vtx, int edgeCount,
+ int descendantCount, Boolean overRideProtection ) {
+ String thisNodeType = "";
+ try {
+ thisNodeType = vtx.<String>property("aai-node-type").orElse(null);
+ }
+ catch ( Exception nfe ){
+ // Let the user know something is going on - but they can confirm the delete if they want to.
+ String infMsg = " -- WARNING -- could not get an aai-node-type for this vertex. -- WARNING -- ";
+ System.out.println( infMsg );
+ logger.warn( infMsg );
+ }
+
+ String ntListString = "";
+ String maxDescString = "";
+ String maxEdgeString = "";
+
+ int maxDescCount = 10; // default value
+ int maxEdgeCount = 10; // default value
+ ArrayList <String> protectedNTypes = new ArrayList <String> ();
+ protectedNTypes.add("cloud-region"); // default value
+
+ try {
+ ntListString = AAIConfig.get("aai.forceDel.protected.nt.list");
+ maxDescString = AAIConfig.get("aai.forceDel.protected.descendant.count");
+ maxEdgeString = AAIConfig.get("aai.forceDel.protected.edge.count");
+ }
+ catch ( Exception nfe ){
+ // Don't worry, we will use default values
+ String infMsg = "-- WARNING -- could not get aai.forceDel.protected values from aaiconfig.properties -- will use default values. ";
+ System.out.println( infMsg );
+ logger.warn( infMsg );
+ }
+
+ if( maxDescString != null && !maxDescString.equals("") ){
+ try {
+ maxDescCount = Integer.parseInt(maxDescString);
+ }
+ catch ( Exception nfe ){
+ // Don't worry, we will leave "maxDescCount" set to the default value
+ }
+ }
+
+ if( maxEdgeString != null && !maxEdgeString.equals("") ){
+ try {
+ maxEdgeCount = Integer.parseInt(maxEdgeString);
+ }
+ catch ( Exception nfe ){
+ // Don't worry, we will leave "maxEdgeCount" set to the default value
+ }
+ }
+
+ if( ntListString != null && !ntListString.trim().equals("") ){
+ String [] nodeTypes = ntListString.split("\\|");
+ for( int i = 0; i < nodeTypes.length; i++ ){
+ protectedNTypes.add(nodeTypes[i]);
+ }
+ }
+
+ boolean giveProtOverRideMsg = false;
+ boolean giveProtErrorMsg = false;
+ if( descendantCount > maxDescCount ){
+ // They are trying to delete a node with a lots of descendants
+ String infMsg = " >> WARNING >> This node has more descendant edges than the max ProtectedDescendantCount: " + edgeCount + ". Max = " +
+ maxEdgeCount + ". It can be DANGEROUS to delete one of these. << WARNING << ";
+ System.out.println(infMsg);
+ logger.info(infMsg);
+ if( ! overRideProtection ){
+ // They cannot delete this kind of node without using the override option
+ giveProtErrorMsg = true;
+ }
+ else {
+ giveProtOverRideMsg = true;
+ }
+ }
+
+ if( edgeCount > maxEdgeCount ){
+ // They are trying to delete a node with a lot of edges
+ String infMsg = " >> WARNING >> This node has more edges than the max ProtectedEdgeCount: " + edgeCount + ". Max = " +
+ maxEdgeCount + ". It can be DANGEROUS to delete one of these. << WARNING << ";
+ System.out.println(infMsg);
+ logger.info(infMsg);
+ if( ! overRideProtection ){
+ // They cannot delete this kind of node without using the override option
+ giveProtErrorMsg = true;
+ }
+ else {
+ giveProtOverRideMsg = true;
+ }
+ }
+
+ if( thisNodeType != null && !thisNodeType.equals("") && protectedNTypes.contains(thisNodeType) ){
+ // They are trying to delete a protected Node Type
+ String infMsg = " >> WARNING >> This node is a PROTECTED NODE-TYPE (" + thisNodeType + "). " +
+ " It can be DANGEROUS to delete one of these. << WARNING << ";
+ System.out.println(infMsg);
+ logger.info(infMsg);
+ if( ! overRideProtection ){
+ // They cannot delete this kind of node without using the override option
+ giveProtErrorMsg = true;
+ }
+ else {
+ giveProtOverRideMsg = true;
+ }
+ }
+
+ if( giveProtOverRideMsg ){
+ String infMsg = " !!>> WARNING >>!! you are using the overRideProtection parameter which will let you do this potentially dangerous delete.";
+ System.out.println("\n" + infMsg);
+ logger.info(infMsg);
+ }
+ else if( giveProtErrorMsg ) {
+ String errMsg = " ERROR >> this kind of node can only be deleted if you pass the overRideProtection parameter.";
+ System.out.println("\n" + errMsg);
+ logger.error(errMsg);
+ return false;
+ }
+
+ System.out.print("\n Are you sure you want to do this delete? (y/n): ");
+ Scanner s = new Scanner(System.in);
+ s.useDelimiter("");
+ String confirm = s.next();
+ s.close();
+
+ if (!confirm.equalsIgnoreCase("y")) {
+ String infMsg = " User [" + uid + "] has chosen to abandon this delete request. ";
+ System.out.println("\n" + infMsg);
+ logger.info(infMsg);
+ return false;
+ }
+ else {
+ String infMsg = " User [" + uid + "] has confirmed this delete request. ";
+ System.out.println("\n" + infMsg);
+ logger.info(infMsg);
+ return true;
+ }
+
+ } // End of getNodeDelConfirmation()
+
+}
+
+
diff --git a/aai-resources/src/main/java/org/openecomp/aai/dbgen/GraphMLReaderNew.java b/aai-resources/src/main/java/org/openecomp/aai/dbgen/GraphMLReaderNew.java
new file mode 100644
index 0000000..4f3fee0
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/dbgen/GraphMLReaderNew.java
@@ -0,0 +1,353 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.dbgen;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.reflect.Array;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.events.XMLEvent;
+
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+
+//import com.infrasight.model.UnicodeUtil;
+import com.thinkaurelius.titan.core.TitanGraph;
+
+/**
+ * GraphMLReader writes the data from a GraphML stream to a graph.
+ */
+public class GraphMLReaderNew {
+ public static final Charset charset = Charset.forName("UTF8");
+
+ /**
+ * Input the GraphML stream data into the graph.
+ * In practice, usually the provided graph is empty.
+ *
+ * @param graph the graph to populate with the GraphML data
+ * @param titanGraph the titan graph
+ * @param graphMLInputStream an InputStream of GraphML data
+ * @return the map
+ * @throws XMLStreamException thrown when the GraphML data is not correctly formatted
+ */
+ public static Map<String, Object> inputGraph(final Graph graph, final TitanGraph titanGraph, final InputStream graphMLInputStream) throws XMLStreamException {
+ return inputGraph(graph, titanGraph, new InputStreamReader(graphMLInputStream, charset), 1000);
+ }
+
+/* public static void inputGraphFiltered(final Graph graph, final InputStream graphMLInputStream) throws XMLStreamException {
+ inputGraph(graph, UnicodeUtil.createFilteredReader(new InputStreamReader(graphMLInputStream, charset)), 1000);
+ }*/
+
+ private static class KeySpec {
+ String attrName;
+ String attrType;
+
+ /**
+ * Instantiates a new key spec.
+ *
+ * @param name the name
+ * @param type the type
+ */
+ public KeySpec(String name, String type) {
+ this.attrName = name;
+ this.attrType = type;
+ }
+ }
+
+ /**
+ * Input the GraphML stream data into the graph.
+ * More control over how data is streamed is provided by this method.
+ *
+ * @param graph the graph to populate with the GraphML data
+ * @param titanGraph the titan graph
+ * @param inputReader an Reader of GraphML character data
+ * @param bufferSize the amount of elements to hold in memory before committing a transactions (only valid for TransactionalGraphs)
+ * @return the map
+ * @throws XMLStreamException thrown when the GraphML data is not correctly formatted
+ */
+ public static Map<String, Object> inputGraph(final Graph graph, final TitanGraph titanGraph, final Reader inputReader, int bufferSize) throws XMLStreamException {
+
+ XMLInputFactory inputFactory = XMLInputFactory.newInstance();
+ inputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
+ inputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(inputReader);
+
+ //final BatchGraph<?> graph = BatchGraph.wrap(inputGraph, bufferSize);
+
+ Map<String, KeySpec> keyMap = new HashMap<String, KeySpec>();
+
+ // Buffered Vertex Data
+ String vertexId = null;
+ Map<String, Object> vertexProps = null;
+ boolean inVertex = false;
+
+ // Buffered Edge Data
+ String edgeId = null;
+ String edgeLabel = null;
+ Vertex edgeInVertex = null;
+ Vertex edgeOutVertex = null;
+ Map<String, Object> edgeProps = null;
+ boolean inEdge = false;
+ Map<String, Object> vertexIdSetMap = new HashMap<String, Object>();
+
+ while (reader.hasNext()) {
+
+ Integer eventType = reader.next();
+ if (eventType.equals(XMLEvent.START_ELEMENT)) {
+ String elementName = reader.getName().getLocalPart();
+
+ if (elementName.equals(GraphMLTokens.KEY)) {
+ String id = reader.getAttributeValue(null, GraphMLTokens.ID);
+ String attributeName = reader.getAttributeValue(null, GraphMLTokens.ATTR_NAME);
+ String attributeType = reader.getAttributeValue(null, GraphMLTokens.ATTR_TYPE);
+ keyMap.put(id, new KeySpec(attributeName, attributeType));
+
+ } else if (elementName.equals(GraphMLTokens.NODE)) {
+ vertexId = reader.getAttributeValue(null, GraphMLTokens.ID);
+ inVertex = true;
+ vertexProps = new HashMap<String, Object>();
+
+ } else if (elementName.equals(GraphMLTokens.EDGE)) {
+
+
+ edgeId = reader.getAttributeValue(null, GraphMLTokens.ID);
+ edgeLabel = reader.getAttributeValue(null, GraphMLTokens.LABEL);
+ edgeLabel = edgeLabel == null ? GraphMLTokens._DEFAULT : edgeLabel;
+
+ String outVertexId = reader.getAttributeValue(null, GraphMLTokens.SOURCE);
+ String inVertexId = reader.getAttributeValue(null, GraphMLTokens.TARGET);
+
+ edgeOutVertex = graph.vertices(outVertexId).next();
+ edgeInVertex = graph.vertices(inVertexId).next();
+
+ if (null == edgeOutVertex) {
+ edgeOutVertex = graph.addVertex(outVertexId);
+ }
+ if (null == edgeInVertex) {
+ edgeInVertex = graph.addVertex(inVertexId);
+ }
+
+ inEdge = true;
+ edgeProps = new HashMap<String, Object>();
+
+ } else if (elementName.equals(GraphMLTokens.DATA)) {
+ String key = reader.getAttributeValue(null, GraphMLTokens.KEY);
+ KeySpec keySpec = keyMap.get(key);
+
+ if (keySpec != null) {
+ Object value = readData(reader, keySpec.attrType);
+ if(value == null)
+ throw new RuntimeException("Empty data");
+ if (inVertex == true) {
+ vertexProps.put(keySpec.attrName, value);
+ } else if (inEdge == true) {
+ edgeProps.put(keySpec.attrName, value);
+ }
+ }
+
+ }
+ } else if (eventType.equals(XMLEvent.END_ELEMENT)) {
+ String elementName = reader.getName().getLocalPart();
+
+ if (elementName.equals(GraphMLTokens.NODE)) {
+
+ Vertex currentVertex = graph.vertices(vertexId).next();
+ if (currentVertex != null)
+ throw new RuntimeException("Duplicate vertex ID: "+vertexId);
+ currentVertex = graph.addVertex(vertexId);
+ Boolean hasCollection = false;
+ for (Entry<String, Object> prop : vertexProps.entrySet()) {
+ // multi-properties need a addProperty and need to use a TitanVertex - BluePrint
+ // Vertex does not support this
+ Object value = prop.getValue();
+ if (value instanceof Collection) {
+ hasCollection = true;
+ vertexIdSetMap.put(currentVertex.id().toString() + "." + prop.getKey(), vertexProps);
+ currentVertex.property("has-collection", "true");
+ } else {
+ currentVertex.property(prop.getKey(), value);
+ }
+ }
+ if (hasCollection)
+ System.out.println("---Found node with SET property vertex id:" + vertexId + " properties:" + vertexProps.toString());
+ vertexId = null;
+ vertexProps = null;
+ inVertex = false;
+ } else if (elementName.equals(GraphMLTokens.EDGE)) {
+ Edge currentEdge = edgeOutVertex.addEdge(edgeLabel, edgeInVertex);
+ //addEdge(edgeId, edgeOutVertex, edgeInVertex, edgeLabel);
+
+ for (Entry<String, Object> prop : edgeProps.entrySet()) {
+ currentEdge.property(prop.getKey(), prop.getValue());
+ }
+
+ edgeId = null;
+ edgeLabel = null;
+ edgeInVertex = null;
+ edgeOutVertex = null;
+ edgeProps = null;
+ inEdge = false;
+ }
+
+ }
+
+ }
+
+ reader.close();
+ graph.tx().close();
+
+ return vertexIdSetMap;
+
+ }
+
+ /**
+ * Read data.
+ *
+ * @param reader the reader
+ * @param type the type
+ * @return the object
+ * @throws XMLStreamException the XML stream exception
+ */
+ private static Object readData(XMLStreamReader reader, String type) throws XMLStreamException {
+ Collection<Object> col = new ArrayList<Object>();
+
+ int pos = type.indexOf('-');
+ if(pos < 0)
+ return typeCastValue(reader.getElementText(), type);
+ String arrayType = type.substring(0, pos);
+ type = type.substring(pos+1);
+
+ boolean done = false;
+ while(!done) {
+ Integer eventType = reader.next();
+ if(eventType.equals(XMLEvent.START_ELEMENT)) {
+ String text = reader.getElementText();
+ Object value = typeCastValue(text, type);
+ col.add(value);
+ }
+ if(eventType.equals(XMLEvent.END_ELEMENT)) {
+ String elementName = reader.getName().getLocalPart();
+ if(elementName.equals(GraphMLTokens.DATA)) {
+ done = true;
+ continue;
+ }
+ }
+ }
+
+ if(arrayType.equals(GraphMLTokens.ARRAY)) {
+ Object arr = Array.newInstance(typeToClass(type), col.size());
+ int i = 0;
+ for(Object obj : col) {
+ Array.set(arr, i, obj);
+ i++;
+ }
+ return arr;
+ }
+ else if(arrayType.equals(GraphMLTokens.SET))
+ return new HashSet<Object>(col);
+ else if(type.startsWith(GraphMLTokens.LIST))
+ return new HashSet<Object>(col);
+
+ return col;
+ }
+
+ /**
+ * Type to class.
+ *
+ * @param type the type
+ * @return the class
+ */
+ private static Class<?> typeToClass(String type) {
+ if (type.equals(GraphMLTokens.STRING))
+ return String.class;
+ else if (type.equals(GraphMLTokens.FLOAT))
+ return Float.TYPE;
+ else if (type.equals(GraphMLTokens.INT))
+ return Integer.TYPE;
+ else if (type.equals(GraphMLTokens.DOUBLE))
+ return Double.TYPE;
+ else if (type.equals(GraphMLTokens.BOOLEAN))
+ return Boolean.TYPE;
+ else if (type.equals(GraphMLTokens.LONG))
+ return Long.TYPE;
+ else
+ throw new RuntimeException("Unsupported type: "+type);
+ }
+
+ /**
+ * Type cast value.
+ *
+ * @param value the value
+ * @param type the type
+ * @return the object
+ */
+ private static Object typeCastValue(String value, String type) {
+ if (type.equals(GraphMLTokens.STRING))
+ return value;
+ else if (type.equals(GraphMLTokens.FLOAT))
+ return Float.valueOf(value);
+ else if (type.equals(GraphMLTokens.INT))
+ return Integer.valueOf(value);
+ else if (type.equals(GraphMLTokens.DOUBLE))
+ return Double.valueOf(value);
+ else if (type.equals(GraphMLTokens.BOOLEAN))
+ return Boolean.valueOf(value);
+ else if (type.equals(GraphMLTokens.LONG))
+ return Long.valueOf(value);
+ else
+ throw new RuntimeException("Unsupported type: "+type);
+ }
+
+/* TitanVertex titanVertex = (TitanVertex) titanGraph.getVertex(vertexId);
+ if (titanVertex != null)
+ throw new RuntimeException("Duplicate vertex ID: "+vertexId);
+ titanVertex = (TitanVertex) titanGraph.addVertex(vertexId);
+ for (Entry<String, Object> prop : vertexProps.entrySet()) {
+ // multi-properties need a addProperty and need to use a TitanVertex - BluePrint
+ // Vertex does not support this
+ Object value = prop.getValue();
+ if (value instanceof Collection) {
+ try {
+ for(Object obj : ((Collection<?>)value)) {
+ System.out.println("vertex id:property name:property value="+ vertexId + ":" + prop.getKey() + ":" + obj.toString());
+ titanVertex.addProperty(prop.getKey(), obj.toString());
+ }
+ }
+ catch (Exception e) {
+ System.out.println("Can't set SET/LIST properties - skipping");
+ }
+
+ } else
+ titanVertex.setProperty(prop.getKey(), prop.getValue());
+ }*/
+}
diff --git a/aai-resources/src/main/java/org/openecomp/aai/dbgen/GraphMLTokens.java b/aai-resources/src/main/java/org/openecomp/aai/dbgen/GraphMLTokens.java
new file mode 100644
index 0000000..f863a52
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/dbgen/GraphMLTokens.java
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.dbgen;
+
+/**
+ * A collection of tokens used for GraphML related data.
+ */
+public class GraphMLTokens {
+ public static final String GRAPHML = "graphml";
+ public static final String XMLNS = "xmlns";
+ public static final String GRAPHML_XMLNS = "http://graphml.graphdrawing.org/xmlns";
+ public static final String G = "G";
+ public static final String EDGEDEFAULT = "edgedefault";
+ public static final String DIRECTED = "directed";
+ public static final String KEY = "key";
+ public static final String FOR = "for";
+ public static final String ID = "id";
+ public static final String ATTR_NAME = "attr.name";
+ public static final String ATTR_TYPE = "attr.type";
+ public static final String GRAPH = "graph";
+ public static final String NODE = "node";
+ public static final String EDGE = "edge";
+ public static final String SOURCE = "source";
+ public static final String TARGET = "target";
+ public static final String DATA = "data";
+ public static final String LABEL = "label";
+ public static final String STRING = "string";
+ public static final String FLOAT = "float";
+ public static final String DOUBLE = "double";
+ public static final String LONG = "long";
+ public static final String BOOLEAN = "boolean";
+ public static final String INT = "int";
+ public static final String ARRAY = "array";
+ public static final String SET = "set";
+ public static final String LIST = "list";
+ public static final String ITEM = "item";
+ public static final String _DEFAULT = "_default";
+
+}
diff --git a/aai-resources/src/main/java/org/openecomp/aai/dbgen/GraphMLWriterNew.java b/aai-resources/src/main/java/org/openecomp/aai/dbgen/GraphMLWriterNew.java
new file mode 100644
index 0000000..1704428
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/dbgen/GraphMLWriterNew.java
@@ -0,0 +1,358 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.dbgen;
+
+
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+
+/**
+ * GraphMLWriter writes a Graph to a GraphML OutputStream.
+ */
+public class GraphMLWriterNew {
+
+ private static class KeySpec {
+ String attrName;
+ String attrType;
+
+ /**
+ * Instantiates a new key spec.
+ *
+ * @param name the name
+ * @param type the type
+ */
+ public KeySpec(String name, String type) {
+ this.attrName = name;
+ this.attrType = type;
+ }
+ }
+
+ /**
+ * Write the data in a Graph to a GraphML OutputStream.
+ *
+ * @param graph the Graph to pull the data from
+ * @param graphMLOutputStream the GraphML OutputStream to write the Graph data to
+ * @throws XMLStreamException thrown if there is an error generating the GraphML data
+ */
+ public static void outputGraph(final Graph graph, final OutputStream graphMLOutputStream) throws XMLStreamException {
+ Map<String, KeySpec> vertexKeyTypes = new HashMap<String, KeySpec>();
+ Map<String, KeySpec> edgeKeyTypes = new HashMap<String, KeySpec>();
+
+
+ Iterator<Vertex> vertices = graph.vertices();
+ Vertex vertex = null;
+ Iterator<VertexProperty<Object>> propertyIterator = null;
+ VertexProperty<Object> property = null;
+ while (vertices.hasNext()) {
+ vertex = vertices.next();
+ propertyIterator = vertex.properties();
+ while (propertyIterator.hasNext()) {
+ property = propertyIterator.next();
+ Object value = property.value();
+ String key = property.key();
+ if(value == null)
+ continue;
+ String type = getStringType(value);
+ if(type == null)
+ continue;
+ String id = key+"-"+type;
+ if (!vertexKeyTypes.containsKey(id)) {
+ vertexKeyTypes.put(id, new KeySpec(key, type));
+ }
+ }
+ }
+ Iterator<Edge> edges = graph.edges();
+ Edge edge = null;
+ Iterator<Property<Object>> edgePropertyIterator = null;
+ Property<Object> edgeProperty = null;
+
+ while (edges.hasNext()) {
+ edge = edges.next();
+ edgePropertyIterator = edge.properties();
+ while (edgePropertyIterator.hasNext()) {
+ edgeProperty = edgePropertyIterator.next();
+ Object value = edgeProperty.value();
+ String key = edgeProperty.key();
+ if(value == null)
+ continue;
+ String type = getStringType(value);
+ if(type == null)
+ continue;
+ String id = key+"-"+type;
+ if (!edgeKeyTypes.containsKey(id)) {
+ edgeKeyTypes.put(id, new KeySpec(key, type));
+ }
+ }
+ }
+ outputGraph(graph, graphMLOutputStream, vertexKeyTypes, edgeKeyTypes);
+ }
+
+ /**
+ * Write the data in a Graph to a GraphML OutputStream.
+ *
+ * @param graph the Graph to pull the data from
+ * @param graphMLOutputStream the GraphML OutputStream to write the Graph data to
+ * @param vertexKeyTypes a Map of the data types of the vertex keys
+ * @param edgeKeyTypes a Map of the data types of the edge keys
+ * @throws XMLStreamException thrown if there is an error generating the GraphML data
+ */
+ public static void outputGraph(final Graph graph, final OutputStream graphMLOutputStream, final Map<String, KeySpec> vertexKeyTypes, final Map<String, KeySpec> edgeKeyTypes) throws XMLStreamException {
+ XMLOutputFactory inputFactory = XMLOutputFactory.newInstance();
+ XMLStreamWriter writer = inputFactory.createXMLStreamWriter(graphMLOutputStream, "UTF8");
+
+ writer.writeStartDocument("UTF-8", "1.0");
+ writer.writeStartElement(GraphMLTokens.GRAPHML);
+ writer.writeAttribute(GraphMLTokens.XMLNS, GraphMLTokens.GRAPHML_XMLNS);
+ //<key id="weight" for="edge" attr.name="weight" attr.type="float"/>
+ for (Map.Entry<String, KeySpec> entry : vertexKeyTypes.entrySet()) {
+ writer.writeStartElement(GraphMLTokens.KEY);
+ writer.writeAttribute(GraphMLTokens.ID, entry.getKey());
+ writer.writeAttribute(GraphMLTokens.FOR, GraphMLTokens.NODE);
+ writer.writeAttribute(GraphMLTokens.ATTR_NAME, entry.getValue().attrName);
+ writer.writeAttribute(GraphMLTokens.ATTR_TYPE, entry.getValue().attrType);
+ writer.writeEndElement();
+ }
+ for (Map.Entry<String, KeySpec> entry : edgeKeyTypes.entrySet()) {
+ writer.writeStartElement(GraphMLTokens.KEY);
+ writer.writeAttribute(GraphMLTokens.ID, entry.getKey());
+ writer.writeAttribute(GraphMLTokens.FOR, GraphMLTokens.EDGE);
+ writer.writeAttribute(GraphMLTokens.ATTR_NAME, entry.getValue().attrName);
+ writer.writeAttribute(GraphMLTokens.ATTR_TYPE, entry.getValue().attrType);
+ writer.writeEndElement();
+ }
+
+ writer.writeStartElement(GraphMLTokens.GRAPH);
+ writer.writeAttribute(GraphMLTokens.ID, GraphMLTokens.G);
+ writer.writeAttribute(GraphMLTokens.EDGEDEFAULT, GraphMLTokens.DIRECTED);
+ Iterator<Vertex> vertices = graph.vertices();
+ Vertex vertex = null;
+ Iterator<VertexProperty<Object>> propertyIterator = null;
+ VertexProperty<Object> property = null;
+ while (vertices.hasNext()) {
+ vertex = vertices.next();
+ writer.writeStartElement(GraphMLTokens.NODE);
+ writer.writeAttribute(GraphMLTokens.ID, vertex.id().toString());
+ propertyIterator = vertex.properties();
+ while (propertyIterator.hasNext()) {
+ property = propertyIterator.next();
+ String key = property.key();
+ writeData(writer, key, property.value());
+ }
+ writer.writeEndElement();
+ }
+
+ Iterator<Edge> edges = graph.edges();
+ Edge edge = null;
+ Iterator<Property<Object>> edgePropertyIterator = null;
+ Property<Object> edgeProperty = null;
+
+ while (edges.hasNext()) {
+ edge = edges.next();
+ edgePropertyIterator = edge.properties();
+ writer.writeStartElement(GraphMLTokens.EDGE);
+ writer.writeAttribute(GraphMLTokens.ID, edge.id().toString());
+ writer.writeAttribute(GraphMLTokens.SOURCE, edge.outVertex().id().toString());
+ writer.writeAttribute(GraphMLTokens.TARGET, edge.inVertex().id().toString());
+ writer.writeAttribute(GraphMLTokens.LABEL, edge.label());
+
+ while (edgePropertyIterator.hasNext()) {
+ edgeProperty = edgePropertyIterator.next();
+ String key = edgeProperty.key();
+ writeData(writer, key, edgeProperty.value());
+ }
+ writer.writeEndElement();
+ }
+
+ writer.writeEndElement(); // graph
+ writer.writeEndElement(); // graphml
+ writer.writeEndDocument();
+
+ writer.flush();
+ writer.close();
+
+ }
+
+ /**
+ * Write data.
+ *
+ * @param writer the writer
+ * @param key the key
+ * @param value the value
+ * @throws XMLStreamException the XML stream exception
+ */
+ private static void writeData(XMLStreamWriter writer, String key, Object value) throws XMLStreamException {
+ if(value == null)
+ return;
+ String type = getStringType(value);
+ if(type == null)
+ return;
+ String id = key+"-"+type;
+
+ writer.writeStartElement(GraphMLTokens.DATA);
+ writer.writeAttribute(GraphMLTokens.KEY, id);
+ if(type.startsWith(GraphMLTokens.ARRAY) ||
+ type.startsWith(GraphMLTokens.LIST) ||
+ type.startsWith(GraphMLTokens.SET))
+ writeDataArray(writer, value);
+ else
+ writer.writeCharacters(propertyValueToString(value));
+ writer.writeEndElement();
+ }
+
+ /**
+ * Write data array.
+ *
+ * @param writer the writer
+ * @param value the value
+ * @throws XMLStreamException the XML stream exception
+ */
+ private static void writeDataArray(XMLStreamWriter writer, Object value) throws XMLStreamException {
+ if(value.getClass().isArray()) {
+ for(int i = 0; i < Array.getLength(value); i++) {
+ writer.writeStartElement(GraphMLTokens.ITEM);
+ writer.writeCharacters(Array.get(value, i).toString());
+ writer.writeEndElement();
+ }
+ }
+ else if(value instanceof Collection) {
+ for(Object obj : ((Collection<?>)value)) {
+ writer.writeStartElement(GraphMLTokens.ITEM);
+ writer.writeCharacters(obj.toString());
+ writer.writeEndElement();
+ }
+ }
+ }
+
+ /**
+ * Gets the string type.
+ *
+ * @param object the object
+ * @return the string type
+ */
+ private static String getStringType(final Object object) {
+ if(object.getClass().isArray())
+ return GraphMLTokens.ARRAY+"-"+getStringType(object.getClass().getComponentType());
+ if(object instanceof Collection) {
+ String colType;
+ if(object instanceof Set)
+ colType = GraphMLTokens.SET;
+ else if(object instanceof List)
+ colType = GraphMLTokens.LIST;
+ else
+ throw new RuntimeException("Unhandled Collection type: "+object.getClass());
+
+ Collection<?> col = (Collection<?>)object;
+ if(col.size() == 0)
+ return null;
+ return colType+"-"+getStringType(col.iterator().next());
+ }
+ if (object instanceof String)
+ return GraphMLTokens.STRING;
+ else if (object instanceof Integer)
+ return GraphMLTokens.INT;
+ else if (object instanceof Long)
+ return GraphMLTokens.LONG;
+ else if (object instanceof Float)
+ return GraphMLTokens.FLOAT;
+ else if (object instanceof Double)
+ return GraphMLTokens.DOUBLE;
+ else if (object instanceof Boolean)
+ return GraphMLTokens.BOOLEAN;
+ else
+ throw new RuntimeException("Unsupported type: "+object.getClass());
+ }
+
+ /**
+ * Gets the string type.
+ *
+ * @param clazz the clazz
+ * @return the string type
+ */
+ private static String getStringType(final Class<?> clazz) {
+ if(clazz.equals(String.class))
+ return GraphMLTokens.STRING;
+ else if(clazz.equals(Integer.TYPE) || clazz.equals(Integer.class))
+ return GraphMLTokens.INT;
+ else if(clazz.equals(Long.TYPE) || clazz.equals(Long.class))
+ return GraphMLTokens.LONG;
+ else if(clazz.equals(Float.TYPE) || clazz.equals(Float.class))
+ return GraphMLTokens.FLOAT;
+ else if(clazz.equals(Double.TYPE) || clazz.equals(Double.class))
+ return GraphMLTokens.DOUBLE;
+ else if(clazz.equals(Boolean.TYPE) || clazz.equals(Boolean.class))
+ return GraphMLTokens.BOOLEAN;
+ else
+ throw new RuntimeException("Unsupported array item type: "+clazz);
+ }
+
+ /**
+ * Property value to string.
+ *
+ * @param value the value
+ * @return the string
+ */
+ private static String propertyValueToString(Object value) {
+ if(value == null)
+ return null;
+
+ if(value.getClass().isArray()) {
+ String str = "[";
+ for(int i = 0; i < Array.getLength(value); i++) {
+ if(i > 0)
+ str += ", ";
+ str += Array.get(value, i);
+ }
+ str += "]";
+ return str;
+ }
+ else if(value instanceof Collection) {
+ String str = "[";
+ int i = 0;
+ for(Object obj : ((Collection<?>)value)) {
+ if(i > 0)
+ str += ", ";
+ str += obj.toString();
+ i++;
+ }
+ str += "]";
+ return str;
+ }
+ return value.toString();
+ }
+
+}
diff --git a/aai-resources/src/main/java/org/openecomp/aai/dbgen/PropertyNameChange.java b/aai-resources/src/main/java/org/openecomp/aai/dbgen/PropertyNameChange.java
new file mode 100644
index 0000000..3f7f351
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/dbgen/PropertyNameChange.java
@@ -0,0 +1,317 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.dbgen;
+
+import java.util.Iterator;
+import java.util.Properties;
+
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+
+import org.openecomp.aai.dbmap.AAIGraph;
+import org.openecomp.aai.logging.ErrorLogHelper;
+import org.openecomp.aai.util.AAIConfig;
+import org.openecomp.aai.util.AAIConstants;
+import com.att.eelf.configuration.Configuration;
+import com.thinkaurelius.titan.core.PropertyKey;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanProperty;
+import com.thinkaurelius.titan.core.TitanVertex;
+import com.thinkaurelius.titan.core.schema.TitanManagement;
+
+
+public class PropertyNameChange {
+
+ /**
+ * The main method.
+ *
+ * @param args the arguments
+ */
+ public static void main(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);
+
+ // NOTE -- We're just working with properties that are used for NODES for now.
+
+ TitanGraph graph = null;
+ TitanManagement graphMgt = null;;
+ Boolean preserveData = true;
+ String propName = "";
+ String targetPropName = "";
+ String targetNodeType = "";
+ String skipCommit = "";
+ boolean noCommit = false;
+
+
+ String usageString = "Usage: PropertyNameChange propertyName targetPropertyName nodeType(or NA) skipCommit(true|false) \n";
+ if( args.length != 4 ){
+ String emsg = "Four Parameters are required. \n" + usageString;
+ System.out.println( emsg );
+ System.exit(1);
+ }
+ else {
+ propName = args[0];
+ targetPropName = args[1];
+ targetNodeType = args[2];
+ skipCommit = args[3];
+ if ( skipCommit.toLowerCase().equals("true"))
+ noCommit = true;
+ }
+
+ if( propName.equals("") ){
+ String emsg = "Bad parameter - propertyName cannot be empty. \n" + usageString;
+ System.out.println( emsg );
+ System.exit(1);
+ }
+
+
+
+ try {
+ AAIConfig.init();
+ ErrorLogHelper.loadProperties();
+ }
+ catch( Exception ae ){
+ String emsg = "Problem with either AAIConfig.init() or ErrorLogHelper.LoadProperties(). ";
+ System.out.println( emsg + "[" + ae.getMessage() + "]");
+ System.exit(1);
+ }
+
+
+ System.out.println(">>> 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) {
+ System.out.println( " DB Schema Update has been aborted. ");
+ System.exit(1);
+ }
+
+ try {
+ System.out.println(" ---- NOTE --- about to open graph (takes a little while)\n");
+
+ graph = AAIGraph.getInstance().getGraph();
+ if( graph == null ){
+ String emsg = "Not able to get a graph object in SchemaMod.java\n";
+ System.out.println( emsg );
+ System.exit(1);
+ }
+
+ // Make sure this property is in the DB.
+ graphMgt = graph.openManagement();
+ if( graphMgt == null ){
+ String emsg = "Not able to get a graph Management object in SchemaMod.java\n";
+ System.out.println( emsg );
+ System.exit(1);
+ }
+ PropertyKey origPropKey = graphMgt.getPropertyKey(propName);
+ if( origPropKey == null ){
+ String emsg = "The propName = [" + propName + "] is not defined in our graph. ";
+ System.out.println( emsg );
+ System.exit(1);
+ }
+ origPropKey = graphMgt.getPropertyKey(targetPropName);
+ if( origPropKey == null ){
+ String emsg = "The targetPropName = [" + targetPropName + "] is not defined in our graph. ";
+ System.out.println( emsg );
+ System.exit(1);
+ }
+
+ if ( !targetNodeType.equals("NA")) {
+ if ( graphMgt.getVertexLabel(targetNodeType) == null ) {
+ String emsg = "The targetNodeType = [" + targetNodeType + "] is not defined in our graph. ";
+ System.out.println( emsg );
+ System.exit(1);
+ }
+ }
+
+ // For each node that has this property, update the new from the old and then remove the
+ // old property from that node
+ Iterable<TitanVertex> verts = null;
+ int vtxCount = 0;
+ String label;
+ long longId;
+
+ int propertyCount;
+
+ Iterator<VertexProperty<Object>> titanProperties = null;
+
+ VertexProperty<Object> tmpProperty = null;
+ Object origVal;
+ Object targetVal;
+
+ if ( targetNodeType.equals("NA")) {
+ verts= graph.query().has(propName).vertices();
+ Iterator<TitanVertex> it = verts.iterator();
+
+ while( it.hasNext() ){
+
+ TitanVertex tmpVtx = (TitanVertex)it.next();
+ String tmpVid = tmpVtx.id().toString();
+
+ origVal = tmpVtx.<Object>property(propName).orElse(null);
+ targetVal = tmpVtx.<Object>property(targetPropName).orElse(null);
+
+ label = tmpVtx.label();
+ longId = tmpVtx.longId();
+
+ if ( targetVal != null ) {
+ System.out.println( "vertex [" + label + "] id " + tmpVid + " has " + targetPropName +
+ " with value " + targetVal + ", skip adding with value " + origVal);
+ continue;
+ }
+ vtxCount++;
+ titanProperties = tmpVtx.properties(); // current properties
+
+ propertyCount = 0;
+
+ while( titanProperties.hasNext() ){
+
+ tmpProperty = titanProperties.next();
+
+ if ( propertyCount == 0 )
+ System.out.print( "adding to [" + label + "] vertex id " + tmpVid + " with existing properties " +
+ tmpProperty.toString() );
+ else
+ System.out.print(", " + tmpProperty.toString());
+ ++propertyCount;
+ }
+
+ if ( propertyCount > 0 ) {
+ System.out.println("");
+
+ tmpVtx.property(targetPropName,origVal);
+ System.out.println("INFO -- just did the add using " + longId +
+ " with label " + label + "] and updated it with the orig value (" +
+ origVal.toString() + ")");
+ titanProperties = tmpVtx.properties(); // current properties
+ propertyCount = 0;
+
+
+ while( titanProperties.hasNext() ){
+ tmpProperty = titanProperties.next();
+ if ( propertyCount == 0 )
+ System.out.print( "new property list for [" + label + "] vertex id " + tmpVid + " with existing properties " +
+ tmpProperty.toString() );
+ else
+ System.out.print(", " + tmpProperty.toString());
+ ++propertyCount;
+ }
+
+ if ( propertyCount > 0 )
+ System.out.println("");
+ }
+ }
+ } else {
+ // targetNodeType is NA
+
+ verts= graph.query().has("aai-node-type", targetNodeType).vertices();
+ if( verts != null ){
+ // We did find some matching vertices
+ Iterator <?> it = verts.iterator();
+ Object propVal;
+ while( it.hasNext() ){
+ TitanVertex v = (TitanVertex)it.next();
+ label = v.label();
+ longId = v.longId();
+ targetVal = v.<Object>property(targetPropName).orElse(null);
+ origVal = v.<Object>property(propName).orElse(null);
+
+ if ( origVal == null)
+ continue;
+
+ if ( targetVal != null ) {
+ System.out.println( "vertex [" + label + "] id " + longId + " has " + targetPropName +
+ " with value " + targetVal + ", skip adding with value " + origVal);
+ continue;
+ }
+ titanProperties = v.properties(); // current properties
+ propertyCount = 0;
+ if ( v.<Object>property(propName).orElse(null) != null ) {
+ propVal = v.<Object>property(propName).orElse(null);
+ v.property(targetPropName, propVal);
+ ++vtxCount;
+ while( titanProperties.hasNext() ){
+
+ tmpProperty = titanProperties.next();
+ if ( propertyCount == 0 )
+ System.out.print( "adding to vertex id " + longId + " with existing properties " +
+ tmpProperty.toString() );
+ else
+ System.out.print(", " + tmpProperty.toString());
+ ++propertyCount;
+ }
+
+ if ( propertyCount > 0 )
+ System.out.println("");
+ System.out.println("INFO -- just did the add target [" + targetNodeType + "] using " + longId +
+ " with label " + label + "] and updated it with the orig value (" +
+ propVal.toString() + ")");
+ propertyCount = 0;
+ while( titanProperties.hasNext() ){
+
+ tmpProperty = titanProperties.next();
+ if ( propertyCount == 0 )
+ System.out.print( "new property list for vertex [" + label + "] id " + longId + " with existing properties " +
+ tmpProperty.toString() );
+ else
+ System.out.print(", " + tmpProperty.toString());
+ ++propertyCount;
+ }
+
+ if ( propertyCount > 0 )
+ System.out.println("");
+ }
+ }
+ }
+
+ }
+
+ System.out.println("added properties data for " + vtxCount + " vertexes. noCommit " + noCommit);
+ if ( !noCommit )
+ graph.tx().commit();
+ }
+ catch (Exception ex) {
+ System.out.print("Threw a regular Exception:\n");
+ System.out.println(ex.getMessage());
+ }
+ finally {
+ if( graphMgt != null && graphMgt.isOpen() ){
+ // Any changes that worked correctly should have already done their commits.
+ graphMgt.rollback();
+ }
+ if( graph != null ){
+ // Any changes that worked correctly should have already done their commits.
+ graph.tx().rollback();
+ graph.close();
+ }
+ }
+
+ System.exit(0);
+
+ }// End of main()
+
+
+}
+
+
diff --git a/aai-resources/src/main/java/org/openecomp/aai/dbgen/SchemaMod.java b/aai-resources/src/main/java/org/openecomp/aai/dbgen/SchemaMod.java
new file mode 100644
index 0000000..9cc6cf3
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/dbgen/SchemaMod.java
@@ -0,0 +1,441 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.dbgen;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.TimeZone;
+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.slf4j.MDC;
+
+import org.openecomp.aai.dbmap.AAIGraph;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.ingestModel.DbMaps;
+import org.openecomp.aai.ingestModel.IngestModelMoxyOxm;
+import org.openecomp.aai.logging.ErrorLogHelper;
+import org.openecomp.aai.util.AAIConfig;
+import org.openecomp.aai.util.AAIConstants;
+import org.openecomp.aai.util.UniquePropertyCheck;
+import com.att.eelf.configuration.Configuration;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.thinkaurelius.titan.core.Cardinality;
+import com.thinkaurelius.titan.core.PropertyKey;
+import com.thinkaurelius.titan.core.TitanEdge;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanVertex;
+import com.thinkaurelius.titan.core.schema.TitanManagement;
+
+public class SchemaMod {
+
+ private static final String FROMAPPID = "AAI-UTILS";
+ private static final String TRANSID = UUID.randomUUID().toString();
+ private static final String COMPONENT = "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.
+
+ TitanGraph graph = null;
+ TitanManagement graphMgt = null;
+
+ Boolean preserveData = true;
+ 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);
+ } else {
+ if (preserveDataFlag.equals("true")) {
+ preserveData = true;
+ } else if (preserveDataFlag.equals("false")) {
+ preserveData = false;
+ } else {
+ String emsg = "Unsupported preserveDataFlag. We only support: 'true' or 'false'.\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);
+ }
+
+ DbMaps dbMaps = null;
+ try {
+ ArrayList<String> apiVersions = new ArrayList<String>();
+ apiVersions.add(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+ final IngestModelMoxyOxm m = new IngestModelMoxyOxm();
+ m.init(apiVersions, false);
+ dbMaps = m.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+ } catch (AAIException ae) {
+ String emsg = "Could not instantiate a copy of DbMaps. ";
+ logAndPrint(logger, emsg + "[" + ae.getMessage() + "]");
+ System.exit(1);
+ } catch (Exception e) {
+ String emsg = "exception, Could not instantiate a copy of DbMaps. ";
+ logAndPrint(logger, emsg + "[" + e.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);
+ }
+
+ try {
+ Class dType = null;
+ if (targetDataType.equals("String")) {
+ dType = String.class;
+ } else if (targetDataType.equals("Set<String>")) {
+ dType = String.class;
+ } else if (targetDataType.equals("Integer")) {
+ dType = Integer.class;
+ } else if (targetDataType.equals("Boolean")) {
+ dType = Boolean.class;
+ } else if (targetDataType.equals("Character")) {
+ dType = Character.class;
+ } else if (targetDataType.equals("Long")) {
+ dType = Long.class;
+ } else if (targetDataType.equals("Float")) {
+ dType = Float.class;
+ } else if (targetDataType.equals("Double")) {
+ dType = Double.class;
+ } else {
+ String emsg = "Not able translate the targetDataType [" + targetDataType + "] to a Class variable.\n";
+ logAndPrint(logger, emsg);
+ System.exit(1);
+ }
+ String cardinality = "SINGLE"; // Default cardinality to SINGLE
+
+ if (targetDataType.equals("Set<String>")) {
+ cardinality = "SET";
+ }
+ logAndPrint(logger, " ---- NOTE --- about to open graph (takes a little while)\n");
+
+ graph = AAIGraph.getInstance().getGraph();
+ if (graph == null) {
+ String emsg = "Not able to get a graph object in SchemaMod.java\n";
+ logAndPrint(logger, emsg);
+ System.exit(1);
+ }
+
+ // Make sure this property is in the DB.
+ graphMgt = graph.openManagement();
+ 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 (targetIndexInfo.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,
+ graph.newTransaction(), 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)
+
+ SimpleDateFormat d = new SimpleDateFormat("MMddHHmm");
+ d.setTimeZone(TimeZone.getTimeZone("GMT"));
+ String dteStr = d.format(new Date()).toString();
+ 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(dType)
+ .cardinality(Cardinality.valueOf(cardinality)).make();
+
+ // Create the appropriate index (if any)
+ if (targetIndexInfo.equals("uniqueIndex")) {
+ String freshIndexName = propName + dteStr;
+ graphMgt.buildIndex(freshIndexName, Vertex.class).addKey(freshPropKey).unique().buildCompositeIndex();
+ } else if (targetIndexInfo.equals("index")) {
+ String freshIndexName = propName + dteStr;
+ graphMgt.buildIndex(freshIndexName, Vertex.class).addKey(freshPropKey).buildCompositeIndex();
+ }
+
+ logAndPrint(logger, "Committing schema changes with graphMgt.commit()");
+ graphMgt.commit();
+ graph.tx().commit();
+
+ // 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
+ Iterable<?> verts = null;
+ verts = graph.query().has(retiredName).vertices();
+ Iterator<?> it = verts.iterator();
+ int vtxCount = 0;
+ ArrayList<String> alreadySeenVals = new ArrayList<String>();
+ while (it.hasNext()) {
+ vtxCount++;
+ TitanVertex tmpVtx = (TitanVertex) it.next();
+ String tmpVid = tmpVtx.id().toString();
+
+ Object origVal = tmpVtx.<Object> property(retiredName).orElse(null);
+ if (preserveData) {
+ tmpVtx.property(propName, origVal);
+ if (targetIndexInfo.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 + ")");
+ }
+
+ logAndPrint(logger, "Updated data for " + vtxCount + " vertexes. Now call graph2.commit(). ");
+ graph.tx().commit();
+ } 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 (graph != null) {
+ // Any changes that worked correctly should have already done
+ // their commits.
+ graph.tx().rollback();
+ graph.close();
+ }
+ }
+
+ }
+
+ /**
+ * 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, TitanVertex 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()) {
+ TitanEdge ed = (TitanEdge) eI.next();
+ String lab = ed.label();
+ TitanVertex vtx = (TitanVertex) ed.otherVertex(tVert);
+ 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/openecomp/aai/dbgen/UpdateEdgeTags.java b/aai-resources/src/main/java/org/openecomp/aai/dbgen/UpdateEdgeTags.java
new file mode 100644
index 0000000..c2ebf6f
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/dbgen/UpdateEdgeTags.java
@@ -0,0 +1,380 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.dbgen;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+
+import org.openecomp.aai.dbmap.AAIGraph;
+import org.openecomp.aai.dbmodel.DbEdgeRules;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.logging.ErrorLogHelper;
+import org.openecomp.aai.serialization.db.EdgeRule;
+import org.openecomp.aai.serialization.db.EdgeRules;
+import org.openecomp.aai.util.AAIConfig;
+import com.thinkaurelius.titan.core.TitanEdge;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanTransaction;
+import com.thinkaurelius.titan.core.TitanVertex;
+
+
+
+public class UpdateEdgeTags {
+
+ private static final String FROMAPPID = "AAI-DB";
+ private static final String TRANSID = UUID.randomUUID().toString();
+
+ /**
+ * The main method.
+ *
+ * @param args the arguments
+ */
+ public static void main(String[] args) {
+
+ 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);
+ System.exit(1);
+ }
+ String edgeRuleKeyVal = args[0];
+
+ TitanGraph graph = null;
+
+ 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 ();
+
+ int tagCount = DbEdgeRules.EdgeInfoMap.size();
+ // Loop through all the edge-rules make sure they look right and
+ // collect info about which labels support duplicate ruleKeys.
+ Iterator<String> edgeRulesIterator = DbEdgeRules.EdgeRules.keySet().iterator();
+ while( edgeRulesIterator.hasNext() ){
+ String ruleKey = edgeRulesIterator.next();
+ Collection <String> edRuleColl = DbEdgeRules.EdgeRules.get(ruleKey);
+ Iterator <String> ruleItr = edRuleColl.iterator();
+ if( ruleItr.hasNext() ){
+ // For now, we only look for one type of edge between two nodes.
+ String fullRuleString = ruleItr.next();
+ edgeRulesFullHash.put(ruleKey,fullRuleString);
+ // An EdgeRule is comma-separated and the first item is the edgeLabel
+ String [] rules = fullRuleString.split(",");
+ //System.out.println( "rules.length = " + rules.length + ", tagCount = " + tagCount );
+ if( rules.length != tagCount ){
+ String detail = "Bad EdgeRule data (itemCount=" + rules.length + ") for key = [" + ruleKey + "].";
+ System.out.println(detail);
+ System.exit(0);
+ }
+ String edgeLabel = rules[0];
+ 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 <String> edRuleColl = DbEdgeRules.EdgeRules.get(edgeRuleKeyVal);
+ Iterator <String> ruleItr = edRuleColl.iterator();
+ if( ruleItr.hasNext() ){
+ // For now, we only look for one type of edge between two nodes (Ie. for one key).
+ String 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);
+ System.exit(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);
+ System.exit(0);
+ }
+ }
+ catch (AAIException e1) {
+ String msg = e1.getErrorObject().toString();
+ System.out.println(msg);
+ System.exit(0);
+ }
+ catch (Exception e2) {
+ String msg = e2.toString();
+ System.out.println(msg);
+ e2.printStackTrace();
+ System.exit(0);
+ }
+
+ TitanTransaction g = graph.newTransaction();
+ try {
+ Iterable <?> edges = graph.query().edges();
+ Iterator <?> edgeItr = edges.iterator();
+
+ // 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() ){
+ TitanEdge tmpEd = (TitanEdge) 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.vertex(Direction.IN);
+ 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.vertex(Direction.OUT);
+ 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();
+ }
+ System.exit(0);
+ }
+
+ System.exit(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, TitanTransaction graph,
+ TitanEdge tEdge ) throws AAIException{
+
+ TitanVertex fromVtx = tEdge.outVertex();
+ TitanVertex 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 4 rule.
+ *
+ * @param transId the trans id
+ * @param fromAppId the from app id
+ * @param edRule the ed rule
+ * @return the edge tag prop put hash 4 rule
+ * @throws AAIException the AAI exception
+ */
+ public static HashMap <String,Object> getEdgeTagPropPutHash4Rule( String transId, String fromAppId, String edRule )
+ throws AAIException{
+ // For a given edgeRule - already pulled out of DbEdgeRules.EdgeRules -- parse out the "tags" that
+ // need to be set for this kind of edge.
+ // These are the Boolean properties like, "isParent", "usesResource" etc.
+ HashMap <String,Object> retEdgePropPutMap = new HashMap <String,Object>();
+
+ if( (edRule == null) || edRule.equals("") ){
+ // No edge rule found for this
+ throw new AAIException("AAI_6120", "blank edRule passed to getEdgeTagPropPutHash4Rule()");
+ }
+
+ int tagCount = DbEdgeRules.EdgeInfoMap.size();
+ String [] rules = edRule.split(",");
+ if( rules.length != tagCount ){
+ throw new AAIException("AAI_6121", "Bad EdgeRule data (itemCount =" + rules.length + ") for rule = [" + edRule + "].");
+ }
+
+ // In DbEdgeRules.EdgeRules -- What we have as "edRule" is a comma-delimited set of strings.
+ // The first item is the edgeLabel.
+ // The second in the list is always "direction" which is always OUT for the way we've implemented it.
+ // Items starting at "firstTagIndex" and up are all assumed to be booleans that map according to
+ // tags as defined in EdgeInfoMap.
+ // Note - if they are tagged as 'reverse', that means they get the tag name with "-REV" on it
+ for( int i = DbEdgeRules.firstTagIndex; i < tagCount; i++ ){
+ String booleanStr = rules[i];
+ Integer mapKey = new Integer(i);
+ String propName = DbEdgeRules.EdgeInfoMap.get(mapKey);
+ String revPropName = propName + "-REV";
+
+ if( booleanStr.equals("true") ){
+ retEdgePropPutMap.put(propName, true);
+ retEdgePropPutMap.put(revPropName,false);
+ }
+ else if( booleanStr.equals("false") ){
+ retEdgePropPutMap.put(propName, false);
+ retEdgePropPutMap.put(revPropName,false);
+ }
+ else if( booleanStr.equals("reverse") ){
+ retEdgePropPutMap.put(propName, false);
+ retEdgePropPutMap.put(revPropName,true);
+ }
+ else {
+ throw new AAIException("AAI_6121", "Bad EdgeRule data for rule = [" + edRule + "], val = [" + booleanStr + "].");
+ }
+
+ }
+
+ return retEdgePropPutMap;
+
+ } // End of getEdgeTagPropPutHash()
+
+
+ /**
+ * 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/openecomp/aai/dmaap/AAIDmaapEventJMSConsumer.java b/aai-resources/src/main/java/org/openecomp/aai/dmaap/AAIDmaapEventJMSConsumer.java
index fc11e5d..c016bb1 100644
--- a/aai-resources/src/main/java/org/openecomp/aai/dmaap/AAIDmaapEventJMSConsumer.java
+++ b/aai-resources/src/main/java/org/openecomp/aai/dmaap/AAIDmaapEventJMSConsumer.java
@@ -126,7 +126,7 @@ public class AAIDmaapEventJMSConsumer implements MessageListener {
//String aaiEvent = "";
//String eventName = "";
-
+
//String environment = "";
//if (message instanceof TextMessage) {
diff --git a/aai-resources/src/main/java/org/openecomp/aai/migration/EventAction.java b/aai-resources/src/main/java/org/openecomp/aai/migration/EventAction.java
new file mode 100644
index 0000000..82b7cad
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/migration/EventAction.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.migration;
+
+public enum EventAction {
+ CREATE,
+ UPDATE,
+ DELETE
+}
diff --git a/aai-resources/src/main/java/org/openecomp/aai/migration/NotificationHelper.java b/aai-resources/src/main/java/org/openecomp/aai/migration/NotificationHelper.java
new file mode 100644
index 0000000..b956705
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/migration/NotificationHelper.java
@@ -0,0 +1,103 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.migration;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.introspection.Loader;
+import org.openecomp.aai.introspection.exceptions.AAIUnknownObjectException;
+import org.openecomp.aai.rest.ueb.UEBNotification;
+import org.openecomp.aai.serialization.db.DBSerializer;
+import org.openecomp.aai.serialization.engines.TransactionalGraphEngine;
+import org.openecomp.aai.serialization.engines.query.QueryEngine;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public class NotificationHelper {
+
+ private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(NotificationHelper.class);
+ protected final DBSerializer serializer;
+ protected final Loader loader;
+ protected final TransactionalGraphEngine engine;
+ protected final String transactionId;
+ protected final String sourceOfTruth;
+ protected final UEBNotification notification;
+
+ public NotificationHelper(Loader loader, DBSerializer serializer, TransactionalGraphEngine engine, String transactionId, String sourceOfTruth) {
+ this.loader = loader;
+ this.serializer = serializer;
+ this.engine = engine;
+ this.transactionId = transactionId;
+ this.sourceOfTruth = sourceOfTruth;
+ this.notification = new UEBNotification(loader);
+ }
+
+ public void addEvent(Vertex v, Introspector obj, EventAction action, URI uri) throws UnsupportedEncodingException, AAIException {
+ HashMap<String, Introspector> relatedObjects = new HashMap<>();
+ Status status = mapAction(action);
+ if (!obj.isTopLevel()) {
+ relatedObjects = this.getRelatedObjects(serializer, engine.getQueryEngine(), v);
+ }
+ notification.createNotificationEvent(transactionId, sourceOfTruth, status, uri, obj, relatedObjects);
+
+ }
+
+ private HashMap<String, Introspector> getRelatedObjects(DBSerializer serializer, QueryEngine queryEngine, Vertex v) throws AAIException {
+ HashMap<String, Introspector> relatedVertices = new HashMap<>();
+ List<Vertex> vertexChain = queryEngine.findParents(v);
+ for (Vertex vertex : vertexChain) {
+ try {
+ final Introspector vertexObj = serializer.getVertexProperties(vertex);
+ relatedVertices.put(vertexObj.getObjectId(), vertexObj);
+ } catch (AAIUnknownObjectException | UnsupportedEncodingException e) {
+ LOGGER.warn("Unable to get vertex properties, partial list of related vertices returned");
+ }
+
+ }
+
+ return relatedVertices;
+ }
+
+ private Status mapAction(EventAction action) {
+ if (EventAction.CREATE.equals(action)) {
+ return Status.CREATED;
+ } else if (EventAction.UPDATE.equals(action)) {
+ return Status.OK;
+ } else if (EventAction.DELETE.equals(action)) {
+ return Status.NO_CONTENT;
+ } else {
+ return Status.OK;
+ }
+ }
+
+ public void triggerEvents() throws AAIException {
+ notification.triggerEvents();
+ }
+}
diff --git a/aai-resources/src/main/java/org/openecomp/aai/migration/VertexMerge.java b/aai-resources/src/main/java/org/openecomp/aai/migration/VertexMerge.java
new file mode 100644
index 0000000..6bb17a9
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/migration/VertexMerge.java
@@ -0,0 +1,245 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.migration;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+
+import org.openecomp.aai.db.props.AAIProperties;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.introspection.Loader;
+import org.openecomp.aai.introspection.exceptions.AAIUnknownObjectException;
+import org.openecomp.aai.serialization.db.DBSerializer;
+import org.openecomp.aai.serialization.db.EdgeRules;
+import org.openecomp.aai.serialization.db.EdgeType;
+import org.openecomp.aai.serialization.engines.TransactionalGraphEngine;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+/**
+ * This class recursively merges two vertices passed in.
+ * <br>
+ * You can start with any two vertices, but after the vertices are merged based off the equality of their keys
+ *
+ */
+public class VertexMerge {
+
+ private final EELFLogger logger = EELFManager.getInstance().getLogger(this.getClass().getSimpleName());
+
+ private final GraphTraversalSource g;
+ private final TransactionalGraphEngine engine;
+ private final DBSerializer serializer;
+ private final EdgeRules rules;
+ private final Loader loader;
+ private final NotificationHelper notificationHelper;
+ private final boolean hasNotifications;
+ private VertexMerge(Builder builder) {
+ this.engine = builder.getEngine();
+ this.serializer = builder.getSerializer();
+ this.g = engine.asAdmin().getTraversalSource();
+ this.rules = EdgeRules.getInstance();
+ this.loader = builder.getLoader();
+ this.notificationHelper = builder.getHelper();
+ this.hasNotifications = builder.isHasNotifications();
+ }
+
+ /**
+ * Merges vertices. forceCopy is a map of the form [{aai-node-type}:{set of properties}]
+ * @param primary
+ * @param secondary
+ * @param forceCopy
+ * @throws AAIException
+ * @throws UnsupportedEncodingException
+ */
+ public void performMerge(Vertex primary, Vertex secondary, Map<String, Set<String>> forceCopy) throws AAIException, UnsupportedEncodingException {
+ final Optional<Introspector> secondarySnapshot;
+ if (this.hasNotifications) {
+ secondarySnapshot = Optional.of(serializer.getLatestVersionView(secondary));
+ } else {
+ secondarySnapshot = Optional.empty();
+ }
+ mergeProperties(primary, secondary, forceCopy);
+
+ Collection<Vertex> secondaryChildren = this.engine.getQueryEngine().findChildren(secondary);
+ Collection<Vertex> primaryChildren = this.engine.getQueryEngine().findChildren(primary);
+
+ mergeChildren(primary, secondary, primaryChildren, secondaryChildren, forceCopy);
+
+ Collection<Vertex> secondaryCousins = this.engine.getQueryEngine().findCousinVertices(secondary);
+ Collection<Vertex> primaryCousins = this.engine.getQueryEngine().findCousinVertices(primary);
+
+ secondaryCousins.removeAll(primaryCousins);
+ logger.info("removing vertex after merge: " + secondary );
+ if (this.hasNotifications && secondarySnapshot.isPresent()) {
+ this.notificationHelper.addEvent(secondary, secondarySnapshot.get(), EventAction.DELETE, this.serializer.getURIForVertex(secondary, false));
+ }
+ secondary.remove();
+ for (Vertex v : secondaryCousins) {
+ this.rules.addEdgeIfPossible(g, v, primary);
+ }
+ if (this.hasNotifications) {
+ final Introspector primarySnapshot = serializer.getLatestVersionView(primary);
+ this.notificationHelper.addEvent(primary, primarySnapshot, EventAction.UPDATE, this.serializer.getURIForVertex(primary, false));
+ }
+ }
+
+ /**
+ * This method may go away if we choose to event on each modification performed
+ * @param primary
+ * @param secondary
+ * @param forceCopy
+ * @throws AAIException
+ * @throws UnsupportedEncodingException
+ */
+ protected void performMergeHelper(Vertex primary, Vertex secondary, Map<String, Set<String>> forceCopy) throws AAIException, UnsupportedEncodingException {
+ mergeProperties(primary, secondary, forceCopy);
+
+ Collection<Vertex> secondaryChildren = this.engine.getQueryEngine().findChildren(secondary);
+ Collection<Vertex> primaryChildren = this.engine.getQueryEngine().findChildren(primary);
+
+ mergeChildren(primary, secondary, primaryChildren, secondaryChildren, forceCopy);
+
+ Collection<Vertex> secondaryCousins = this.engine.getQueryEngine().findCousinVertices(secondary);
+ Collection<Vertex> primaryCousins = this.engine.getQueryEngine().findCousinVertices(primary);
+
+ secondaryCousins.removeAll(primaryCousins);
+ secondary.remove();
+ for (Vertex v : secondaryCousins) {
+ this.rules.addEdgeIfPossible(g, v, primary);
+ }
+ }
+
+ private String getURI(Vertex v) throws UnsupportedEncodingException, AAIException {
+ Introspector obj = loader.introspectorFromName(v.<String>property(AAIProperties.NODE_TYPE).orElse(""));
+ this.serializer.dbToObject(Collections.singletonList(v), obj, 0, true, "false");
+ return obj.getURI();
+
+ }
+ private void mergeChildren(Vertex primary, Vertex secondary, Collection<Vertex> primaryChildren, Collection<Vertex> secondaryChildren, Map<String, Set<String>> forceCopy) throws UnsupportedEncodingException, AAIException {
+ Map<String, Vertex> primaryMap = uriMap(primaryChildren);
+ Map<String, Vertex> secondaryMap = uriMap(secondaryChildren);
+ Set<String> primaryKeys = new HashSet<>(primaryMap.keySet());
+ Set<String> secondaryKeys = new HashSet<>(secondaryMap.keySet());
+ primaryKeys.retainAll(secondaryKeys);
+ final Set<String> mergeItems = new HashSet<>(primaryKeys);
+ primaryKeys = new HashSet<>(primaryMap.keySet());
+ secondaryKeys = new HashSet<>(secondaryMap.keySet());
+ secondaryKeys.removeAll(primaryKeys);
+ final Set<String> copyItems = new HashSet<>(secondaryKeys);
+
+ for (String key : mergeItems) {
+ this.performMergeHelper(primaryMap.get(key), secondaryMap.get(key), forceCopy);
+ }
+
+ for (String key : copyItems) {
+ this.rules.addTreeEdgeIfPossible(g, secondaryMap.get(key), primary);
+ this.serializer.getEdgeBetween(EdgeType.TREE, secondary, secondaryMap.get(key)).remove();
+ }
+
+ }
+
+ private Map<String, Vertex> uriMap(Collection<Vertex> vertices) throws UnsupportedEncodingException, AAIException {
+ final Map<String, Vertex> result = new HashMap<>();
+ for (Vertex v : vertices) {
+ result.put(getURI(v), v);
+ }
+ return result;
+ }
+
+ private void mergeProperties(Vertex primary, Vertex secondary, Map<String, Set<String>> forceCopy) throws AAIUnknownObjectException {
+ final String primaryType = primary.<String>property(AAIProperties.NODE_TYPE).orElse("");
+ final String secondaryType = secondary.<String>property(AAIProperties.NODE_TYPE).orElse("");
+
+ final Introspector secondaryObj = loader.introspectorFromName(secondaryType);
+ secondary.properties().forEachRemaining(prop -> {
+ if (!primary.property(prop.key()).isPresent() || forceCopy.getOrDefault(primaryType, new HashSet<String>()).contains(prop.key())) {
+ primary.property(prop.key(), prop.value());
+ }
+ if (primary.property(prop.key()).isPresent() && secondary.property(prop.key()).isPresent() && secondaryObj.isListType(prop.key())) {
+ mergeCollection(primary, prop.key(), secondary.values(prop.key()));
+ }
+ });
+ }
+ private void mergeCollection(Vertex primary, String propName, Iterator<Object> secondaryValues) {
+ secondaryValues.forEachRemaining(item -> {
+ primary.property(propName, item);
+ });
+ }
+
+
+ public static class Builder {
+ private final TransactionalGraphEngine engine;
+
+ private final DBSerializer serializer;
+ private final Loader loader;
+ private NotificationHelper helper = null;
+ private boolean hasNotifications = false;
+ public Builder(Loader loader, TransactionalGraphEngine engine, DBSerializer serializer) {
+ this.loader = loader;
+ this.engine = engine;
+ this.serializer = serializer;
+ }
+
+ public Builder addNotifications(NotificationHelper helper) {
+ this.helper = helper;
+ this.hasNotifications = true;
+ return this;
+ }
+
+
+ public VertexMerge build() {
+ return new VertexMerge(this);
+ }
+
+ protected TransactionalGraphEngine getEngine() {
+ return engine;
+ }
+
+ protected DBSerializer getSerializer() {
+ return serializer;
+ }
+
+ protected Loader getLoader() {
+ return loader;
+ }
+
+ protected NotificationHelper getHelper() {
+ return helper;
+ }
+
+ protected boolean isHasNotifications() {
+ return hasNotifications;
+ }
+
+ }
+
+}
diff --git a/aai-resources/src/main/java/org/openecomp/aai/rest/LegacyMoxyConsumer.java b/aai-resources/src/main/java/org/openecomp/aai/rest/LegacyMoxyConsumer.java
index 7af432d..ca5fc33 100644
--- a/aai-resources/src/main/java/org/openecomp/aai/rest/LegacyMoxyConsumer.java
+++ b/aai-resources/src/main/java/org/openecomp/aai/rest/LegacyMoxyConsumer.java
@@ -140,6 +140,7 @@ public class LegacyMoxyConsumer extends RESTAPI {
dbEngine = httpEntry.getDbEngine();
URI uriObject = UriBuilder.fromPath(uri).build();
+ this.validateURI(uriObject);
QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject);
@@ -421,7 +422,8 @@ public class LegacyMoxyConsumer extends RESTAPI {
throw new AAIException("AAI_3102", "You must supply a relationship");
}
URI uriObject = UriBuilder.fromPath(uri).build();
-
+ this.validateURI(uriObject);
+
QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject);
Introspector wrappedEntity = loader.unmarshal("relationship", content, org.openecomp.aai.restcore.MediaType.getEnum(this.getInputMediaType(inputMediaType)));
@@ -524,7 +526,6 @@ public class LegacyMoxyConsumer extends RESTAPI {
Boolean success = true;
try {
-
validateRequest(info);
version = Version.valueOf(versionParam);
@@ -533,7 +534,7 @@ public class LegacyMoxyConsumer extends RESTAPI {
loader = httpEntry.getLoader();
dbEngine = httpEntry.getDbEngine();
URI uriObject = UriBuilder.fromPath(uri).build();
-
+ this.validateURI(uriObject);
QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject);
String objName = uriQuery.getResultType();
if (content.length() == 0) {
@@ -580,4 +581,14 @@ public class LegacyMoxyConsumer extends RESTAPI {
return response;
}
+ private void validateURI(URI uri) throws AAIException {
+ if (hasRelatedTo(uri)) {
+ throw new AAIException("AAI_3010");
+ }
+ }
+ private boolean hasRelatedTo(URI uri) {
+
+ return uri.toString().contains("/" + RestTokens.COUSIN + "/");
+
+ }
}
diff --git a/aai-resources/src/main/java/org/openecomp/aai/rest/RestTokens.java b/aai-resources/src/main/java/org/openecomp/aai/rest/RestTokens.java
new file mode 100644
index 0000000..13bfe65
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/rest/RestTokens.java
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.rest;
+
+public enum RestTokens {
+
+ COUSIN("related-to");
+ private final String name;
+
+ private RestTokens(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/aai-resources/src/main/java/org/openecomp/aai/rest/retired/V7V8Models.java b/aai-resources/src/main/java/org/openecomp/aai/rest/retired/V7V8Models.java
new file mode 100644
index 0000000..3eb53da
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/rest/retired/V7V8Models.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.rest.retired;
+
+import javax.ws.rs.Path;
+
+@Path("{version: v[78]}/service-design-and-creation/models")
+public class V7V8Models extends RetiredConsumer {
+
+}
diff --git a/aai-resources/src/main/java/org/openecomp/aai/rest/retired/V7V8NamedQueries.java b/aai-resources/src/main/java/org/openecomp/aai/rest/retired/V7V8NamedQueries.java
new file mode 100644
index 0000000..3f022a2
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/rest/retired/V7V8NamedQueries.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.rest.retired;
+
+import javax.ws.rs.Path;
+
+@Path("{version: v[78]}/service-design-and-creation/named-queries")
+public class V7V8NamedQueries extends RetiredConsumer {
+
+}
diff --git a/aai-resources/src/main/java/org/openecomp/aai/rest/ueb/NotificationEvent.java b/aai-resources/src/main/java/org/openecomp/aai/rest/ueb/NotificationEvent.java
index 389d296..e473e9d 100644
--- a/aai-resources/src/main/java/org/openecomp/aai/rest/ueb/NotificationEvent.java
+++ b/aai-resources/src/main/java/org/openecomp/aai/rest/ueb/NotificationEvent.java
@@ -31,12 +31,13 @@ import org.openecomp.aai.util.StoreNotificationEvent;
*/
public class NotificationEvent {
- private Loader loader = null;
+ private final Loader loader;
- private Introspector eventHeader = null;
-
- private Introspector obj = null;
+ private final Introspector eventHeader;
+ private final Introspector obj;
+ private final String transactionId;
+ private final String sourceOfTruth;
/**
* Instantiates a new notification event.
*
@@ -44,10 +45,12 @@ public class NotificationEvent {
* @param eventHeader the event header
* @param obj the obj
*/
- public NotificationEvent (Loader loader, Introspector eventHeader, Introspector obj) {
+ public NotificationEvent (Loader loader, Introspector eventHeader, Introspector obj, String transactionId, String sourceOfTruth) {
this.loader = loader;
this.eventHeader = eventHeader;
this.obj = obj;
+ this.transactionId = transactionId;
+ this.sourceOfTruth = sourceOfTruth;
}
/**
@@ -57,7 +60,7 @@ public class NotificationEvent {
*/
public void trigger() throws AAIException {
- StoreNotificationEvent sne = new StoreNotificationEvent();
+ StoreNotificationEvent sne = new StoreNotificationEvent(transactionId, sourceOfTruth);
sne.storeEvent(loader, eventHeader, obj);
diff --git a/aai-resources/src/main/java/org/openecomp/aai/rest/ueb/UEBNotification.java b/aai-resources/src/main/java/org/openecomp/aai/rest/ueb/UEBNotification.java
index 397082f..8cb16e1 100644
--- a/aai-resources/src/main/java/org/openecomp/aai/rest/ueb/UEBNotification.java
+++ b/aai-resources/src/main/java/org/openecomp/aai/rest/ueb/UEBNotification.java
@@ -50,7 +50,6 @@ public class UEBNotification {
private Loader currentVersionLoader = null;
protected List<NotificationEvent> events = null;
- private String urlBase = null;
private Version notificationVersion = null;
/**
@@ -61,7 +60,6 @@ public class UEBNotification {
public UEBNotification(Loader loader) {
events = new ArrayList<>();
currentVersionLoader = LoaderFactory.createLoaderForVersion(loader.getModelType(), AAIProperties.LATEST);
- urlBase = AAIConfig.get("aai.server.url.base","");
notificationVersion = Version.valueOf(AAIConfig.get("aai.notification.current.version","v10"));
}
@@ -78,7 +76,7 @@ public class UEBNotification {
* @throws IllegalArgumentException the illegal argument exception
* @throws UnsupportedEncodingException the unsupported encoding exception
*/
- public void createNotificationEvent(String transactionId, String sourceOfTruth, Status status, URI uri, Introspector obj, HashMap<String, Introspector> relatedObjects) throws AAIException, IllegalArgumentException, UnsupportedEncodingException {
+ public void createNotificationEvent(String transactionId, String sourceOfTruth, Status status, URI uri, Introspector obj, HashMap<String, Introspector> relatedObjects) throws AAIException, UnsupportedEncodingException {
String action = "UPDATE";
@@ -96,9 +94,9 @@ public class UEBNotification {
String entityLink = "";
if (uri.toString().startsWith("/")) {
- entityLink = urlBase + notificationVersion + uri;
+ entityLink = "/aai/" + notificationVersion + uri;
} else {
- entityLink = urlBase + notificationVersion + "/" + uri;
+ entityLink = "/aai/" + notificationVersion + "/" + uri;
}
@@ -148,7 +146,7 @@ public class UEBNotification {
}
}
- final NotificationEvent event = new NotificationEvent(currentVersionLoader, eventHeader, eventObject);
+ final NotificationEvent event = new NotificationEvent(currentVersionLoader, eventHeader, eventObject, transactionId, sourceOfTruth);
events.add(event);
} catch (AAIUnknownObjectException e) {
throw new RuntimeException("Fatal error - notification-event-header object not found!");
diff --git a/aai-resources/src/main/java/org/openecomp/aai/util/DataConversionHelper.java b/aai-resources/src/main/java/org/openecomp/aai/util/DataConversionHelper.java
new file mode 100644
index 0000000..c1d601d
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/util/DataConversionHelper.java
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.util;
+
+
+/**
+ * Utility to convert data from one form to another
+ *
+ */
+public class DataConversionHelper {
+
+ public static final String IPVERSION_IPV4 = "ipv4";
+ public static final String IPVERSION_IPV6 = "ipv6";
+ public static final String IPVERSION_UNKNOWN = "unknown";
+
+ /**
+ * Instantiates a new data conversion helper.
+ */
+ public DataConversionHelper() { }
+
+ /**
+ * Convert from 4 or 6 to ipv4 or ipv6. Returns unknown if 4 or 6 not passed.
+ * @param numVal expects good input but won't error if that's not what's passed
+ * @return IPVERSION constant, .
+ * @see org.openecomp.aai.domain.yang.IpVersion
+ */
+ public static String convertIPVersionNumToString(String numVal) {
+ if ("4".equals(numVal)) return IPVERSION_IPV4;
+ else if ("6".equals(numVal))return IPVERSION_IPV6;
+ else return IPVERSION_UNKNOWN;
+ }
+
+ /**
+ * Convert from ipv4 or ipv6 to 4 or 6. Returns 0 on bad input.
+ * @param stringVal expects good input but won't error if that's not what's passed
+ * @return 4 or 6, or 0 if a bad string is sent.
+ * @see org.openecomp.aai.domain.yang.IpVersion
+ */
+ public static String convertIPVersionStringToNum(String stringVal) {
+ if (IPVERSION_IPV4.equals(stringVal)) return "4";
+ else if (IPVERSION_IPV6.equals(stringVal)) return "6";
+ else return "0";
+ }
+
+}
diff --git a/aai-resources/src/main/java/org/openecomp/aai/util/DeleteResource.java b/aai-resources/src/main/java/org/openecomp/aai/util/DeleteResource.java
index 81ee621..5e60c5c 100644
--- a/aai-resources/src/main/java/org/openecomp/aai/util/DeleteResource.java
+++ b/aai-resources/src/main/java/org/openecomp/aai/util/DeleteResource.java
@@ -41,7 +41,7 @@ import com.google.common.base.CaseFormat;
public class DeleteResource {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(DeleteResource.class);
+ private static EELFLogger LOGGER;
private static final String FROMAPPID = "AAI-TOOLS";
private static final String TRANSID = UUID.randomUUID().toString();
// the logic below to parse the url is dependent on the node types
@@ -64,7 +64,7 @@ public class DeleteResource {
Properties props = System.getProperties();
props.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, AAIConstants.AAI_DELTOOL_LOGBACK_PROPS);
props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES);
-
+ LOGGER = EELFManager.getInstance().getLogger(DeleteResource.class);
String url = null;
try {
if ((args.length < 1) || ((args.length > 1) )) {
@@ -113,8 +113,12 @@ public class DeleteResource {
String resourceClass = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, resource);
resourceClass = "org.openecomp.aai.domain.yang." + resourceClass;
- LOGGER.debug("class=" + resourceClass);
- LOGGER.debug("path=" + path);
+ String dMsg = "class=" + resourceClass;
+ System.out.println(dMsg);
+ LOGGER.debug(dMsg);
+ dMsg = "path=" + path;
+ System.out.println(dMsg);
+ LOGGER.debug(dMsg);
if (bResVersionEnabled)
{
@@ -127,7 +131,9 @@ public class DeleteResource {
{
RestController.<T>Get(t, FROMAPPID, TRANSID, path, restObj, false);
t = restObj.get();
- LOGGER.info(" GET resoruceversion succeeded\n");
+ String infMsg = " GET resoruceversion succeeded\n";
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
String resourceUpdateVersion = GetResourceVersion(t);
path += "?resource-version=" + resourceUpdateVersion;
} catch (AAIException e) {
@@ -150,12 +156,14 @@ public class DeleteResource {
String confirm = s.next();
if (!confirm.equalsIgnoreCase("y")) {
- LOGGER.info("User chose to exit before deleting");
+ String infMsg = "User chose to exit before deleting";
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
System.exit(1);
}
RestController.Delete(FROMAPPID, TRANSID, path);
-
+
s.close();
System.exit(0);
diff --git a/aai-resources/src/main/java/org/openecomp/aai/util/GetResource.java b/aai-resources/src/main/java/org/openecomp/aai/util/GetResource.java
index f16efb3..a0a3297 100644
--- a/aai-resources/src/main/java/org/openecomp/aai/util/GetResource.java
+++ b/aai-resources/src/main/java/org/openecomp/aai/util/GetResource.java
@@ -36,7 +36,7 @@ import com.sun.jersey.api.client.ClientResponse;
public class GetResource {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(GetResource.class);
+ private static EELFLogger LOGGER;
private static final String FROMAPPID = "AAI-TOOLS";
private static final String TRANSID = UUID.randomUUID().toString();
private static final String USAGE_STRING = "Usage: getTool.sh <resource-path> \n + "
@@ -53,7 +53,7 @@ public class GetResource {
Properties props = System.getProperties();
props.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, AAIConstants.AAI_GETRES_LOGBACK_PROPS);
props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES);
-
+ LOGGER = EELFManager.getInstance().getLogger(GetResource.class);
String url = null;
try {
if (args.length < 1) {
@@ -66,16 +66,23 @@ public class GetResource {
url = args[0].replaceFirst("^/", "");
url = AAIConfig.get(AAIConstants.AAI_SERVER_URL) + url;
- LOGGER.debug("url=" + url);
+ String dmsg = "url=" + url;
+ LOGGER.debug( dmsg );
+ System.out.println( dmsg );
+
getNode(url);
System.exit(0);
}
} catch (AAIException e) {
- LOGGER.error("GET failed: " + e.getMessage());
+ String emsg = "GET failed: " + e.getMessage();
+ System.out.println(emsg);
+ LOGGER.error(emsg);
ErrorLogHelper.logException(e);
System.exit(1);
} catch (Exception e) {
- LOGGER.error("GET failed: " + e.getMessage());
+ String emsg = "GET failed: " + e.getMessage();
+ System.out.println(emsg);
+ LOGGER.error(emsg);
ErrorLogHelper.logError("AAI_7402", e.getMessage());
System.exit(1);
}
@@ -113,8 +120,10 @@ public class GetResource {
.get(ClientResponse.class);
if (cres.getStatus() == 404) { // resource not found
- LOGGER.info("\nResource does not exist: " + cres.getStatus()
- + ":" + cres.getEntity(String.class));
+ String infmsg = "\nResource does not exist: " + cres.getStatus()
+ + ":" + cres.getEntity(String.class);
+ System.out.println(infmsg);
+ LOGGER.info(infmsg);
throw new AAIException("AAI_7404", "Resource does not exist");
} else if (cres.getStatus() == 200){
String msg = cres.getEntity(String.class);
@@ -122,10 +131,13 @@ public class GetResource {
Object json = mapper.readValue(msg, Object.class);
String indented = mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(json);
+ System.out.println(indented);
LOGGER.info(indented);
} else {
- LOGGER.error("Getting the Resource failed: " + cres.getStatus()
- + ":\n" + cres.getEntity(String.class));
+ String emsg = "Getting the Resource failed: " + cres.getStatus()
+ + ":\n" + cres.getEntity(String.class);
+ System.out.println(emsg);
+ LOGGER.error(emsg);
throw new AAIException("AAI_7402", "Error during GET");
}
} catch (AAIException e) {
diff --git a/aai-resources/src/main/java/org/openecomp/aai/util/HttpsAuthClient.java b/aai-resources/src/main/java/org/openecomp/aai/util/HttpsAuthClient.java
index 89562f7..000ebd0 100644
--- a/aai-resources/src/main/java/org/openecomp/aai/util/HttpsAuthClient.java
+++ b/aai-resources/src/main/java/org/openecomp/aai/util/HttpsAuthClient.java
@@ -176,4 +176,62 @@ public class HttpsAuthClient{
}
+
+ public static Client getClient() throws KeyManagementException {
+
+ ClientConfig config = new DefaultClientConfig();
+ config.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
+ config.getClasses().add(org.openecomp.aai.restcore.CustomJacksonJaxBJsonProvider.class);
+
+ SSLContext ctx = null;
+ try {
+ String truststore_path = AAIConstants.AAI_HOME_ETC_AUTH + AAIConfig.get(AAIConstants.AAI_TRUSTSTORE_FILENAME);
+ String truststore_password = AAIConfig.get(AAIConstants.AAI_TRUSTSTORE_PASSWD);
+ String keystore_path = AAIConstants.AAI_HOME_ETC_AUTH + AAIConfig.get(AAIConstants.AAI_KEYSTORE_FILENAME);
+ String keystore_password = AAIConfig.get(AAIConstants.AAI_KEYSTORE_PASSWD);
+
+ System.setProperty("javax.net.ssl.trustStore", truststore_path);
+ System.setProperty("javax.net.ssl.trustStorePassword", truststore_password);
+ HttpsURLConnection.setDefaultHostnameVerifier( new HostnameVerifier(){
+ public boolean verify(String string,SSLSession ssls) {
+ return true;
+ }
+ });
+
+ ctx = SSLContext.getInstance("TLSv1.2");
+ KeyManagerFactory kmf = null;
+ try {
+ kmf = KeyManagerFactory.getInstance("SunX509");
+ FileInputStream fin = new FileInputStream(keystore_path);
+ KeyStore ks = KeyStore.getInstance("PKCS12");
+ char[] pwd = keystore_password.toCharArray();
+ ks.load(fin, pwd);
+ kmf.init(ks, pwd);
+ } catch (Exception e) {
+ System.out.println("Error setting up kmf: exiting");
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ ctx.init(kmf.getKeyManagers(), null, null);
+ config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
+ new HTTPSProperties( new HostnameVerifier() {
+ @Override
+ public boolean verify( String s, SSLSession sslSession ) {
+ return true;
+ }
+ }, ctx));
+ } catch (Exception e) {
+ System.out.println("Error setting up config: exiting");
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ Client client = Client.create(config);
+ // uncomment this line to get more logging for the request/response
+ // client.addFilter(new LoggingFilter(System.out));
+
+ return client;
+ }
+
}
diff --git a/aai-resources/src/main/java/org/openecomp/aai/util/JettyObfuscationConversionCommandLineUtil.java b/aai-resources/src/main/java/org/openecomp/aai/util/JettyObfuscationConversionCommandLineUtil.java
new file mode 100644
index 0000000..befa59c
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/util/JettyObfuscationConversionCommandLineUtil.java
@@ -0,0 +1,99 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.util;
+
+import org.apache.commons.cli.BasicParser;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.eclipse.jetty.util.security.Password;
+
+import org.openecomp.aai.exceptions.AAIException;
+
+/*
+ * The purpose of this class is to be a tool for
+ * manually applying jetty obfuscation/deobfuscation
+ * so that one can obfuscate the various passwords/secrets
+ * in aaiconfig.properties.
+ *
+ * Originally, they were being encrypted by a similar
+ * command line utility, however the encryption key
+ * was being hardcoded in the src package
+ * which is a security violation.
+ * Since this ultimately just moved the problem of how
+ * to hide secrets to a different secret in a different file,
+ * and since that encryption was really just being done to
+ * obfuscate those values in case someone needed to look at
+ * properties with others looking at their screen,
+ * we decided that jetty obfuscation would be adequate
+ * for that task as well as
+ * removing the "turtles all the way down" secret-to-hide-
+ * the-secret-to-hide-the-secret problem.
+ */
+public class JettyObfuscationConversionCommandLineUtil {
+
+ /**
+ * The main method.
+ *
+ * @param args the arguments
+ */
+ public static void main(String[] args){
+ Options options = new Options();
+ options.addOption("e", true, "obfuscate the given string");
+ options.addOption("d", true, "deobfuscate the given string");
+
+ CommandLineParser parser = new BasicParser();
+
+ try {
+ CommandLine cmd = parser.parse(options, args);
+ String toProcess = null;
+
+ if (cmd.hasOption("e")){
+ toProcess = cmd.getOptionValue("e");
+ String encoded = Password.obfuscate(toProcess);
+ System.out.println(encoded);
+ } else if (cmd.hasOption("d")) {
+ toProcess = cmd.getOptionValue("d");
+ String decoded_str = Password.deobfuscate(toProcess);
+ System.out.println(decoded_str);
+ } else {
+ usage();
+ }
+ } catch (ParseException e) {
+ System.out.println("failed to parse input");
+ System.out.println(e.toString());
+ usage();
+ } catch (Exception e) {
+ System.out.println("exception:" + e.toString());
+ }
+ }
+
+ /**
+ * Usage.
+ */
+ private static void usage(){
+ System.out.println("usage:");;
+ System.out.println("-e [string] to obfuscate");
+ System.out.println("-d [string] to deobfuscate");
+ System.out.println("-h help");
+ }
+}
diff --git a/aai-resources/src/main/java/org/openecomp/aai/util/PostResource.java b/aai-resources/src/main/java/org/openecomp/aai/util/PostResource.java
index 72fcd86..1caeb09 100644
--- a/aai-resources/src/main/java/org/openecomp/aai/util/PostResource.java
+++ b/aai-resources/src/main/java/org/openecomp/aai/util/PostResource.java
@@ -41,7 +41,7 @@ import com.google.common.base.CaseFormat;
*/
public class PostResource {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(PostResource.class);
+ private static EELFLogger LOGGER;
private static final String FROMAPPID = "AAI-TOOLS";
private static final String TRANSID = UUID.randomUUID().toString();
private static final String USAGE_STRING = "Usage: postTool.sh <resource-path> <filename>\n" +
@@ -61,7 +61,7 @@ public class PostResource {
Properties props = System.getProperties();
props.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, AAIConstants.AAI_POSTTOOL_LOGBACK_PROPS);
props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES);
-
+ LOGGER = EELFManager.getInstance().getLogger(PostResource.class);
try {
if (args.length < 2) {
System.out.println("Insufficient arguments");
@@ -85,8 +85,13 @@ public class PostResource {
System.exit(1);
}
- LOGGER.debug("class=" + resourceClass);
- LOGGER.debug("path=" + path);
+ String dMsg = "class=" + resourceClass;
+ System.out.println(dMsg);
+ LOGGER.debug(dMsg);
+
+ dMsg = "path=" + path;
+ System.out.println(dMsg);
+ LOGGER.debug(dMsg);
@SuppressWarnings("unchecked")
T resJson1 = (T)readJsonFile(Class.forName(resourceClass), args[1]);
@@ -95,9 +100,17 @@ public class PostResource {
ObjectMapper mapper = new ObjectMapper();
Object json = mapper.readValue(response, Object.class);
- LOGGER.info(" POST succeeded\n");
- LOGGER.info("Response = " + mapper.writer().withDefaultPrettyPrinter().writeValueAsString(json));
- LOGGER.info("\nDone!!");
+ String infMsg = " POST succeeded\n";
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
+
+ infMsg = "Response = " + mapper.writer().withDefaultPrettyPrinter().writeValueAsString(json);
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
+
+ infMsg = "\nDone!!";
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
System.exit(0);
diff --git a/aai-resources/src/main/java/org/openecomp/aai/util/PutResource.java b/aai-resources/src/main/java/org/openecomp/aai/util/PutResource.java
index 70fccb1..b4275b7 100644
--- a/aai-resources/src/main/java/org/openecomp/aai/util/PutResource.java
+++ b/aai-resources/src/main/java/org/openecomp/aai/util/PutResource.java
@@ -48,7 +48,7 @@ import com.sun.jersey.api.client.ClientResponse;
*/
public class PutResource {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(PutResource.class);
+ private static EELFLogger LOGGER;
private static final String FROMAPPID = "AAI-TOOLS";
private static final String TRANSID = UUID.randomUUID().toString();
private static final String USAGE_STRING = "Usage: putTool.sh <resource-path> <filename> <UpdatingRelationshiplist> <UpdatingChild> <ChildNameList> <SkipIfExists>\n" +
@@ -74,7 +74,7 @@ public class PutResource {
Properties props = System.getProperties();
props.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, AAIConstants.AAI_PUTTOOL_LOGBACK_PROPS);
props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES);
-
+ LOGGER = EELFManager.getInstance().getLogger(PutResource.class);
Boolean bResVersionEnabled = false;
try
@@ -144,16 +144,21 @@ public class PutResource {
LOGGER.debug("url=" + url);
if ( nodeExists( url) ) {
- LOGGER.info("PUT succeeded, the resource exists already in the DB. Skipping the put based on the skipIfExists command line parameter.\n");
- System.exit(0);
+ String infMsg ="PUT succeeded, the resource exists already in the DB. Skipping the put based on the skipIfExists command line parameter.\n";
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
+ System.exit(0);
}
-
}
RestController.<T>Get(t2, FROMAPPID, TRANSID, path, restObj, false);
t2 = restObj.get();
- LOGGER.info(" GET succeeded\n");
+ String infMsg = " GET succeeded\n";
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
+
} catch (AAIException e) {
- if ( !doPutIfExists ) {
+ if ( !doPutIfExists ) {
+ System.out.println("Warning - Caught exception while attempting to PUT resource");
LOGGER.warn("Caught exception while attempting to PUT resource", e);
}
bExist = false;
@@ -161,6 +166,7 @@ public class PutResource {
catch (Exception e1)
{
if ( !doPutIfExists ) {
+ System.out.println("Warning - GET exception ignored with skipExists parameter\n");
LOGGER.warn(" GET exception ignored with skipExists parameter\n", e1);
}
bExist = false;
@@ -177,17 +183,24 @@ public class PutResource {
String DBresourceVersion = GetResourceVersion(t2);
if ( !doPutIfExists ) {
- LOGGER.info("PUT succeeded, the resource exists already in the DB. Skipping the put based on the skipIfExists command line parameter.\n");
- System.exit(0);
+ String infMsg = "PUT succeeded, the resource exists already in the DB. Skipping the put based on the skipIfExists command line parameter.\n";
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
+ System.exit(0);
}
if (resourceUpdateVersion == null || resourceUpdateVersion.isEmpty())
{
- if ( DBresourceVersion != null && !DBresourceVersion.isEmpty())
- LOGGER.error("The resource with version = " + DBresourceVersion + " exists already in the DB. Please supply the right resourceVersion in input data file.\n");
- else
- LOGGER.error("The resource exists already in the DB. Please supply the right resourceVersion in input data file.\n");
-
+ if ( DBresourceVersion != null && !DBresourceVersion.isEmpty()){
+ String eMsg = "The resource with version = " + DBresourceVersion + " exists already in the DB. Please supply the right resourceVersion in input data file.\n";
+ System.out.println(eMsg);
+ LOGGER.error(eMsg);
+ }
+ else{
+ String eMsg = "The resource exists already in the DB. Please supply the right resourceVersion in input data file.\n";
+ System.out.println(eMsg);
+ LOGGER.error(eMsg);
+ }
System.exit(1);
}
@@ -196,7 +209,9 @@ public class PutResource {
if ( resourceUpdateVersion != null && !resourceUpdateVersion.isEmpty() )
if (!DBresourceVersion.equals(resourceUpdateVersion))
{
- LOGGER.error("DB version doesn't match current version. Please get the latest version and modify.\n");
+ String eMsg = "DB version doesn't match current version. Please get the latest version and modify.\n";
+ System.out.println(eMsg);
+ LOGGER.error(eMsg);
System.exit(1);
}
}
@@ -205,8 +220,10 @@ public class PutResource {
{
if ( bResVersionEnabled && resourceUpdateVersion != null && !resourceUpdateVersion.isEmpty())
{
- LOGGER.error("DB doesn't have this resource any more. Please create a new version by taking out the resourceVersion tag from your input resource data file.\n");
- System.exit(1);
+ String eMsg = "DB doesn't have this resource any more. Please create a new version by taking out the resourceVersion tag from your input resource data file.\n";
+ System.out.println(eMsg);
+ LOGGER.error(eMsg);
+ System.exit(1);
}
}
@@ -247,8 +264,12 @@ public class PutResource {
RestController.<T>Put(resJson1, FROMAPPID, TRANSID, path, false);
- LOGGER.info(" PUT succeeded");
- LOGGER.info("Done!!");
+ String infMsg = " PUT succeeded";
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
+ infMsg = "Done!!";
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
System.exit(0);
@@ -256,8 +277,13 @@ public class PutResource {
if ( !doPutIfExists ) { // ignore 412 failure
if ( e.getMessage().equals("AAI_7116") ) {
if ( e.getMessage().indexOf("status=412") > 0) {
- LOGGER.info("PUT succeeded, return 412 ignored\n");
- LOGGER.info("\nDone!!");
+ String infMsg = "PUT succeeded, return 412 ignored\n";
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
+
+ infMsg = "\nDone!!";
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
System.exit(0);
}
}
@@ -383,12 +409,14 @@ public class PutResource {
client = HttpsAuthClient.getTwoWaySSLClient();
}
- LOGGER.info("Getting the resource...: " + url);
-
+ String infMsg = "Getting the resource...: " + url;
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
+
ClientResponse cres = client.resource(url)
.header("X-TransactionId", TRANSID)
.header("X-FromAppId", FROMAPPID)
- .header("Authorization", HttpsAuthClient.getBasicAuthHeaderValue())
+ .header("Authorization", HttpsAuthClient.getBasicAuthHeaderValue())
.accept("application/json")
.get(ClientResponse.class);
@@ -398,9 +426,11 @@ public class PutResource {
} else if (cres.getStatus() == 200){
return true;
} else {
- LOGGER.error("Getting the Resource failed: " + cres.getStatus()
- + ": " + cres.getEntity(String.class));
- return false;
+ String eMsg = "Getting the Resource failed: " + cres.getStatus()
+ + ": " + cres.getEntity(String.class);
+ System.out.println(eMsg);
+ LOGGER.error(eMsg);
+ return false;
}
} catch (KeyManagementException e) {
throw new AAIException("AAI_7401", e, "Error during GET");
diff --git a/aai-resources/src/main/java/org/openecomp/aai/util/RelationshipPutDel.java b/aai-resources/src/main/java/org/openecomp/aai/util/RelationshipPutDel.java
new file mode 100644
index 0000000..a6a21ca
--- /dev/null
+++ b/aai-resources/src/main/java/org/openecomp/aai/util/RelationshipPutDel.java
@@ -0,0 +1,211 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.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.openecomp.aai.util;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.util.Properties;
+import java.util.UUID;
+
+import org.openecomp.aai.domain.yang.Relationship;
+import org.openecomp.aai.exceptions.AAIException;
+import com.att.eelf.configuration.Configuration;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+
+
+public class RelationshipPutDel {
+
+ private static final String FROMAPPID = "AAI-TOOLS";
+ private static final String TRANSID = UUID.randomUUID().toString();
+ private static EELFLogger LOGGER;
+ private static final String USAGE_STRING = "Usage: rshipTool.sh <PUT|DELETE> <resource-path> <filename>\n" +
+ "resource-path for a particular resource starting after the aai/<version>, relationship-list/relationship gets added by script\n" +
+ "filename is the path to a file which contains the json input for the relationship payload" +
+ "for example: relTool.sh PUT cloud-infrastructure/oam-networks/oam-network/test-100-oam /tmp/putrship.json\n";
+
+ /**
+ * The main method.
+ *
+ * @param args the arguments
+ */
+ public static void main(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_RSHIPTOOL_LOGBACK_PROPS);
+ props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES);
+ LOGGER = EELFManager.getInstance().getLogger(RelationshipPutDel.class);
+ String dMsg = "Start processing...";
+ System.out.println(dMsg);
+ LOGGER.debug(dMsg);
+
+ String rshipURL, resURL = null;
+ Relationship rship = null;
+
+ try {
+ if ((args.length < 3) || (!args[0].equalsIgnoreCase("PUT") && !args[0].equalsIgnoreCase("DELETE"))) {
+ System.out.println("Insufficient or Invalid arguments");
+ System.out.println(USAGE_STRING);
+ System.exit(1);
+ }
+
+ rship = readJsonFile(args[2]);
+
+ // Assume the config AAI_SERVER_URL has a last slash so remove if
+ // resource-path has it as the first char
+ resURL = args[1].replaceFirst("^/", "");
+ resURL = AAIConfig.get(AAIConstants.AAI_SERVER_URL) + resURL;
+ rshipURL = resURL.concat("/relationship-list/relationship");
+
+ dMsg = "Resource URL=" + rshipURL;
+ System.out.println(dMsg);
+ LOGGER.debug(dMsg);
+
+ PutDelRelationship(rshipURL, rship, args[0]);
+
+ String infMsg = args[0] + " Relationship succeeded to: " + rship.getRelatedTo() + "\n";
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
+
+ GetResource.getNode(resURL);
+ infMsg = "Done!!";
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
+
+ System.exit(0);
+
+ } catch (AAIException e) {
+ LOGGER.error(args[0] + " Relationship PUT/DELETE failed", e);
+ System.out.println(args[0] + " Relationship PUT/DELETE failed");
+ System.exit(1);
+ } catch (Exception e) {
+ LOGGER.error(args[0] + " Relationship PUT/DELETE failed", e);
+ System.out.println(args[0] + " Relationship PUT/DELETE failed");
+ System.exit(1);
+ }
+ }
+
+ /**
+ * Read json file.
+ *
+ * @param fName the f name
+ * @return the relationship
+ * @throws AAIException the AAI exception
+ */
+ public static Relationship readJsonFile( String fName ) throws AAIException {
+ String jsonData = "";
+ BufferedReader br = null;
+ Relationship rship = new Relationship();
+
+ try {
+ String line;
+ br = new BufferedReader(new FileReader(fName));
+ while ((line = br.readLine()) != null) {
+ jsonData += line + "\n";
+ }
+ } catch (IOException e) {
+ throw new AAIException("AAI_7403", e, "Error opening json file");
+ } finally {
+ try {
+ if (br != null)
+ br.close();
+ } catch (IOException ex) {
+ throw new AAIException("AAI_7403", ex, "Error closing json file");
+ }
+ }
+
+ try {
+ rship = MapperUtil.readWithDashesAsObjectOf(Relationship.class, jsonData);
+ }
+ catch (Exception je){
+ throw new AAIException("AAI_7403", je, "Error parsing json file");
+ }
+
+ return rship;
+
+ }//End readJsonFile()
+
+
+ /**
+ * Put del relationship.
+ *
+ * @param aaiLogger the aai logger
+ * @param logline the logline
+ * @param rshipURL the rship URL
+ * @param rship the rship
+ * @param action the action
+ * @throws AAIException the AAI exception
+ */
+ public static void PutDelRelationship(String rshipURL,
+ Relationship rship,
+ String action) throws AAIException{
+ try {
+ Client client = HttpsAuthClient.getClient();
+ ClientResponse cres = null;
+
+ if (action.equalsIgnoreCase("PUT"))
+ cres = client.resource(rshipURL)
+ .header("X-TransactionId", TRANSID)
+ .header("X-FromAppId", FROMAPPID)
+ .accept("application/json")
+ .entity(rship)
+ .put(ClientResponse.class);
+ else
+ cres = client.resource(rshipURL)
+ .header("X-TransactionId", TRANSID)
+ .header("X-FromAppId", FROMAPPID)
+ .accept("application/json")
+ .entity(rship)
+ .delete(ClientResponse.class);
+
+ if (cres.getStatus() == 404) { // resource not found
+ String infMsg = "Resource does not exist...: " + cres.getStatus()
+ + ":\n" + cres.getEntity(String.class);
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
+ throw new AAIException("AAI_7404", "Resource does not exist");
+ } else if ((action.equalsIgnoreCase("PUT") && cres.getStatus() == 200) ||
+ (action.equalsIgnoreCase("DELETE") && cres.getStatus() == 204)) {
+ String infMsg = action + " Resource status: " + cres.getStatus();
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
+ } else {
+ String eMsg = action + " Resource failed: " + cres.getStatus()
+ + ":\n" + cres.getEntity(String.class);
+ System.out.println(eMsg);
+ LOGGER.error(eMsg);
+ throw new AAIException("AAI_7402", "Error during PutDel");
+ }
+ } catch (AAIException e) {
+ throw e;
+ } catch (KeyManagementException e) {
+ throw new AAIException("AAI_7401", "Error during PutDel");
+ } catch (Exception e) {
+ throw new AAIException("AAI_7402", "Error during PutDel");
+ }
+ }
+
+}
diff --git a/aai-resources/src/main/java/org/openecomp/aai/util/StoreNotificationEvent.java b/aai-resources/src/main/java/org/openecomp/aai/util/StoreNotificationEvent.java
index ea674ed..181627b 100644
--- a/aai-resources/src/main/java/org/openecomp/aai/util/StoreNotificationEvent.java
+++ b/aai-resources/src/main/java/org/openecomp/aai/util/StoreNotificationEvent.java
@@ -25,20 +25,17 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
import java.util.UUID;
import javax.xml.bind.Marshaller;
-import org.apache.cxf.helpers.CastUtils;
-import org.apache.cxf.message.Message;
-import org.apache.cxf.phase.PhaseInterceptorChain;
import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
import org.json.JSONException;
import org.json.JSONObject;
+
import org.openecomp.aai.dmaap.AAIDmaapEventJMSProducer;
+import org.openecomp.aai.domain.notificationEvent.NotificationEvent;
import org.openecomp.aai.exceptions.AAIException;
import org.openecomp.aai.introspection.Introspector;
import org.openecomp.aai.introspection.Loader;
@@ -49,31 +46,90 @@ public class StoreNotificationEvent {
private AAIDmaapEventJMSProducer messageProducer;
private String fromAppId = "";
private String transId = "";
-
+ private final String transactionId;
+ private final String sourceOfTruth;
/**
* Instantiates a new store notification event.
*/
- public StoreNotificationEvent() {
+ public StoreNotificationEvent(String transactionId, String sourceOfTruth) {
this.messageProducer = new AAIDmaapEventJMSProducer();
- Message inMessage = PhaseInterceptorChain.getCurrentMessage().getExchange().getInMessage();
- Map<String, List<String>> headersList = CastUtils.cast((Map<?, ?>) inMessage.get(Message.PROTOCOL_HEADERS));
- if (headersList != null) {
- List<String> xt = headersList.get("X-TransactionId");
- if (xt != null) {
- for (String transIdValue : xt) {
- transId = transIdValue;
- }
- }
- List<String> fa = headersList.get("X-FromAppId");
- if (fa != null) {
- for (String fromAppIdValue : fa) {
+ this.transactionId = transactionId;
+ this.sourceOfTruth = sourceOfTruth;
+ }
- fromAppId = fromAppIdValue;
- }
- }
+ /**
+ * Store event.
+ *
+ * @param eh
+ * the eh
+ * @param obj
+ * the obj
+ * @throws AAIException
+ * the AAI exception
+ */
+ public void storeEvent(NotificationEvent.EventHeader eh, Object obj) throws AAIException {
+
+ if (obj == null) {
+ throw new AAIException("AAI_7350");
}
- }
+ org.openecomp.aai.domain.notificationEvent.ObjectFactory factory = new org.openecomp.aai.domain.notificationEvent.ObjectFactory();
+
+ org.openecomp.aai.domain.notificationEvent.NotificationEvent ne = factory.createNotificationEvent();
+
+ if (eh.getId() == null) {
+ eh.setId(genDate2() + "-" + UUID.randomUUID().toString());
+ }
+ if (eh.getTimestamp() == null) {
+ eh.setTimestamp(genDate());
+ }
+
+ // there's no default, but i think we want to put this in hbase?
+
+ if (eh.getEntityLink() == null) {
+ eh.setEntityLink("UNK");
+ }
+
+ if (eh.getAction() == null) {
+ eh.setAction("UNK");
+ }
+
+ if (eh.getEventType() == null) {
+ eh.setEventType(AAIConfig.get("aai.notificationEvent.default.eventType", "UNK"));
+ }
+
+ if (eh.getDomain() == null) {
+ eh.setDomain(AAIConfig.get("aai.notificationEvent.default.domain", "UNK"));
+ }
+
+ if (eh.getSourceName() == null) {
+ eh.setSourceName(AAIConfig.get("aai.notificationEvent.default.sourceName", "UNK"));
+ }
+
+ if (eh.getSequenceNumber() == null) {
+ eh.setSequenceNumber(AAIConfig.get("aai.notificationEvent.default.sequenceNumber", "UNK"));
+ }
+
+ if (eh.getSeverity() == null) {
+ eh.setSeverity(AAIConfig.get("aai.notificationEvent.default.severity", "UNK"));
+ }
+
+ if (eh.getVersion() == null) {
+ eh.setVersion(AAIConfig.get("aai.notificationEvent.default.version", "UNK"));
+ }
+
+ ne.setCambriaPartition(AAIConstants.UEB_PUB_PARTITION_AAI);
+ ne.setEventHeader(eh);
+ ne.setEntity(obj);
+
+ try {
+ PojoUtils pu = new PojoUtils();
+ String entityJson = pu.getJsonFromObject(ne);
+ sendToDmaapJmsQueue(entityJson);
+ } catch (Exception e) {
+ throw new AAIException("AAI_7350", e);
+ }
+ }
/**
* Store dynamic event.
diff --git a/aai-resources/src/main/java/org/openecomp/aai/util/UpdateResource.java b/aai-resources/src/main/java/org/openecomp/aai/util/UpdateResource.java
index adecfb1..1597a7b 100644
--- a/aai-resources/src/main/java/org/openecomp/aai/util/UpdateResource.java
+++ b/aai-resources/src/main/java/org/openecomp/aai/util/UpdateResource.java
@@ -35,7 +35,7 @@ import com.att.eelf.configuration.EELFManager;
public class UpdateResource {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(UpdateResource.class.getName());
+ private static EELFLogger LOGGER;
private static final String FROMAPPID = "AAIUPDT";
private static final String TRANSID = UUID.randomUUID().toString();
private static final String UPDATE_URL = "actions/update";
@@ -59,7 +59,7 @@ public class UpdateResource {
Properties props = System.getProperties();
props.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, AAIConstants.AAI_UPDTOOL_LOGBACK_PROPS);
props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES);
-
+ LOGGER = EELFManager.getInstance().getLogger(UpdateResource.class.getName());
try {
if (args.length < 3) {
System.out.println("Nothing to update or Insufficient arguments");
@@ -76,9 +76,11 @@ public class UpdateResource {
System.exit(0);
} catch (AAIException e) {
+ System.out.println("Error - Update Failed.");
ErrorLogHelper.logException(e);
System.exit(1);
} catch (Exception e) {
+ System.out.println("Error - Update Failed." + e.getMessage());
ErrorLogHelper.logError("AAI_7402", "Update failed: " + e.getMessage());
System.exit(1);
}
@@ -113,10 +115,16 @@ public class UpdateResource {
update.getAction().add(action);
- LOGGER.info("updating the resource... ");
-
+ String infMsg = "updating the resource... ";
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
+
RestController.<Update>Put(update, FROMAPPID, TRANSID, UPDATE_URL);
- LOGGER.info("Update Successful");
+
+ infMsg = "Update Successful";
+ System.out.println(infMsg);
+ LOGGER.info(infMsg);
+
} catch (AAIException e) {
throw e;
} catch (Exception e) {