diff options
Diffstat (limited to 'aai-resources/src/main/java/org')
78 files changed, 2082 insertions, 8400 deletions
diff --git a/aai-resources/src/main/java/org/onap/aai/IncreaseNodesTool.java b/aai-resources/src/main/java/org/onap/aai/IncreaseNodesTool.java new file mode 100644 index 0000000..5f94141 --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/IncreaseNodesTool.java @@ -0,0 +1,153 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.janusgraph.core.JanusGraph; +import org.janusgraph.core.JanusGraphTransaction; +import org.onap.aai.dbmap.AAIGraph; +import org.onap.aai.introspection.Introspector; +import org.onap.aai.introspection.Loader; +import org.onap.aai.introspection.LoaderFactory; +import org.onap.aai.introspection.ModelType; +import org.onap.aai.introspection.exceptions.AAIUnknownObjectException; +import org.onap.aai.setup.SchemaVersions; +import org.onap.aai.util.AAISystemExitUtil; +import org.onap.aai.util.PositiveNumValidator; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +public class IncreaseNodesTool { + + public static long nodeCount = 0; + + private LoaderFactory loaderFactory; + private SchemaVersions schemaVersions; + + public IncreaseNodesTool(LoaderFactory loaderFactory, SchemaVersions schemaVersions){ + this.loaderFactory = loaderFactory; + this.schemaVersions = schemaVersions; + } + + public static void main(String[] args) throws AAIUnknownObjectException, UnsupportedEncodingException { + + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + "org.onap.aai.config", + "org.onap.aai.setup" + ); + + LoaderFactory loaderFactory = context.getBean(LoaderFactory.class); + SchemaVersions schemaVersions = context.getBean(SchemaVersions.class); + + IncreaseNodesTool increaseNodesTool = new IncreaseNodesTool(loaderFactory, schemaVersions); + JanusGraph janusGraph = AAIGraph.getInstance().getGraph(); + increaseNodesTool.run(janusGraph,args); + AAISystemExitUtil.systemExitCloseAAIGraph(0); + + } + + + public void run(JanusGraph janusGraph, String[] args) throws AAIUnknownObjectException, UnsupportedEncodingException { + CommandLineArgs cArgs = new CommandLineArgs(); + JCommander jCommander = new JCommander(cArgs,args); + jCommander.setProgramName(IncreaseNodesTool.class.getSimpleName()); + + Loader loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDefaultVersion()); + Introspector obj = loader.introspectorFromName(cArgs.nodeType); + + List<String> propList = new ArrayList<String>(); + propList.addAll(obj.getRequiredProperties()); + + + nodeCount = Long.parseLong(cArgs.numberOfNodes); + addVertex(janusGraph, cArgs.nodeType,propList,cArgs); + } + + /*** + * adds a vertex based on user inputs of node type number of nodes and the node uri + * /cloud-infrastructure/pservers/pserver/ + * /network/pnfs/pnf/ + * /cloud-infrastructure/pservers/pserver/random-056fd6c4-7313-4fa0-b854-0d9983bdb0ab/DevB/p-interfaces/p-interface/ + * @param nodeType + * @param propList + * @param cArgs + */ + public void addVertex(JanusGraph janusGraph, String nodeType, List<String> propList,CommandLineArgs cArgs){ + + long startTime = System.currentTimeMillis(); + + try (JanusGraphTransaction transaction = janusGraph.newTransaction()) { + boolean success = true; + + try { + GraphTraversalSource g = transaction.traversal(); + for (long i = 1; i <= nodeCount; i++) { + String randomId = UUID.randomUUID().toString(); + Vertex v = g.addV().next(); + v.property("aai-node-type", nodeType); + v.property("source-of-truth", "IncreaseNodesTool"); + v.property("aai-uri", cArgs.uri+"random-"+randomId); + + for(String propName : propList){ + if(propName.equals("in-maint")){ + v.property(propName,"false"); + } + v.property(propName, "random-" + randomId); + System.out.println("node " + i + " added " + propList.get(0)+": " + "random-"+randomId); + } + } + } catch (Exception ex) { + success = false; + } finally { + if (success) { + transaction.commit(); + System.out.println("Transaction Committed"); + long endTime = System.currentTimeMillis(); + System.out.println("Total Time: "+ ((endTime - startTime)/ 1000.0) + "seconds"); + } else { + transaction.rollback(); + } + } + } + } + +} + +class CommandLineArgs { + + @Parameter(names = "-numberOfNodes", description = "how many nodes you would like to enter", required = true , validateWith = PositiveNumValidator.class) + public String numberOfNodes; + + @Parameter(names = "-nodeType", description = "They aai-node-type of the node being entered", required = true) + public String nodeType; + + @Parameter(names = "-uri", description = "uri to be passed for the node") + public String uri; +} + diff --git a/aai-resources/src/main/java/org/onap/aai/Profiles.java b/aai-resources/src/main/java/org/onap/aai/Profiles.java index f17d6b9..f0419d8 100644 --- a/aai-resources/src/main/java/org/onap/aai/Profiles.java +++ b/aai-resources/src/main/java/org/onap/aai/Profiles.java @@ -22,6 +22,7 @@ package org.onap.aai; public final class Profiles { public static final String DMAAP = "dmaap"; + public static final String DME2 = "dme2"; public static final String ONE_WAY_SSL = "one-way-ssl"; public static final String TWO_WAY_SSL = "two-way-ssl"; diff --git a/aai-resources/src/main/java/org/onap/aai/ResourcesApp.java b/aai-resources/src/main/java/org/onap/aai/ResourcesApp.java index 057ac16..988b057 100644 --- a/aai-resources/src/main/java/org/onap/aai/ResourcesApp.java +++ b/aai-resources/src/main/java/org/onap/aai/ResourcesApp.java @@ -19,15 +19,21 @@ */ package org.onap.aai; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; +import java.util.Map; +import java.util.UUID; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; + import org.onap.aai.config.PropertyPasswordConfiguration; +import org.onap.aai.config.SpringContextAware; import org.onap.aai.dbmap.AAIGraph; import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.ModelInjestor; + import org.onap.aai.logging.LoggingContext; -import org.onap.aai.migration.MigrationControllerInternal; +import org.onap.aai.logging.LoggingContext.StatusCode; import org.onap.aai.util.AAIConfig; +import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -37,10 +43,11 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerA import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.core.env.Environment; +import org.onap.aai.nodes.NodeIngestor; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import java.util.UUID; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; @SpringBootApplication // Component Scan provides a way to look for spring beans @@ -50,6 +57,7 @@ import java.util.UUID; @ComponentScan(basePackages = { "org.onap.aai.config", "org.onap.aai.web", + "org.onap.aai.setup", "org.onap.aai.tasks", "org.onap.aai.service", "org.onap.aai.rest" @@ -64,10 +72,21 @@ public class ResourcesApp { private static final EELFLogger logger = EELFManager.getInstance().getLogger(ResourcesApp.class.getName()); private static final String APP_NAME = "aai-resources"; + private static Map<String,String> contextMap; @Autowired private Environment env; + @Autowired + private NodeIngestor nodeIngestor; + + @Autowired + private SpringContextAware context; + + @Autowired + private SpringContextAware loaderFactory; + + @PostConstruct private void init() throws AAIException { System.setProperty("org.onap.aai.serverStarted", "false"); @@ -80,22 +99,22 @@ public class ResourcesApp { LoggingContext.requestId(UUID.randomUUID().toString()); LoggingContext.serviceName(APP_NAME); LoggingContext.targetServiceName("contextInitialized"); - + LoggingContext.statusCode(StatusCode.COMPLETE); + + contextMap = MDC.getCopyOfContextMap(); logger.info("AAI Server initialization started..."); // Setting this property to allow for encoded slash (/) in the path parameter // This is only needed for tomcat keeping this as temporary System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true"); - logger.info("Starting AAIGraph connections and the ModelInjestor"); + logger.info("Starting AAIGraph connections and the NodeInjestor"); if(env.acceptsProfiles(Profiles.TWO_WAY_SSL) && env.acceptsProfiles(Profiles.ONE_WAY_SSL)){ logger.warn("You have seriously misconfigured your application"); } - AAIConfig.init(); - ModelInjestor.getInstance(); - AAIGraph.getInstance(); + LoggingContext.restoreIfPossible(); } @PreDestroy @@ -104,29 +123,46 @@ public class ResourcesApp { AAIGraph.getInstance().graphShutdown(); } - public static void main(String[] args) { + public static void main(String[] args) throws AAIException { setDefaultProps(); + + LoggingContext.save(); + LoggingContext.component("init"); + LoggingContext.partnerName("NA"); + LoggingContext.targetEntity(APP_NAME); + LoggingContext.requestId(UUID.randomUUID().toString()); + LoggingContext.serviceName(APP_NAME); + LoggingContext.targetServiceName("contextInitialized"); + LoggingContext.statusCode(StatusCode.COMPLETE); + + SpringApplication app = new SpringApplication(ResourcesApp.class); + app.setLogStartupInfo(false); app.setRegisterShutdownHook(true); app.addInitializers(new PropertyPasswordConfiguration()); Environment env = app.run(args).getEnvironment(); - + MDC.setContextMap (contextMap); logger.info( "Application '{}' is running on {}!" , env.getProperty("spring.application.name"), env.getProperty("server.port") ); - if ("true".equals(AAIConfig.get("aai.run.migrations", "false"))) { - MigrationControllerInternal migrations = new MigrationControllerInternal(); - migrations.run(new String[]{"--commit"}); - } + // The main reason this was moved from the constructor is due + // to the SchemaGenerator needs the bean and during the constructor + // the Spring Context is not yet initialized + + AAIConfig.init(); + AAIGraph.getInstance(); logger.info("Resources MicroService Started"); logger.error("Resources MicroService Started"); logger.debug("Resources MicroService Started"); + System.out.println("Resources Microservice Started"); + + LoggingContext.restoreIfPossible(); } public static void setDefaultProps(){ @@ -150,6 +186,5 @@ public class ResourcesApp { System.setProperty("BUNDLECONFIG_DIR", "aai-resources/src/main/resources"); } } - } } diff --git a/aai-resources/src/main/java/org/onap/aai/config/ErrorHandler.java b/aai-resources/src/main/java/org/onap/aai/config/ErrorHandler.java new file mode 100644 index 0000000..22e12a6 --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/config/ErrorHandler.java @@ -0,0 +1,87 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.config; + +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.logging.ErrorLogHelper; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Responsible for dealing with uri that doesn't start with basePath + * All of the other interceptors will handle any uri that starts with basePath + * So we need this to ensure that these cases are properly handled + */ +@Order(1) +@Component +public class ErrorHandler extends OncePerRequestFilter { + + private String basePath; + + public ErrorHandler(@Value("${schema.uri.base.path}") String basePath){ + this.basePath = basePath; + if(!basePath.endsWith("/")){ + this.basePath = basePath + "/"; + } + } + + @Override + protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { + + String uri = httpServletRequest.getRequestURI(); + + if (uri != null && !(uri.startsWith(basePath))) { + + AAIException e = new AAIException("AAI_3012"); + ArrayList<String> templateVars = new ArrayList<>(); + + List<MediaType> mediaTypeList = new ArrayList<>(); + + String acceptHeader = httpServletRequest.getHeader("Accept"); + if (acceptHeader == null) { + mediaTypeList.add(MediaType.APPLICATION_XML_TYPE); + } else { + mediaTypeList.add(MediaType.valueOf(acceptHeader)); + } + + String message = ErrorLogHelper.getRESTAPIErrorResponse(mediaTypeList, e, templateVars); + + httpServletResponse.setStatus(400); + httpServletResponse.setContentType(mediaTypeList.get(0).toString()); + httpServletResponse.getWriter().print(message); + httpServletResponse.getWriter().close(); + return; + } + + filterChain.doFilter(httpServletRequest, httpServletResponse); + } + +} diff --git a/aai-resources/src/main/java/org/onap/aai/dbgen/DataSnapshot.java b/aai-resources/src/main/java/org/onap/aai/dbgen/DataSnapshot.java deleted file mode 100644 index 982a1bb..0000000 --- a/aai-resources/src/main/java/org/onap/aai/dbgen/DataSnapshot.java +++ /dev/null @@ -1,270 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.dbgen; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -import org.apache.tinkerpop.gremlin.structure.io.IoCore; -import org.apache.tinkerpop.gremlin.structure.io.graphson.LegacyGraphSONReader; -import org.onap.aai.dbmap.AAIGraph; -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.logging.ErrorLogHelper; -import org.onap.aai.util.AAIConfig; -import org.onap.aai.util.AAIConstants; -import org.onap.aai.util.AAISystemExitUtil; -import org.onap.aai.util.FormatDate; - -import com.att.eelf.configuration.Configuration; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; -import org.janusgraph.core.JanusGraph; -import org.janusgraph.core.util.JanusGraphCleanup; - -public class DataSnapshot { - - private static final String OLD_SNAPSHOT_FILE_ = "oldSnapshotFile "; - private static final String _COULD_NOT_BE_FOUND = " could not be found."; - private static final String _COULD_NOT_BE_READ = " could not be read."; - private static final String _HAD_NO_DATA = " had no data."; - - /** - * The main method. - * - * @param args - * the arguments - */ - public static void main(String[] args) { - // Set the logging file properties to be used by EELFManager - System.setProperty("aai.service.name", DataSnapshot.class.getSimpleName()); - Properties props = System.getProperties(); - props.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, AAIConstants.AAI_DATA_SNAPSHOT_LOGBACK_PROPS); - props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES); - - Boolean dbClearFlag = false; - JanusGraph graph = null; - String command = "JUST_TAKE_SNAPSHOT"; // This is the default - String oldSnapshotFileName = ""; - if (args.length == 1) { - command = args[0]; - } - if (args.length == 2) { - // If they pass in a RELOAD_ENTIRE_DB argument, then we will be - // reloading the database - // from the filename passed in -which will be expected to be found - // in our snapshot directory. - command = args[0]; - oldSnapshotFileName = args[1]; - } - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - AAIConfig.init(); - ErrorLogHelper.loadProperties(); - System.out.println("Command = " + command + ", oldSnapshotFileName = " + oldSnapshotFileName); - String targetDir = AAIConstants.AAI_HOME + AAIConstants.AAI_FILESEP + "logs" + AAIConstants.AAI_FILESEP + "data" + AAIConstants.AAI_FILESEP + "dataSnapshots"; - - // Make sure the dataSnapshots directory is there - new File(targetDir).mkdirs(); - - 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 DataSnapshot.java\n"; - System.out.println(emsg); - AAISystemExitUtil.systemExitCloseAAIGraph(1); - } - - if ("JUST_TAKE_SNAPSHOT".equals(command)) { - // ------------------------------------------ - // They just want to take a snapshot. - // ------------------------------------------ - FormatDate fd = new FormatDate("yyyyMMddHHmm", "GMT"); - String dteStr = fd.getDateTime(); - String newSnapshotOutFname = targetDir + AAIConstants.AAI_FILESEP + "dataSnapshot.graphSON." + dteStr; - - graph.io(IoCore.graphson()).writeGraph(newSnapshotOutFname); - - System.out.println("Snapshot written to " + newSnapshotOutFname); - /**** - * Don't really want to do this every hour ************** int - * vCount = 0; Iterator vIt = - * graph.query().vertices().iterator(); while( vIt.hasNext() ){ - * vCount++; vIt.next(); } System.out.println( - * "A little after taking the snapshot, we see: " + vCount + - * " vertices in the db."); - ************/ - } else if ("CLEAR_ENTIRE_DATABASE".equals(command)) { - // ------------------------------------------------------------------ - // They are calling this to clear the db before re-loading it - // later - // ------------------------------------------------------------------ - - // First - make sure the backup file they will be using can be - // found and has data - if (oldSnapshotFileName.isEmpty()) { - String emsg = "No oldSnapshotFileName passed to DataSnapshot."; - System.out.println(emsg); - AAISystemExitUtil.systemExitCloseAAIGraph(1); - } - String oldSnapshotFullFname = targetDir + AAIConstants.AAI_FILESEP + oldSnapshotFileName; - File f = new File(oldSnapshotFullFname); - if (!f.exists()) { - String emsg = OLD_SNAPSHOT_FILE_ + oldSnapshotFullFname + _COULD_NOT_BE_FOUND; - System.out.println(emsg); - AAISystemExitUtil.systemExitCloseAAIGraph(1); - } else if (!f.canRead()) { - String emsg = OLD_SNAPSHOT_FILE_ + oldSnapshotFullFname + _COULD_NOT_BE_READ; - System.out.println(emsg); - AAISystemExitUtil.systemExitCloseAAIGraph(1); - } else if (f.length() == 0) { - String emsg = OLD_SNAPSHOT_FILE_ + oldSnapshotFullFname + _HAD_NO_DATA; - System.out.println(emsg); - AAISystemExitUtil.systemExitCloseAAIGraph(1); - } - - System.out.println("\n>>> WARNING <<<< "); - System.out.println(">>> All data and schema in this database will be removed at this point. <<<"); - System.out.println(">>> Processing will begin in 5 seconds. <<<"); - System.out.println(">>> WARNING <<<< "); - - try { - // Give them a chance to back out of this - Thread.sleep(5000); - } catch (java.lang.InterruptedException ie) { - System.out.println(" DB Clearing has been aborted. "); - Thread.currentThread().interrupt(); - AAISystemExitUtil.systemExitCloseAAIGraph(1); - } - - System.out.println(" Begin clearing out old data. "); - graph.close(); - JanusGraphCleanup.clear(graph); - System.out.println(" Done clearing data. "); - System.out.println(">>> IMPORTANT - NOTE >>> you need to run the SchemaGenerator (use GenTester) before "); - System.out.println(" reloading data or the data will be put in without indexes. "); - dbClearFlag = true; - - } else if ("RELOAD_LEGACY_DATA".equals(command)) { - // ------------------------------------------------------------------- - // They want to restore the database from an old snapshot file - // ------------------------------------------------------------------- - if (oldSnapshotFileName.isEmpty()) { - String emsg = "No oldSnapshotFileName passed to DataSnapshot when RELOAD_LEGACY_DATA used."; - System.out.println(emsg); - AAISystemExitUtil.systemExitCloseAAIGraph(1); - } - String oldSnapshotFullFname = targetDir + AAIConstants.AAI_FILESEP + oldSnapshotFileName; - File f = new File(oldSnapshotFullFname); - if (!f.exists()) { - String emsg = OLD_SNAPSHOT_FILE_ + oldSnapshotFullFname + _COULD_NOT_BE_FOUND; - System.out.println(emsg); - AAISystemExitUtil.systemExitCloseAAIGraph(1); - } else if (!f.canRead()) { - String emsg = OLD_SNAPSHOT_FILE_ + oldSnapshotFullFname + _COULD_NOT_BE_READ; - System.out.println(emsg); - AAISystemExitUtil.systemExitCloseAAIGraph(1); - } else if (f.length() == 0) { - String emsg = OLD_SNAPSHOT_FILE_ + oldSnapshotFullFname + _HAD_NO_DATA; - System.out.println(emsg); - AAISystemExitUtil.systemExitCloseAAIGraph(1); - } - - System.out.println("We will load data IN from the file = " + oldSnapshotFullFname); - System.out.println(" Begin reloading JanusGraph 0.5 data. "); - - LegacyGraphSONReader lgr = LegacyGraphSONReader.build().create(); - InputStream is = new FileInputStream(oldSnapshotFullFname); - lgr.readGraph(is, graph); - - System.out.println("Completed the inputGraph command, now try to commit()... "); - graph.tx().commit(); - System.out.println("Completed reloading JanusGraph 0.5 data."); - - long vCount = graph.traversal().V().count().next(); - System.out.println("A little after repopulating from an old snapshot, we see: " + vCount + " vertices in the db."); - } else if (command.equals("RELOAD_DATA")) { - // ------------------------------------------------------------------- - // They want to restore the database from an old snapshot file - // ------------------------------------------------------------------- - if (oldSnapshotFileName.equals("")) { - String emsg = "No oldSnapshotFileName passed to DataSnapshot when RELOAD_DATA used."; - System.out.println(emsg); - AAISystemExitUtil.systemExitCloseAAIGraph(1); - } - String oldSnapshotFullFname = targetDir + AAIConstants.AAI_FILESEP + oldSnapshotFileName; - File f = new File(oldSnapshotFullFname); - if (!f.exists()) { - String emsg = OLD_SNAPSHOT_FILE_ + oldSnapshotFullFname + _COULD_NOT_BE_FOUND; - System.out.println(emsg); - AAISystemExitUtil.systemExitCloseAAIGraph(1); - } else if (!f.canRead()) { - String emsg = OLD_SNAPSHOT_FILE_ + oldSnapshotFullFname + _COULD_NOT_BE_READ; - System.out.println(emsg); - AAISystemExitUtil.systemExitCloseAAIGraph(1); - } else if (f.length() == 0) { - String emsg = OLD_SNAPSHOT_FILE_ + oldSnapshotFullFname + _HAD_NO_DATA; - System.out.println(emsg); - AAISystemExitUtil.systemExitCloseAAIGraph(1); - } - - System.out.println("We will load data IN from the file = " + oldSnapshotFullFname); - System.out.println(" Begin reloading data. "); - graph.io(IoCore.graphson()).readGraph(oldSnapshotFullFname); - System.out.println("Completed the inputGraph command, now try to commit()... "); - graph.tx().commit(); - System.out.println("Completed reloading data."); - - long vCount = graph.traversal().V().count().next(); - - System.out.println("A little after repopulating from an old snapshot, we see: " + vCount + " vertices in the db."); - } else { - String emsg = "Bad command passed to DataSnapshot: [" + command + "]"; - System.out.println(emsg); - AAISystemExitUtil.systemExitCloseAAIGraph(1); - } - - } catch (AAIException e) { - ErrorLogHelper.logError("AAI_6128", e.getMessage()); - } catch (Exception ex) { - ErrorLogHelper.logError("AAI_6128", ex.getMessage()); - } finally { - if (!dbClearFlag && graph != null && graph.isOpen()) { - // Any changes that worked correctly should have already done - // thier commits. - graph.tx().rollback(); - graph.close(); - } - try { - baos.close(); - } catch (IOException iox) { - } - } - - AAISystemExitUtil.systemExitCloseAAIGraph(0); - - }// End of main() - -} diff --git a/aai-resources/src/main/java/org/onap/aai/dbgen/DupeTool.java b/aai-resources/src/main/java/org/onap/aai/dbgen/DupeTool.java deleted file mode 100644 index 1e323b0..0000000 --- a/aai-resources/src/main/java/org/onap/aai/dbgen/DupeTool.java +++ /dev/null @@ -1,1877 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.dbgen; -import java.io.FileInputStream; -import java.io.InputStream; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; - -import java.util.Properties; -import java.util.UUID; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -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.Vertex; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; -import org.onap.aai.db.props.AAIProperties; -import org.onap.aai.dbmap.AAIGraphConfig; -import org.onap.aai.dbmap.AAIGraph; -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.Introspector; -import org.onap.aai.introspection.Loader; -import org.onap.aai.introspection.LoaderFactory; -import org.onap.aai.introspection.ModelType; -import org.onap.aai.logging.ErrorLogHelper; -import org.onap.aai.logging.LogFormatTools; -import org.onap.aai.logging.LoggingContext; -import org.onap.aai.logging.LoggingContext.StatusCode; -import org.onap.aai.util.AAIConfig; -import org.onap.aai.util.AAIConstants; -import org.slf4j.MDC; - -import com.att.eelf.configuration.Configuration; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; -import org.janusgraph.core.JanusGraphFactory; -import org.janusgraph.core.JanusGraph; - - - -public class DupeTool { - - private static final String FROMAPPID = "AAI-DB"; - private static final String TRANSID = UUID.randomUUID().toString(); - private static final String COULD_NOT_FIND_EDGE_ID_ = " >>> COULD NOT FIND VERTEX on the other side of this edge edgeId = "; - private static final String AAI_NODE_TYPE = "aai-node-type"; - private static final String KEEP_VID = "KeepVid"; - private static final String INMEMORY = "inmemory"; - - private static String graphType = "realdb"; - - public static boolean SHOULD_EXIT_VM = true; - - public static int EXIT_VM_STATUS_CODE = -1; - - public static void exit(int statusCode){ - if(SHOULD_EXIT_VM){ - System.exit(1); - } - EXIT_VM_STATUS_CODE = statusCode; - } - - - /** - * The main method. - * - * @param args the arguments - */ - public static void main(String[] args) { - System.setProperty("aai.service.name", DupeTool.class.getSimpleName()); - // Set the logging file properties to be used by EELFManager - Properties props = System.getProperties(); - props.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, "dupeTool-logback.xml"); - props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES); - EELFLogger logger = EELFManager.getInstance().getLogger(DupeTool.class.getSimpleName()); - MDC.put("logFilenameAppender", DupeTool.class.getSimpleName()); - - LoggingContext.init(); - LoggingContext.partnerName(FROMAPPID); - LoggingContext.serviceName(AAIConstants.AAI_RESOURCES_MS); - LoggingContext.component("dupeTool"); - LoggingContext.targetEntity(AAIConstants.AAI_RESOURCES_MS); - LoggingContext.targetServiceName("main"); - LoggingContext.requestId(TRANSID); - LoggingContext.statusCode(StatusCode.COMPLETE); - LoggingContext.responseCode(LoggingContext.SUCCESS); - - String defVersion = "v9"; - try { - defVersion = AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP); - } - catch ( AAIException ae ){ - String emsg = "Error trying to get default API Version property \n"; - System.out.println(emsg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logger.error(emsg); - exit(0); - } - - Loader loader= null; - try { - loader = LoaderFactory.createLoaderForVersion(ModelType.MOXY, AAIProperties.LATEST); - - } - catch (Exception ex){ - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.UNKNOWN_ERROR); - logger.error("ERROR - Could not do the moxyMod.init() " + LogFormatTools.getStackTop(ex)); - exit(1); - } - JanusGraph graph1 = null; - JanusGraph graph2 = null; - Graph gt1 = null; - Graph gt2 = null; - - boolean specialTenantRule = false; - - try { - AAIConfig.init(); - int maxRecordsToFix = AAIConstants.AAI_DUPETOOL_DEFAULT_MAX_FIX; - int sleepMinutes = AAIConstants.AAI_DUPETOOL_DEFAULT_SLEEP_MINUTES; - int timeWindowMinutes = 0; // A value of 0 means that we will not have a time-window -- we will look - // at all nodes of the passed-in nodeType. - long windowStartTime = 0; // Translation of the window into a starting timestamp - - try { - String maxFixStr = AAIConfig.get("aai.dupeTool.default.max.fix"); - if( maxFixStr != null && !maxFixStr.isEmpty() ){ - maxRecordsToFix = Integer.parseInt(maxFixStr); - } - String sleepStr = AAIConfig.get("aai.dupeTool.default.sleep.minutes"); - if( sleepStr != null && !sleepStr.isEmpty() ){ - sleepMinutes = Integer.parseInt(sleepStr); - } - } - catch ( Exception e ){ - // Don't worry, we'll just use the defaults that we got from AAIConstants - logger.warn("WARNING - could not pick up aai.dupeTool values from aaiconfig.properties file. Will use defaults. "); - } - - String nodeTypeVal = ""; - String userIdVal = ""; - String filterParams = ""; - Boolean skipHostCheck = false; - Boolean autoFix = false; - String argStr4Msg = ""; - Introspector obj = null; - - 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 ("-nodeType".equals(thisArg)) { - i++; - if (i >= args.length) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(" No value passed with -nodeType option. "); - exit(0); - } - nodeTypeVal = args[i]; - argStr4Msg = argStr4Msg + " " + nodeTypeVal; - } - else if ("-sleepMinutes".equals(thisArg)) { - i++; - if (i >= args.length) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error("No value passed with -sleepMinutes option."); - exit(0); - } - String nextArg = args[i]; - try { - sleepMinutes = Integer.parseInt(nextArg); - } catch (Exception e) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error("Bad value passed with -sleepMinutes option: [" - + nextArg + "]"); - exit(0); - } - argStr4Msg = argStr4Msg + " " + sleepMinutes; - } - else if ("-maxFix".equals(thisArg)) { - i++; - if (i >= args.length) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error("No value passed with -maxFix option."); - exit(0); - } - String nextArg = args[i]; - try { - maxRecordsToFix = Integer.parseInt(nextArg); - } catch (Exception e) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error("Bad value passed with -maxFix option: [" - + nextArg + "]"); - exit(0); - } - argStr4Msg = argStr4Msg + " " + maxRecordsToFix; - } - else if ("-timeWindowMinutes".equals(thisArg)) { - i++; - if (i >= args.length) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error("No value passed with -timeWindowMinutes option."); - exit(0); - } - String nextArg = args[i]; - try { - timeWindowMinutes = Integer.parseInt(nextArg); - } catch (Exception e) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error("Bad value passed with -timeWindowMinutes option: [" - + nextArg + "]"); - exit(0); - } - argStr4Msg = argStr4Msg + " " + timeWindowMinutes; - } - else if ("-skipHostCheck".equals(thisArg)) { - skipHostCheck = true; - } - else if ("-specialTenantRule".equals(thisArg)) { - specialTenantRule = true; - } - else if ("-autoFix".equals(thisArg)) { - autoFix = true; - } - else if ("-userId".equals(thisArg)) { - i++; - if (i >= args.length) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(" No value passed with -userId option. "); - exit(0); - } - userIdVal = args[i]; - argStr4Msg = argStr4Msg + " " + userIdVal; - } - else if ("-params4Collect".equals(thisArg)) { - i++; - if (i >= args.length) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(" No value passed with -params4Collect option. "); - exit(0); - } - filterParams = args[i]; - argStr4Msg = argStr4Msg + " " + filterParams; - } - else { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(" Unrecognized argument passed to DupeTool: [" - + thisArg + "]. "); - logger.error(" Valid values are: -action -userId -vertexId -edgeId -overRideProtection "); - exit(0); - } - } - } - - userIdVal = userIdVal.trim(); - if( (userIdVal.length() < 6) || "AAIADMIN".equalsIgnoreCase(userIdVal) ){ - String emsg = "userId parameter is required. [" + userIdVal + "] passed to DupeTool(). userId must be not empty and not aaiadmin \n"; - System.out.println(emsg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(emsg); - exit(0); - } - - nodeTypeVal = nodeTypeVal.trim(); - if( nodeTypeVal.isEmpty() ){ - String emsg = " nodeType is a required parameter for DupeTool().\n"; - System.out.println(emsg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(emsg); - exit(0); - } - obj = loader.introspectorFromName(nodeTypeVal); - - if (skipHostCheck) { - logger.info(" We will skip the HostCheck as requested. "); - } - - if( timeWindowMinutes > 0 ){ - // Translate the window value (ie. 30 minutes) into a unix timestamp like - // we use in the db - so we can select data created after that time. - windowStartTime = figureWindowStartTime( timeWindowMinutes ); - } - - String msg = ""; - msg = "DupeTool called with these params: [" + argStr4Msg + "]"; - System.out.println(msg); - logger.info(msg); - - // Determine what the key fields are for this nodeType (and we want them ordered) - ArrayList <String> keyPropNamesArr = new ArrayList<String>(obj.getKeys()); - - // Determine what kinds of nodes (if any) this nodeType is dependent on for uniqueness - ArrayList<String> depNodeTypeList = new ArrayList<String>(); - Collection<String> depNTColl = obj.getDependentOn(); - Iterator<String> ntItr = depNTColl.iterator(); - while( ntItr.hasNext() ){ - depNodeTypeList.add(ntItr.next()); - } - - // Based on the nodeType, window and filterData, figure out the vertices that we will be checking - System.out.println(" ---- NOTE --- about to open graph (takes a little while)--------\n"); - graph1 = setupGraph(logger); - gt1 = getGraphTransaction( graph1, logger ); - ArrayList<Vertex> verts2Check = new ArrayList<Vertex>(); - - verts2Check = figureOutNodes2Check( TRANSID, FROMAPPID, gt1, - nodeTypeVal, windowStartTime, filterParams, logger ); - - if( verts2Check == null || verts2Check.isEmpty() ){ - msg = " No vertices found to check. Used nodeType = [" + nodeTypeVal - + "], windowMinutes = " + timeWindowMinutes - + ", filterData = [" + filterParams + "]."; - logger.info( msg ); - System.out.println( msg ); - exit(0); - } - else { - msg = " Found " + verts2Check.size() + " nodes of type " + nodeTypeVal - + " to check using passed filterParams and windowStartTime. "; - logger.info( msg ); - System.out.println( msg ); - } - - ArrayList<String> firstPassDupeSets = new ArrayList <String>(); - ArrayList <String> secondPassDupeSets = new ArrayList <String>(); - Boolean isDependentOnParent = false; - if( !obj.getDependentOn().isEmpty() ){ - isDependentOnParent = true; - } - - if( isDependentOnParent ){ - firstPassDupeSets = getDupeSets4DependentNodes( TRANSID, FROMAPPID, gt1, - defVersion, nodeTypeVal, verts2Check, keyPropNamesArr, loader, - specialTenantRule, logger ); - } - else { - firstPassDupeSets = getDupeSets4NonDepNodes( TRANSID, FROMAPPID, gt1, - defVersion, nodeTypeVal, verts2Check, keyPropNamesArr, - specialTenantRule, loader, logger ); - } - - msg = " Found " + firstPassDupeSets.size() + " sets of duplicates for this request. "; - logger.info( msg ); - System.out.println( msg ); - if( !firstPassDupeSets.isEmpty() ){ - msg = " Here is what they look like: "; - logger.info( msg ); - System.out.println( msg ); - for( int x = 0; x < firstPassDupeSets.size(); x++ ){ - msg = " Set " + x + ": [" + firstPassDupeSets.get(x) +"] "; - logger.info( msg ); - System.out.println( msg ); - showNodeDetailsForADupeSet(gt1, firstPassDupeSets.get(x), logger); - } - } - - boolean didSomeDeletesFlag = false; - ArrayList <String> dupeSetsToFix = new ArrayList <String> (); - if( autoFix && firstPassDupeSets.isEmpty() ){ - msg = "AutoFix option is on, but no dupes were found on the first pass. Nothing to fix."; - logger.info( msg ); - System.out.println( msg ); - } - else if( autoFix ){ - // We will try to fix any dupes that we can - but only after sleeping for a - // time and re-checking the list of duplicates using a seperate transaction. - try { - msg = "\n\n----------- About to sleep for " + sleepMinutes + " minutes." - + " -----------\n\n"; - logger.info( msg ); - System.out.println( msg ); - int sleepMsec = sleepMinutes * 60 * 1000; - Thread.sleep(sleepMsec); - } catch (InterruptedException ie) { - msg = "\n >>> Sleep Thread has been Interrupted <<< "; - Thread.currentThread().interrupt(); - logger.info( msg ); - System.out.println( msg ); - exit(0); - } - - graph2 = setupGraph(logger); - gt2 = getGraphTransaction( graph2, logger ); - if( isDependentOnParent ){ - secondPassDupeSets = getDupeSets4DependentNodes( TRANSID, FROMAPPID, gt2, - defVersion, nodeTypeVal, verts2Check, keyPropNamesArr, loader, - specialTenantRule, logger ); - } - else { - secondPassDupeSets = getDupeSets4NonDepNodes( TRANSID, FROMAPPID, gt2, - defVersion, nodeTypeVal, verts2Check, keyPropNamesArr, - specialTenantRule, loader, logger ); - } - - dupeSetsToFix = figureWhichDupesStillNeedFixing( firstPassDupeSets, secondPassDupeSets, logger ); - msg = "\nAfter running a second pass, there were " + dupeSetsToFix.size() - + " sets of duplicates that we think can be deleted. "; - logger.info( msg ); - System.out.println( msg ); - if( !dupeSetsToFix.isEmpty()){ - msg = " Here is what the sets look like: "; - logger.info( msg ); - System.out.println( msg ); - for( int x = 0; x < dupeSetsToFix.size(); x++ ){ - msg = " Set " + x + ": [" + dupeSetsToFix.get(x) +"] "; - logger.info( msg ); - System.out.println( msg ); - showNodeDetailsForADupeSet(gt2, dupeSetsToFix.get(x), logger); - } - } - - if( !dupeSetsToFix.isEmpty() ){ - if( dupeSetsToFix.size() > maxRecordsToFix ){ - String infMsg = " >> WARNING >> Dupe list size (" - + dupeSetsToFix.size() - + ") is too big. The maxFix we are using is: " - + maxRecordsToFix - + ". No nodes will be deleted. (use the" - + " -maxFix option to override this limit.)"; - System.out.println(infMsg); - logger.info(infMsg); - } - else { - // Call the routine that fixes known dupes - didSomeDeletesFlag = deleteNonKeepers( gt2, dupeSetsToFix, logger ); - } - } - if( didSomeDeletesFlag ){ - gt2.tx().commit(); - } - } - - } catch (AAIException e) { - logger.error("Caught AAIException while running the dupeTool: " + LogFormatTools.getStackTop(e)); - ErrorLogHelper.logException(e); - } catch (Exception ex) { - logger.error("Caught exception while running the dupeTool: "+ LogFormatTools.getStackTop(ex)); - ErrorLogHelper.logError("AAI_6128", ex.getMessage() + ", resolve and rerun the dupeTool. "); - } finally { - if (gt1 != null && gt1.tx().isOpen()) { - // We don't change any data with gt1 - so just roll it back so it knows we're done. - try { - gt1.tx().rollback(); - } - catch (Exception ex) { - // Don't throw anything because JanusGraph sometimes is just saying that the graph is already closed - logger.warn("WARNING from final gt1.rollback() " + LogFormatTools.getStackTop(ex)); - } - } - - if (gt2 != null && gt2.tx().isOpen()) { - // Any changes that worked correctly should have already done - // their commits. - try { - gt2.tx().rollback(); - } catch (Exception ex) { - // Don't throw anything because JanusGraph sometimes is just saying that the graph is already closed - logger.warn("WARNING from final gt2.rollback() " + LogFormatTools.getStackTop(ex)); - } - } - - try { - if( graph1 != null && graph1.isOpen() ){ - closeGraph(graph1, logger); - } - } catch (Exception ex) { - // Don't throw anything because JanusGraph sometimes is just saying that the graph is already closed{ - logger.warn("WARNING from final graph1.shutdown() " + LogFormatTools.getStackTop(ex)); - } - - try { - if( graph2 != null && graph2.isOpen() ){ - closeGraph(graph2, logger); - } - } catch (Exception ex) { - // Don't throw anything because JanusGraph sometimes is just saying that the graph is already closed{ - logger.warn("WARNING from final graph2.shutdown() " + LogFormatTools.getStackTop(ex)); - } - } - - exit(0); - - }// end of main() - - - /** - * Collect Duplicate Sets for nodes that are NOT dependent on parent nodes. - * - * @param transId the trans id - * @param fromAppId the from app id - * @param g the g - * @param version the version - * @param nType the n type - * @param passedVertList the passed vert list - * @return the array list - */ - private static ArrayList<String> getDupeSets4NonDepNodes( String transId, - String fromAppId, Graph g, String version, String nType, - ArrayList<Vertex> passedVertList, - ArrayList <String> keyPropNamesArr, - Boolean specialTenantRule, Loader loader, EELFLogger logger ) { - - ArrayList<String> returnList = new ArrayList<String>(); - - // We've been passed a set of nodes that we want to check. - // They are all NON-DEPENDENT nodes meaning that they should be - // unique in the DB based on their KEY DATA alone. So, if - // we group them by their key data - if any key has more than one - // vertex mapped to it, those vertices are dupes. - // - // When we find duplicates, we return then as a String (there can be - // more than one duplicate for one set of key data): - // Each element in the returned arrayList might look like this: - // "1234|5678|keepVid=UNDETERMINED" (if there were 2 dupes, and we - // couldn't figure out which one to keep) - // or, "100017|200027|30037|keepVid=30037" (if there were 3 dupes and we - // thought the third one was the one that should survive) - - HashMap <String, ArrayList<String>> keyVals2VidHash = new HashMap <String, ArrayList<String>>(); - HashMap <String,Vertex> vtxHash = new HashMap <String,Vertex>(); - Iterator<Vertex> pItr = passedVertList.iterator(); - while (pItr.hasNext()) { - try { - Vertex tvx = pItr.next(); - String thisVid = tvx.id().toString(); - vtxHash.put(thisVid, tvx); - - // if there are more than one vertexId mapping to the same keyProps -- they are dupes - String hKey = getNodeKeyValString( tvx, keyPropNamesArr, logger ); - if( keyVals2VidHash.containsKey(hKey) ){ - // We've already seen this key - ArrayList <String> tmpVL = keyVals2VidHash.get(hKey); - tmpVL.add(thisVid); - keyVals2VidHash.put(hKey, tmpVL); - } - else { - // First time for this key - ArrayList <String> tmpVL = new ArrayList <String>(); - tmpVL.add(thisVid); - keyVals2VidHash.put(hKey, tmpVL); - } - } - catch (Exception e) { - logger.warn(" >>> Threw an error in getDupeSets4NonDepNodes - just absorb this error and move on. " + LogFormatTools.getStackTop(e)); - } - } - - for( Map.Entry<String, ArrayList<String>> entry : keyVals2VidHash.entrySet() ){ - ArrayList <String> vidList = entry.getValue(); - try { - if( !vidList.isEmpty() && vidList.size() > 1 ){ - // There are more than one vertex id's using the same key info - String dupesStr = ""; - ArrayList <Vertex> vertList = new ArrayList <Vertex> (); - for (int i = 0; i < vidList.size(); i++) { - String tmpVid = vidList.get(i); - dupesStr = dupesStr + tmpVid + "|"; - vertList.add(vtxHash.get(tmpVid)); - } - - if (dupesStr != "") { - Vertex prefV = getPreferredDupe(transId, fromAppId, - g, vertList, version, specialTenantRule, loader, logger); - if (prefV == null) { - // We could not determine which duplicate to keep - dupesStr = dupesStr + "KeepVid=UNDETERMINED"; - returnList.add(dupesStr); - } else { - dupesStr = dupesStr + "KeepVid=" + prefV.id(); - returnList.add(dupesStr); - } - } - } - } - catch (Exception e) { - logger.warn(" >>> Threw an error in getDupeSets4NonDepNodes - just absorb this error and move on. " + LogFormatTools.getStackTop(e)); - } - - } - return returnList; - - }// End of getDupeSets4NonDepNodes() - - - /** - * Collect Duplicate Sets for nodes that are dependent on parent nodes. - * - * @param transId the trans id - * @param fromAppId the from app id - * @param g the g - * @param version the version - * @param nType the n type - * @param passedVertList the passed vert list - * @param keyPropNamesArr Array (ordered) of keyProperty names - * @param specialTenantRule flag - * @param logger the logger - * @return the array list - */ - private static ArrayList<String> getDupeSets4DependentNodes( String transId, - String fromAppId, Graph g, String version, String nType, - ArrayList<Vertex> passedVertList, - ArrayList <String> keyPropNamesArr, Loader loader, - Boolean specialTenantRule, EELFLogger logger ) { - - // This is for nodeTypes that DEPEND ON A PARENT NODE FOR UNIQUNESS - - ArrayList<String> returnList = new ArrayList<String>(); - ArrayList<String> alreadyFoundDupeVidArr = new ArrayList<String>(); - - // We've been passed a set of nodes that we want to check. These are - // all nodes that ARE DEPENDENT on a PARENT Node for uniqueness. - // The first thing to do is to identify the key properties for the node-type - // and pull from the db just using those properties. - // Then, we'll check those nodes with their parent nodes to see if there - // are any duplicates. - // - // When we find duplicates, we return then as a String (there can be - // more than one duplicate for one set of key data): - // Each element in the returned arrayList might look like this: - // "1234|5678|keepVid=UNDETERMINED" (if there were 2 dupes, and we - // couldn't figure out which one to keep) - // or, "100017|200027|30037|keepVid=30037" (if there were 3 dupes and we - // thought the third one was the one that should survive) - HashMap<String, Object> checkVertHash = new HashMap <String,Object> (); - try { - Iterator<Vertex> pItr = passedVertList.iterator(); - while (pItr.hasNext()) { - Vertex tvx = pItr.next(); - String passedId = tvx.id().toString(); - if( !alreadyFoundDupeVidArr.contains(passedId) ){ - // We haven't seen this one before - so we should check it. - HashMap <String,Object> keyPropValsHash = getNodeKeyVals( tvx, keyPropNamesArr, logger ); - ArrayList <Vertex> tmpVertList = getNodeJustUsingKeyParams( transId, fromAppId, g, - nType, keyPropValsHash, version, logger ); - - if( tmpVertList.size() <= 1 ){ - // Even without a parent node, this thing is unique so don't worry about it. - } - else { - for( int i = 0; i < tmpVertList.size(); i++ ){ - Vertex tmpVtx = (tmpVertList.get(i)); - String tmpVid = tmpVtx.id().toString(); - alreadyFoundDupeVidArr.add(tmpVid); - - String hKey = getNodeKeyValString( tmpVtx, keyPropNamesArr, logger ); - if( checkVertHash.containsKey(hKey) ){ - // add it to an existing list - ArrayList <Vertex> tmpVL = (ArrayList <Vertex>)checkVertHash.get(hKey); - tmpVL.add(tmpVtx); - checkVertHash.put(hKey, tmpVL); - } - else { - // First time for this key - ArrayList <Vertex> tmpVL = new ArrayList <Vertex>(); - tmpVL.add(tmpVtx); - checkVertHash.put(hKey, tmpVL); - } - } - } - } - } - - // More than one node have the same key fields since they may - // depend on a parent node for uniqueness. Since we're finding - // more than one, we want to check to see if any of the - // vertices that have this set of keys are also pointing at the - // same 'parent' node. - // Note: for a given set of key data, it is possible that there - // could be more than one set of duplicates. - for (Entry<String, Object> lentry : checkVertHash.entrySet()) { - ArrayList <Vertex> thisIdSetList = (ArrayList <Vertex>)lentry.getValue(); - if (thisIdSetList == null || thisIdSetList.size() < 2) { - // Nothing to check for this set. - continue; - } - - HashMap<String, ArrayList<Vertex>> vertsGroupedByParentHash = groupVertsByDepNodes( - transId, fromAppId, g, version, nType, - thisIdSetList, loader); - for (Map.Entry<String, ArrayList<Vertex>> entry : vertsGroupedByParentHash - .entrySet()) { - ArrayList<Vertex> thisParentsVertList = entry - .getValue(); - if (thisParentsVertList.size() > 1) { - // More than one vertex found with the same key info - // hanging off the same parent/dependent node - String dupesStr = ""; - for (int i = 0; i < thisParentsVertList.size(); i++) { - dupesStr = dupesStr + thisParentsVertList.get(i).id() + "|"; - } - if (dupesStr != "") { - Vertex prefV = getPreferredDupe(transId, - fromAppId, g, thisParentsVertList, - version, specialTenantRule, loader, logger); - - if (prefV == null) { - // We could not determine which duplicate to keep - dupesStr = dupesStr + "KeepVid=UNDETERMINED"; - returnList.add(dupesStr); - } - else { - dupesStr = dupesStr + "KeepVid=" - + prefV.id().toString(); - returnList.add(dupesStr); - } - } - } - } - } - - } catch (Exception e) { - logger.warn(" >>> Threw an error in checkAndProcessDupes - just absorb this error and move on. " + LogFormatTools.getStackTop(e)); - } - - return returnList; - - }// End of getDupeSets4DependentNodes() - - - private static Graph getGraphTransaction(JanusGraph graph, EELFLogger logger){ - - Graph gt = null; - try { - if( graph != null ){ - gt = graph.newTransaction(); - } else { - String emsg = "could not get graph object in DupeTool. \n"; - System.out.println(emsg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.AVAILABILITY_TIMEOUT_ERROR); - logger.error(emsg); - exit(0); - } - } - catch (Exception e) { - String msg = e.toString(); - System.out.println(msg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.UNKNOWN_ERROR); - logger.error(msg); - exit(0); - } - - return gt; - - }// End of getGraphTransaction() - - - - 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 ); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.UNKNOWN_ERROR); - logger.warn(warnMsg); - LoggingContext.statusCode(StatusCode.COMPLETE); - LoggingContext.responseCode(LoggingContext.SUCCESS); - } - - }// End of showNodeInfo() - - 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_EDGE_ID_ + ed.id() + " <<< "); - continue; - } - - 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() - - - private static long figureWindowStartTime( int timeWindowMinutes ){ - // Given a window size, calculate what the start-timestamp would be. - - if( timeWindowMinutes <= 0 ){ - // This just means that there is no window... - return 0; - } - long unixTimeNow = System.currentTimeMillis(); - long windowInMillis = timeWindowMinutes * 60l * 1000l; - - return unixTimeNow - windowInMillis; - } // End of figureWindowStartTime() - - - - /** - * Gets the node(s) just using key params. - * - * @param transId the trans id - * @param fromAppId the from app id - * @param graph the graph - * @param nodeType the node type - * @param keyPropsHash the key props hash - * @param apiVersion the api version - * @return the node just using key params - * @throws AAIException the AAI exception - */ - public static ArrayList <Vertex> getNodeJustUsingKeyParams( String transId, String fromAppId, Graph graph, String nodeType, - HashMap<String,Object> keyPropsHash, String apiVersion, EELFLogger logger ) throws AAIException{ - - ArrayList <Vertex> retVertList = new ArrayList <Vertex> (); - - // We assume that all NodeTypes have at least one key-property defined. - // Note - instead of key-properties (the primary key properties), a user could pass - // alternate-key values if they are defined for the nodeType. - ArrayList<String> kName = new ArrayList<String>(); - ArrayList<Object> kVal = new ArrayList<Object>(); - if( keyPropsHash == null || keyPropsHash.isEmpty() ) { - throw new AAIException("AAI_6120", " NO key properties passed for this getNodeJustUsingKeyParams() request. NodeType = [" + nodeType + "]. "); - } - - int i = -1; - for( Map.Entry<String, Object> entry : keyPropsHash.entrySet() ){ - i++; - kName.add(i, entry.getKey()); - kVal.add(i, entry.getValue()); - } - int topPropIndex = i; - Vertex tiV = null; - String propsAndValuesForMsg = ""; - Iterator<Vertex> verts = null; - GraphTraversalSource g = graph.traversal(); - try { - if( topPropIndex == 0 ){ - propsAndValuesForMsg = " (" + kName.get(0) + " = " + kVal.get(0) + ") "; - verts= g.V().has(kName.get(0),kVal.get(0)).has(AAI_NODE_TYPE,nodeType); - } - else if( topPropIndex == 1 ){ - propsAndValuesForMsg = " (" + kName.get(0) + " = " + kVal.get(0) + ", " - + kName.get(1) + " = " + kVal.get(1) + ") "; - verts = g.V().has(kName.get(0),kVal.get(0)).has(kName.get(1),kVal.get(1)).has(AAI_NODE_TYPE,nodeType); - } - else if( topPropIndex == 2 ){ - propsAndValuesForMsg = " (" + kName.get(0) + " = " + kVal.get(0) + ", " - + kName.get(1) + " = " + kVal.get(1) + ", " - + kName.get(2) + " = " + kVal.get(2) + ") "; - verts= g.V().has(kName.get(0),kVal.get(0)).has(kName.get(1),kVal.get(1)).has(kName.get(2),kVal.get(2)).has(AAI_NODE_TYPE,nodeType); - } - else if( topPropIndex == 3 ){ - propsAndValuesForMsg = " (" + kName.get(0) + " = " + kVal.get(0) + ", " - + kName.get(1) + " = " + kVal.get(1) + ", " - + kName.get(2) + " = " + kVal.get(2) + ", " - + kName.get(3) + " = " + kVal.get(3) + ") "; - verts= g.V().has(kName.get(0),kVal.get(0)).has(kName.get(1),kVal.get(1)).has(kName.get(2),kVal.get(2)).has(kName.get(3),kVal.get(3)).has(AAI_NODE_TYPE,nodeType); - } - else { - throw new AAIException("AAI_6114", " We only support 4 keys per nodeType for now \n"); - } - } - catch( Exception ex ){ - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logger.error( " ERROR trying to get node for: [" + propsAndValuesForMsg + "] " + LogFormatTools.getStackTop(ex)); - LoggingContext.statusCode(StatusCode.COMPLETE); - LoggingContext.responseCode(LoggingContext.SUCCESS); - } - - if( verts != null ){ - while( verts.hasNext() ){ - tiV = verts.next(); - retVertList.add(tiV); - } - } - - if( retVertList.isEmpty() ){ - logger.debug("DEBUG No node found for nodeType = [" + nodeType + - "], propsAndVal = " + propsAndValuesForMsg ); - } - - return retVertList; - - }// End of getNodeJustUsingKeyParams() - - - - /** - * Gets the node(s) just using key params. - * - * @param transId the trans id - * @param fromAppId the from app id - * @param graph the graph - * @param nodeType the node type - * @param windowStartTime the window start time - * @return the nodes - * @throws AAIException the AAI exception - */ - public static ArrayList <Vertex> figureOutNodes2Check( String transId, String fromAppId, - Graph graph, String nodeType, long windowStartTime, - String propsString, EELFLogger logger ) { - - ArrayList <Vertex> retVertList = new ArrayList <Vertex> (); - String msg = ""; - GraphTraversal<Vertex,Vertex> tgQ = graph.traversal().V().has(AAI_NODE_TYPE,nodeType); - String qStringForMsg = "graph.traversal().V().has(\"aai-node-type\"," + nodeType + ")"; - - if( propsString != null && !propsString.trim().isEmpty() ){ - propsString = propsString.trim(); - int firstPipeLoc = propsString.indexOf("|"); - if( firstPipeLoc <= 0 ){ - msg = "Bad props4Collect passed: [" + propsString + "]. \n Expecting a format like, 'propName1|propVal1,propName2|propVal2'"; - System.out.println(msg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logger.error(msg); - exit(0); - } - - // Note - if they're only passing on parameter, there won't be any commas - String [] paramArr = propsString.split(","); - for( int i = 0; i < paramArr.length; i++ ){ - int pipeLoc = paramArr[i].indexOf("|"); - if( pipeLoc <= 0 ){ - msg = "Bad propsString passed: [" + propsString + "]. \n Expecting a format like, 'propName1|propVal1,propName2|propVal2'"; - System.out.println(msg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logger.error(msg); - 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) { - Iterator<Vertex> vertItor = tgQ; - while (vertItor.hasNext()) { - Vertex tiV = vertItor.next(); - if (windowStartTime <= 0) { - // We're not applying a time-window - retVertList.add(tiV); - continue; - } - - Object objTimeStamp = tiV.property("aai-created-ts").orElse(null); - if (objTimeStamp == null) { - // No timestamp - so just take it - retVertList.add(tiV); - continue; - } - - long thisNodeCreateTime = (long) objTimeStamp; - if (thisNodeCreateTime > windowStartTime) { - // It is in our window, so we can take it - retVertList.add(tiV); - } - } - } else { - msg = "Bad JanusGraphQuery object. "; - System.out.println(msg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.AVAILABILITY_TIMEOUT_ERROR); - logger.error(msg); - exit(0); - } - - if( retVertList.isEmpty() ){ - logger.debug("DEBUG No node found for: [" + qStringForMsg + ", with aai-created-ts > " + windowStartTime ); - } - - return retVertList; - - }// End of figureOutNodes2Check() - - - /** - * Gets the preferred dupe. - * - * @param transId the trans id - * @param fromAppId the from app id - * @param g the g - * @param dupeVertexList the dupe vertex list - * @param ver the ver - * @param logger the logger - * @return Vertex - * @throws AAIException the AAI exception - */ - public static Vertex getPreferredDupe( String transId, - String fromAppId, Graph g, - ArrayList<Vertex> dupeVertexList, String ver, - Boolean specialTenantRule, Loader loader, EELFLogger logger ) - throws AAIException { - - // This method assumes that it is being passed a List of vertex objects - // which violate our uniqueness constraints. - - Vertex nullVtx = null; - - if (dupeVertexList == null) { - return nullVtx; - } - int listSize = dupeVertexList.size(); - if (listSize == 0) { - return nullVtx; - } - if (listSize == 1) { - return ( dupeVertexList.get(0)); - } - - Vertex vtxPreferred = null; - Vertex currentFaveVtx = dupeVertexList.get(0); - for (int i = 1; i < listSize; i++) { - Vertex vtxB = dupeVertexList.get(i); - vtxPreferred = pickOneOfTwoDupes(transId, fromAppId, g, - currentFaveVtx, vtxB, ver, specialTenantRule, loader, logger); - if (vtxPreferred == null) { - // We couldn't choose one - return nullVtx; - } else { - currentFaveVtx = vtxPreferred; - } - } - - return (currentFaveVtx); - - } // end of getPreferredDupe() - - - /** - * Pick one of two dupes. - * - * @param transId the trans id - * @param fromAppId the from app id - * @param g the g - * @param vtxA the vtx A - * @param vtxB the vtx B - * @param ver the ver - * @param specialTenantRule flag - * @param logger the logger - * @return Vertex - * @throws AAIException the AAI exception - */ - public static Vertex pickOneOfTwoDupes(String transId, - String fromAppId, Graph g, Vertex vtxA, - Vertex vtxB, String ver, Boolean specialTenantRule, Loader loader, EELFLogger logger) throws AAIException { - - Vertex nullVtx = null; - Vertex preferredVtx = null; - - Long vidA = new Long(vtxA.id().toString()); - Long vidB = new Long(vtxB.id().toString()); - - String vtxANodeType = ""; - String vtxBNodeType = ""; - Object obj = vtxA.<Object>property(AAI_NODE_TYPE).orElse(null); - if (obj != null) { - vtxANodeType = obj.toString(); - } - obj = vtxB.<Object>property(AAI_NODE_TYPE).orElse(null); - if (obj != null) { - vtxBNodeType = obj.toString(); - } - - if (vtxANodeType.isEmpty() || (!vtxANodeType.equals(vtxBNodeType))) { - // Either they're not really dupes or there's some bad data - so - // don't pick one - return nullVtx; - } - - // Check that node A and B both have the same key values (or else they - // are not dupes) - // (We'll check dep-node later) - Collection<String> keyProps = loader.introspectorFromName(vtxANodeType).getKeys(); - Iterator<String> keyPropI = keyProps.iterator(); - while (keyPropI.hasNext()) { - String propName = keyPropI.next(); - String vtxAKeyPropVal = ""; - obj = vtxA.<Object>property(propName).orElse(null); - if (obj != null) { - vtxAKeyPropVal = obj.toString(); - } - String vtxBKeyPropVal = ""; - obj = vtxB.<Object>property(propName).orElse(null); - if (obj != null) { - vtxBKeyPropVal = obj.toString(); - } - - if (vtxAKeyPropVal.equals("") - || (!vtxAKeyPropVal.equals(vtxBKeyPropVal))) { - // Either they're not really dupes or they are missing some key - // data - so don't pick one - return nullVtx; - } - } - - // Collect the vid's and aai-node-types of the vertices that each vertex - // (A and B) is connected to. - ArrayList<String> vtxIdsConn2A = new ArrayList<String>(); - ArrayList<String> vtxIdsConn2B = new ArrayList<String>(); - HashMap<String, String> nodeTypesConn2A = new HashMap<String, String>(); - HashMap<String, String> nodeTypesConn2B = new HashMap<String, String>(); - - ArrayList <String> retArr = new ArrayList <String> (); - Iterator <Edge> eAI = vtxA.edges(Direction.BOTH); - while( eAI.hasNext() ){ - Edge ed = eAI.next(); - Vertex tmpVtx; - if (vtxA.equals(ed.inVertex())) { - tmpVtx = ed.outVertex(); - } else { - tmpVtx = ed.inVertex(); - } - if( tmpVtx == null ){ - retArr.add(COULD_NOT_FIND_EDGE_ID_ + ed.id() + " <<< "); - } - else { - String conVid = tmpVtx.id().toString(); - String nt = ""; - obj = tmpVtx.<Object>property(AAI_NODE_TYPE).orElse(null); - if (obj != null) { - nt = obj.toString(); - } - nodeTypesConn2A.put(nt, conVid); - vtxIdsConn2A.add(conVid); - } - } - - Iterator <Edge> eBI = vtxB.edges(Direction.BOTH); - while( eBI.hasNext() ){ - Edge ed = eBI.next(); - Vertex tmpVtx; - - if (vtxB.equals(ed.inVertex())) { - tmpVtx = ed.outVertex(); - } else { - tmpVtx = ed.inVertex(); - } - if( tmpVtx == null ){ - retArr.add(COULD_NOT_FIND_EDGE_ID_ + ed.id() + " <<< "); - } - else { - String conVid = tmpVtx.id().toString(); - String nt = ""; - obj = tmpVtx.<Object>property(AAI_NODE_TYPE).orElse(null); - if (obj != null) { - nt = obj.toString(); - } - nodeTypesConn2B.put(nt, conVid); - vtxIdsConn2B.add(conVid); - } - } - - // 1 - If this kind of node needs a dependent node for uniqueness, then - // verify that they both nodes point to the same dependent - // node (otherwise they're not really duplicates) - // Note - there are sometimes more than one dependent node type since - // one nodeType can be used in different ways. But for a - // particular node, it will only have one dependent node that - // it's connected to. - Collection<String> depNodeTypes = loader.introspectorFromName(vtxANodeType).getDependentOn(); - if (depNodeTypes.isEmpty()) { - // This kind of node is not dependent on any other. That is ok. - } else { - String depNodeVtxId4A = ""; - String depNodeVtxId4B = ""; - Iterator<String> iter = depNodeTypes.iterator(); - while (iter.hasNext()) { - String depNodeType = iter.next(); - if (nodeTypesConn2A.containsKey(depNodeType)) { - // This is the dependent node type that vertex A is using - depNodeVtxId4A = nodeTypesConn2A.get(depNodeType); - } - if (nodeTypesConn2B.containsKey(depNodeType)) { - // This is the dependent node type that vertex B is using - depNodeVtxId4B = nodeTypesConn2B.get(depNodeType); - } - } - if (depNodeVtxId4A.isEmpty() - || (!depNodeVtxId4A.equals(depNodeVtxId4B))) { - // Either they're not really dupes or there's some bad data - so - // don't pick either one - return nullVtx; - } - } - - if (vtxIdsConn2A.size() == vtxIdsConn2B.size()) { - // 2 - If they both have edges to all the same vertices, then return - // the one with the lower vertexId. - - // OR (2b)-- if this is the SPECIAL case -- of - // "tenant|vserver vs. tenant|service-subscription" - // then we pick/prefer the one that's connected to - // the service-subscription. AAI-8172 - boolean allTheSame = true; - Iterator<String> iter = vtxIdsConn2A.iterator(); - while (iter.hasNext()) { - String vtxIdConn2A = iter.next(); - if (!vtxIdsConn2B.contains(vtxIdConn2A)) { - allTheSame = false; - break; - } - } - - if (allTheSame) { - if (vidA < vidB) { - preferredVtx = vtxA; - } else { - preferredVtx = vtxB; - } - } - else if ( specialTenantRule && vtxIdsConn2A.size() == 2 && "tenant".equals(vtxANodeType)){ - // They asked us to apply a special rule if it applies - // We're dealing with two tenant nodes which each just have - // two connections. One must be the parent (cloud-region) - // which we check in step 1 above. If one connects to - // a vserver and the other connects to a service-subscription, - // our special rule is to keep the one connected - // to the - if( nodeTypesConn2A.containsKey("vserver") && nodeTypesConn2B.containsKey("service-subscription") ){ - String infMsg = " WARNING >>> we are using the special tenant rule to choose to " + - " delete tenant vtxId = " + vidA + ", and keep tenant vtxId = " + vidB ; - System.out.println(infMsg); - logger.info( infMsg ); - preferredVtx = vtxB; - } - else if( nodeTypesConn2B.containsKey("vserver") && nodeTypesConn2A.containsKey("service-subscription") ){ - String infMsg = " WARNING >>> we are using the special tenant rule to choose to " + - " delete tenant vtxId = " + vidB + ", and keep tenant vtxId = " + vidA ; - System.out.println(infMsg); - logger.info( infMsg ); - preferredVtx = vtxA; - } - } - } else if (vtxIdsConn2A.size() > vtxIdsConn2B.size()) { - // 3 - VertexA is connected to more things than vtxB. - // We'll pick VtxA if its edges are a superset of vtxB's edges. - boolean missingOne = false; - Iterator<String> iter = vtxIdsConn2B.iterator(); - while (iter.hasNext()) { - String vtxIdConn2B = iter.next(); - if (!vtxIdsConn2A.contains(vtxIdConn2B)) { - missingOne = true; - break; - } - } - if (!missingOne) { - preferredVtx = vtxA; - } - } else if (vtxIdsConn2B.size() > vtxIdsConn2A.size()) { - // 4 - VertexB is connected to more things than vtxA. - // We'll pick VtxB if its edges are a superset of vtxA's edges. - boolean missingOne = false; - Iterator<String> iter = vtxIdsConn2A.iterator(); - while (iter.hasNext()) { - String vtxIdConn2A = iter.next(); - if (!vtxIdsConn2B.contains(vtxIdConn2A)) { - missingOne = true; - break; - } - } - if (!missingOne) { - preferredVtx = vtxB; - } - } else { - preferredVtx = nullVtx; - } - - return (preferredVtx); - - } // end of pickOneOfTwoDupes() - - - /** - * Group verts by dep nodes. - * - * @param transId the trans id - * @param fromAppId the from app id - * @param g the g - * @param version the version - * @param nType the n type - * @param passedVertList the passed vert list - * @param loader loader - * @return the hash map - * @throws AAIException the AAI exception - */ - private static HashMap<String, ArrayList<Vertex>> groupVertsByDepNodes( - String transId, String fromAppId, Graph g, String version, - String nType, ArrayList<Vertex> passedVertList, Loader loader) - throws AAIException { - - // Given a list of JanusGraph Vertices, group them together by dependent - // nodes. Ie. if given a list of ip address nodes (assumed to all - // have the same key info) they might sit under several different - // parent vertices. - // Under Normal conditions, there would only be one per parent -- but - // we're trying to find duplicates - so we allow for the case - // where more than one is under the same parent node. - - HashMap<String, ArrayList<Vertex>> retHash = new HashMap<String, ArrayList<Vertex>>(); - - // Find out what types of nodes the passed in nodes can depend on - ArrayList<String> depNodeTypeL = new ArrayList<String>(); - Collection<String> depNTColl = loader.introspectorFromName(nType).getDependentOn(); - Iterator<String> ntItr = depNTColl.iterator(); - while (ntItr.hasNext()) { - depNodeTypeL.add(ntItr.next()); - } - // For each vertex they passed us, we want find the vertex it - // is dependent on so we can keep track of who-all is connected - // to that parent. - if (passedVertList != null) { - Iterator<Vertex> iter = passedVertList.iterator(); - while (iter.hasNext()) { - Vertex thisVert = iter.next(); - Iterator <String> depNtItr = depNTColl.iterator(); - while (depNtItr.hasNext()) { - GraphTraversal<Vertex, Vertex> modPipe = null; - // NOTE -- if we change the direction of parent/child edges, we will need - // the "in" below to become "out" - modPipe = g.traversal().V(thisVert).in().has(AAI_NODE_TYPE, depNtItr.next() ); - if( modPipe == null || !modPipe.hasNext() ){ - //System.out.println("DEBUG - didn't find any [" + targetStep + "] connected to this guy (which is ok)"); - continue; - } - - while( modPipe.hasNext() ){ - Vertex depVert = modPipe.next(); - String parentVid = depVert.id().toString(); - if (retHash.containsKey(parentVid)) { - // add this vert to the list for this parent key - retHash.get(parentVid).add(thisVert); - } else { - // This is the first one we found on this parent - ArrayList<Vertex> vList = new ArrayList<Vertex>(); - vList.add(thisVert); - retHash.put(parentVid, vList); - } - } - } - } - } - - return retHash; - - }// end of groupVertsByDepNodes() - - - /** - * Delete non keepers if appropriate. - * - * @param g the g - * @param dupeInfoList the dupe info string - * @param logger the EELFLogger - * @return the boolean - */ - private static Boolean deleteNonKeepers(Graph g, - ArrayList<String> dupeInfoList, EELFLogger logger ) { - - // This assumes that each dupeInfoString is in the format of - // pipe-delimited vid's followed by either "keepVid=xyz" or "keepVid=UNDETERMINED" - // ie. "3456|9880|keepVid=3456" - - boolean didADelFlag = false; - for( int n = 0; n < dupeInfoList.size(); n++ ){ - String dupeInfoString = dupeInfoList.get(n); - boolean tmpFlag = deleteNonKeeperForOneSet( g, dupeInfoString, logger ); - didADelFlag = tmpFlag || didADelFlag; - } - - return didADelFlag; - - }// end of deleteNonKeepers() - - - /** - * Delete non keepers if appropriate. - * - * @param g the g - * @param dupeInfoString the dupe string - * @param logger the EELFLogger - * @return the boolean - */ - private static Boolean deleteNonKeeperForOneSet(Graph g, - String dupeInfoString, EELFLogger logger ) { - - Boolean deletedSomething = false; - // This assumes that each dupeInfoString is in the format of - // pipe-delimited vid's followed by either "keepVid=xyz" or "keepVid=UNDETERMINED" - // ie. "3456|9880|keepVid=3456" - - - String[] dupeArr = dupeInfoString.split("\\|"); - ArrayList<String> idArr = new ArrayList<String>(); - int lastIndex = dupeArr.length - 1; - for (int i = 0; i <= lastIndex; i++) { - if (i < lastIndex) { - // This is not the last entry, it is one of the dupes, - String vidString = dupeArr[i]; - idArr.add(vidString); - continue; - } - - // This is the last entry which should tell us if we have a - // preferred keeper - String prefString = dupeArr[i]; - if ("KeepVid=UNDETERMINED".equals(prefString)) { - // They sent us a bad string -- nothing should be deleted if - // no dupe could be tagged as preferred. - return false; - } - // If we know which to keep, then the prefString should look - // like, "KeepVid=12345" - String[] prefArr = prefString.split("="); - if (prefArr.length != 2 || !KEEP_VID.equals(prefArr[0])) { - String emsg = "Bad format. Expecting KeepVid=999999"; - System.out.println(emsg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logger.error(emsg); - LoggingContext.statusCode(StatusCode.COMPLETE); - LoggingContext.responseCode(LoggingContext.SUCCESS); - return false; - } - - String keepVidStr = prefArr[1]; - if (idArr.contains(keepVidStr)) { - idArr.remove(keepVidStr); - // So now, the idArr should just contain the vid's - // that we want to remove. - for (int x = 0; x < idArr.size(); x++) { - boolean okFlag = true; - String thisVid = idArr.get(x); - try { - long longVertId = Long.parseLong(thisVid); - Vertex vtx = g.traversal().V(longVertId).next(); - String msg = "--->>> We will delete node with VID = " + thisVid + " <<<---"; - System.out.println(msg); - logger.info(msg); - vtx.remove(); - } - catch (Exception e) { - okFlag = false; - String emsg = "ERROR trying to delete VID = " + thisVid + ", [" + e + "]"; - System.out.println(emsg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logger.error(emsg); - LoggingContext.statusCode(StatusCode.COMPLETE); - LoggingContext.responseCode(LoggingContext.SUCCESS); - } - if (okFlag) { - String infMsg = " DELETED VID = " + thisVid; - logger.info(infMsg); - System.out.println(infMsg); - deletedSomething = true; - } - } - } else { - String emsg = "ERROR - Vertex Id to keep not found in list of dupes. dupeInfoString = [" - + dupeInfoString + "]"; - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logger.error(emsg); - LoggingContext.statusCode(StatusCode.COMPLETE); - LoggingContext.responseCode(LoggingContext.SUCCESS); - System.out.println(emsg); - return false; - } - - }// for each vertex in a group - - return deletedSomething; - - }// end of deleteNonKeeperForOneSet() - - - /** - * Get values of the key properties for a node. - * - * @param tvx the vertex to pull the properties from - * @param keyPropNamesArr ArrayList (ordered) of key prop names - * @param logger the EELFLogger - * @return a hashMap of the propertyNames/values - */ - private static HashMap <String,Object> getNodeKeyVals( Vertex tvx, - ArrayList <String> keyPropNamesArr, EELFLogger logger ) { - - HashMap <String,Object> retHash = new HashMap <String,Object>(); - Iterator <String> propItr = keyPropNamesArr.iterator(); - while( propItr.hasNext() ){ - String propName = propItr.next(); - if( tvx != null ){ - Object propValObj = tvx.property(propName).orElse(null); - retHash.put(propName, propValObj); - } - } - return retHash; - - }// End of getNodeKeyVals() - - - /** - * Get values of the key properties for a node as a single string - * - * @param tvx the vertex to pull the properties from - * @param keyPropNamesArr collection of key prop names - * @param logger the EELFLogger - * @return a String of concatenated values - */ - private static String getNodeKeyValString( Vertex tvx, - ArrayList <String> keyPropNamesArr, EELFLogger logger ) { - - // -- NOTE -- for what we're using this for, we would need to - // guarantee that the properties are always in the same order - - String retString = ""; - Iterator <String> propItr = keyPropNamesArr.iterator(); - while( propItr.hasNext() ){ - String propName = propItr.next(); - if( tvx != null ){ - Object propValObj = tvx.property(propName).orElse(null); - retString = " " + retString + propValObj.toString(); - } - } - return retString; - - }// End of getNodeKeyValString() - - - /** - * Find duplicate sets from two dupe runs. - * - * @param firstPassDupeSets from the first pass - * @param secondPassDupeSets from the second pass - * @param logger logger - * @return commonDupeSets that are common to both passes and have a determined keeper - */ - private static ArrayList <String> figureWhichDupesStillNeedFixing( ArrayList <String>firstPassDupeSets, - ArrayList <String> secondPassDupeSets, EELFLogger logger ){ - - ArrayList <String> common2BothSet = new ArrayList <String> (); - - // We just want to look for entries from the first set which have identical (almost) - // entries in the secondary set. I say "almost" because the order of the - // vid's to delete may be in a different order, but we only want to use it if - // they have all the same values. Note also - we're just looking for - // the sets where we have a candidate to delete. - - // The duplicate-set Strings are in this format: - // "1234|5678|keepVid=UNDETERMINED" (if there were 2 dupes, and we - // couldn't figure out which one to keep) - // or, "100017|200027|30037|keepVid=30037" (if there were 3 dupes and we - // thought the third one was the one that should survive) - - if( firstPassDupeSets == null || firstPassDupeSets.isEmpty() - || secondPassDupeSets == null || secondPassDupeSets.isEmpty() ){ - // If either set is empty, then our return list has to be empty too - return common2BothSet; - } - - boolean needToParse = false; - for( int x = 0; x < secondPassDupeSets.size(); x++ ){ - String secPassDupeSetStr = secondPassDupeSets.get(x); - if( secPassDupeSetStr.endsWith("UNDETERMINED") ){ - // This is a set of dupes where we could not pick one - // to delete - so don't include it on our list for - // fixing. - } - else if( firstPassDupeSets.contains(secPassDupeSetStr) ){ - // We have lucked out and do not even need to parse this since - // it was in the other array with any dupes listed in the same order - // This is actually the most common scenario since there is - // usually only one dupe, so order doesn't matter. - common2BothSet.add(secPassDupeSetStr); - } - else { - // We'll need to do some parsing to check this one - needToParse = true; - } - } - - if( needToParse ){ - // Make a hash from the first and second Pass data - // where the key is the vid to KEEP and the value is an - // array of (String) vids that would get deleted. - HashMap <String,ArrayList<String>> firstPassHash = makeKeeperHashOfDupeStrings( firstPassDupeSets, common2BothSet, logger ); - - HashMap <String,ArrayList<String>> secPassHash = makeKeeperHashOfDupeStrings( secondPassDupeSets, common2BothSet, logger ); - - // Loop through the secondPass data and keep the ones - // that check out against the firstPass set. - for( Map.Entry<String, ArrayList<String>> entry : secPassHash.entrySet() ){ - boolean skipThisOne = false; - String secKey = entry.getKey(); - ArrayList <String> secList = entry.getValue(); - if( !firstPassHash.containsKey(secKey) ){ - // The second pass found this delete candidate, but not the first pass - skipThisOne = true; - } - else { - // They both think they should keep this VID, check the associated deletes for it. - ArrayList <String> firstList = firstPassHash.get(secKey); - for( int z = 0; z < secList.size(); z++ ){ - if( !firstList.contains(secList.get(z)) ){ - // The first pass did not think this needed to be deleted - skipThisOne = true; - } - } - } - if( skipThisOne ) { - continue; - } - - // Put the string back together and pass it back - // Not beautiful, but no time to make it nice right now... - // Put it back in the format: "3456|9880|keepVid=3456" - String thisDelSetStr = ""; - for( int z = 0; z < secList.size(); z++ ){ - if( z == 0 ){ - thisDelSetStr = secList.get(z); - } - else { - thisDelSetStr = thisDelSetStr + "|" + secList.get(z); - } - } - thisDelSetStr = thisDelSetStr + "|keepVid=" + secKey; - common2BothSet.add(thisDelSetStr); - } - } - return common2BothSet; - - }// figureWhichDupesStillNeedFixing - - - private static HashMap <String, ArrayList <String>> makeKeeperHashOfDupeStrings( ArrayList <String> dupeSets, - ArrayList <String> excludeSets, EELFLogger logger ){ - - HashMap <String,ArrayList<String>> keeperHash = new HashMap <String, ArrayList<String>>(); - - for( int x = 0; x < dupeSets.size(); x++ ){ - String tmpSetStr = dupeSets.get(x); - if( excludeSets.contains(tmpSetStr) ){ - // This isn't one of the ones we needed to parse. - continue; - } - - String[] dupeArr = tmpSetStr.split("\\|"); - ArrayList<String> delIdArr = new ArrayList<String>(); - int lastIndex = dupeArr.length - 1; - for (int i = 0; i <= lastIndex; i++) { - if (i < lastIndex) { - // This is not the last entry, it is one of the dupes - delIdArr.add(dupeArr[i]); - continue; - } - - // This is the last entry which should tell us if we - // have a preferred keeper and how many dupes we had - String prefString = dupeArr[i]; - if( i == 1 ){ - // There was only one dupe, so if we were gonna find - // it, we would have found it above with no parsing. - } - else if ("KeepVid=UNDETERMINED".equals(prefString)) { - // This one had no determined keeper, so we don't - // want it. - } - else { - // If we know which to keep, then the prefString - // should look like, "KeepVid=12345" - String[] prefArr = prefString.split("="); - if( prefArr.length != 2 || !KEEP_VID.equals(prefArr[0]) ) { - String infMsg = "Bad format in figureWhichDupesStillNeedFixing(). Expecting " + - " KeepVid=999999 but string looks like: [" + tmpSetStr + "]"; - System.out.println(infMsg); - logger.info(infMsg); - } - else { - keeperHash.put(prefArr[0], delIdArr); - } - } - - } - } - - return keeperHash; - - }// End makeHashOfDupeStrings() - - - /** - * Get values of the key properties for a node. - * - * @param g the g - * @param dupeInfoString - * @param logger the EELFLogger - * @return void - */ - static private void showNodeDetailsForADupeSet(Graph g, String dupeInfoString, EELFLogger logger) { - - // dang... parsing this string once again... - - String[] dupeArr = dupeInfoString.split("\\|"); - int lastIndex = dupeArr.length - 1; - for (int i = 0; i <= lastIndex; i++) { - if (i < lastIndex) { - // This is not the last entry, it is one of the dupes, - String vidString = dupeArr[i]; - long longVertId = Long.parseLong(vidString); - Vertex vtx = g.traversal().V(longVertId).next(); - showNodeInfo(logger, vtx, false); - } else { - // This is the last entry which should tell us if we have a - // preferred keeper - String prefString = dupeArr[i]; - if (prefString.equals("KeepVid=UNDETERMINED")) { - String msg = " Our algorithm cannot choose from among these, so they will all be kept. -------\n"; - System.out.println(msg); - logger.info(msg); - } else { - // If we know which to keep, then the prefString should look - // like, "KeepVid=12345" - String[] prefArr = prefString.split("="); - if (prefArr.length != 2 || (!prefArr[0].equals(KEEP_VID))) { - String emsg = "Bad format. Expecting KeepVid=999999"; - System.out.println(emsg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logger.error(emsg); - LoggingContext.statusCode(StatusCode.COMPLETE); - LoggingContext.responseCode(LoggingContext.SUCCESS); - } else { - String keepVidStr = prefArr[1]; - String msg = " vid = " + keepVidStr + " is the one that we would KEEP. ------\n"; - System.out.println(msg); - logger.info(msg); - } - } - } - } - - }// End of showNodeDetailsForADupeSet() - - private static int graphIndex = 1; - - public static JanusGraph setupGraph(EELFLogger logger){ - - JanusGraph janusGraph = null; - - - try (InputStream inputStream = new FileInputStream(AAIConstants.REALTIME_DB_CONFIG);){ - - Properties properties = new Properties(); - properties.load(inputStream); - - if(INMEMORY.equals(properties.get("storage.backend"))){ - janusGraph = AAIGraph.getInstance().getGraph(); - graphType = INMEMORY; - } else { - janusGraph = JanusGraphFactory.open(new AAIGraphConfig.Builder(AAIConstants.REALTIME_DB_CONFIG).forService(DupeTool.class.getSimpleName()).withGraphType("realtime" + graphIndex).buildConfiguration()); - graphIndex++; - } - } catch (Exception e) { - logger.error("Unable to open the graph", LogFormatTools.getStackTop(e)); - } - - return janusGraph; - } - - public static void closeGraph(JanusGraph graph, EELFLogger logger){ - - try { - if(INMEMORY.equals(graphType)) { - return; - } - if( graph != null && graph.isOpen() ){ - graph.tx().close(); - graph.close(); - } - } catch (Exception ex) { - // Don't throw anything because JanusGraph sometimes is just saying that the graph is already closed{ - logger.warn("WARNING from final graph.shutdown()", ex); - } - } -} - - diff --git a/aai-resources/src/main/java/org/onap/aai/dbgen/ForceDeleteTool.java b/aai-resources/src/main/java/org/onap/aai/dbgen/ForceDeleteTool.java deleted file mode 100644 index 42d401b..0000000 --- a/aai-resources/src/main/java/org/onap/aai/dbgen/ForceDeleteTool.java +++ /dev/null @@ -1,864 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.dbgen; -import java.io.FileInputStream; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Properties; -import java.util.Scanner; -import java.util.UUID; - -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; -import org.apache.tinkerpop.gremlin.structure.Direction; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; -import org.onap.aai.dbmap.AAIGraphConfig; -import org.onap.aai.dbmap.AAIGraph; -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.logging.LogFormatTools; -import org.onap.aai.logging.LoggingContext; -import org.onap.aai.logging.LoggingContext.StatusCode; -import org.onap.aai.serialization.db.AAIDirection; -import org.onap.aai.serialization.db.EdgeProperty; -import org.onap.aai.util.AAIConfig; -import org.onap.aai.util.AAIConstants; -import org.slf4j.MDC; - -import com.att.eelf.configuration.Configuration; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; -import org.janusgraph.core.JanusGraphFactory; -import org.janusgraph.core.JanusGraph; - - - -public class ForceDeleteTool { - private static final String FROMAPPID = "AAI-DB"; - private static final String TRANSID = UUID.randomUUID().toString(); - private static final String DELETE_NODE = "DELETE_NODE"; - private static final String DELETE_EDGE = "DELETE_EDGE"; - private static String graphType = "realdb"; - private static String FOUND_VERTEX_ID_ = ">>> Found Vertex with VertexId = "; - private static String PROPERTIES_ = ", properties: "; - private static String INMEMORY = "inmemory"; - - public static boolean SHOULD_EXIT_VM = true; - - public static int EXIT_VM_STATUS_CODE = -1; - - public static void exit(int statusCode){ - if(SHOULD_EXIT_VM){ - System.exit(1); - } - EXIT_VM_STATUS_CODE = statusCode; - } - - /* - * 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. - - System.setProperty("aai.service.name", ForceDelete.class.getSimpleName()); - // 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()); - - LoggingContext.init(); - LoggingContext.partnerName(FROMAPPID); - LoggingContext.serviceName(AAIConstants.AAI_RESOURCES_MS); - LoggingContext.component("forceDeleteTool"); - LoggingContext.targetEntity(AAIConstants.AAI_RESOURCES_MS); - LoggingContext.targetServiceName("main"); - LoggingContext.requestId(TRANSID); - LoggingContext.statusCode(StatusCode.COMPLETE); - LoggingContext.responseCode(LoggingContext.SUCCESS); - - 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) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(" No value passed with -action option. "); - exit(0); - } - actionVal = args[i]; - argStr4Msg = argStr4Msg + " " + actionVal; - } - else if ("-userId".equals(thisArg)) { - i++; - if (i >= args.length) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(" No value passed with -userId option. "); - exit(0); - } - userIdVal = args[i]; - argStr4Msg = argStr4Msg + " " + userIdVal; - } - else if ("-overRideProtection".equals(thisArg)) { - overRideProtection = true; - } - else if ("-DISPLAY_ALL_VIDS".equals(thisArg)) { - displayAllVidsFlag = true; - } - else if ("-vertexId".equals(thisArg)) { - i++; - if (i >= args.length) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(" No value passed with -vertexId option. "); - exit(0); - } - String nextArg = args[i]; - argStr4Msg = argStr4Msg + " " + nextArg; - try { - vertexIdLong = Long.parseLong(nextArg); - } catch (Exception e) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error("Bad value passed with -vertexId option: [" - + nextArg + "]"); - exit(0); - } - } - else if ("-params4Collect".equals(thisArg)) { - i++; - if (i >= args.length) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(" No value passed with -params4Collect option. "); - exit(0); - } - dataString = args[i]; - argStr4Msg = argStr4Msg + " " + dataString; - } - else if ("-edgeId".equals(thisArg)) { - i++; - if (i >= args.length) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(" No value passed with -edgeId option. "); - exit(0); - } - String nextArg = args[i]; - argStr4Msg = argStr4Msg + " " + nextArg; - edgeIdStr = nextArg; - } - else { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(" Unrecognized argument passed to ForceDeleteTool: [" - + thisArg + "]. "); - logger.error(" Valid values are: -action -userId -vertexId -edgeId -overRideProtection -params4Collect -DISPLAY_ALL_VIDS"); - exit(0); - } - } - } - - if( !"COLLECT_DATA".equals(actionVal) && !DELETE_NODE.equals(actionVal) && !DELETE_EDGE.equals(actionVal)){ - String emsg = "Bad action parameter [" + actionVal + "] passed to ForceDeleteTool(). Valid values = COLLECT_DATA or DELETE_NODE or DELETE_EDGE\n"; - System.out.println(emsg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(emsg); - exit(0); - } - - if( DELETE_NODE.equals(actionVal) && vertexIdLong == 0 ){ - String emsg = "ERROR: No vertex ID passed on DELETE_NODE request. \n"; - System.out.println(emsg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(emsg); - exit(0); - } - else if( DELETE_EDGE.equals(actionVal) && edgeIdStr.isEmpty()){ - String emsg = "ERROR: No edge ID passed on DELETE_EDGE request. \n"; - System.out.println(emsg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(emsg); - exit(0); - } - - - userIdVal = userIdVal.trim(); - if( (userIdVal.length() < 6) || "AAIADMIN".equalsIgnoreCase(userIdVal) ){ - String emsg = "Bad userId parameter [" + userIdVal + "] passed to ForceDeleteTool(). must be not empty and not aaiadmin \n"; - System.out.println(emsg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(emsg); - exit(0); - } - - String msg = ""; - JanusGraph graph = null; - try { - AAIConfig.init(); - System.out.println(" ---- NOTE --- about to open graph (takes a little while)--------\n"); - graph = setupGraph(logger); - if( graph == null ){ - String emsg = "could not get graph object in ForceDeleteTool() \n"; - System.out.println(emsg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.AVAILABILITY_TIMEOUT_ERROR); - logger.error(emsg); - exit(0); - } - } - catch (AAIException e1) { - msg = e1.getErrorObject().toString(); - System.out.println(msg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.UNKNOWN_ERROR); - logger.error(msg); - exit(0); - } - catch (Exception e2) { - msg = e2.toString(); - System.out.println(msg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.UNKNOWN_ERROR); - logger.error(msg); - exit(0); - } - - msg = "ForceDelete called by: userId [" + userIdVal + "] with these params: [" + argStr4Msg + "]"; - System.out.println(msg); - logger.info(msg); - - ForceDelete fd = new ForceDelete(graph); - if( "COLLECT_DATA".equals(actionVal) ){ - // 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); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(msg); - exit(0); - } - GraphTraversal<Vertex, Vertex> g = null; - String qStringForMsg = null; - if (graph != null) { - g = graph.traversal().V(); - qStringForMsg = " graph.traversal().V()"; - // 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); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(msg); - exit(0); - } else { - String propName = paramArr[i].substring(0, pipeLoc); - String propVal = paramArr[i].substring(pipeLoc + 1); - g = g.has(propName, propVal); - qStringForMsg = qStringForMsg + ".has(" + propName + "," + propVal + ")"; - } - } - } - if( (g != null)){ - Iterator<Vertex> vertItor = g; - while( vertItor.hasNext() ){ - resCount++; - Vertex v = vertItor.next(); - fd.showNodeInfo( logger, v, displayAllVidsFlag ); - int descendantCount = fd.countDescendants( logger, v, 0 ); - String infMsg = " Found " + descendantCount + " descendant nodes \n"; - System.out.println( infMsg ); - logger.info( infMsg ); - } - } - else { - msg = "Bad JanusGraphQuery object. "; - System.out.println(msg); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logger.error(msg); - exit(0); - } - - String infMsg = "\n\n Found: " + resCount + " nodes for this query: [" + qStringForMsg + "]\n"; - System.out.println( infMsg ); - logger.info( infMsg ); - } - else if( DELETE_NODE.equals(actionVal) ){ - Iterator <Vertex> vtxItr = graph.vertices( vertexIdLong ); - if( vtxItr != null && vtxItr.hasNext() ) { - Vertex vtx = vtxItr.next(); - fd.showNodeInfo( logger, vtx, displayAllVidsFlag ); - int descendantCount = fd.countDescendants( logger, 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 = fd.countEdges( logger, vtx ); - - infMsg = " Found total of " + edgeCount + " edges incident on this node. \n"; - System.out.println( infMsg ); - logger.info( infMsg ); - - if( fd.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( DELETE_EDGE.equals(actionVal) ){ - Edge thisEdge = null; - Iterator <Edge> edItr = graph.edges( edgeIdStr ); - if( edItr != null && edItr.hasNext() ) { - thisEdge = edItr.next(); - } - - if( thisEdge == null ){ - String infMsg = ">>>>>>>>>> Edge with edgeId = " + edgeIdStr + " not found."; - logger.info( infMsg ); - System.out.println(infMsg); - exit(0); - } - - if( fd.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 ); - } - 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 ); - exit(0); - } - - closeGraph(graph, logger); - exit(0); - - }// end of main() - - public static class ForceDelete { - - private final int MAXDESCENDENTDEPTH = 15; - private final JanusGraph graph; - public ForceDelete(JanusGraph graph) { - this.graph = graph; - } - public void showNodeInfo(EELFLogger logger, Vertex tVert, Boolean displayAllVidsFlag ){ - - try { - Iterator<VertexProperty<Object>> pI = tVert.properties(); - String infStr = FOUND_VERTEX_ID_ + 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 ); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logger.warn(warnMsg); - LoggingContext.successStatusFields(); - } - - }// End of showNodeInfo() - - - public void showPropertiesForEdge( EELFLogger logger, Edge 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); - Vertex inVtx = tEd.inVertex(); - Iterator<VertexProperty<Object>> pI = inVtx.properties(); - String infStr = FOUND_VERTEX_ID_ + 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); - Vertex outVtx = tEd.outVertex(); - Iterator<VertexProperty<Object>> pI = outVtx.properties(); - String infStr = FOUND_VERTEX_ID_ + 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 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() + " <<< "); - continue; - } - - 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 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 ); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logger.warn( wMsg ); - LoggingContext.successStatusFields(); - } - return edgeCount; - - }// end of countEdges() - - - public int countDescendants(EELFLogger logger, Vertex 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 ); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logger.warn( wMsg ); - return totalCount; - } - - try { - Iterator <Vertex> vertI = graph.traversal().V(vtx).union(__.outE().has(EdgeProperty.CONTAINS.toString(), AAIDirection.OUT.toString()).inV(), __.inE().has(EdgeProperty.CONTAINS.toString(), AAIDirection.IN.toString()).outV()); - while( vertI != null && vertI.hasNext() ){ - totalCount++; - Vertex childVtx = 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 ); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logger.warn( wMsg ); - LoggingContext.successStatusFields(); - - } - - return totalCount; - }// end of countDescendants() - - - public boolean getEdgeDelConfirmation( EELFLogger logger, String uid, Edge 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 (!"y".equalsIgnoreCase(confirm)) { - 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 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 ); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logger.warn( infMsg ); - LoggingContext.successStatusFields(); - } - - 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 ); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logger.warn( infMsg ); - LoggingContext.successStatusFields(); - } - - if( maxDescString != null && !maxDescString.isEmpty() ){ - try { - maxDescCount = Integer.parseInt(maxDescString); - } - catch ( Exception nfe ){ - // Don't worry, we will leave "maxDescCount" set to the default value - } - } - - if( maxEdgeString != null && !maxEdgeString.isEmpty() ){ - 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().isEmpty() ){ - 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); - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logger.error(errMsg); - LoggingContext.successStatusFields(); - 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 (!"y".equalsIgnoreCase(confirm)) { - 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() - } - - public static JanusGraph setupGraph(EELFLogger logger){ - - JanusGraph janusGraph = null; - - try (InputStream inputStream = new FileInputStream(AAIConstants.REALTIME_DB_CONFIG);){ - - Properties properties = new Properties(); - properties.load(inputStream); - - if(INMEMORY.equals(properties.get("storage.backend"))){ - janusGraph = AAIGraph.getInstance().getGraph(); - graphType = INMEMORY; - } else { - janusGraph = JanusGraphFactory.open( - new AAIGraphConfig.Builder(AAIConstants.REALTIME_DB_CONFIG) - .forService(ForceDeleteTool.class.getSimpleName()) - .withGraphType("realtime1") - .buildConfiguration() - ); - } - } catch (Exception e) { - logger.error("Unable to open the graph", LogFormatTools.getStackTop(e)); - } - - return janusGraph; - } - - public static void closeGraph(JanusGraph graph, EELFLogger logger){ - - try { - if(INMEMORY.equals(graphType)) { - return; - } - if( graph != null && graph.isOpen() ){ - graph.tx().close(); - graph.close(); - } - } catch (Exception ex) { - // Don't throw anything because JanusGraph sometimes is just saying that the graph is already closed{ - logger.warn("WARNING from final graph.shutdown()", ex); - } - } -} - - diff --git a/aai-resources/src/main/java/org/onap/aai/dbgen/GraphMLTokens.java b/aai-resources/src/main/java/org/onap/aai/dbgen/GraphMLTokens.java deleted file mode 100644 index d43b57f..0000000 --- a/aai-resources/src/main/java/org/onap/aai/dbgen/GraphMLTokens.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.dbgen; - -/** - * 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/onap/aai/dbgen/SchemaMod.java b/aai-resources/src/main/java/org/onap/aai/dbgen/SchemaMod.java deleted file mode 100644 index 81adb68..0000000 --- a/aai-resources/src/main/java/org/onap/aai/dbgen/SchemaMod.java +++ /dev/null @@ -1,183 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.dbgen; - -import java.util.Properties; - -import org.onap.aai.dbmap.DBConnectionType; -import org.onap.aai.introspection.Loader; -import org.onap.aai.introspection.LoaderFactory; -import org.onap.aai.introspection.ModelType; -import org.onap.aai.introspection.Version; -import org.onap.aai.logging.ErrorLogHelper; -import org.onap.aai.serialization.engines.QueryStyle; -import org.onap.aai.serialization.engines.JanusGraphDBEngine; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; -import org.onap.aai.util.AAIConfig; -import org.onap.aai.util.AAIConstants; -import org.onap.aai.util.UniquePropertyCheck; -import org.slf4j.MDC; - -import com.att.eelf.configuration.Configuration; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; - -public class SchemaMod { - - - - /** - * The main method. - * - * @param args the arguments - */ - public static void main(String[] args) { - - SchemaMod.execute(args); - System.exit(0); - - }// End of main() - - /** - * Execute. - * - * @param args the args - */ - public static void execute(String[] args) { - - // Set the logging file properties to be used by EELFManager - Properties props = System.getProperties(); - props.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, AAIConstants.AAI_SCHEMA_MOD_LOGBACK_PROPS); - props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES); - - EELFLogger logger = EELFManager.getInstance().getLogger(UniquePropertyCheck.class.getSimpleName()); - MDC.put("logFilenameAppender", SchemaMod.class.getSimpleName()); - - // NOTE -- We're just working with properties that are used for NODES - // for now. - String propName = ""; - String targetDataType = ""; - String targetIndexInfo = ""; - String preserveDataFlag = ""; - - String usageString = "Usage: SchemaMod propertyName targetDataType targetIndexInfo preserveDataFlag \n"; - if (args.length != 4) { - String emsg = "Four Parameters are required. \n" + usageString; - logAndPrint(logger, emsg); - System.exit(1); - } else { - propName = args[0]; - targetDataType = args[1]; - targetIndexInfo = args[2]; - preserveDataFlag = args[3]; - } - - if (propName.equals("")) { - String emsg = "Bad parameter - propertyName cannot be empty. \n" + usageString; - logAndPrint(logger, emsg); - System.exit(1); - } else if (!targetDataType.equals("String") && !targetDataType.equals("Set<String>") - && !targetDataType.equals("Integer") && !targetDataType.equals("Long") - && !targetDataType.equals("Boolean")) { - String emsg = "Unsupported targetDataType. We only support String, Set<String>, Integer, Long or Boolean for now.\n" - + usageString; - logAndPrint(logger, emsg); - System.exit(1); - } else if (!targetIndexInfo.equals("uniqueIndex") && !targetIndexInfo.equals("index") - && !targetIndexInfo.equals("noIndex")) { - String emsg = "Unsupported IndexInfo. We only support: 'uniqueIndex', 'index' or 'noIndex'.\n" - + usageString; - logAndPrint(logger, emsg); - System.exit(1); - } - - try { - AAIConfig.init(); - ErrorLogHelper.loadProperties(); - } catch (Exception ae) { - String emsg = "Problem with either AAIConfig.init() or ErrorLogHelper.LoadProperties(). "; - logAndPrint(logger, emsg + "[" + ae.getMessage() + "]"); - System.exit(1); - } - - - // Give a big warning if the DbMaps.PropertyDataTypeMap value does not - // agree with what we're doing - String warningMsg = ""; - /*if (!dbMaps.PropertyDataTypeMap.containsKey(propName)) { - String emsg = "Property Name = [" + propName + "] not found in PropertyDataTypeMap. "; - logAndPrint(logger, emsg); - System.exit(1); - } else { - String currentDataType = dbMaps.PropertyDataTypeMap.get(propName); - if (!currentDataType.equals(targetDataType)) { - warningMsg = "TargetDataType [" + targetDataType + "] does not match what is in DbRules.java (" - + currentDataType + ")."; - } - }*/ - - if (!warningMsg.equals("")) { - logAndPrint(logger, "\n>>> WARNING <<<< "); - logAndPrint(logger, ">>> " + warningMsg + " <<<"); - } - - logAndPrint(logger, ">>> Processing will begin in 5 seconds (unless interrupted). <<<"); - try { - // Give them a chance to back out of this - Thread.sleep(5000); - } catch (java.lang.InterruptedException ie) { - logAndPrint(logger, " DB Schema Update has been aborted. "); - Thread.currentThread().interrupt(); - System.exit(1); - } - - logAndPrint(logger, " ---- NOTE --- about to open graph (takes a little while)\n"); - - Version version = Version.getLatest(); - QueryStyle queryStyle = QueryStyle.TRAVERSAL; - ModelType introspectorFactoryType = ModelType.MOXY; - Loader loader = LoaderFactory.createLoaderForVersion(introspectorFactoryType, version); - TransactionalGraphEngine engine = null; - try { - engine = new JanusGraphDBEngine(queryStyle, DBConnectionType.REALTIME, loader); - SchemaModInternal internal = new SchemaModInternal(engine, logger, propName, targetDataType, targetIndexInfo, new Boolean(preserveDataFlag)); - internal.execute(); - engine.startTransaction(); - engine.tx().close(); - } catch (Exception e) { - String emsg = "Not able to get a graph object in SchemaMod.java\n"; - logAndPrint(logger, e.getMessage()); - logAndPrint(logger, emsg); - System.exit(1); - } - } - /** - * Log and print. - * - * @param logger the logger - * @param msg the msg - */ - protected static void logAndPrint(EELFLogger logger, String msg) { - System.out.println(msg); - logger.info(msg); - } - - -} diff --git a/aai-resources/src/main/java/org/onap/aai/dbgen/SchemaModInternal.java b/aai-resources/src/main/java/org/onap/aai/dbgen/SchemaModInternal.java deleted file mode 100644 index 1aa33ee..0000000 --- a/aai-resources/src/main/java/org/onap/aai/dbgen/SchemaModInternal.java +++ /dev/null @@ -1,309 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.aai.dbgen; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.UUID; - -import org.apache.tinkerpop.gremlin.structure.Direction; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; -import org.onap.aai.util.FormatDate; -import org.onap.aai.util.UniquePropertyCheck; - -import com.att.eelf.configuration.EELFLogger; -import org.janusgraph.core.Cardinality; -import org.janusgraph.core.PropertyKey; -import org.janusgraph.core.schema.JanusGraphManagement; - -public class SchemaModInternal { - private static final String FROMAPPID = "AAI-UTILS"; - private final String TRANSID = UUID.randomUUID().toString(); - private final TransactionalGraphEngine engine; - private final String propName; - private final Class<?> type; - private final String indexType; - private final boolean preserveData; - private final Cardinality cardinality; - private final EELFLogger logger; - - public SchemaModInternal(TransactionalGraphEngine engine, EELFLogger logger, String propName, String type, String indexType, boolean preserveData) { - this.engine = engine; - this.propName = propName; - this.type = determineClass(type); - this.indexType = indexType; - this.preserveData = preserveData; - this.cardinality = determineCardinality(type); - this.logger = logger; - } - - - private Class<?> determineClass(String type) { - final Class<?> result; - if (type.equals("String")) { - result = String.class; - } else if (type.equals("Set<String>")) { - result = String.class; - } else if (type.equals("Integer")) { - result = Integer.class; - } else if (type.equals("Boolean")) { - result = Boolean.class; - } else if (type.equals("Character")) { - result = Character.class; - } else if (type.equals("Long")) { - result = Long.class; - } else if (type.equals("Float")) { - result = Float.class; - } else if (type.equals("Double")) { - result = Double.class; - } else { - String emsg = "Not able translate the targetDataType [" + type + "] to a Class variable.\n"; - logAndPrint(logger, emsg); - throw new RuntimeException(emsg); - } - - return result; - } - private Cardinality determineCardinality(String type) { - if (type.equals("Set<String>")) { - return Cardinality.SET; - } else { - return Cardinality.SINGLE; - } - } - public void execute() { - JanusGraphManagement graphMgt = null; - boolean success = false; - try { - // Make sure this property is in the DB. - graphMgt = engine.asAdmin().getManagementSystem(); - if (graphMgt == null) { - String emsg = "Not able to get a graph Management object in SchemaMod.java\n"; - logAndPrint(logger, emsg); - System.exit(1); - } - PropertyKey origPropKey = graphMgt.getPropertyKey(propName); - if (origPropKey == null) { - String emsg = "The propName = [" + propName + "] is not defined in our graph. "; - logAndPrint(logger, emsg); - System.exit(1); - } - - if (indexType.equals("uniqueIndex")) { - // Make sure the data in the property being changed can have a - // unique-index put on it. - // Ie. if there are duplicate values, we will not be able to - // migrate the data back into the property. - Boolean foundDupesFlag = UniquePropertyCheck.runTheCheckForUniqueness(TRANSID, FROMAPPID, - engine.tx(), propName, logger); - if (foundDupesFlag) { - logAndPrint(logger, - "\n\n!!!!!! >> Cannot add a uniqueIndex for the property: [" + propName - + "] because duplicate values were found. See the log for details on which" - + " nodes have this value. \nThey will need to be resolved (by updating those values to new" - + " values or deleting unneeded nodes) using the standard REST-API \n"); - System.exit(1); - } - } - - // -------------- If we made it to here - we must be OK with making - // this change ------------ - - // Rename this property to a backup name (old name with "retired_" - // appended plus a dateStr) - - FormatDate fd = new FormatDate("MMddHHmm", "GMT"); - String dteStr= fd.getDateTime(); - - String retiredName = propName + "-" + dteStr + "-RETIRED"; - graphMgt.changeName(origPropKey, retiredName); - - // Create a new property using the original property name and the - // targetDataType - PropertyKey freshPropKey = graphMgt.makePropertyKey(propName).dataType(type) - .cardinality(cardinality).make(); - - // Create the appropriate index (if any) - if (indexType.equals("uniqueIndex")) { - String freshIndexName = propName + dteStr; - graphMgt.buildIndex(freshIndexName, Vertex.class).addKey(freshPropKey).unique().buildCompositeIndex(); - } else if (indexType.equals("index")) { - String freshIndexName = propName + dteStr; - graphMgt.buildIndex(freshIndexName, Vertex.class).addKey(freshPropKey).buildCompositeIndex(); - } - - logAndPrint(logger, "Committing schema changes with graphMgt.commit()"); - graphMgt.commit(); - engine.startTransaction(); - // Get A new graph object - logAndPrint(logger, " ---- NOTE --- about to open a second graph object (takes a little while)\n"); - - // For each node that has this property, update the new from the old - // and then remove the - // old property from that node - Iterator<Vertex> verts = engine.asAdmin().getTraversalSource().V().has(retiredName); - int vtxCount = 0; - ArrayList<String> alreadySeenVals = new ArrayList<String>(); - while (verts.hasNext()) { - vtxCount++; - Vertex tmpVtx = verts.next(); - String tmpVid = tmpVtx.id().toString(); - - Object origVal = tmpVtx.<Object> property(retiredName).orElse(null); - if (preserveData) { - tmpVtx.property(propName, origVal); - if (indexType.equals("uniqueIndex")) { - // We're working on a property that is being used as a - // unique index - String origValStr = ""; - if (origVal != null) { - origValStr = origVal.toString(); - } - if (alreadySeenVals.contains(origValStr)) { - // This property is supposed to be unique, but we've - // already seen this value in this loop - // This should have been caught up in the first part - // of SchemaMod, but since it wasn't, we - // will just log the problem. - logAndPrint(logger, - "\n\n ---------- ERROR - could not migrate the old data [" + origValStr - + "] for propertyName [" + propName - + "] because this property is having a unique index put on it."); - showPropertiesAndEdges(TRANSID, FROMAPPID, tmpVtx, logger); - logAndPrint(logger, "-----------------------------------\n"); - } else { - // Ok to add this prop in as a unique value - tmpVtx.property(propName, origVal); - logAndPrint(logger, - "INFO -- just did the add of the freshPropertyKey and updated it with the orig value (" - + origValStr + ")"); - } - alreadySeenVals.add(origValStr); - } else { - // We are not working with a unique index - tmpVtx.property(propName, origVal); - logAndPrint(logger, - "INFO -- just did the add of the freshPropertyKey and updated it with the orig value (" - + origVal.toString() + ")"); - } - } else { - // existing nodes just won't have that property anymore - // Not sure if we'd ever actually want to do this -- maybe - // we'd do this if the new - // data type was not compatible with the old? - } - tmpVtx.property(retiredName).remove(); - - logAndPrint(logger, "INFO -- just did the remove of the " + retiredName + " from this vertex. (vid=" - + tmpVid + ")"); - } - - success = true; - } catch (Exception ex) { - logAndPrint(logger, "Threw a regular Exception: "); - logAndPrint(logger, ex.getMessage()); - } finally { - if (graphMgt != null && graphMgt.isOpen()) { - // Any changes that worked correctly should have already done - // their commits. - graphMgt.rollback(); - } - if (engine != null) { - if (success) { - engine.commit(); - } else { - engine.rollback(); - } - } - } - } - - /** - * Show properties and edges. - * - * @param transId the trans id - * @param fromAppId the from app id - * @param tVert the t vert - * @param logger the logger - */ - private static void showPropertiesAndEdges(String transId, String fromAppId, Vertex tVert, EELFLogger logger) { - - if (tVert == null) { - logAndPrint(logger, "Null node passed to showPropertiesAndEdges."); - } else { - String nodeType = ""; - Object ob = tVert.<String> property("aai-node-type"); - if (ob == null) { - nodeType = "null"; - } else { - nodeType = ob.toString(); - } - - logAndPrint(logger, " AAINodeType/VtxID for this Node = [" + nodeType + "/" + tVert.id() + "]"); - logAndPrint(logger, " Property Detail: "); - Iterator<VertexProperty<Object>> pI = tVert.properties(); - while (pI.hasNext()) { - VertexProperty<Object> tp = pI.next(); - Object val = tp.value(); - logAndPrint(logger, "Prop: [" + tp.key() + "], val = [" + val + "] "); - } - - Iterator<Edge> eI = tVert.edges(Direction.BOTH); - if (!eI.hasNext()) { - logAndPrint(logger, "No edges were found for this vertex. "); - } - while (eI.hasNext()) { - Edge ed = eI.next(); - String lab = ed.label(); - Vertex vtx; - if (tVert.equals(ed.inVertex())) { - vtx = ed.outVertex(); - } else { - vtx = ed.inVertex(); - } - if (vtx == null) { - logAndPrint(logger, - " >>> COULD NOT FIND VERTEX on the other side of this edge edgeId = " + ed.id() + " <<< "); - } else { - String nType = vtx.<String> property("aai-node-type").orElse(null); - String vid = vtx.id().toString(); - logAndPrint(logger, "Found an edge (" + lab + ") from this vertex to a [" + nType - + "] node with VtxId = " + vid); - } - } - } - } // End of showPropertiesAndEdges() - - /** - * Log and print. - * - * @param logger the logger - * @param msg the msg - */ - protected static void logAndPrint(EELFLogger logger, String msg) { - System.out.println(msg); - logger.info(msg); - } - -} diff --git a/aai-resources/src/main/java/org/onap/aai/dbgen/UpdateEdgeTags.java b/aai-resources/src/main/java/org/onap/aai/dbgen/UpdateEdgeTags.java deleted file mode 100644 index aebc456..0000000 --- a/aai-resources/src/main/java/org/onap/aai/dbgen/UpdateEdgeTags.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.dbgen; - -import org.onap.aai.dbgen.tags.UpdateEdgeTagsCmd; -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.logging.LoggingContext; -import org.onap.aai.logging.LoggingContext.StatusCode; -import org.onap.aai.util.AAIConstants; -import org.onap.aai.util.AAISystemExitUtil; - -import java.util.UUID; - - -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) { - - System.setProperty("aai.service.name", UpdateEdgeTags.class.getSimpleName()); - - 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); - } - LoggingContext.init(); - LoggingContext.partnerName(FROMAPPID); - LoggingContext.serviceName(AAIConstants.AAI_RESOURCES_MS); - LoggingContext.component("updateEdgeTags"); - LoggingContext.targetEntity(AAIConstants.AAI_RESOURCES_MS); - LoggingContext.targetServiceName("main"); - LoggingContext.requestId(TRANSID); - LoggingContext.statusCode(StatusCode.COMPLETE); - LoggingContext.responseCode("0"); - - String edgeRuleKeyVal = args[0]; - - try { - UpdateEdgeTagsCmd edgeOp = new UpdateEdgeTagsCmd(edgeRuleKeyVal); - edgeOp.execute(); - } catch (AAIException e) { - e.printStackTrace(); - } finally { - AAISystemExitUtil.systemExitCloseAAIGraph(0); - } - - }// end of main() -} - - - diff --git a/aai-resources/src/main/java/org/onap/aai/dbgen/tags/UpdateEdgeTagsCmd.java b/aai-resources/src/main/java/org/onap/aai/dbgen/tags/UpdateEdgeTagsCmd.java deleted file mode 100644 index 6e10853..0000000 --- a/aai-resources/src/main/java/org/onap/aai/dbgen/tags/UpdateEdgeTagsCmd.java +++ /dev/null @@ -1,220 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.dbgen.tags; - -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Graph; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.janusgraph.core.JanusGraph; -import org.onap.aai.dbmap.AAIGraph; -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.logging.ErrorLogHelper; -import org.onap.aai.serialization.db.EdgeRule; -import org.onap.aai.serialization.db.EdgeRules; -import org.onap.aai.util.AAIConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -public class UpdateEdgeTagsCmd implements Command { - private JanusGraph graph; - private String rulesFilename; - private EdgeRules edgeRulesInstance = null; - private String[] edgeRuleKeys = null; - - private String filter = "all"; - private static final String FROMAPPID = "AAI-DB"; - private static final String TRANSID = UUID.randomUUID().toString(); - - - static final Logger logger = LoggerFactory.getLogger(UpdateEdgeTagsCmd.class); - - /** - * @param filter - */ - public UpdateEdgeTagsCmd(String filter) throws AAIException { - super(); - this.filter = filter; - createEdgeRuleSet(); - } - - /** - * @param filter - * @param rulesFilename - */ - public UpdateEdgeTagsCmd(String filter, String rulesFilename) { - super(); - this.rulesFilename = rulesFilename; - this.filter = filter; - this.createEdgeRuleSet(); - } - - @Override - public void execute() throws AAIException { - try { - ErrorLogHelper.loadProperties(); - if(graph == null) { - AAIConfig.init(); - logger.info(" ---- NOTE --- about to open graph (takes a little while)--------\n"); - graph = AAIGraph.getInstance().getGraph(); - } - if( graph == null ){ - String emsg = "null graph object in updateEdgeTags() \n"; - logger.info(emsg); - return; - } - } - catch (AAIException e1) { - String msg = e1.getErrorObject().toString(); - System.out.println(msg); - return; - } - catch (Exception e2) { - String msg = e2.toString(); - System.out.println(msg); - e2.printStackTrace(); - return; - } - - Graph g = graph.newTransaction(); - try { - Iterator<Edge> edgeItr = graph.traversal().E(); -/* - if("all".equalsIgnoreCase(filter)) { - edgeItr = graph.traversal().E(); - } else { - edgeItr = graph.traversal().E()..inV().property("aai-node-type",this.edgeRuleKeys[0]); - edgeItr = graph.traversal().E().inV().has("aai-node-type").values(this.edgeRuleKeys[0]).outV().has("aai-node-type").values(this.edgeRuleKeys[1]); - } -*/ - //Iterate over all the edges of the in memory graph - while( edgeItr != null && edgeItr.hasNext() ){ - - Edge thisEdge = edgeItr.next(); - //The filter can limit the application of changes to edges between vertices of one pair of node-types - //Other node type pairs found in in-memory graph are skipped - if(! passesFilter(thisEdge) ) { - continue; - } - - //Find the rules in the file between the node-type pair for the current in-memory edge - if( edgeRulesInstance.hasEdgeRule(thisEdge.inVertex().<String>property("aai-node-type").orElse(null),thisEdge.outVertex().<String>property("aai-node-type").orElse(null))) { - logger.info("key = " + thisEdge.inVertex().<String>property("aai-node-type").orElse(null)+"|"+ thisEdge.outVertex().<String>property("aai-node-type").orElse(null)+ ", label = " + thisEdge.label() - + ", for id = " + thisEdge.id().toString() + ", set: "+thisEdge.keys()+"\n"); - //Get the rule map from the FILE for the node-type pair, filtered by label found on the in-memory Edge; expecting one rule - //Note: the filter label does not work -- adding equals/contains(thisEdge.label() tests below - Map<String, EdgeRule> edgeRules =edgeRulesInstance.getEdgeRules(thisEdge.inVertex().<String>property("aai-node-type").orElse(null),thisEdge.outVertex().<String>property("aai-node-type").orElse(null), thisEdge.label()); -// Collection<EdgeRule> edgeRules = edgeRuleMultimap.get(derivedEdgeKey); - //Apply the Edge properties from the FILE rule to the in-memory Edge - for(EdgeRule e : edgeRules.values()) { - if(e.getLabel().equals(thisEdge.label())) { - logger.info("EdgeRule e: " + String.join("|",thisEdge.outVertex().<String>property("aai-node-type").orElse(null),thisEdge.inVertex().<String>property("aai-node-type").orElse(null),e.getLabel())); - edgeRulesInstance.addProperties(thisEdge, e); - } - } - //The FILE ruleset is broken? -- run away; discard all changes! - if(! edgeRules.containsKey(thisEdge.label())) { - // Couldn't find a rule for this edge - logger.error("Broken EdgeSet in edgeRuleFile: " + thisEdge.bothVertices()); - throw new AAIException("AAI_6120", "No EdgeRule found for nodeTypes: " + String.join("|",thisEdge.outVertex().<String>property("aai-node-type").orElse(null),thisEdge.inVertex().<String>property("aai-node-type").orElse(null),thisEdge.label())); - } - } else { - //The expected FILE ruleset could not be found -- run away; discard all changes! - logger.error("Missing EdgeSet in edgeRuleFile: " + thisEdge.bothVertices()); - throw new AAIException("AAI_6120", "No EdgeRule found for nodeTypes: " + String.join("|",thisEdge.outVertex().<String>property("aai-node-type").orElse(null),thisEdge.inVertex().<String>property("aai-node-type").orElse(null),thisEdge.label())); - } - - } // End of looping over all in-memory edges - graph.tx().commit(); - logger.info("- committed updates for listed edges " ); - } - catch (Exception e2) { - String msg = e2.toString(); - logger.error(msg); - e2.printStackTrace(); - if( g != null ){ - graph.tx().rollback(); - } - if(e2 instanceof AAIException) { - throw e2; - } - return; - } - finally { - try { - g.close(); - } - catch (Exception e) { - logger.error("Error occured while closing Transaction with graph" + e.getMessage()); - } - } - } - - - /** - * @return the rulesFilename - */ - public String getRulesFilename() { - return this.rulesFilename; - } - - /** - * @return the graph - */ - public JanusGraph getGraph() { - return this.graph; - } - - /** - * @param graph the graph to set - */ - public void setGraph(JanusGraph graph) { - this.graph = graph; - } - - private void createEdgeRuleSet() { - if(this.filter != null) this.edgeRuleKeys = filter.split("\\|"); - edgeRulesInstance = (this.rulesFilename == null) ? EdgeRules.getInstance() : EdgeRules.getInstance(rulesFilename); - return; - } - - private boolean passesFilter(Edge tEdge) { - if("all".equalsIgnoreCase(filter) ) { - logger.debug("EdgeRule PROCESSALL: " + String.join("|",tEdge.outVertex().<String>property("aai-node-type").orElse(null),tEdge.inVertex().<String>property("aai-node-type").orElse(null),tEdge.label())); - return true; - } - Iterator<Vertex> vItr = tEdge.bothVertices(); - - ArrayList<String> l = new ArrayList<String>(Arrays.asList(edgeRuleKeys)); - while( vItr != null && vItr.hasNext() ) { - Vertex v = vItr.next(); - int i = l.indexOf(v.property("aai-node-type").value()); - if (i >= 0) l.remove(i); - } - if(l.isEmpty()) { - logger.debug("EdgeRule filterPROCESS: " + String.join("|",tEdge.outVertex().<String>property("aai-node-type").orElse(null),tEdge.inVertex().<String>property("aai-node-type").orElse(null),tEdge.label())); - } - else { - logger.debug("EdgeRule filterSKIP: " + String.join("|",tEdge.outVertex().<String>property("aai-node-type").orElse(null),tEdge.inVertex().<String>property("aai-node-type").orElse(null),tEdge.label())); - } - return l.isEmpty(); - } -} diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/package-info.java b/aai-resources/src/main/java/org/onap/aai/interceptors/package-info.java index f6498af..ee9c334 100644 --- a/aai-resources/src/main/java/org/onap/aai/interceptors/package-info.java +++ b/aai-resources/src/main/java/org/onap/aai/interceptors/package-info.java @@ -33,4 +33,4 @@ * </code> * </pre> */ -package org.onap.aai.interceptors; +package org.onap.aai.interceptors;
\ No newline at end of file diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/post/AAIResponseFilterPriority.java b/aai-resources/src/main/java/org/onap/aai/interceptors/post/AAIResponseFilterPriority.java index d91e7f6..146f847 100644 --- a/aai-resources/src/main/java/org/onap/aai/interceptors/post/AAIResponseFilterPriority.java +++ b/aai-resources/src/main/java/org/onap/aai/interceptors/post/AAIResponseFilterPriority.java @@ -19,14 +19,22 @@ */ package org.onap.aai.interceptors.post; +/** + * Response Filter order is done reverse sorted + * so in the following case the first response filter would be + * HEADER_MANIPULATION, RESPONSE_TRANS_LOGGING, RESET_LOGGING_CONTEXT, + * and INVALID_RESPONSE_STATUS + */ public final class AAIResponseFilterPriority { private AAIResponseFilterPriority() {} - public static final int HEADER_MANIPULATION = 1000; + public static final int INVALID_RESPONSE_STATUS = 1000; + + public static final int RESET_LOGGING_CONTEXT = 2000; - public static final int RESPONSE_TRANS_LOGGING = 2000; + public static final int RESPONSE_TRANS_LOGGING = 3000; - public static final int RESET_LOGGING_CONTEXT = 3000; + public static final int HEADER_MANIPULATION = 4000; } diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/post/InvalidResponseStatus.java b/aai-resources/src/main/java/org/onap/aai/interceptors/post/InvalidResponseStatus.java new file mode 100644 index 0000000..7fd0b9c --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/interceptors/post/InvalidResponseStatus.java @@ -0,0 +1,65 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.interceptors.post; + +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.interceptors.AAIContainerFilter; +import org.onap.aai.logging.ErrorLogHelper; + +import javax.annotation.Priority; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +@Priority(AAIResponseFilterPriority.INVALID_RESPONSE_STATUS) +public class InvalidResponseStatus extends AAIContainerFilter implements ContainerResponseFilter { + + @Override + public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) + throws IOException { + + if(responseContext.getStatus() == 405){ + + responseContext.setStatus(400); + AAIException e = new AAIException("AAI_3012"); + ArrayList<String> templateVars = new ArrayList<>(); + + List<MediaType> mediaTypeList = new ArrayList<>(); + + String contentType = responseContext.getHeaderString("Content-Type"); + + if (contentType == null) { + mediaTypeList.add(MediaType.APPLICATION_XML_TYPE); + } else { + mediaTypeList.add(MediaType.valueOf(contentType)); + } + + String message = ErrorLogHelper.getRESTAPIErrorResponse(mediaTypeList, e, templateVars); + + responseContext.setEntity(message); + } + + } + +} diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/post/ResetLoggingContext.java b/aai-resources/src/main/java/org/onap/aai/interceptors/post/ResetLoggingContext.java index f8c5644..04f0391 100644 --- a/aai-resources/src/main/java/org/onap/aai/interceptors/post/ResetLoggingContext.java +++ b/aai-resources/src/main/java/org/onap/aai/interceptors/post/ResetLoggingContext.java @@ -26,6 +26,8 @@ import javax.servlet.http.HttpServletRequest; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.Response.StatusType; import org.onap.aai.interceptors.AAIContainerFilter; import org.onap.aai.logging.LoggingContext; @@ -47,23 +49,52 @@ public class ResetLoggingContext extends AAIContainerFilter implements Container public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { - this.cleanLoggingContext(); + this.cleanLoggingContext(responseContext); } - private void cleanLoggingContext() { - final String responseCode = LoggingContext.responseCode(); - String url = httpServletRequest.getRequestURL().toString(); + private void cleanLoggingContext(ContainerResponseContext responseContext) { + //String url = httpServletRequest.getRequestURL().toString(); + boolean success = true; + String uri = httpServletRequest.getRequestURI(); + String queryString = httpServletRequest.getQueryString(); - if (responseCode != null && responseCode.startsWith("ERR.")) { - LoggingContext.statusCode(StatusCode.ERROR); - LOGGER.error(url + " call failed with responseCode=" + responseCode); - } else { - LoggingContext.statusCode(StatusCode.COMPLETE); - LOGGER.info(url + " call succeeded"); + if(queryString != null && !queryString.isEmpty()){ + uri = uri + "?" + queryString; } + // For now, we use the the HTTP status code, + // This may change, once the requirements for response codes are defined + int httpStatusCode = responseContext.getStatus(); + if ( httpStatusCode < 100 || httpStatusCode > 599 ) { + httpStatusCode = Status.INTERNAL_SERVER_ERROR.getStatusCode(); + } + LoggingContext.responseCode(Integer.toString(httpStatusCode)); + + StatusType sType = responseContext.getStatusInfo(); + if ( sType != null ) { + Status.Family sFamily = sType.getFamily(); + if ( ! ( Status.Family.SUCCESSFUL.equals(sFamily) || + ( Status.NOT_FOUND.equals(Status.fromStatusCode(httpStatusCode)) ) ) ) { + success = false; + } + } + else { + if ( (httpStatusCode < 200 || httpStatusCode > 299) && ( ! ( Status.NOT_FOUND.equals(Status.fromStatusCode(httpStatusCode) ) ) ) ) { + success = false; + } + } + if (success) { + LoggingContext.statusCode(StatusCode.COMPLETE); + LOGGER.info(uri + " call succeeded"); + } + else { + LoggingContext.statusCode(StatusCode.ERROR); + LOGGER.error(uri + " call failed with responseCode=" + httpStatusCode); + } LoggingContext.clear(); + + } } diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/post/ResponseHeaderManipulation.java b/aai-resources/src/main/java/org/onap/aai/interceptors/post/ResponseHeaderManipulation.java index 6d6dbd8..3809540 100644 --- a/aai-resources/src/main/java/org/onap/aai/interceptors/post/ResponseHeaderManipulation.java +++ b/aai-resources/src/main/java/org/onap/aai/interceptors/post/ResponseHeaderManipulation.java @@ -25,6 +25,7 @@ import javax.annotation.Priority; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.core.MediaType; import org.onap.aai.interceptors.AAIContainerFilter; import org.onap.aai.interceptors.AAIHeaderProperties; @@ -32,6 +33,7 @@ import org.onap.aai.interceptors.AAIHeaderProperties; @Priority(AAIResponseFilterPriority.HEADER_MANIPULATION) public class ResponseHeaderManipulation extends AAIContainerFilter implements ContainerResponseFilter { + private static final String DEFAULT_XML_TYPE = MediaType.APPLICATION_XML; @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) @@ -43,7 +45,21 @@ public class ResponseHeaderManipulation extends AAIContainerFilter implements Co private void updateResponseHeaders(ContainerRequestContext requestContext, ContainerResponseContext responseContext) { + responseContext.getHeaders().add(AAIHeaderProperties.AAI_TX_ID, requestContext.getProperty(AAIHeaderProperties.AAI_TX_ID)); + + String responseContentType = responseContext.getHeaderString("Content-Type"); + + if(responseContentType == null){ + String acceptType = requestContext.getHeaderString("Accept"); + + if(acceptType == null || "*/*".equals(acceptType)){ + responseContext.getHeaders().putSingle("Content-Type", DEFAULT_XML_TYPE); + } else { + responseContext.getHeaders().putSingle("Content-Type", acceptType); + } + } + } } diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/AAIRequestFilterPriority.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/AAIRequestFilterPriority.java index 0db7b44..c3d9d3b 100644 --- a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/AAIRequestFilterPriority.java +++ b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/AAIRequestFilterPriority.java @@ -31,9 +31,16 @@ public final class AAIRequestFilterPriority { public static final int HTTP_HEADER = 4000; + public static final int LATEST = 4250; + public static final int AUTHORIZATION = 4500; - public static final int HEADER_MANIPULATION = 5000; + public static final int RETIRED_SERVICE = 5000; + + public static final int VERSION = 5500; + + public static final int HEADER_MANIPULATION = 6000; + + public static final int REQUEST_MODIFICATION = 7000; - public static final int REQUEST_MODIFICATION = 6000; } diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/OneWaySslAuthorization.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/OneWaySslAuthorization.java index 8fe2d6e..1f8a6ec 100644 --- a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/OneWaySslAuthorization.java +++ b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/OneWaySslAuthorization.java @@ -19,11 +19,13 @@ */ package org.onap.aai.interceptors.pre; +import org.onap.aai.Profiles; import org.onap.aai.exceptions.AAIException; import org.onap.aai.interceptors.AAIContainerFilter; import org.onap.aai.logging.ErrorLogHelper; import org.onap.aai.service.AuthorizationService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; import javax.annotation.Priority; import javax.ws.rs.container.ContainerRequestContext; @@ -36,6 +38,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +@Profile(Profiles.ONE_WAY_SSL) @PreMatching @Priority(AAIRequestFilterPriority.AUTHORIZATION) public class OneWaySslAuthorization extends AAIContainerFilter implements ContainerRequestFilter { diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/RequestHeaderManipulation.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/RequestHeaderManipulation.java index 7f74f1e..97562d2 100644 --- a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/RequestHeaderManipulation.java +++ b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/RequestHeaderManipulation.java @@ -39,15 +39,10 @@ import org.springframework.beans.factory.annotation.Autowired; @Priority(AAIRequestFilterPriority.HEADER_MANIPULATION) public class RequestHeaderManipulation extends AAIContainerFilter implements ContainerRequestFilter { - @Autowired - private HttpServletRequest httpServletRequest; - - private static final Pattern versionedEndpoint = Pattern.compile("^/aai/(v\\d+)"); - @Override - public void filter(ContainerRequestContext requestContext) throws IOException { + public void filter(ContainerRequestContext requestContext) { - String uri = httpServletRequest.getRequestURI(); + String uri = requestContext.getUriInfo().getPath(); this.addRequestContext(uri, requestContext.getHeaders()); } @@ -56,7 +51,7 @@ public class RequestHeaderManipulation extends AAIContainerFilter implements Con String rc = ""; - Matcher match = versionedEndpoint.matcher(uri); + Matcher match = VersionInterceptor.EXTRACT_VERSION_PATTERN.matcher(uri); if (match.find()) { rc = match.group(1); } diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/RequestModification.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/RequestModification.java index 50e87b0..797f9c9 100644 --- a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/RequestModification.java +++ b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/RequestModification.java @@ -36,7 +36,7 @@ import javax.ws.rs.core.UriBuilder; import org.onap.aai.interceptors.AAIContainerFilter; @PreMatching -@Priority(AAIRequestFilterPriority.HEADER_VALIDATION) +@Priority(AAIRequestFilterPriority.REQUEST_MODIFICATION) public class RequestModification extends AAIContainerFilter implements ContainerRequestFilter { @Override diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/RequestTransactionLogging.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/RequestTransactionLogging.java index e9e8d5f..f9976c2 100644 --- a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/RequestTransactionLogging.java +++ b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/RequestTransactionLogging.java @@ -25,12 +25,14 @@ import java.io.IOException; import java.io.InputStream; import java.util.Random; import java.util.UUID; +import java.security.SecureRandom; import javax.annotation.Priority; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.PreMatching; +import javax.ws.rs.core.MediaType; import org.glassfish.jersey.message.internal.ReaderWriter; import org.glassfish.jersey.server.ContainerException; @@ -43,6 +45,7 @@ import org.onap.aai.util.HbaseSaltPrefixer; import org.springframework.beans.factory.annotation.Autowired; import com.google.gson.JsonObject; +import org.springframework.util.StringUtils; @PreMatching @Priority(AAIRequestFilterPriority.REQUEST_TRANS_LOGGING) @@ -51,6 +54,13 @@ public class RequestTransactionLogging extends AAIContainerFilter implements Con @Autowired private HttpServletRequest httpServletRequest; + private static final String DEFAULT_CONTENT_TYPE = MediaType.APPLICATION_JSON; + private static final String DEFAULT_RESPONSE_TYPE = MediaType.APPLICATION_XML; + + private static final String CONTENT_TYPE = "Content-Type"; + private static final String ACCEPT = "Accept"; + private static final String TEXT_PLAIN = "text/plain"; + @Override public void filter(ContainerRequestContext requestContext) throws IOException { @@ -59,17 +69,34 @@ public class RequestTransactionLogging extends AAIContainerFilter implements Con this.addToRequestContext(requestContext, AAIHeaderProperties.AAI_TX_ID, fullId); this.addToRequestContext(requestContext, AAIHeaderProperties.AAI_REQUEST, this.getRequest(requestContext, fullId)); this.addToRequestContext(requestContext, AAIHeaderProperties.AAI_REQUEST_TS, currentTimeStamp); + this.addDefaultContentType(requestContext); } private void addToRequestContext(ContainerRequestContext requestContext, String name, String aaiTxIdToHeader) { requestContext.setProperty(name, aaiTxIdToHeader); } + private void addDefaultContentType(ContainerRequestContext requestContext) { + + String contentType = requestContext.getHeaderString(CONTENT_TYPE); + String acceptType = requestContext.getHeaderString(ACCEPT); + + if(contentType == null || contentType.contains(TEXT_PLAIN)){ + requestContext.getHeaders().putSingle(CONTENT_TYPE, DEFAULT_CONTENT_TYPE); + } + + if(StringUtils.isEmpty(acceptType) || acceptType.contains(TEXT_PLAIN)){ + requestContext.getHeaders().putSingle(ACCEPT, DEFAULT_RESPONSE_TYPE); + } + } + private String getAAITxIdToHeader(String currentTimeStamp) { String txId = UUID.randomUUID().toString(); try { + Random rand = new SecureRandom(); + int number = rand.nextInt(99999); txId = HbaseSaltPrefixer.getInstance().prependSalt(AAIConfig.get(AAIConstants.AAI_NODENAME) + "-" - + currentTimeStamp + "-" + new Random(System.currentTimeMillis()).nextInt(99999)); + + currentTimeStamp + "-" + number ); //new Random(System.currentTimeMillis()).nextInt(99999) } catch (AAIException e) { } @@ -81,7 +108,7 @@ public class RequestTransactionLogging extends AAIContainerFilter implements Con JsonObject request = new JsonObject(); request.addProperty("ID", fullId); request.addProperty("Http-Method", requestContext.getMethod()); - request.addProperty("Content-Type", httpServletRequest.getContentType()); + request.addProperty(CONTENT_TYPE, httpServletRequest.getContentType()); request.addProperty("Headers", requestContext.getHeaders().toString()); ByteArrayOutputStream out = new ByteArrayOutputStream(); diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/RetiredInterceptor.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/RetiredInterceptor.java new file mode 100644 index 0000000..643793d --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/RetiredInterceptor.java @@ -0,0 +1,148 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.interceptors.pre; + +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.interceptors.AAIContainerFilter; +import org.onap.aai.logging.ErrorLogHelper; +import org.onap.aai.service.RetiredService; +import org.onap.aai.util.AAIConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; + +import javax.annotation.Priority; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.PreMatching; +import javax.ws.rs.core.Response; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +// Can cache this so if the uri was already cached then it won't run the string +// matching each time but only does it for the first time + +@PreMatching +@Priority(AAIRequestFilterPriority.RETIRED_SERVICE) +public class RetiredInterceptor extends AAIContainerFilter implements ContainerRequestFilter { + + private static final Pattern VERSION_PATTERN = Pattern.compile("v\\d+|latest"); + + private RetiredService retiredService; + + private String basePath; + + @Autowired + public RetiredInterceptor(RetiredService retiredService, @Value("${schema.uri.base.path}") String basePath){ + this.retiredService = retiredService; + this.basePath = basePath; + if(!basePath.endsWith("/")){ + this.basePath = basePath + "/"; + } + } + @Override + public void filter(ContainerRequestContext containerRequestContext) throws IOException { + + String requestURI = containerRequestContext.getUriInfo().getAbsolutePath().getPath(); + + String version = extractVersionFromPath(requestURI); + + List<Pattern> retiredAllVersionList = retiredService.getRetiredAllVersionList(); + + + if(checkIfUriRetired(containerRequestContext, retiredAllVersionList, version, requestURI, "")){ + return; + } + + List<Pattern> retiredVersionList = retiredService.getRetiredPatterns(); + + checkIfUriRetired(containerRequestContext, retiredVersionList, version, requestURI); + } + + public boolean checkIfUriRetired(ContainerRequestContext containerRequestContext, + List<Pattern> retiredPatterns, + String version, + String requestURI, + String message){ + + + for(Pattern retiredPattern : retiredPatterns){ + if(retiredPattern.matcher(requestURI).matches()){ + AAIException e; + + if(message == null){ + e = new AAIException("AAI_3007"); + } else { + e = new AAIException("AAI_3015"); + } + + ArrayList<String> templateVars = new ArrayList<>(); + + if (templateVars.isEmpty()) { + templateVars.add("PUT"); + if(requestURI != null){ + requestURI = requestURI.replaceAll(basePath, ""); + } + templateVars.add(requestURI); + if(message == null){ + templateVars.add(version); + templateVars.add(AAIConfig.get("aai.default.api.version", "")); + } + } + + Response response = Response + .status(e.getErrorObject().getHTTPResponseCode()) + .entity( + ErrorLogHelper + .getRESTAPIErrorResponse( + containerRequestContext.getAcceptableMediaTypes(), e, templateVars + ) + ) + .build(); + + containerRequestContext.abortWith(response); + + return true; + } + } + + return false; + } + + public boolean checkIfUriRetired(ContainerRequestContext containerRequestContext, + List<Pattern> retiredPatterns, + String version, + String requestURI){ + return checkIfUriRetired(containerRequestContext, retiredPatterns, version, requestURI, null); + } + + protected String extractVersionFromPath(String requestURI) { + Matcher versionMatcher = VERSION_PATTERN.matcher(requestURI); + String version = null; + + if(versionMatcher.find()){ + version = versionMatcher.group(0); + } + return version; + } + +} diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/SetLoggingContext.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/SetLoggingContext.java index c991017..368d071 100644 --- a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/SetLoggingContext.java +++ b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/SetLoggingContext.java @@ -64,6 +64,7 @@ public class SetLoggingContext extends AAIContainerFilter implements ContainerRe LoggingContext.component(fromAppId); LoggingContext.serviceName(httpMethod + " " + uri); LoggingContext.targetServiceName(httpMethod + " " + uri); + LoggingContext.statusCode(LoggingContext.StatusCode.COMPLETE); } } diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/TwoWaySslAuthorization.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/TwoWaySslAuthorization.java new file mode 100644 index 0000000..d4e8c4f --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/TwoWaySslAuthorization.java @@ -0,0 +1,188 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.interceptors.pre; + +import java.io.IOException; +import java.security.cert.X509Certificate; +import java.util.*; +import java.util.stream.Collectors; + +import javax.annotation.Priority; +import javax.security.auth.x500.X500Principal; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.PreMatching; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.onap.aai.auth.AAIAuthCore; +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.interceptors.AAIContainerFilter; +import org.onap.aai.interceptors.AAIHeaderProperties; +import org.onap.aai.logging.ErrorLogHelper; +import org.onap.aai.restcore.HttpMethod; +import org.onap.aai.util.AAIConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; + +@PreMatching +@Priority(AAIRequestFilterPriority.AUTHORIZATION) +@Profile("two-way-ssl") +public class TwoWaySslAuthorization extends AAIContainerFilter implements ContainerRequestFilter { + + @Autowired + private HttpServletRequest httpServletRequest; + + @Autowired + private AAIAuthCore aaiAuthCore; + + @Override + public void filter(ContainerRequestContext requestContext) { + + Optional<Response> oResp; + + String uri = requestContext.getUriInfo().getAbsolutePath().getPath(); + String httpMethod = getHttpMethod(requestContext); + + List<MediaType> acceptHeaderValues = requestContext.getAcceptableMediaTypes(); + + Optional<String> authUser = getUser(this.httpServletRequest); + + if (authUser.isPresent()) { + oResp = this.authorize(uri, httpMethod, acceptHeaderValues, authUser.get(), + this.getHaProxyUser(this.httpServletRequest), getCertIssuer(this.httpServletRequest)); + if (oResp.isPresent()) { + requestContext.abortWith(oResp.get()); + return; + } + } else { + AAIException aaie = new AAIException("AAI_9107"); + requestContext + .abortWith(Response + .status(aaie.getErrorObject().getHTTPResponseCode()).entity(ErrorLogHelper + .getRESTAPIErrorResponseWithLogging(acceptHeaderValues, aaie, new ArrayList<>())) + .build()); + } + + } + + private String getCertIssuer(HttpServletRequest hsr) { + String issuer = hsr.getHeader("X-AAI-SSL-Issuer"); + if (issuer != null && !issuer.isEmpty()) { + // the haproxy header replaces the ', ' with '/' and reverses on the '/' need to undo that. + List<String> broken = Arrays.asList(issuer.split("/")); + broken = broken.stream().filter(s -> !s.isEmpty()).collect(Collectors.toList()); + Collections.reverse(broken); + issuer = String.join(", ", broken); + } else { + if (hsr.getAttribute("javax.servlet.request.cipher_suite") != null) { + X509Certificate[] certChain = (X509Certificate[]) hsr.getAttribute("javax.servlet.request.X509Certificate"); + if (certChain != null && certChain.length > 0) { + X509Certificate clientCert = certChain[0]; + issuer = clientCert.getIssuerX500Principal().getName(); + } + } + } + return issuer; + } + + private String getHttpMethod(ContainerRequestContext requestContext) { + String httpMethod = requestContext.getMethod(); + if ("POST".equalsIgnoreCase(httpMethod) + && "PATCH".equals(requestContext.getHeaderString(AAIHeaderProperties.HTTP_METHOD_OVERRIDE))) { + httpMethod = HttpMethod.MERGE_PATCH.toString(); + } + if (httpMethod.equalsIgnoreCase(HttpMethod.MERGE_PATCH.toString()) || "patch".equalsIgnoreCase(httpMethod)) { + httpMethod = HttpMethod.PUT.toString(); + } + return httpMethod; + } + + private Optional<String> getUser(HttpServletRequest hsr) { + String authUser = null; + if (hsr.getAttribute("javax.servlet.request.cipher_suite") != null) { + X509Certificate[] certChain = (X509Certificate[]) hsr.getAttribute("javax.servlet.request.X509Certificate"); + + /* + * If the certificate is null or the certificate chain length is zero Then + * retrieve the authorization in the request header Authorization Check that it + * is not null and that it starts with Basic and then strip the basic portion to + * get the base64 credentials Check if this is contained in the AAIBasicAuth + * Singleton class If it is, retrieve the username associated with that + * credentials and set to authUser Otherwise, get the principal from certificate + * and use that authUser + */ + + if (certChain == null || certChain.length == 0) { + + String authorization = hsr.getHeader("Authorization"); + + if (authorization != null && authorization.startsWith("Basic ")) { + authUser = authorization.replace("Basic ", ""); + } + + } else { + X509Certificate clientCert = certChain[0]; + X500Principal subjectDN = clientCert.getSubjectX500Principal(); + authUser = subjectDN.toString().toLowerCase(); + } + } + + return Optional.ofNullable(authUser); + } + + private String getHaProxyUser(HttpServletRequest hsr) { + String haProxyUser; + if (Objects.isNull(hsr.getHeader("X-AAI-SSL-Client-CN")) + || Objects.isNull(hsr.getHeader("X-AAI-SSL-Client-OU")) + || Objects.isNull(hsr.getHeader("X-AAI-SSL-Client-O")) + || Objects.isNull(hsr.getHeader("X-AAI-SSL-Client-L")) + || Objects.isNull(hsr.getHeader("X-AAI-SSL-Client-ST")) + || Objects.isNull(hsr.getHeader("X-AAI-SSL-Client-C"))) { + haProxyUser = ""; + } else { + haProxyUser = String.format("CN=%s, OU=%s, O=\"%s\", L=%s, ST=%s, C=%s", + Objects.toString(hsr.getHeader("X-AAI-SSL-Client-CN"), ""), + Objects.toString(hsr.getHeader("X-AAI-SSL-Client-OU"), ""), + Objects.toString(hsr.getHeader("X-AAI-SSL-Client-O"), ""), + Objects.toString(hsr.getHeader("X-AAI-SSL-Client-L"), ""), + Objects.toString(hsr.getHeader("X-AAI-SSL-Client-ST"), ""), + Objects.toString(hsr.getHeader("X-AAI-SSL-Client-C"), "")).toLowerCase(); + } + return haProxyUser; + } + + private Optional<Response> authorize(String uri, String httpMethod, List<MediaType> acceptHeaderValues, + String authUser, String haProxyUser, String issuer) { + Response response = null; + try { + if (!aaiAuthCore.authorize(authUser, uri, httpMethod, haProxyUser, issuer)) { + throw new AAIException("AAI_9101", "Request on " + httpMethod + " " + uri + " status is not OK"); + } + } catch (AAIException e) { + response = Response.status(e.getErrorObject().getHTTPResponseCode()) + .entity(ErrorLogHelper.getRESTAPIErrorResponseWithLogging(acceptHeaderValues, e, new ArrayList<>())) + .build(); + } + return Optional.ofNullable(response); + } + +} diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/VersionInterceptor.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/VersionInterceptor.java new file mode 100644 index 0000000..f3c5768 --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/VersionInterceptor.java @@ -0,0 +1,102 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.interceptors.pre; + +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.interceptors.AAIContainerFilter; +import org.onap.aai.logging.ErrorLogHelper; +import org.onap.aai.setup.SchemaVersion; +import org.onap.aai.setup.SchemaVersions; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.annotation.Priority; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.PreMatching; +import javax.ws.rs.core.Response; +import java.net.URI; +import java.util.ArrayList; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +@PreMatching +@Priority(AAIRequestFilterPriority.VERSION) +public class VersionInterceptor extends AAIContainerFilter implements ContainerRequestFilter { + + public static final Pattern EXTRACT_VERSION_PATTERN = Pattern.compile("^(v[1-9][0-9]*).*$"); + + private final Set<String> allowedVersions; + + private final SchemaVersions schemaVersions; + + @Autowired + public VersionInterceptor(SchemaVersions schemaVersions){ + this.schemaVersions = schemaVersions; + allowedVersions = schemaVersions.getVersions() + .stream() + .map(SchemaVersion::toString) + .collect(Collectors.toSet()); + + } + + @Override + public void filter(ContainerRequestContext requestContext) { + + String uri = requestContext.getUriInfo().getPath(); + + if (uri.startsWith("search") || uri.startsWith("util/echo") || uri.startsWith("tools")) { + return; + } + + Matcher matcher = EXTRACT_VERSION_PATTERN.matcher(uri); + + String version = null; + if(matcher.matches()){ + version = matcher.group(1); + } else { + requestContext.abortWith(createInvalidVersionResponse("AAI_3017", requestContext, version)); + return; + } + + if(!allowedVersions.contains(version)){ + requestContext.abortWith(createInvalidVersionResponse("AAI_3016", requestContext, version)); + } + } + + private Response createInvalidVersionResponse(String errorCode, ContainerRequestContext context, String version) { + AAIException e = new AAIException(errorCode); + ArrayList<String> templateVars = new ArrayList<>(); + + if (templateVars.isEmpty()) { + templateVars.add(context.getMethod()); + templateVars.add(context.getUriInfo().getPath()); + templateVars.add(version); + } + + String entity = ErrorLogHelper.getRESTAPIErrorResponse(context.getAcceptableMediaTypes(), e, templateVars); + + return Response + .status(e.getErrorObject().getHTTPResponseCode()) + .entity(entity) + .build(); + } +} diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/VersionLatestInterceptor.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/VersionLatestInterceptor.java new file mode 100644 index 0000000..61008b6 --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/VersionLatestInterceptor.java @@ -0,0 +1,56 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.interceptors.pre; + +import org.onap.aai.interceptors.AAIContainerFilter; +import org.onap.aai.setup.SchemaVersions; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.annotation.Priority; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.PreMatching; +import java.net.URI; + +@PreMatching +@Priority(AAIRequestFilterPriority.LATEST) +public class VersionLatestInterceptor extends AAIContainerFilter implements ContainerRequestFilter { + + private final SchemaVersions schemaVersions; + + @Autowired + public VersionLatestInterceptor(SchemaVersions schemaVersions){ + this.schemaVersions = schemaVersions; + } + + @Override + public void filter(ContainerRequestContext requestContext) { + + String uri = requestContext.getUriInfo().getPath(); + + if(uri.startsWith("latest")){ + String absolutePath = requestContext.getUriInfo().getAbsolutePath().toString(); + String latest = absolutePath.replaceFirst("latest", schemaVersions.getDefaultVersion().toString()); + requestContext.setRequestUri(URI.create(latest)); + return; + } + + } +} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/EdgeMigrator.java b/aai-resources/src/main/java/org/onap/aai/migration/EdgeMigrator.java deleted file mode 100644 index 5149912..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/EdgeMigrator.java +++ /dev/null @@ -1,144 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration; - -import java.util.Map; -import java.util.List; -import java.util.ArrayList; -import org.javatuples.Pair; - -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.onap.aai.db.props.AAIProperties; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; -import org.onap.aai.serialization.db.EdgeRule; -import org.onap.aai.serialization.db.EdgeRules; - -/** - * A migration template for migrating all edge properties between "from" and "to" node from the DbedgeRules.json - * - */ -@MigrationPriority(0) -@MigrationDangerRating(1) -public abstract class EdgeMigrator extends Migrator { - - private boolean success = true; - private EdgeRules rules; - - public EdgeMigrator(TransactionalGraphEngine engine) { - super(engine); - rules = EdgeRules.getInstance(); - } - - public EdgeMigrator(TransactionalGraphEngine engine, List<Pair<String, String>> nodePairList) { - super(engine); - rules = EdgeRules.getInstance(); - } - - - /** - * Do not override this method as an inheritor of this class - */ - @Override - public void run() { - - executeModifyOperation(); - - } - - /** - * This is where inheritors should add their logic - */ - protected void executeModifyOperation() { - - changeEdgeProperties(); - - } - - protected void changeEdgeLabels() { - //TODO: when json file has edge label as well as edge property changes - } - - - - protected void changeEdgeProperties() { - try { - List<Pair<String, String>> nodePairList = this.getAffectedNodePairTypes(); - for (Pair<String, String> nodePair : nodePairList) { - - String NODE_A = nodePair.getValue0(); - String NODE_B = nodePair.getValue1(); - Map<String, EdgeRule> result = rules.getEdgeRules(NODE_A, NODE_B); - - GraphTraversal<Vertex, Vertex> g = this.engine.asAdmin().getTraversalSource().V(); - /* - * Find Out-Edges from Node A to Node B and change them - * Also Find Out-Edges from Node B to Node A and change them - */ - g.union(__.has(AAIProperties.NODE_TYPE, NODE_A).outE().where(__.inV().has(AAIProperties.NODE_TYPE, NODE_B)), - __.has(AAIProperties.NODE_TYPE, NODE_B).outE().where(__.inV().has(AAIProperties.NODE_TYPE, NODE_A))) - .sideEffect(t -> { - Edge e = t.get(); - try { - Vertex out = e.outVertex(); - Vertex in = e.inVertex(); - if (out == null || in == null) { - logger.error( - e.id() + " invalid because one vertex was null: out=" + out + " in=" + in); - } else { - if (result.containsKey(e.label())) { - EdgeRule rule = result.get(e.label()); - e.properties().forEachRemaining(prop -> prop.remove()); - rules.addProperties(e, rule); - } else { - logger.info("found vertices connected by unkwown label: out=" + out + " label=" - + e.label() + " in=" + in); - } - } - } catch (Exception e1) { - throw new RuntimeException(e1); - } - }).iterate(); - } - - } catch (Exception e) { - logger.error("error encountered", e); - success = false; - } - } - - @Override - public Status getStatus() { - if (success) { - return Status.SUCCESS; - } else { - return Status.FAILURE; - } - } - - /** - * List of node pairs("from" and "to"), you would like EdgeMigrator to migrate from json files - * @return - */ - public abstract List<Pair<String, String>> getAffectedNodePairTypes() ; - -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/EdgeSwingMigrator.java b/aai-resources/src/main/java/org/onap/aai/migration/EdgeSwingMigrator.java deleted file mode 100644 index 3ce5669..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/EdgeSwingMigrator.java +++ /dev/null @@ -1,285 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration; - - -import org.apache.tinkerpop.gremlin.structure.Direction; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Property; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.javatuples.Pair; -import org.onap.aai.db.props.AAIProperties; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** - * A migration template for "swinging" edges that terminate on an old-node to a new target node. - * That is, given an oldNode and a newNode we will swing edges that terminate on the - * oldNode and terminate them on the newNode (actually we drop the old edges and add new ones). - * - * - * We allow the passing of some parameters to restrict what edges get swung over: - * > otherEndNodeTypeRestriction: only swing edges that terminate on the oldNode if the - * node at the other end of the edge is of this nodeType. - * > edgeLabelRestriction: Only swing edges that have this edgeLabel - * > edgeDirectionRestriction: Only swing edges that go this direction (from the oldNode) - * this is a required parameter. valid values are: BOTH, IN, OUT - * - */ -@MigrationPriority(0) -@MigrationDangerRating(1) -public abstract class EdgeSwingMigrator extends Migrator { - - private boolean success = true; - private String nodeTypeRestriction = null; - private String edgeLabelRestriction = null; - private String edgeDirRestriction = null; - private List<Pair<Vertex, Vertex>> nodePairList; - - - public EdgeSwingMigrator(TransactionalGraphEngine engine ) { - super(engine); - } - - - /** - * Do not override this method as an inheritor of this class - */ - @Override - public void run() { - executeModifyOperation(); - cleanupAsAppropriate(this.nodePairList); - } - - /** - * This is where inheritors should add their logic - */ - protected void executeModifyOperation() { - - try { - this.nodeTypeRestriction = this.getNodeTypeRestriction(); - this.edgeLabelRestriction = this.getEdgeLabelRestriction(); - this.edgeDirRestriction = this.getEdgeDirRestriction(); - nodePairList = this.getAffectedNodePairs(); - for (Pair<Vertex, Vertex> nodePair : nodePairList) { - Vertex fromNode = nodePair.getValue0(); - Vertex toNode = nodePair.getValue1(); - this.swingEdges(fromNode, toNode, - this.nodeTypeRestriction,this.edgeLabelRestriction,this.edgeDirRestriction); - } - } catch (Exception e) { - logger.error("error encountered", e); - success = false; - } - } - - - protected void swingEdges(Vertex oldNode, Vertex newNode, String nodeTypeRestr, String edgeLabelRestr, String edgeDirRestr) { - try { - // If the old and new Vertices aren't populated, throw an exception - if( oldNode == null ){ - logger.info ( "null oldNode passed to swingEdges() "); - success = false; - return; - } - else if( newNode == null ){ - logger.info ( "null newNode passed to swingEdges() "); - success = false; - return; - } - else if( edgeDirRestr == null || - (!edgeDirRestr.equals("BOTH") - && !edgeDirRestr.equals("IN") - && !edgeDirRestr.equals("OUT") ) - ){ - logger.info ( "invalid direction passed to swingEdges(). valid values are BOTH/IN/OUT "); - success = false; - return; - } - else if( edgeLabelRestr != null - && (edgeLabelRestr.trim().equals("none") || edgeLabelRestr.trim().equals("")) ){ - edgeLabelRestr = null; - } - else if( nodeTypeRestr == null || nodeTypeRestr.trim().equals("") ){ - nodeTypeRestr = "none"; - } - - String oldNodeType = oldNode.value(AAIProperties.NODE_TYPE); - String oldUri = oldNode.<String> property("aai-uri").isPresent() ? oldNode.<String> property("aai-uri").value() : "URI Not present"; - - String newNodeType = newNode.value(AAIProperties.NODE_TYPE); - String newUri = newNode.<String> property("aai-uri").isPresent() ? newNode.<String> property("aai-uri").value() : "URI Not present"; - - // If the nodeTypes don't match, throw an error - if( !oldNodeType.equals(newNodeType) ){ - logger.info ( "Can not swing edge from a [" + oldNodeType + "] node to a [" + - newNodeType + "] node. "); - success = false; - return; - } - - // Find and migrate any applicable OUT edges. - if( edgeDirRestr.equals("BOTH") || edgeDirRestr.equals("OUT") ){ - Iterator <Edge> edgeOutIter = null; - if( edgeLabelRestr == null ) { - edgeOutIter = oldNode.edges(Direction.OUT); - } - else { - edgeOutIter = oldNode.edges(Direction.OUT, edgeLabelRestr); - } - - while( edgeOutIter.hasNext() ){ - Edge oldOutE = edgeOutIter.next(); - String eLabel = oldOutE.label(); - Vertex otherSideNode4ThisEdge = oldOutE.inVertex(); - String otherSideNodeType = otherSideNode4ThisEdge.value(AAIProperties.NODE_TYPE); - if( nodeTypeRestr.equals("none") || nodeTypeRestr.toLowerCase().equals(otherSideNodeType) ){ - Iterator <Property<Object>> propsIter = oldOutE.properties(); - HashMap<String, String> propMap = new HashMap<String,String>(); - while( propsIter.hasNext() ){ - Property<Object> ep = propsIter.next(); - propMap.put(ep.key(), ep.value().toString()); - } - - String otherSideUri = otherSideNode4ThisEdge.<String> property("aai-uri").isPresent() ? otherSideNode4ThisEdge.<String> property("aai-uri").value() : "URI Not present"; - logger.info ( "\nSwinging [" + eLabel + "] OUT edge. \n >> Unchanged side is [" - + otherSideNodeType + "][" + otherSideUri + "] \n >> Edge used to go to [" + oldNodeType - + "][" + oldUri + "],\n >> now swung to [" + newNodeType + "][" + newUri + "]. "); - // remove the old edge - oldOutE.remove(); - - // add the new edge with properties that match the edge that was deleted. We don't want to - // change any edge properties - just swinging one end of the edge to a new node. - // NOTE - addEdge adds an OUT edge to the vertex passed as a parameter, so we are - // adding from the newNode side. - Edge newOutE = newNode.addEdge(eLabel, otherSideNode4ThisEdge); - - Iterator it = propMap.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry pair = (Map.Entry)it.next(); - newOutE.property(pair.getKey().toString(), pair.getValue().toString() ); - } - - } - } - } - - // Find and migrate any applicable IN edges. - if( edgeDirRestr.equals("BOTH") || edgeDirRestr.equals("IN") ){ - Iterator <Edge> edgeInIter = null; - if( edgeLabelRestr == null ) { - edgeInIter = oldNode.edges(Direction.IN); - } - else { - edgeInIter = oldNode.edges(Direction.IN, edgeLabelRestr); - } - - while( edgeInIter.hasNext() ){ - Edge oldInE = edgeInIter.next(); - String eLabel = oldInE.label(); - Vertex otherSideNode4ThisEdge = oldInE.outVertex(); - String otherSideNodeType = otherSideNode4ThisEdge.value(AAIProperties.NODE_TYPE); - if( nodeTypeRestr.equals("none") || nodeTypeRestr.toLowerCase().equals(otherSideNodeType) ){ - Iterator <Property<Object>> propsIter = oldInE.properties(); - HashMap<String, String> propMap = new HashMap<String,String>(); - while( propsIter.hasNext() ){ - Property<Object> ep = propsIter.next(); - propMap.put(ep.key(), ep.value().toString()); - } - - String otherSideUri = otherSideNode4ThisEdge.<String> property("aai-uri").isPresent() ? otherSideNode4ThisEdge.<String> property("aai-uri").value() : "URI Not present"; - logger.info ( "\nSwinging [" + eLabel + "] IN edge. \n >> Unchanged side is [" - + otherSideNodeType + "][" + otherSideUri + "] \n >> Edge used to go to [" + oldNodeType - + "][" + oldUri + "],\n >> now swung to [" + newNodeType + "][" + newUri + "]. "); - - // remove the old edge - oldInE.remove(); - - // add the new edge with properties that match the edge that was deleted. We don't want to - // change any edge properties - just swinging one end of the edge to a new node. - // NOTE - addEdge adds an OUT edge to the vertex passed as a parameter, so we are - // adding from the node on the other-end of the original edge so we'll get - // an IN-edge to the newNode. - Edge newInE = otherSideNode4ThisEdge.addEdge(eLabel, newNode); - - Iterator it = propMap.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry pair = (Map.Entry)it.next(); - newInE.property(pair.getKey().toString(), pair.getValue().toString() ); - } - } - } - } - - } catch (Exception e) { - logger.error("error encountered", e); - success = false; - } - } - - @Override - public Status getStatus() { - if (success) { - return Status.SUCCESS; - } else { - return Status.FAILURE; - } - } - - - /** - * Get the List of node pairs("from" and "to"), you would like EdgeSwingMigrator to migrate from json files - * @return - */ - public abstract List<Pair<Vertex, Vertex>> getAffectedNodePairs() ; - - - /** - * Get the nodeTypeRestriction that you want EdgeSwingMigrator to use - * @return - */ - public abstract String getNodeTypeRestriction() ; - - - /** - * Get the nodeTypeRestriction that you want EdgeSwingMigrator to use - * @return - */ - public abstract String getEdgeLabelRestriction() ; - - /** - * Get the nodeTypeRestriction that you want EdgeSwingMigrator to use - * @return - */ - public abstract String getEdgeDirRestriction() ; - - - - /** - * Cleanup (remove) the nodes that edges were moved off of if appropriate - * @return - */ - public abstract void cleanupAsAppropriate(List<Pair<Vertex, Vertex>> nodePairL); - -}
\ No newline at end of file diff --git a/aai-resources/src/main/java/org/onap/aai/migration/EventAction.java b/aai-resources/src/main/java/org/onap/aai/migration/EventAction.java deleted file mode 100644 index 830685b..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/EventAction.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration; - -/** - * Used to describe the type of DMaaP event you would like to create - */ -public enum EventAction { - CREATE, - UPDATE, - DELETE -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/MigrationController.java b/aai-resources/src/main/java/org/onap/aai/migration/MigrationController.java deleted file mode 100644 index f5854f8..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/MigrationController.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration; - -import java.util.UUID; - -import org.onap.aai.dbmap.AAIGraph; -import org.onap.aai.logging.LoggingContext; -import org.onap.aai.logging.LoggingContext.StatusCode; -import org.onap.aai.util.AAIConstants; - -/** - * Wrapper class to allow {@link org.onap.aai.migration.MigrationControllerInternal MigrationControllerInternal} - * to be run from a shell script - */ -public class MigrationController { - - /** - * The main method. - * - * @param args - * the arguments - */ - public static void main(String[] args) { - LoggingContext.init(); - LoggingContext.partnerName("Migration"); - LoggingContext.serviceName(AAIConstants.AAI_RESOURCES_MS); - LoggingContext.component("MigrationController"); - LoggingContext.targetEntity(AAIConstants.AAI_RESOURCES_MS); - LoggingContext.targetServiceName("main"); - LoggingContext.requestId(UUID.randomUUID().toString()); - LoggingContext.statusCode(StatusCode.COMPLETE); - LoggingContext.responseCode(LoggingContext.SUCCESS); - MigrationControllerInternal internal = new MigrationControllerInternal(); - - try { - internal.run(args); - } catch (Exception e) { - e.printStackTrace(); - } - AAIGraph.getInstance().graphShutdown(); - System.exit(0); - } -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/MigrationControllerInternal.java b/aai-resources/src/main/java/org/onap/aai/migration/MigrationControllerInternal.java deleted file mode 100644 index 62007c4..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/MigrationControllerInternal.java +++ /dev/null @@ -1,477 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Properties; -import java.util.Set; -import java.util.stream.Collectors; - -import org.apache.activemq.broker.BrokerService; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.PropertiesConfiguration; -import org.apache.commons.lang.exception.ExceptionUtils; -import org.apache.tinkerpop.gremlin.structure.Graph; -import org.apache.tinkerpop.gremlin.structure.io.IoCore; -import org.onap.aai.db.props.AAIProperties; -import org.onap.aai.dbmap.AAIGraph; -import org.onap.aai.dbmap.DBConnectionType; -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.Loader; -import org.onap.aai.introspection.LoaderFactory; -import org.onap.aai.introspection.ModelType; -import org.onap.aai.introspection.Version; -import org.onap.aai.logging.LoggingContext; -import org.onap.aai.logging.LoggingContext.StatusCode; -import org.onap.aai.serialization.engines.QueryStyle; -import org.onap.aai.serialization.engines.JanusGraphDBEngine; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; -import org.onap.aai.util.AAIConstants; -import org.onap.aai.util.FormatDate; -import org.reflections.Reflections; -import org.slf4j.MDC; - -import com.att.eelf.configuration.Configuration; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; -import com.beust.jcommander.JCommander; -import com.beust.jcommander.Parameter; - -/** - * Runs a series of migrations from a defined directory based on the presence of - * the {@link org.onap.aai.migration.Enabled Enabled} annotation - * - * It will also write a record of the migrations run to the database. - */ -public class MigrationControllerInternal { - - private EELFLogger logger; - private final int DANGER_ZONE = 10; - private static final String VERTEX_TYPE = "migration-list-" + Version.getLatest().toString(); - private final List<String> resultsSummary = new ArrayList<>(); - private BrokerService broker; - private final List<NotificationHelper> notifications = new ArrayList<>(); - private static final String SNAPSHOT_LOCATION = AAIConstants.AAI_HOME + AAIConstants.AAI_FILESEP + "logs" + AAIConstants.AAI_FILESEP + "data" + AAIConstants.AAI_FILESEP + "migrationSnapshots"; - /** - * The main method. - * - * @param args - * the arguments - */ - public void run(String[] args) { - // Set the logging file properties to be used by EELFManager - System.setProperty("aai.service.name", MigrationController.class.getSimpleName()); - Properties props = System.getProperties(); - props.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, "migration-logback.xml"); - props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES); - - logger = EELFManager.getInstance().getLogger(MigrationControllerInternal.class.getSimpleName()); - MDC.put("logFilenameAppender", MigrationController.class.getSimpleName()); - - boolean loadSnapshot = false; - - CommandLineArgs cArgs = new CommandLineArgs(); - - JCommander jCommander = new JCommander(cArgs, args); - jCommander.setProgramName(MigrationController.class.getSimpleName()); - - // Set flag to load from snapshot based on the presence of snapshot and - // graph storage backend of inmemory - if (cArgs.dataSnapshot != null && !cArgs.dataSnapshot.isEmpty()) { - try { - PropertiesConfiguration config = new PropertiesConfiguration(cArgs.config); - if (config.getString("storage.backend").equals("inmemory")) { - loadSnapshot = true; - System.setProperty("load.snapshot.file", "true"); - System.setProperty("snapshot.location", cArgs.dataSnapshot); - } - } catch (ConfigurationException e) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logAndPrint("ERROR: Could not load janusgraph configuration.\n" + ExceptionUtils.getFullStackTrace(e)); - return; - } - } - System.setProperty("realtime.db.config", cArgs.config); - logAndPrint("\n\n---------- Connecting to Graph ----------"); - AAIGraph.getInstance(); - - logAndPrint("---------- Connection Established ----------"); - Version version = AAIProperties.LATEST; - QueryStyle queryStyle = QueryStyle.TRAVERSAL; - ModelType introspectorFactoryType = ModelType.MOXY; - Loader loader = LoaderFactory.createLoaderForVersion(introspectorFactoryType, version); - TransactionalGraphEngine engine = new JanusGraphDBEngine(queryStyle, DBConnectionType.REALTIME, loader); - - if (cArgs.help) { - jCommander.usage(); - engine.rollback(); - return; - } - - Reflections reflections = new Reflections("org.onap.aai.migration"); - List<Class<? extends Migrator>> migratorClasses = new ArrayList<>(findClasses(reflections)); - //Displays list of migration classes which needs to be executed.Pass flag "-l" following by the class names - if (cArgs.list) { - listMigrationWithStatus(cArgs, migratorClasses, engine); - return; - } - - logAndPrint("---------- Looking for migration scripts to be executed. ----------"); - //Excluding any migration class when run migration from script.Pass flag "-e" following by the class names - if (!cArgs.excludeClasses.isEmpty()) { - migratorClasses = filterMigrationClasses(cArgs.excludeClasses, migratorClasses); - listMigrationWithStatus(cArgs, migratorClasses, engine); - } - List<Class<? extends Migrator>> migratorClassesToRun = createMigratorList(cArgs, migratorClasses); - - sortList(migratorClassesToRun); - - if (!cArgs.scripts.isEmpty() && migratorClassesToRun.isEmpty()) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR); - logAndPrint("\tERROR: Failed to find migrations " + cArgs.scripts + "."); - logAndPrint("---------- Done ----------"); - LoggingContext.successStatusFields(); - } - - logAndPrint("\tFound " + migratorClassesToRun.size() + " migration scripts."); - logAndPrint("---------- Executing Migration Scripts ----------"); - - - if (!cArgs.skipPreMigrationSnapShot) { - takePreSnapshotIfRequired(engine, cArgs, migratorClassesToRun); - } - - for (Class<? extends Migrator> migratorClass : migratorClassesToRun) { - String name = migratorClass.getSimpleName(); - Migrator migrator; - if (migratorClass.isAnnotationPresent(Enabled.class)) { - - try { - engine.startTransaction(); - if (!cArgs.forced && hasAlreadyRun(name, engine)) { - logAndPrint("Migration " + name + " has already been run on this database and will not be executed again. Use -f to force execution"); - continue; - } - migrator = migratorClass.getConstructor(TransactionalGraphEngine.class).newInstance(engine); - } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logAndPrint("EXCEPTION caught initalizing migration class " + migratorClass.getSimpleName() + ".\n" + ExceptionUtils.getFullStackTrace(e)); - LoggingContext.successStatusFields(); - engine.rollback(); - continue; - } - logAndPrint("\tRunning " + migratorClass.getSimpleName() + " migration script."); - logAndPrint("\t\t See " + System.getProperty("AJSC_HOME") + "/logs/migration/" + migratorClass.getSimpleName() + "/* for logs."); - MDC.put("logFilenameAppender", migratorClass.getSimpleName() + "/" + migratorClass.getSimpleName()); - - migrator.run(); - - commitChanges(engine, migrator, cArgs); - } else { - logAndPrint("\tSkipping " + migratorClass.getSimpleName() + " migration script because it has been disabled."); - } - } - MDC.put("logFilenameAppender", MigrationController.class.getSimpleName()); - for (NotificationHelper notificationHelper : notifications) { - try { - notificationHelper.triggerEvents(); - } catch (AAIException e) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.AVAILABILITY_TIMEOUT_ERROR); - logAndPrint("\tcould not event"); - logger.error("could not event", e); - LoggingContext.successStatusFields(); - } - } - logAndPrint("---------- Done ----------"); - - // Save post migration snapshot if snapshot was loaded - if (!cArgs.skipPostMigrationSnapShot) { - generateSnapshot(engine, "post"); - } - - outputResultsSummary(); - } - - /** - * This method is used to remove excluded classes from migration from the - * script command. - * - * @param excludeClasses - * : Classes to be removed from Migration - * @param migratorClasses - * : Classes to execute migration. - * @return - */ - private List<Class<? extends Migrator>> filterMigrationClasses( - List<String> excludeClasses, - List<Class<? extends Migrator>> migratorClasses) { - - List<Class<? extends Migrator>> filteredMigratorClasses = migratorClasses - .stream() - .filter(migratorClass -> !excludeClasses.contains(migratorClass - .getSimpleName())).collect(Collectors.toList()); - - return filteredMigratorClasses; - } - - private void listMigrationWithStatus(CommandLineArgs cArgs, - List<Class<? extends Migrator>> migratorClasses, TransactionalGraphEngine engine) { - sortList(migratorClasses); - engine.startTransaction(); - System.out.println("---------- List of all migrations ----------"); - migratorClasses.forEach(migratorClass -> { - boolean enabledAnnotation = migratorClass.isAnnotationPresent(Enabled.class); - String enabled = enabledAnnotation ? "Enabled" : "Disabled"; - StringBuilder sb = new StringBuilder(); - sb.append(migratorClass.getSimpleName()); - sb.append(" in package "); - sb.append(migratorClass.getPackage().getName().substring(migratorClass.getPackage().getName().lastIndexOf('.')+1)); - sb.append(" is "); - sb.append(enabled); - sb.append(" "); - sb.append("[" + getDbStatus(migratorClass.getSimpleName(), engine) + "]"); - System.out.println(sb.toString()); - }); - engine.rollback(); - System.out.println("---------- Done ----------"); - } - - private String getDbStatus(String name, TransactionalGraphEngine engine) { - if (hasAlreadyRun(name, engine)) { - return "Already executed in this env"; - } - return "Will be run on next execution if Enabled"; - } - - private boolean hasAlreadyRun(String name, TransactionalGraphEngine engine) { - return engine.asAdmin().getReadOnlyTraversalSource().V().has(AAIProperties.NODE_TYPE, VERTEX_TYPE).has(name, true).hasNext(); - } - private Set<Class<? extends Migrator>> findClasses(Reflections reflections) { - Set<Class<? extends Migrator>> migratorClasses = reflections.getSubTypesOf(Migrator.class); - /* - * TODO- Change this to make sure only classes in the specific $release are added in the runList - * Or add a annotation like exclude which folks again need to remember to add ?? - */ - - migratorClasses.remove(PropertyMigrator.class); - migratorClasses.remove(EdgeMigrator.class); - return migratorClasses; - } - - - private void takePreSnapshotIfRequired(TransactionalGraphEngine engine, CommandLineArgs cArgs, List<Class<? extends Migrator>> migratorClassesToRun) { - - /*int sum = 0; - for (Class<? extends Migrator> migratorClass : migratorClassesToRun) { - if (migratorClass.isAnnotationPresent(Enabled.class)) { - sum += migratorClass.getAnnotation(MigrationPriority.class).value(); - } - } - - if (sum >= DANGER_ZONE) { - - logAndPrint("Entered Danger Zone. Taking snapshot."); - }*/ - - //always take snapshot for now - - generateSnapshot(engine, "pre"); - - } - - - private List<Class<? extends Migrator>> createMigratorList(CommandLineArgs cArgs, - List<Class<? extends Migrator>> migratorClasses) { - List<Class<? extends Migrator>> migratorClassesToRun = new ArrayList<>(); - - for (Class<? extends Migrator> migratorClass : migratorClasses) { - if (!cArgs.scripts.isEmpty() && !cArgs.scripts.contains(migratorClass.getSimpleName())) { - continue; - } else { - migratorClassesToRun.add(migratorClass); - } - } - return migratorClassesToRun; - } - - - private void sortList(List<Class<? extends Migrator>> migratorClasses) { - Collections.sort(migratorClasses, (m1, m2) -> { - try { - if (m1.getAnnotation(MigrationPriority.class).value() > m2.getAnnotation(MigrationPriority.class).value()) { - return 1; - } else if (m1.getAnnotation(MigrationPriority.class).value() < m2.getAnnotation(MigrationPriority.class).value()) { - return -1; - } else { - return m1.getSimpleName().compareTo(m2.getSimpleName()); - } - } catch (Exception e) { - return 0; - } - }); - } - - - private void generateSnapshot(TransactionalGraphEngine engine, String phase) { - - FormatDate fd = new FormatDate("yyyyMMddHHmm", "GMT"); - String dateStr= fd.getDateTime(); - String fileName = SNAPSHOT_LOCATION + File.separator + phase + "Migration." + dateStr + ".graphson"; - logAndPrint("Saving snapshot of inmemory graph " + phase + " migration to " + fileName); - Graph transaction = null; - try { - - Path pathToFile = Paths.get(fileName); - if (!pathToFile.toFile().exists()) { - Files.createDirectories(pathToFile.getParent()); - } - transaction = engine.startTransaction(); - transaction.io(IoCore.graphson()).writeGraph(fileName); - engine.rollback(); - } catch (IOException e) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.AVAILABILITY_TIMEOUT_ERROR); - logAndPrint("ERROR: Could not write in memory graph to " + phase + "Migration file. \n" + ExceptionUtils.getFullStackTrace(e)); - LoggingContext.successStatusFields(); - engine.rollback(); - } - - logAndPrint( phase + " migration snapshot saved to " + fileName); - } - /** - * Log and print. - * - * @param msg - * the msg - */ - protected void logAndPrint(String msg) { - System.out.println(msg); - logger.info(msg); - } - - /** - * Commit changes. - * - * @param engine - * the graph transaction - * @param migrator - * the migrator - * @param cArgs - */ - protected void commitChanges(TransactionalGraphEngine engine, Migrator migrator, CommandLineArgs cArgs) { - - String simpleName = migrator.getClass().getSimpleName(); - String message; - if (migrator.getStatus().equals(Status.FAILURE)) { - message = "Migration " + simpleName + " Failed. Rolling back."; - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logAndPrint("\t" + message); - LoggingContext.successStatusFields(); - migrator.rollback(); - } else if (migrator.getStatus().equals(Status.CHECK_LOGS)) { - message = "Migration " + simpleName + " encountered an anomaly, check logs. Rolling back."; - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseCode(LoggingContext.DATA_ERROR); - logAndPrint("\t" + message); - LoggingContext.successStatusFields(); - migrator.rollback(); - } else { - MDC.put("logFilenameAppender", simpleName + "/" + simpleName); - - if (cArgs.commit) { - if (!engine.asAdmin().getTraversalSource().V().has(AAIProperties.NODE_TYPE, VERTEX_TYPE).hasNext()) { - engine.asAdmin().getTraversalSource().addV(AAIProperties.NODE_TYPE, VERTEX_TYPE).iterate(); - } - engine.asAdmin().getTraversalSource().V().has(AAIProperties.NODE_TYPE, VERTEX_TYPE) - .property(simpleName, true).iterate(); - MDC.put("logFilenameAppender", MigrationController.class.getSimpleName()); - notifications.add(migrator.getNotificationHelper()); - migrator.commit(); - message = "Migration " + simpleName + " Succeeded. Changes Committed."; - logAndPrint("\t"+ message +"\t"); - } else { - message = "--commit not specified. Not committing changes for " + simpleName + " to database."; - logAndPrint("\t" + message); - migrator.rollback(); - } - - } - - resultsSummary.add(message); - - } - - private void outputResultsSummary() { - logAndPrint("---------------------------------"); - logAndPrint("-------------Summary-------------"); - for (String result : resultsSummary) { - logAndPrint(result); - } - logAndPrint("---------------------------------"); - logAndPrint("---------------------------------"); - } - -} - -class CommandLineArgs { - - @Parameter(names = "--help", help = true) - public boolean help; - - @Parameter(names = "-c", description = "location of configuration file") - public String config; - - @Parameter(names = "-m", description = "names of migration scripts") - public List<String> scripts = new ArrayList<>(); - - @Parameter(names = "-l", description = "list the status of migrations") - public boolean list = false; - - @Parameter(names = "-d", description = "location of data snapshot", hidden = true) - public String dataSnapshot; - - @Parameter(names = "-f", description = "force migrations to be rerun") - public boolean forced = false; - - @Parameter(names = "--commit", description = "commit changes to graph") - public boolean commit = false; - - @Parameter(names = "-e", description = "exclude list of migrator classes") - public List<String> excludeClasses = new ArrayList<>(); - - @Parameter(names = "--skipPreMigrationSnapShot", description = "skips taking the PRE migration snapshot") - public boolean skipPreMigrationSnapShot = false; - - @Parameter(names = "--skipPostMigrationSnapShot", description = "skips taking the POST migration snapshot") - public boolean skipPostMigrationSnapShot = false; -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/MigrationDangerRating.java b/aai-resources/src/main/java/org/onap/aai/migration/MigrationDangerRating.java deleted file mode 100644 index 1d82dc3..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/MigrationDangerRating.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -/** - * Used to enable a migration to be picked up by the {@link com.openecomp.aai.migration.MigrationControllerInternal MigrationController} - * - * The larger the number, the more danger - * - * Range is 0-10 - */ -@Target(ElementType.TYPE) -@Retention(value = RetentionPolicy.RUNTIME) -public @interface MigrationDangerRating { - - int value(); - -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/Migrator.java b/aai-resources/src/main/java/org/onap/aai/migration/Migrator.java deleted file mode 100644 index fa6a88a..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/Migrator.java +++ /dev/null @@ -1,281 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration; - -import java.util.Collections; -import java.util.Iterator; -import java.util.Optional; - -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; -import org.apache.tinkerpop.gremlin.structure.Direction; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Property; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; -import org.json.JSONException; -import org.json.JSONObject; -import org.onap.aai.db.props.AAIProperties; -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.Loader; -import org.onap.aai.introspection.LoaderFactory; -import org.onap.aai.introspection.ModelType; -import org.onap.aai.introspection.Version; -import org.onap.aai.serialization.db.DBSerializer; -import org.onap.aai.serialization.db.EdgeRules; -import org.onap.aai.serialization.db.EdgeType; -import org.onap.aai.serialization.db.exceptions.NoEdgeRuleFoundException; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; - -/** - * This class defines an A&AI Migration - */ -@MigrationPriority(0) -@MigrationDangerRating(0) -public abstract class Migrator implements Runnable { - - protected EELFLogger logger = null; - - protected DBSerializer serializer = null; - protected Loader loader = null; - - protected TransactionalGraphEngine engine; - protected NotificationHelper notificationHelper; - - /** - * Instantiates a new migrator. - * - * @param g the g - */ - public Migrator(TransactionalGraphEngine engine){ - this.engine = engine; - initDBSerializer(); - this.notificationHelper = new NotificationHelper(loader, serializer, engine, "AAI-MIGRATION", this.getMigrationName()); - logger = EELFManager.getInstance().getLogger(this.getClass().getSimpleName()); - logger.info("\tInitilization of " + this.getClass().getSimpleName() + " migration script complete."); - } - - /** - * Gets the status. - * - * @return the status - */ - public abstract Status getStatus(); - - /** - * Rollback. - */ - public void rollback() { - engine.rollback(); - } - - /** - * Commit. - */ - public void commit() { - engine.commit(); - } - - - /** - * As string. - * - * @param v the v - * @return the string - */ - protected String asString(Vertex v) { - final JSONObject result = new JSONObject(); - Iterator<VertexProperty<Object>> properties = v.properties(); - Property<Object> pk = null; - try { - while (properties.hasNext()) { - pk = properties.next(); - result.put(pk.key(), pk.value()); - } - } catch (JSONException e) { - logger.error("Warning error reading vertex: " + e); - } - - return result.toString(); - } - - /** - * As string. - * - * @param edge the edge - * @return the string - */ - protected String asString(Edge edge) { - final JSONObject result = new JSONObject(); - Iterator<Property<Object>> properties = edge.properties(); - Property<Object> pk = null; - try { - while (properties.hasNext()) { - pk = properties.next(); - result.put(pk.key(), pk.value()); - } - } catch (JSONException e) { - logger.error("Warning error reading edge: " + e); - } - - return result.toString(); - } - - /** - * - * @param v - * @param numLeadingTabs number of leading \t char's - * @return - */ - protected String toStringForPrinting(Vertex v, int numLeadingTabs) { - String prefix = String.join("", Collections.nCopies(numLeadingTabs, "\t")); - if (v == null) { - return ""; - } - final StringBuilder sb = new StringBuilder(); - sb.append(prefix + v + "\n"); - v.properties().forEachRemaining(prop -> sb.append(prefix + prop + "\n")); - return sb.toString(); - } - - /** - * - * @param e - * @param numLeadingTabs number of leading \t char's - * @return - */ - protected String toStringForPrinting(Edge e, int numLeadingTabs) { - String prefix = String.join("", Collections.nCopies(numLeadingTabs, "\t")); - if (e == null) { - return ""; - } - final StringBuilder sb = new StringBuilder(); - sb.append(prefix + e + "\n"); - sb.append(prefix + e.label() + "\n"); - e.properties().forEachRemaining(prop -> sb.append(prefix + "\t" + prop + "\n")); - return sb.toString(); - } - - /** - * Checks for edge between. - * - * @param a a - * @param b b - * @param d d - * @param edgeLabel the edge label - * @return true, if successful - */ - protected boolean hasEdgeBetween(Vertex a, Vertex b, Direction d, String edgeLabel) { - - if (d.equals(Direction.OUT)) { - return engine.asAdmin().getReadOnlyTraversalSource().V(a).out(edgeLabel).where(__.otherV().hasId(b)).hasNext(); - } else { - return engine.asAdmin().getReadOnlyTraversalSource().V(a).in(edgeLabel).where(__.otherV().hasId(b)).hasNext(); - } - - } - - /** - * Creates the edge - * - * @param type the edge type - COUSIN or TREE - * @param out the out - * @param in the in - * @return the edge - */ - protected Edge createEdge(EdgeType type, Vertex out, Vertex in) throws AAIException { - Edge newEdge = null; - try { - if (type.equals(EdgeType.COUSIN)){ - newEdge = EdgeRules.getInstance().addEdge(this.engine.asAdmin().getTraversalSource(), out, in); - } else { - newEdge = EdgeRules.getInstance().addTreeEdge(this.engine.asAdmin().getTraversalSource(), out, in); - } - } catch (NoEdgeRuleFoundException e) { - throw new AAIException("AAI_6129", e); - } - return newEdge; - } - - /** - * Creates the TREE edge - * - * @param out the out - * @param in the in - * @return the edge - */ - protected Edge createTreeEdge(Vertex out, Vertex in) throws AAIException { - Edge newEdge = createEdge(EdgeType.TREE, out, in); - return newEdge; - } - - /** - * Creates the COUSIN edge - * - * @param out the out - * @param in the in - * @return the edge - */ - protected Edge createCousinEdge(Vertex out, Vertex in) throws AAIException { - Edge newEdge = createEdge(EdgeType.COUSIN, out, in); - return newEdge; - } - - protected Edge createCousinEdgeBestEffort(Vertex out, Vertex in) throws AAIException { - return EdgeRules.getInstance().addEdgeIfPossible(this.engine.asAdmin().getTraversalSource(), out, in); - } - private void initDBSerializer() { - Version version = AAIProperties.LATEST; - ModelType introspectorFactoryType = ModelType.MOXY; - loader = LoaderFactory.createLoaderForVersion(introspectorFactoryType, version); - try { - this.serializer = new DBSerializer(version, this.engine, introspectorFactoryType, this.getMigrationName()); - } catch (AAIException e) { - throw new RuntimeException("could not create seralizer", e); - } - } - - /** - * These are the node types you would like your traversal to process - * @return - */ - public abstract Optional<String[]> getAffectedNodeTypes(); - - /** - * used as the "fromAppId" when modifying vertices - * @return - */ - public abstract String getMigrationName(); - - /** - * updates all internal vertex properties - * @param v - * @param isNewVertex - */ - protected void touchVertexProperties(Vertex v, boolean isNewVertex) { - this.serializer.touchStandardVertexProperties(v, isNewVertex); - } - - public NotificationHelper getNotificationHelper() { - return this.notificationHelper; - } -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/NotificationHelper.java b/aai-resources/src/main/java/org/onap/aai/migration/NotificationHelper.java deleted file mode 100644 index 3319a08..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/NotificationHelper.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration; - -import java.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.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.Introspector; -import org.onap.aai.introspection.Loader; -import org.onap.aai.introspection.exceptions.AAIUnknownObjectException; -import org.onap.aai.rest.ueb.UEBNotification; -import org.onap.aai.serialization.db.DBSerializer; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; -import org.onap.aai.serialization.engines.query.QueryEngine; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; - -/** - * Allows for DMaaP notifications from Migrations - */ -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/onap/aai/migration/PropertyMigrator.java b/aai-resources/src/main/java/org/onap/aai/migration/PropertyMigrator.java deleted file mode 100644 index ed43724..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/PropertyMigrator.java +++ /dev/null @@ -1,132 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration; - -import java.util.Optional; - -import org.apache.tinkerpop.gremlin.process.traversal.P; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.onap.aai.db.props.AAIProperties; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; - -import org.janusgraph.core.Cardinality; -import org.janusgraph.core.PropertyKey; -import org.janusgraph.core.schema.JanusGraphManagement; - -/** - * A migration template for migrating a property from one name to another - */ -@MigrationPriority(0) -@MigrationDangerRating(1) -public abstract class PropertyMigrator extends Migrator { - - protected final String OLD_FIELD; - protected final String NEW_FIELD; - protected final Class<?> fieldType; - protected final Cardinality cardinality; - protected final JanusGraphManagement graphMgmt; - - public PropertyMigrator(TransactionalGraphEngine engine, String oldName, String newName, Class<?> type, Cardinality cardinality) { - super(engine); - this.OLD_FIELD = oldName; - this.NEW_FIELD = newName; - this.fieldType = type; - this.cardinality = cardinality; - this.graphMgmt = engine.asAdmin().getManagementSystem(); - } - - /** - * Do not override this method as an inheritor of this class - */ - @Override - public void run() { - - modifySchema(); - executeModifyOperation(); - - } - - protected void modifySchema() { - this.addIndex(this.addProperty()); - graphMgmt.commit(); - } - - /** - * This is where inheritors should add their logic - */ - protected void executeModifyOperation() { - changePropertyName(); - } - - protected void changePropertyName() { - GraphTraversal<Vertex, Vertex> g = this.engine.asAdmin().getTraversalSource().V(); - if (this.getAffectedNodeTypes().isPresent()) { - g.has(AAIProperties.NODE_TYPE, P.within(this.getAffectedNodeTypes().get())); - } - g.has(OLD_FIELD).sideEffect(t -> { - final Vertex v = t.get(); - final String value = v.value(OLD_FIELD); - v.property(OLD_FIELD).remove(); - v.property(NEW_FIELD, value); - this.touchVertexProperties(v, false); - }).iterate(); - } - - @Override - public Status getStatus() { - GraphTraversal<Vertex, Vertex> g = this.engine.asAdmin().getTraversalSource().V(); - if (this.getAffectedNodeTypes().isPresent()) { - g.has(AAIProperties.NODE_TYPE, P.within(this.getAffectedNodeTypes().get())); - } - long result = g.has(OLD_FIELD).count().next(); - if (result == 0) { - return Status.SUCCESS; - } else { - return Status.FAILURE; - } - } - - protected Optional<PropertyKey> addProperty() { - - if (!graphMgmt.containsPropertyKey(this.NEW_FIELD)) { - logger.info(" PropertyKey [" + this.NEW_FIELD + "] created in the DB. "); - return Optional.of(graphMgmt.makePropertyKey(this.NEW_FIELD).dataType(this.fieldType).cardinality(this.cardinality) - .make()); - } else { - logger.info(" PropertyKey [" + this.NEW_FIELD + "] already existed in the DB. "); - return Optional.empty(); - } - - } - - protected void addIndex(Optional<PropertyKey> key) { - if (isIndexed() && key.isPresent()) { - if (graphMgmt.containsGraphIndex(key.get().name())) { - logger.debug(" Index [" + key.get().name() + "] already existed in the DB. "); - } else { - logger.info("Add index for PropertyKey: [" + key.get().name() + "]"); - graphMgmt.buildIndex(key.get().name(), Vertex.class).addKey(key.get()).buildCompositeIndex(); - } - } - } - public abstract boolean isIndexed(); - -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/Status.java b/aai-resources/src/main/java/org/onap/aai/migration/Status.java deleted file mode 100644 index 0338594..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/Status.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration; - -/** - * Defines the status of the completed migration - */ -public enum Status { - SUCCESS, - CHECK_LOGS, - FAILURE -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/ValueMigrator.java b/aai-resources/src/main/java/org/onap/aai/migration/ValueMigrator.java deleted file mode 100644 index eb562a2..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/ValueMigrator.java +++ /dev/null @@ -1,100 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration; - -import java.util.Map; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.onap.aai.db.props.AAIProperties; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; -import org.janusgraph.core.schema.JanusGraphManagement; - -/** - * A migration template for filling in default values that are missing or are empty - */ -@MigrationPriority(0) -@MigrationDangerRating(1) -public abstract class ValueMigrator extends Migrator { - - protected final Map<String, Map<String, ?>> propertyValuePairByNodeType; - protected final Boolean updateExistingValues; - protected final JanusGraphManagement graphMgmt; - - /** - * - * @param engine - * @param propertyValuePairByNodeType - format {nodeType: { property: newValue}} - * @param updateExistingValues - if true, updates the value regardless if it already exists - */ - public ValueMigrator(TransactionalGraphEngine engine, Map propertyValuePairByNodeType, Boolean updateExistingValues) { - super(engine); - this.propertyValuePairByNodeType = propertyValuePairByNodeType; - this.updateExistingValues = updateExistingValues; - this.graphMgmt = engine.asAdmin().getManagementSystem(); - } - - /** - * Do not override this method as an inheritor of this class - */ - @Override - public void run() { - updateValues(); - } - - protected void updateValues() { - for (Map.Entry<String, Map<String, ?>> entry: propertyValuePairByNodeType.entrySet()) { - String nodeType = entry.getKey(); - Map<String, ?> propertyValuePair = entry.getValue(); - for (Map.Entry<String, ?> pair : propertyValuePair.entrySet()) { - String property = pair.getKey(); - Object newValue = pair.getValue(); - try { - GraphTraversal<Vertex, Vertex> g = this.engine.asAdmin().getTraversalSource().V() - .has(AAIProperties.NODE_TYPE, nodeType); - while (g.hasNext()) { - Vertex v = g.next(); - if (v.property(property).isPresent() && !updateExistingValues) { - String propertyValue = v.property(property).value().toString(); - if (propertyValue.isEmpty()) { - v.property(property, newValue); - logger.info(String.format("Node Type %s: Property %s is empty, adding value %s", - nodeType, property, newValue.toString())); - this.touchVertexProperties(v, false); - } else { - logger.info(String.format("Node Type %s: Property %s value already exists - skipping", - nodeType, property)); - } - } else { - logger.info(String.format("Node Type %s: Property %s does not exist or " + - "updateExistingValues flag is set to True - adding the property with value %s", - nodeType, property, newValue.toString())); - v.property(property, newValue); - this.touchVertexProperties(v, false); - } - } - } catch (Exception e) { - logger.error(String.format("caught exception updating aai-node-type %s's property %s's value to " + - "%s: %s", nodeType, property, newValue.toString(), e.getMessage())); - logger.error(e.getMessage()); - } - } - } - } -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/VertexMerge.java b/aai-resources/src/main/java/org/onap/aai/migration/VertexMerge.java deleted file mode 100644 index 304be1e..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/VertexMerge.java +++ /dev/null @@ -1,244 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration; - -import java.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.onap.aai.db.props.AAIProperties; -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.Introspector; -import org.onap.aai.introspection.Loader; -import org.onap.aai.introspection.exceptions.AAIUnknownObjectException; -import org.onap.aai.serialization.db.DBSerializer; -import org.onap.aai.serialization.db.EdgeRules; -import org.onap.aai.serialization.db.EdgeType; -import org.onap.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/onap/aai/migration/v12/ContainmentDeleteOtherVPropertyMigration.java b/aai-resources/src/main/java/org/onap/aai/migration/v12/ContainmentDeleteOtherVPropertyMigration.java deleted file mode 100644 index cc35a3d..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/v12/ContainmentDeleteOtherVPropertyMigration.java +++ /dev/null @@ -1,104 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration.v12; - -import java.util.Optional; - -import org.apache.commons.lang.exception.ExceptionUtils; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.onap.aai.migration.MigrationDangerRating; -import org.onap.aai.migration.Enabled; -import org.onap.aai.migration.MigrationPriority; -import org.onap.aai.migration.Migrator; -import org.onap.aai.migration.Status; -import org.onap.aai.serialization.db.AAIDirection; -import org.onap.aai.serialization.db.EdgeProperty; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; - - - -@Enabled -@MigrationPriority(-100) -@MigrationDangerRating(10) -public class ContainmentDeleteOtherVPropertyMigration extends Migrator { - - private boolean success = true; - - public ContainmentDeleteOtherVPropertyMigration(TransactionalGraphEngine engine) { - super(engine); - } - - //just for testing using test edge rule files - public ContainmentDeleteOtherVPropertyMigration(TransactionalGraphEngine engine, String edgeRulesFile) { - super(engine); - } - - @Override - public void run() { - try { - engine.asAdmin().getTraversalSource().E().sideEffect(t -> { - Edge e = t.get(); - logger.info("out vertex: " + e.outVertex().property("aai-node-type").value() + - " in vertex: " + e.inVertex().property("aai-node-type").value() + - " label : " + e.label()); - if (e.property(EdgeProperty.CONTAINS.toString()).isPresent() && - e.property(EdgeProperty.DELETE_OTHER_V.toString()).isPresent()) { - //in case of orphans - if (!("constrained-element-set".equals(e.inVertex().property("aai-node-type").value()) - && "model-element".equals(e.outVertex().property("aai-node-type").value()))) { - //skip the weird horrible problem child edge - String containment = (String) e.property(EdgeProperty.CONTAINS.toString()).value(); - if (AAIDirection.OUT.toString().equalsIgnoreCase(containment) || - AAIDirection.IN.toString().equalsIgnoreCase(containment) || - AAIDirection.BOTH.toString().equalsIgnoreCase(containment)) { - logger.info("updating delete-other-v property"); - e.property(EdgeProperty.DELETE_OTHER_V.toString(), containment); - } - } - } - }).iterate(); - } catch (Exception e) { - logger.info("error encountered " + e.getClass() + " " + e.getMessage() + " " + ExceptionUtils.getFullStackTrace(e)); - logger.error("error encountered " + e.getClass() + " " + e.getMessage() + " " + ExceptionUtils.getFullStackTrace(e)); - success = false; - } - - } - - @Override - public Status getStatus() { - if (success) { - return Status.SUCCESS; - } else { - return Status.FAILURE; - } - } - - @Override - public Optional<String[]> getAffectedNodeTypes() { - return Optional.empty(); - } - - @Override - public String getMigrationName() { - return "migrate-containment-delete-other-v"; - } - -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/v12/EdgeReportForToscaMigration.java b/aai-resources/src/main/java/org/onap/aai/migration/v12/EdgeReportForToscaMigration.java deleted file mode 100644 index 2ff916c..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/v12/EdgeReportForToscaMigration.java +++ /dev/null @@ -1,141 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration.v12; - -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.onap.aai.migration.*; -import org.onap.aai.serialization.db.EdgeRules; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; - -import java.util.*; - -@Enabled -@MigrationPriority(0) -@MigrationDangerRating(0) -public class EdgeReportForToscaMigration extends Migrator { - - private boolean success = true; - EdgeRules ers = EdgeRules.getInstance(); - - public EdgeReportForToscaMigration(TransactionalGraphEngine graphEngine){ - super(graphEngine); - } - - @Override - public Status getStatus() { - if (success) { - return Status.SUCCESS; - } else { - return Status.FAILURE; - } - } - - @Override - public void run() { - Vertex out = null; - Vertex in = null; - String label = ""; - String outURI = ""; - String inURI = ""; - String parentCousinIndicator = "NONE"; - String oldEdgeString = null; - List<String> edgeMissingParentProperty = new ArrayList<>(); - StringBuilder sb = new StringBuilder(); - Set<String> noURI = new HashSet<>(); - sb.append("----------EDGES----------\n"); - - GraphTraversalSource g = engine.asAdmin().getTraversalSource(); - - try { - Set<Edge> edges = g.E().toSet(); - for (Edge edge : edges) { - out = edge.outVertex(); - in = edge.inVertex(); - label = edge.label(); - outURI = this.getVertexURI(out); - inURI = this.getVertexURI(in); - parentCousinIndicator = "NONE"; - oldEdgeString = this.toStringForPrinting(edge, 1); - - if (!outURI.startsWith("/")) { - noURI.add(outURI); - } - if (!inURI.startsWith("/")) { - noURI.add(inURI); - } - - if (out == null || in == null) { - logger.error(edge.id() + " invalid because one vertex was null: out=" + edge.outVertex() + " in=" + edge.inVertex()); - } else { - - if (edge.property("contains-other-v").isPresent()) { - parentCousinIndicator = edge.property("contains-other-v").value().toString(); - } else if (edge.property("isParent").isPresent()) { - if ((Boolean)edge.property("isParent").value()) { - parentCousinIndicator = "OUT"; - } else if (edge.property("isParent-REV").isPresent() && (Boolean)edge.property("isParent-REV").value()) { - parentCousinIndicator = "IN"; - } - } else { - edgeMissingParentProperty.add(this.toStringForPrinting(edge, 1)); - } - - sb.append(outURI + "|" + label + "|" + inURI + "|" + parentCousinIndicator + "\n"); - } - } - } catch(Exception ex){ - logger.error("exception occurred during migration, failing: out=" + out + " in=" + in + "edge=" + oldEdgeString, ex); - success = false; - } - sb.append("--------EDGES END--------\n"); - - logger.info(sb.toString()); - edgeMissingParentProperty.forEach(s -> logger.warn("Edge Missing Parent Property: " + s)); - logger.info("Edge Missing Parent Property Count: " + edgeMissingParentProperty.size()); - logger.info("Vertex Missing URI Property Count: " + noURI.size()); - - } - - private String getVertexURI(Vertex v) { - if (v.property("aai-uri").isPresent()) { - return v.property("aai-uri").value().toString(); - } else { - return v.id().toString() + "(" + v.property("aai-node-type").value().toString() + ")"; - } - } - - @Override - public Optional<String[]> getAffectedNodeTypes() { - return Optional.empty(); - } - - @Override - public String getMigrationName() { - return "edge-report-for-tosca-migration"; - } - - @Override - public void commit() { - engine.rollback(); - } - -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/v12/MigrateDataFromASDCToConfiguration.java b/aai-resources/src/main/java/org/onap/aai/migration/v12/MigrateDataFromASDCToConfiguration.java deleted file mode 100644 index 113d441..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/v12/MigrateDataFromASDCToConfiguration.java +++ /dev/null @@ -1,128 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration.v12; - -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.onap.aai.db.props.AAIProperties; -import org.onap.aai.migration.*; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; -import org.onap.aai.util.AAIConstants; - -import java.io.*; -import java.util.Optional; - -@MigrationPriority(20) -@MigrationDangerRating(2) -@Enabled -public class MigrateDataFromASDCToConfiguration extends Migrator { - private final String PARENT_NODE_TYPE = "generic-vnf"; - private boolean success = true; - private String entitlementPoolUuid = ""; - private String VNT = ""; - - - public MigrateDataFromASDCToConfiguration(TransactionalGraphEngine engine) { - super(engine); - } - - - @Override - public void run() { - String csvFile = AAIConstants.AAI_HOME_ETC + "VNT-migration-data" + AAIConstants.AAI_FILESEP + "VNT-migration-input.csv"; - logger.info("Reading Csv file: " + csvFile); - BufferedReader br = null; - String line = ""; - String cvsSplitBy = "\t"; - try { - - br = new BufferedReader(new FileReader(new File(csvFile))); - while ((line = br.readLine()) != null) { - line = line.replaceAll("\"", ""); - String[] temp = line.split(cvsSplitBy); - if ("entitlement-pool-uuid".equals(temp[0]) || "vendor-allowed-max-bandwidth (VNT)".equals(temp[1])) { - continue; - } - entitlementPoolUuid = temp[0]; - VNT = temp[1]; - GraphTraversal<Vertex, Vertex> f = this.engine.asAdmin().getTraversalSource().V().has(AAIProperties.NODE_TYPE, "entitlement").has("group-uuid", entitlementPoolUuid) - .out("org.onap.relationships.inventory.BelongsTo").has(AAIProperties.NODE_TYPE, "generic-vnf") - .has("vnf-type", "vHNF").in("org.onap.relationships.inventory.ComposedOf").has(AAIProperties.NODE_TYPE, "service-instance").out("org.onap.relationships.inventory.Uses").has(AAIProperties.NODE_TYPE, "configuration"); - - modify(f); - } - - } catch (FileNotFoundException e) { - success = false; - logger.error("Found Exception" , e); - } catch (IOException e) { - success = false; - logger.error("Found Exception" , e); - } catch (Exception a) { - success= false; - logger.error("Found Exception" , a); - } finally { - if (br != null){ - try { - br.close(); - } catch (IOException e) { - success = false; - logger.error("Found Exception" , e); - } - } - } - - } - - public void modify(GraphTraversal<Vertex, Vertex> g) { - int count = 0; - while (g.hasNext()) { - Vertex v = g.next(); - logger.info("Found node type " + v.property("aai-node-type").value().toString() + " with configuration id: " + v.property("configuration-id").value().toString()); - v.property("vendor-allowed-max-bandwidth", VNT); - logger.info("VNT val after migration: " + v.property("vendor-allowed-max-bandwidth").value().toString()); - count++; - } - - logger.info("modified " + count + " configuration nodes related to Entitlement UUID: " +entitlementPoolUuid); - - } - - @Override - public Status getStatus() { - if (success) { - return Status.SUCCESS; - } else { - return Status.FAILURE; - } - } - - @Override - public Optional<String[]> getAffectedNodeTypes() { - return Optional.of(new String[]{PARENT_NODE_TYPE}); - } - - @Override - public String getMigrationName() { - return "MigrateDataFromASDCToConfiguration"; - } - - -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/v12/MigrateServiceInstanceToConfiguration.java b/aai-resources/src/main/java/org/onap/aai/migration/v12/MigrateServiceInstanceToConfiguration.java deleted file mode 100644 index 7f2a809..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/v12/MigrateServiceInstanceToConfiguration.java +++ /dev/null @@ -1,190 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration.v12; - -import java.io.UnsupportedEncodingException; -import java.util.Iterator; -import java.util.Optional; -import java.util.UUID; - -import org.apache.tinkerpop.gremlin.process.traversal.P; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.structure.Direction; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.onap.aai.db.props.AAIProperties; -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.Introspector; -import org.onap.aai.introspection.exceptions.AAIUnknownObjectException; -import org.onap.aai.migration.Enabled; -import org.onap.aai.migration.MigrationDangerRating; -import org.onap.aai.migration.MigrationPriority; -import org.onap.aai.migration.Migrator; -import org.onap.aai.migration.Status; -import org.onap.aai.serialization.db.EdgeType; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; - -@Enabled -@MigrationPriority(10) -@MigrationDangerRating(10) -public class MigrateServiceInstanceToConfiguration extends Migrator { - - private boolean success = true; - private final String CONFIGURATION_NODE_TYPE = "configuration"; - private final String SERVICE_INSTANCE_NODE_TYPE = "service-instance"; - private Introspector configObj; - - public MigrateServiceInstanceToConfiguration(TransactionalGraphEngine engine) { - super(engine); - try { - this.configObj = this.loader.introspectorFromName(CONFIGURATION_NODE_TYPE); - } catch (AAIUnknownObjectException e) { - this.configObj = null; - } - } - - @Override - public void run() { - Vertex serviceInstance = null; - Vertex configuration = null; - String serviceInstanceId = "", tunnelBandwidth = ""; - String bandwidthTotal, configType, nodeType; - GraphTraversal<Vertex, Vertex> serviceInstanceItr; - Iterator<Vertex> configurationItr; - - try { - serviceInstanceItr = this.engine.asAdmin().getTraversalSource().V() - .has(AAIProperties.NODE_TYPE, P.within(getAffectedNodeTypes().get())) - .where(this.engine.getQueryBuilder() - .createEdgeTraversal(EdgeType.TREE, "service-instance", "service-subscription") - .getVerticesByProperty("service-type", "DHV") - .<GraphTraversal<?, ?>>getQuery()); - - if (serviceInstanceItr == null || !serviceInstanceItr.hasNext()) { - logger.info("No servince-instance nodes found with service-type of DHV"); - return; - } - - // iterate through all service instances of service-type DHV - while (serviceInstanceItr.hasNext()) { - serviceInstance = serviceInstanceItr.next(); - - if (serviceInstance != null && serviceInstance.property("bandwidth-total").isPresent()) { - serviceInstanceId = serviceInstance.value("service-instance-id"); - logger.info("Processing service instance with id=" + serviceInstanceId); - bandwidthTotal = serviceInstance.value("bandwidth-total"); - - if (bandwidthTotal != null && !bandwidthTotal.isEmpty()) { - - // check for existing edges to configuration nodes - configurationItr = serviceInstance.vertices(Direction.OUT, "has"); - - // create new configuration node if service-instance does not have existing ones - if (!configurationItr.hasNext()) { - logger.info(serviceInstanceId + " has no existing configuration nodes, creating new node"); - createConfigurationNode(serviceInstance, bandwidthTotal); - continue; - } - - // in case if configuration nodes exist, but none are DHV - boolean hasDHVConfig = false; - - // service-instance has existing configuration nodes - while (configurationItr.hasNext()) { - configuration = configurationItr.next(); - nodeType = configuration.value("aai-node-type").toString(); - - if (configuration != null && "configuration".equalsIgnoreCase(nodeType)) { - logger.info("Processing configuration node with id=" + configuration.property("configuration-id").value()); - configType = configuration.value("configuration-type"); - logger.info("Configuration type: " + configType); - - // if configuration-type is DHV, update tunnel-bandwidth to bandwidth-total value - if ("DHV".equalsIgnoreCase(configType)) { - if (configuration.property("tunnel-bandwidth").isPresent()) { - tunnelBandwidth = configuration.value("tunnel-bandwidth"); - } else { - tunnelBandwidth = ""; - } - - logger.info("Existing tunnel-bandwidth: " + tunnelBandwidth); - configuration.property("tunnel-bandwidth", bandwidthTotal); - touchVertexProperties(configuration, false); - logger.info("Updated tunnel-bandwidth: " + configuration.value("tunnel-bandwidth")); - hasDHVConfig = true; - } - } - } - - // create new configuration node if none of existing config nodes are of type DHV - if (!hasDHVConfig) { - logger.info(serviceInstanceId + " has existing configuration nodes, but none are DHV, create new node"); - createConfigurationNode(serviceInstance, bandwidthTotal); - } - } - } - } - } catch (AAIException | UnsupportedEncodingException e) { - logger.error("Caught exception while processing service instance with id=" + serviceInstanceId + " | " + e.toString()); - success = false; - } - } - - private void createConfigurationNode(Vertex serviceInstance, String bandwidthTotal) throws UnsupportedEncodingException, AAIException { - // create new vertex - Vertex configurationNode = serializer.createNewVertex(configObj); - - // configuration-id: UUID format - String configurationUUID = UUID.randomUUID().toString(); - configObj.setValue("configuration-id", configurationUUID); - - // configuration-type: DHV - configObj.setValue("configuration-type", "DHV"); - - // migrate the bandwidth-total property from the service-instance to the - // tunnel-bandwidth property of the related configuration object - configObj.setValue("tunnel-bandwidth", bandwidthTotal); - - // create edge between service instance and configuration: cousinEdge(out, in) - createCousinEdge(serviceInstance, configurationNode); - - // serialize edge & vertex, takes care of everything - serializer.serializeSingleVertex(configurationNode, configObj, "migrations"); - logger.info("Created configuration node with uuid=" + configurationUUID + ", tunnel-bandwidth=" + bandwidthTotal); - } - - @Override - public Status getStatus() { - if (success) { - return Status.SUCCESS; - } else { - return Status.FAILURE; - } - } - - @Override - public Optional<String[]> getAffectedNodeTypes() { - return Optional.of(new String[] {SERVICE_INSTANCE_NODE_TYPE}); - } - - @Override - public String getMigrationName() { - return "service-instance-to-configuration"; - } -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/v12/SDWANSpeedChangeMigration.java b/aai-resources/src/main/java/org/onap/aai/migration/v12/SDWANSpeedChangeMigration.java deleted file mode 100644 index 57e3e5e..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/v12/SDWANSpeedChangeMigration.java +++ /dev/null @@ -1,254 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration.v12; - -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.migration.*; -import org.onap.aai.serialization.db.EdgeType; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; - -import java.util.*; - -@MigrationPriority(1) -@MigrationDangerRating(1) -@Enabled -public class SDWANSpeedChangeMigration extends Migrator { - - private final String PARENT_NODE_TYPE = "alloted-resource"; - private boolean success = true; - - Vertex allottedRsrcVertex; - - Map<String, String> bandwidthMap = new HashMap<>(); - Set<String> bandWidthSet = new HashSet<>(); - - GraphTraversal<Vertex, Vertex> allottedRsrcTraversal; - GraphTraversal<Vertex, Vertex> tunnelXConnectTraversal; - GraphTraversal<Vertex, Vertex> pinterfaceTraversal; - GraphTraversal<Vertex, Vertex> plinkTraversal; - - public SDWANSpeedChangeMigration(TransactionalGraphEngine engine) { - super(engine); - bandWidthSet.add("bandwidth-up-wan1"); - bandWidthSet.add("bandwidth-down-wan1"); - bandWidthSet.add("bandwidth-up-wan2"); - bandWidthSet.add("bandwidth-down-wan2"); - } - - - @Override - public void run() { - - logger.info("Started the migration "+ getMigrationName()); - - try { - - allottedRsrcTraversal = this.engine.asAdmin().getTraversalSource().V() - .has("aai-node-type", "service-subscription") - .has("service-type", "DHV") - .in("org.onap.relationships.inventory.BelongsTo") - .has("aai-node-type", "service-instance") - .out("org.onap.relationships.inventory.Uses") - .has("aai-node-type", "allotted-resource") - .where( - this.engine.getQueryBuilder() - .createEdgeTraversal(EdgeType.TREE, "allotted-resource", "service-instance") - .createEdgeTraversal(EdgeType.TREE, "service-instance", "service-subscription") - .<GraphTraversal<Vertex, Vertex>>getQuery() - .has("service-type", "VVIG") - ); - - if(!(allottedRsrcTraversal.hasNext())){ - - logger.info("unable to find allotted resource to DHV as cousin and child of VVIG"); - } - - while (allottedRsrcTraversal.hasNext()) { - bandwidthMap.clear(); - - allottedRsrcVertex = allottedRsrcTraversal.next(); - String allottedResourceId = allottedRsrcVertex.property("id").value().toString(); - logger.info("Found an allotted resource with id " + allottedResourceId); - - tunnelXConnectTraversal = this.engine.asAdmin().getTraversalSource() - .V(allottedRsrcVertex) - .in("org.onap.relationships.inventory.BelongsTo") - .has("aai-node-type", "tunnel-xconnect"); - - if (tunnelXConnectTraversal != null && tunnelXConnectTraversal.hasNext()) { - Vertex xConnect = tunnelXConnectTraversal.next(); - String tunnelId = xConnect.property("id").value().toString(); - logger.info("Found an tunnelxconnect object with id " + tunnelId); - extractBandwidthProps(xConnect); - modifyPlink(allottedRsrcVertex); - } else { - logger.info("Unable to find the tunnel connect for the current allotted resource traversal"); - } - - } - } catch (AAIException e) { - e.printStackTrace(); - success = false; - } - - logger.info("Successfully finished the " + getMigrationName()); - } - - public void extractBandwidthProps(Vertex vertex) { - logger.info("Trying to extract bandwith props"); - bandWidthSet.stream().forEach((key) -> { - if (vertex.property(key).isPresent()) { - bandwidthMap.put(key, vertex.property(key).value().toString()); - } - }); - logger.info("Extracted bandwith props for tunnelXConnect " +vertex.value("id")); - } - - public void modifyPlink(Vertex v) { - - try { - pinterfaceTraversal = this.engine.asAdmin().getTraversalSource().V(v) - .in("org.onap.relationships.inventory.Uses").has("aai-node-type", "service-instance") - .where( - __.out("org.onap.relationships.inventory.BelongsTo") - .has("aai-node-type", "service-subscription") - .has("service-type", "DHV") - ) - .out("org.onap.relationships.inventory.ComposedOf").has("aai-node-type", "generic-vnf") - .out("tosca.relationships.HostedOn").has("aai-node-type", "vserver") - .out("tosca.relationships.HostedOn").has("aai-node-type", "pserver") - .in("tosca.relationships.network.BindsTo").has("aai-node-type", "p-interface"); - } catch (Exception e) { - logger.info("error trying to find p interfaces"); - } - - - while (pinterfaceTraversal.hasNext()) { - - Vertex pInterfaceVertex = pinterfaceTraversal.next(); - - String pinterfaceName = pInterfaceVertex.property("interface-name").value().toString(); - logger.info("p-interface "+ pinterfaceName + " found from traversal from allotted-resource " +v.value("id")); - String[] parts = pinterfaceName.split("/"); - - if (parts[parts.length - 1].equals("10")) { - - logger.info("Found the pinterface with the interface name ending with /10"); - - try { - plinkTraversal = this.engine.asAdmin().getTraversalSource() - .V(pInterfaceVertex) - .out("tosca.relationships.network.LinksTo") - .has("aai-node-type", "physical-link"); - } catch (Exception e) { - logger.info("error trying to find the p Link for /10"); - } - if (plinkTraversal != null && plinkTraversal.hasNext()) { - Vertex pLink = plinkTraversal.next(); - - - if ( bandwidthMap.containsKey("bandwidth-up-wan1") - && bandwidthMap.containsKey("bandwidth-down-wan1") - && !(("").equals(bandwidthMap.get("bandwidth-up-wan1").replaceAll("[^0-9]", "").trim())) - && !(("").equals(bandwidthMap.get("bandwidth-down-wan1").replaceAll("[^0-9]", "").trim()))) - { - - pLink.property("service-provider-bandwidth-up-value", Integer.valueOf(bandwidthMap.get("bandwidth-up-wan1").replaceAll("[^0-9]", "").trim())); - pLink.property("service-provider-bandwidth-up-units", "Mbps"); - pLink.property("service-provider-bandwidth-down-value", Integer.valueOf(bandwidthMap.get("bandwidth-down-wan1").replaceAll("[^0-9]", "").trim())); - pLink.property("service-provider-bandwidth-down-units", "Mbps"); - logger.info("Successfully modified the plink with link name ", pLink.property("link-name").value().toString()); - this.touchVertexProperties(pLink, false); - } else { - logger.info("missing up and down vals for the plink with link name ", pLink.property("link-name").value().toString()); - } - - - } else { - logger.info("missing plink for p interface" + pinterfaceName); - } - - } - - if (parts[parts.length - 1].equals("11")) { - - logger.info("Found the pinterface with the interface name ending with /11"); - try { - plinkTraversal = this.engine.asAdmin() - .getTraversalSource() - .V(pInterfaceVertex) - .out("tosca.relationships.network.LinksTo") - .has("aai-node-type", "physical-link"); - } catch (Exception e) { - logger.info("error trying to find the p Link for /11"); - } - - if (plinkTraversal != null && plinkTraversal.hasNext()) { - Vertex pLink = plinkTraversal.next(); - - - if ( bandwidthMap.containsKey("bandwidth-up-wan2") - && bandwidthMap.containsKey("bandwidth-down-wan2") - && !(("").equals(bandwidthMap.get("bandwidth-up-wan2").replaceAll("[^0-9]", "").trim())) - && !(("").equals(bandwidthMap.get("bandwidth-down-wan2").replaceAll("[^0-9]", "").trim()))) - { - pLink.property("service-provider-bandwidth-up-value", Integer.valueOf(bandwidthMap.get("bandwidth-up-wan2").replaceAll("[^0-9]", "").trim())); - pLink.property("service-provider-bandwidth-up-units", "Mbps"); - pLink.property("service-provider-bandwidth-down-value", Integer.valueOf(bandwidthMap.get("bandwidth-down-wan2").replaceAll("[^0-9]", "").trim())); - pLink.property("service-provider-bandwidth-down-units", "Mbps"); - logger.info("Successfully modified the plink with link name ", pLink.property("link-name").value().toString()); - this.touchVertexProperties(pLink, false); - } else { - logger.error("missing up and down vals for the plink with link name ", pLink.property("link-name").value().toString()); - } - - } else { - logger.info("missing plink for p interface" + pinterfaceName); - } - } - } - } - - - @Override - public Status getStatus() { - if (success) { - return Status.SUCCESS; - } else { - return Status.FAILURE; - } - } - - @Override - public Optional<String[]> getAffectedNodeTypes() { - - return Optional.of(new String[]{PARENT_NODE_TYPE}); - } - - @Override - public String getMigrationName() { - return "SDWANSpeedChangeMigration"; - } - - -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/v12/ToscaMigration.java b/aai-resources/src/main/java/org/onap/aai/migration/v12/ToscaMigration.java deleted file mode 100644 index 91ca4d7..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/v12/ToscaMigration.java +++ /dev/null @@ -1,159 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration.v12; - -import java.util.*; - -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.onap.aai.db.props.AAIProperties; -import org.onap.aai.migration.Enabled; -import org.onap.aai.migration.MigrationDangerRating; -import org.onap.aai.migration.MigrationPriority; -import org.onap.aai.migration.Migrator; -import org.onap.aai.migration.Status; -import org.onap.aai.serialization.db.*; -import org.onap.aai.serialization.db.exceptions.EdgeMultiplicityException; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; - -@Enabled - -@MigrationPriority(0) -@MigrationDangerRating(1000) -public class ToscaMigration extends Migrator { - - private boolean success = true; - EdgeRules ers = EdgeRules.getInstance(); - - public ToscaMigration(TransactionalGraphEngine graphEngine){ - super(graphEngine); - } - - @Override - public Status getStatus() { - if (success) { - return Status.SUCCESS; - } else { - return Status.FAILURE; - } - } - - @Override - public void run() { - Vertex out = null; - Vertex in = null; - boolean isCousin = false; - String oldEdgeString = null; - Map<String,Integer> edgeMultiplicityExceptionCtr = new HashMap<>(); - List<String> edgeMissingParentProperty = new ArrayList<>(); - - GraphTraversalSource g = engine.asAdmin().getTraversalSource(); - - try { - Set<Edge> edges = g.E().toSet(); - for (Edge edge : edges) { - // skip if this edge was migrated in a previous run - if (edge.label().contains("org.") || edge.label().contains("tosca.")) { - continue; - } - out = edge.outVertex(); - in = edge.inVertex(); - isCousin = false; - - if (out == null || in == null) { - logger.error(edge.id() + " invalid because one vertex was null: out=" + edge.outVertex() + " in=" + edge.inVertex()); - } else { - - if (edge.property("contains-other-v").isPresent()) { - isCousin = "NONE".equals(edge.property("contains-other-v").value()); - } else if (edge.property("isParent").isPresent()) { - isCousin = !(Boolean)edge.property("isParent").value(); - } else { - edgeMissingParentProperty.add(this.toStringForPrinting(edge, 1)); - } - - String inVertexNodeType = in.value(AAIProperties.NODE_TYPE); - String outVertexNodeType = out.value(AAIProperties.NODE_TYPE); - String label = null; - - - Set<String> edgeLabels = ers.getEdgeRules(outVertexNodeType,inVertexNodeType).keySet(); - - if (edgeLabels.isEmpty()) { - logger.error(edge.id() + " did not migrate as no edge rule found for: out=" + outVertexNodeType + " in=" + inVertexNodeType); - continue; - } else if (edgeLabels.size() > 1) { - if (edgeLabels.contains("org.onap.relationships.inventory.Source")) { - if ("sourceLInterface".equals(edge.label())) { - label = "org.onap.relationships.inventory.Source"; - } else if ("targetLInterface".equals(edge.label())) { - label = "org.onap.relationships.inventory.Destination"; - } else { - label = "tosca.relationships.network.LinksTo"; - } - } - } - - try { - if (isCousin) { - ers.addEdgeIfPossible(g, in, out, label); - } else { - ers.addTreeEdge(g, out, in); - } - edge.remove(); - } catch (EdgeMultiplicityException edgeMultiplicityException) { - logger.warn("Edge Multiplicity Exception: " - + "\nInV:\n" + this.toStringForPrinting(in, 1) - + "Edge:\n" + this.toStringForPrinting(edge, 1) - + "OutV:\n" + this.toStringForPrinting(out, 1) - ); - - final String mapKey = "OUT:" + outVertexNodeType + " " + (isCousin ? EdgeType.COUSIN.toString():EdgeType.TREE.toString()) + " " + "IN:" + inVertexNodeType; - if (edgeMultiplicityExceptionCtr.containsKey(mapKey)) { - edgeMultiplicityExceptionCtr.put(mapKey, edgeMultiplicityExceptionCtr.get(mapKey)+1); - } else { - edgeMultiplicityExceptionCtr.put(mapKey, 1); - } - } - } - } - } catch(Exception ex){ - logger.error("exception occurred during migration, failing: out=" + out + " in=" + in + "edge=" + oldEdgeString, ex); - success = false; - } - - logger.info("Edge Missing Parent Property Count: " + edgeMissingParentProperty.size()); - logger.info("Edge Multiplicity Exception Count : " + edgeMultiplicityExceptionCtr.values().stream().mapToInt(Number::intValue).sum()); - logger.info("Edge Multiplicity Exception Breakdown : " + edgeMultiplicityExceptionCtr); - - } - - @Override - public Optional<String[]> getAffectedNodeTypes() { - return Optional.empty(); - } - - @Override - public String getMigrationName() { - return "migrate-all-edges"; - } - -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/v13/MigrateInstanceGroupSubType.java b/aai-resources/src/main/java/org/onap/aai/migration/v13/MigrateInstanceGroupSubType.java deleted file mode 100644 index feb8a6a..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/v13/MigrateInstanceGroupSubType.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration.v13; -import java.util.Optional; - -import org.onap.aai.migration.Enabled; -import org.onap.aai.migration.MigrationDangerRating; -import org.onap.aai.migration.MigrationPriority; -import org.onap.aai.migration.PropertyMigrator; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; - -import org.janusgraph.core.Cardinality; - -@MigrationPriority(20) -@MigrationDangerRating(2) -@Enabled -public class MigrateInstanceGroupSubType extends PropertyMigrator{ - - protected static final String SUB_TYPE_PROPERTY = "sub-type"; - protected static final String INSTANCE_GROUP_ROLE_PROPERTY = "instance-group-role"; - protected static final String INSTANCE_GROUP_NODE_TYPE = "instance-group"; - - public MigrateInstanceGroupSubType(TransactionalGraphEngine engine) { - super(engine,SUB_TYPE_PROPERTY , INSTANCE_GROUP_ROLE_PROPERTY, String.class,Cardinality.SINGLE); - } - - @Override - public Optional<String[]> getAffectedNodeTypes() { - return Optional.of(new String[]{INSTANCE_GROUP_NODE_TYPE}); - } - - @Override - public String getMigrationName() { - return "MigrateInstanceGroupSubType"; - } - - @Override - public boolean isIndexed() { - return true; - } - -} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/v13/MigrateInstanceGroupType.java b/aai-resources/src/main/java/org/onap/aai/migration/v13/MigrateInstanceGroupType.java deleted file mode 100644 index dc55b40..0000000 --- a/aai-resources/src/main/java/org/onap/aai/migration/v13/MigrateInstanceGroupType.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.migration.v13; -import java.util.Optional; - -import org.onap.aai.migration.Enabled; -import org.onap.aai.migration.MigrationDangerRating; -import org.onap.aai.migration.MigrationPriority; -import org.onap.aai.migration.PropertyMigrator; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; - -import org.janusgraph.core.Cardinality; - -@MigrationPriority(20) -@MigrationDangerRating(2) -@Enabled -public class MigrateInstanceGroupType extends PropertyMigrator{ - - protected static final String TYPE_PROPERTY = "type"; - protected static final String INSTANCE_GROUP_TYPE_PROPERTY = "instance-group-type"; - protected static final String INSTANCE_GROUP_NODE_TYPE = "instance-group"; - - public MigrateInstanceGroupType(TransactionalGraphEngine engine) { - super(engine,TYPE_PROPERTY , INSTANCE_GROUP_TYPE_PROPERTY, String.class,Cardinality.SINGLE); - } - - @Override - public Optional<String[]> getAffectedNodeTypes() { - return Optional.of(new String[]{INSTANCE_GROUP_NODE_TYPE}); - } - - @Override - public String getMigrationName() { - return "MigrateInstanceGroupType"; - } - - @Override - public boolean isIndexed() { - return true; - } - -} diff --git a/aai-resources/src/main/java/org/onap/aai/rest/BulkAddConsumer.java b/aai-resources/src/main/java/org/onap/aai/rest/BulkAddConsumer.java index 50e7634..0c316bf 100644 --- a/aai-resources/src/main/java/org/onap/aai/rest/BulkAddConsumer.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/BulkAddConsumer.java @@ -23,7 +23,7 @@ import javax.ws.rs.Path; import org.onap.aai.restcore.HttpMethod; -@Path("{version: v[8-9]|v1[01234]}/bulkadd") +@Path("{version: v[1-9][0-9]*|latest}/bulkadd") public class BulkAddConsumer extends BulkConsumer { @Override diff --git a/aai-resources/src/main/java/org/onap/aai/rest/BulkConsumer.java b/aai-resources/src/main/java/org/onap/aai/rest/BulkConsumer.java index 1c40859..d6ec93a 100644 --- a/aai-resources/src/main/java/org/onap/aai/rest/BulkConsumer.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/BulkConsumer.java @@ -43,12 +43,13 @@ import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; import org.javatuples.Pair; +import org.onap.aai.config.SpringContextAware; import org.onap.aai.dbmap.DBConnectionType; import org.onap.aai.exceptions.AAIException; import org.onap.aai.introspection.Introspector; import org.onap.aai.introspection.Loader; import org.onap.aai.introspection.ModelType; -import org.onap.aai.introspection.Version; +import org.onap.aai.setup.SchemaVersion; import org.onap.aai.introspection.exceptions.AAIUnmarshallingException; import org.onap.aai.logging.ErrorObjectNotFoundException; import org.onap.aai.logging.LoggingContext; @@ -99,8 +100,8 @@ public abstract class BulkConsumer extends RESTAPI { private ModelType introspectorFactoryType = ModelType.MOXY; /** The query style. */ - private QueryStyle queryStyle = QueryStyle.TRAVERSAL; - + private QueryStyle queryStyle = QueryStyle.TRAVERSAL_URI; + /** * Bulk add. * @@ -121,7 +122,7 @@ public abstract class BulkConsumer extends RESTAPI { String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId"); String realTime = headers.getRequestHeaders().getFirst("Real-Time"); String outputMediaType = getMediaType(headers.getAcceptableMediaTypes()); - Version version = Version.valueOf(versionParam); + SchemaVersion version = new SchemaVersion(versionParam); Response response = null; try { @@ -145,9 +146,10 @@ public abstract class BulkConsumer extends RESTAPI { JsonArray transactions = getTransactions(content, headers); for (int i = 0; i < transactions.size(); i++){ - HttpEntry httpEntry = new HttpEntry(version, introspectorFactoryType, queryStyle, type); - Loader loader = httpEntry.getLoader(); - TransactionalGraphEngine dbEngine = httpEntry.getDbEngine(); + HttpEntry resourceHttpEntry = SpringContextAware.getBean("traversalUriHttpEntry", HttpEntry.class); + resourceHttpEntry.setHttpEntryProperties(version, type); + Loader loader = resourceHttpEntry.getLoader(); + TransactionalGraphEngine dbEngine = resourceHttpEntry.getDbEngine(); URI thisUri = null; List<BulkOperation> bulkOperations = new ArrayList<>(); HttpMethod method = null; @@ -175,7 +177,7 @@ public abstract class BulkConsumer extends RESTAPI { requests.add(request); } - Pair<Boolean, List<Pair<URI, Response>>> results = httpEntry.process(requests, sourceOfTruth, this.enableResourceVersion()); + Pair<Boolean, List<Pair<URI, Response>>> results = resourceHttpEntry.process(requests, sourceOfTruth, this.enableResourceVersion()); List<BulkOperationResponse> responses = BulkOperationResponse.processPairList(method, results.getValue1()); allResponses.add(responses); if (results.getValue0()) { //everything was processed without error @@ -364,7 +366,7 @@ public abstract class BulkConsumer extends RESTAPI { * keep any errors with their corresponding uris for client feedback */ bulkOperation.setUri(uri); - + bulkOperation.addUriInfoQueryParams(uriComponents.getQueryParams()); if (!ValidateEncoding.getInstance().validate(uri)) { diff --git a/aai-resources/src/main/java/org/onap/aai/rest/BulkProcessConsumer.java b/aai-resources/src/main/java/org/onap/aai/rest/BulkProcessConsumer.java index 2cae668..aac2deb 100644 --- a/aai-resources/src/main/java/org/onap/aai/rest/BulkProcessConsumer.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/BulkProcessConsumer.java @@ -23,7 +23,7 @@ import javax.ws.rs.Path; import org.onap.aai.restcore.HttpMethod; -@Path("{version: v[789]|v1[01234]}/bulkprocess") +@Path("{version: v[1-9][0-9]*|latest}/bulkprocess") public class BulkProcessConsumer extends BulkConsumer { @Override diff --git a/aai-resources/src/main/java/org/onap/aai/rest/ExampleConsumer.java b/aai-resources/src/main/java/org/onap/aai/rest/ExampleConsumer.java index d52befd..74884e2 100644 --- a/aai-resources/src/main/java/org/onap/aai/rest/ExampleConsumer.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/ExampleConsumer.java @@ -31,13 +31,14 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; +import org.onap.aai.config.SpringContextAware; import org.onap.aai.exceptions.AAIException; import org.onap.aai.introspection.Introspector; import org.onap.aai.introspection.Loader; import org.onap.aai.introspection.LoaderFactory; import org.onap.aai.introspection.MarshallerProperties; import org.onap.aai.introspection.ModelType; -import org.onap.aai.introspection.Version; +import org.onap.aai.setup.SchemaVersion; import org.onap.aai.introspection.generator.CreateExample; import org.onap.aai.restcore.HttpMethod; import org.onap.aai.restcore.RESTAPI; @@ -45,7 +46,7 @@ import org.onap.aai.restcore.RESTAPI; /** * The Class ExampleConsumer. */ -@Path("/{version: v[789]|v1[01234]}/examples") +@Path("{version: v[1-9][0-9]*|latest}/examples") public class ExampleConsumer extends RESTAPI { @@ -71,8 +72,8 @@ public class ExampleConsumer extends RESTAPI { String mediaType = getMediaType(headers.getAcceptableMediaTypes()); org.onap.aai.restcore.MediaType outputMediaType = org.onap.aai.restcore.MediaType.getEnum(mediaType); - Version version = Version.valueOf(versionParam); - Loader loader = LoaderFactory.createLoaderForVersion(ModelType.MOXY, version); + SchemaVersion version = new SchemaVersion(versionParam); + Loader loader = SpringContextAware.getBean( LoaderFactory.class).createLoaderForVersion(ModelType.MOXY, version); CreateExample example = new CreateExample(loader, type); diff --git a/aai-resources/src/main/java/org/onap/aai/rest/LegacyMoxyConsumer.java b/aai-resources/src/main/java/org/onap/aai/rest/LegacyMoxyConsumer.java index 61f0d88..3c2754d 100644 --- a/aai-resources/src/main/java/org/onap/aai/rest/LegacyMoxyConsumer.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/LegacyMoxyConsumer.java @@ -25,10 +25,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; -import java.util.Map.Entry; import java.util.Set; import java.util.stream.Collectors; -import java.util.concurrent.Callable; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; @@ -52,13 +50,13 @@ import javax.ws.rs.core.UriInfo; import io.swagger.jaxrs.PATCH; import org.javatuples.Pair; +import org.onap.aai.concurrent.AaiCallable; +import org.onap.aai.config.SpringContextAware; import org.onap.aai.dbmap.DBConnectionType; import org.onap.aai.exceptions.AAIException; import org.onap.aai.introspection.Introspector; import org.onap.aai.introspection.Loader; -import org.onap.aai.introspection.ModelType; -import org.onap.aai.introspection.Version; -import org.onap.aai.logging.LoggingContext; +import org.onap.aai.setup.SchemaVersion; import org.onap.aai.parsers.query.QueryParser; import org.onap.aai.rest.db.DBRequest; import org.onap.aai.rest.db.HttpEntry; @@ -66,50 +64,40 @@ import org.onap.aai.rest.exceptions.AAIInvalidXMLNamespace; import org.onap.aai.rest.util.ValidateEncoding; import org.onap.aai.restcore.HttpMethod; import org.onap.aai.restcore.RESTAPI; -import org.onap.aai.serialization.engines.QueryStyle; import org.onap.aai.serialization.engines.TransactionalGraphEngine; import org.onap.aai.util.AAIConstants; -import org.onap.aai.workarounds.RemoveDME2QueryParams; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; import com.google.common.base.Joiner; - /** * The Class LegacyMoxyConsumer. */ -@Path("{version: v[789]|v1[01234]}") +@Controller +@Path("{version: v[1-9][0-9]*|latest}") public class LegacyMoxyConsumer extends RESTAPI { - - private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(LegacyMoxyConsumer.class.getName()); - protected static String authPolicyFunctionName = "REST"; - private ModelType introspectorFactoryType = ModelType.MOXY; - private QueryStyle queryStyle = QueryStyle.TRAVERSAL; - private final static String TARGET_ENTITY = "aai-resources"; - /** - * Update. - * - * @param content the content - * @param versionParam the version param - * @param uri the uri - * @param headers the headers - * @param info the info - * @param req the req - * @return the response - */ + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(LegacyMoxyConsumer.class.getName()); + +// private HttpEntry traversalUriHttpEntry; + +// @Autowired +// public LegacyMoxyConsumer(HttpEntry traversalUriHttpEntry){ +// this.traversalUriHttpEntry = traversalUriHttpEntry; +// } + + public LegacyMoxyConsumer(){ + + } + @PUT @Path("/{uri: .+}") @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response update (String content, @PathParam("version")String versionParam, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) { - String serviceName = "PUT " + uri.toString(); - String queryStr = req.getQueryString(); - if ( queryStr != null ) { - serviceName = serviceName + "?" + queryStr; - } - LoggingContext.serviceName(serviceName); - LoggingContext.targetServiceName(serviceName); MediaType mediaType = headers.getMediaType(); return this.handleWrites(mediaType, HttpMethod.PUT, content, versionParam, uri, headers, info); } @@ -140,25 +128,14 @@ public class LegacyMoxyConsumer extends RESTAPI { TransactionalGraphEngine dbEngine = null; boolean success = true; - String serviceName = req.getMethod() + " " + req.getRequestURI().toString(); - String queryStr = req.getQueryString(); - if ( queryStr != null ) { - serviceName = serviceName + "?" + queryStr; - } - LoggingContext.requestId(transId); - LoggingContext.partnerName(sourceOfTruth); - LoggingContext.serviceName(serviceName); - LoggingContext.targetEntity(TARGET_ENTITY); - LoggingContext.targetServiceName(serviceName); - try { validateRequest(info); - Version version = Version.valueOf(versionParam); - version = Version.valueOf(versionParam); + SchemaVersion version = new SchemaVersion(versionParam); DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime); - HttpEntry httpEntry = new HttpEntry(version, introspectorFactoryType, queryStyle, type); - loader = httpEntry.getLoader(); - dbEngine = httpEntry.getDbEngine(); + HttpEntry traversalUriHttpEntry = SpringContextAware.getBean("traversalUriHttpEntry", HttpEntry.class); + traversalUriHttpEntry.setHttpEntryProperties(version, type); + loader = traversalUriHttpEntry.getLoader(); + dbEngine = traversalUriHttpEntry.getDbEngine(); URI uriObject = UriBuilder.fromPath(uri).build(); this.validateURI(uriObject); @@ -170,7 +147,7 @@ public class LegacyMoxyConsumer extends RESTAPI { DBRequest request = new DBRequest.Builder(HttpMethod.PUT_EDGE, uriObject, uriQuery, wrappedEntity, headers, info, transId).build(); List<DBRequest> requests = new ArrayList<>(); requests.add(request); - Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = httpEntry.process(requests, sourceOfTruth); + Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = traversalUriHttpEntry.process(requests, sourceOfTruth); response = responsesTuple.getValue1().get(0).getValue1(); success = responsesTuple.getValue0(); @@ -214,13 +191,6 @@ public class LegacyMoxyConsumer extends RESTAPI { public Response patch (String content, @PathParam("version")String versionParam, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) { MediaType mediaType = MediaType.APPLICATION_JSON_TYPE; - String serviceName = "PATCH " + uri.toString(); - String queryStr = req.getQueryString(); - if ( queryStr != null ) { - serviceName = serviceName + "?" + queryStr; - } - LoggingContext.serviceName(serviceName); - LoggingContext.targetServiceName(serviceName); return this.handleWrites(mediaType, HttpMethod.MERGE_PATCH, content, versionParam, uri, headers, info); } @@ -249,9 +219,9 @@ public class LegacyMoxyConsumer extends RESTAPI { headers, info, HttpMethod.GET, - new Callable<Response>() { + new AaiCallable<Response>() { @Override - public Response call() { + public Response process() { return getLegacy(content, versionParam, uri, depthParam, cleanUp, headers, info, req, new HashSet<String>(), resultIndex, resultSize); } } @@ -279,25 +249,15 @@ public class LegacyMoxyConsumer extends RESTAPI { Response response = null; TransactionalGraphEngine dbEngine = null; Loader loader = null; - - String serviceName = req.getMethod() + " " + req.getRequestURI().toString(); - String queryStr = req.getQueryString(); - if ( queryStr != null ) { - serviceName = serviceName + "?" + queryStr; - } - LoggingContext.requestId(transId); - LoggingContext.partnerName(sourceOfTruth); - LoggingContext.serviceName(serviceName); - LoggingContext.targetEntity(TARGET_ENTITY); - LoggingContext.targetServiceName(serviceName); try { validateRequest(info); - Version version = Version.valueOf(versionParam); + SchemaVersion version = new SchemaVersion(versionParam); DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime); - final HttpEntry httpEntry = new HttpEntry(version, introspectorFactoryType, queryStyle, type); - dbEngine = httpEntry.getDbEngine(); - loader = httpEntry.getLoader(); + final HttpEntry traversalUriHttpEntry = SpringContextAware.getBean("traversalUriHttpEntry", HttpEntry.class); + traversalUriHttpEntry.setHttpEntryProperties(version, type); + dbEngine = traversalUriHttpEntry.getDbEngine(); + loader = traversalUriHttpEntry.getLoader(); MultivaluedMap<String, String> params = info.getQueryParameters(); params = removeNonFilterableParams(params); @@ -319,7 +279,11 @@ public class LegacyMoxyConsumer extends RESTAPI { new DBRequest.Builder(HttpMethod.GET, uriObject, uriQuery, obj, headers, info, transId).build(); List<DBRequest> requests = new ArrayList<>(); requests.add(request); - Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = httpEntry.process(requests, sourceOfTruth); + if (resultIndex != null && resultIndex != "-1" && resultSize != null && resultSize != "-1") { + traversalUriHttpEntry.setPaginationIndex(Integer.parseInt(resultIndex)); + traversalUriHttpEntry.setPaginationBucket(Integer.parseInt(resultSize)); + } + Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = traversalUriHttpEntry.process(requests, sourceOfTruth); response = responsesTuple.getValue1().get(0).getValue1(); @@ -377,16 +341,6 @@ public class LegacyMoxyConsumer extends RESTAPI { String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId"); String transId = headers.getRequestHeaders().getFirst("X-TransactionId"); String realTime = headers.getRequestHeaders().getFirst("Real-Time"); - String serviceName = req.getMethod() + " " + req.getRequestURI().toString(); - String queryStr = req.getQueryString(); - if ( queryStr != null ) { - serviceName = serviceName + "?" + queryStr; - } - LoggingContext.requestId(transId); - LoggingContext.partnerName(sourceOfTruth); - LoggingContext.serviceName(serviceName); - LoggingContext.targetEntity(TARGET_ENTITY); - LoggingContext.targetServiceName(serviceName); TransactionalGraphEngine dbEngine = null; Response response = Response.status(404) @@ -397,12 +351,12 @@ public class LegacyMoxyConsumer extends RESTAPI { try { validateRequest(info); - Version version = Version.valueOf(versionParam); + SchemaVersion version = new SchemaVersion(versionParam); DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime); - HttpEntry httpEntry = new HttpEntry(version, introspectorFactoryType, queryStyle, type); - - dbEngine = httpEntry.getDbEngine(); - Loader loader = httpEntry.getLoader(); + HttpEntry traversalUriHttpEntry = SpringContextAware.getBean("traversalUriHttpEntry", HttpEntry.class); + traversalUriHttpEntry.setHttpEntryProperties(version, type); + dbEngine = traversalUriHttpEntry.getDbEngine(); + Loader loader = traversalUriHttpEntry.getLoader(); URI uriObject = UriBuilder.fromPath(uri).build(); @@ -413,7 +367,7 @@ public class LegacyMoxyConsumer extends RESTAPI { DBRequest request = new DBRequest.Builder(HttpMethod.DELETE, uriObject, uriQuery, obj, headers, info, transId).build(); List<DBRequest> requests = new ArrayList<>(); requests.add(request); - Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = httpEntry.process(requests, sourceOfTruth); + Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = traversalUriHttpEntry.process(requests, sourceOfTruth); response = responsesTuple.getValue1().get(0).getValue1(); success = responsesTuple.getValue0(); @@ -462,17 +416,6 @@ public class LegacyMoxyConsumer extends RESTAPI { String transId = headers.getRequestHeaders().getFirst("X-TransactionId"); String realTime = headers.getRequestHeaders().getFirst("Real-Time"); - String serviceName = req.getMethod() + " " + req.getRequestURI().toString(); - String queryStr = req.getQueryString(); - if ( queryStr != null ) { - serviceName = serviceName + "?" + queryStr; - } - LoggingContext.requestId(transId); - LoggingContext.partnerName(sourceOfTruth); - LoggingContext.serviceName(serviceName); - LoggingContext.targetEntity(TARGET_ENTITY); - LoggingContext.targetServiceName(serviceName); - Loader loader = null; TransactionalGraphEngine dbEngine = null; Response response = Response.status(404) @@ -482,11 +425,12 @@ public class LegacyMoxyConsumer extends RESTAPI { try { this.validateRequest(info); - Version version = Version.valueOf(versionParam); + SchemaVersion version = new SchemaVersion(versionParam); DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime); - HttpEntry httpEntry = new HttpEntry(version, introspectorFactoryType, queryStyle, type); - loader = httpEntry.getLoader(); - dbEngine = httpEntry.getDbEngine(); + HttpEntry traversalUriHttpEntry = SpringContextAware.getBean("traversalUriHttpEntry", HttpEntry.class); + traversalUriHttpEntry.setHttpEntryProperties(version, type); + loader = traversalUriHttpEntry.getLoader(); + dbEngine = traversalUriHttpEntry.getDbEngine(); if (content.equals("")) { throw new AAIException("AAI_3102", "You must supply a relationship"); @@ -501,7 +445,7 @@ public class LegacyMoxyConsumer extends RESTAPI { DBRequest request = new DBRequest.Builder(HttpMethod.DELETE_EDGE, uriObject, uriQuery, wrappedEntity, headers, info, transId).build(); List<DBRequest> requests = new ArrayList<>(); requests.add(request); - Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = httpEntry.process(requests, sourceOfTruth); + Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = traversalUriHttpEntry.process(requests, sourceOfTruth); response = responsesTuple.getValue1().get(0).getValue1(); success = responsesTuple.getValue0(); @@ -581,25 +525,21 @@ public class LegacyMoxyConsumer extends RESTAPI { Response response = null; TransactionalGraphEngine dbEngine = null; Loader loader = null; - Version version = null; + SchemaVersion version = null; String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId"); String transId = headers.getRequestHeaders().getFirst("X-TransactionId"); String realTime = headers.getRequestHeaders().getFirst("Real-Time"); Boolean success = true; - - //LoggingContext service name and target service name set in calling method - LoggingContext.requestId(transId); - LoggingContext.partnerName(sourceOfTruth); - LoggingContext.targetEntity(TARGET_ENTITY); try { validateRequest(info); - version = Version.valueOf(versionParam); + version = new SchemaVersion(versionParam); DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime); - HttpEntry httpEntry = new HttpEntry(version, introspectorFactoryType, queryStyle, type); - loader = httpEntry.getLoader(); - dbEngine = httpEntry.getDbEngine(); + HttpEntry traversalUriHttpEntry = SpringContextAware.getBean("traversalUriHttpEntry", HttpEntry.class); + traversalUriHttpEntry.setHttpEntryProperties(version, type); + loader = traversalUriHttpEntry.getLoader(); + dbEngine = traversalUriHttpEntry.getDbEngine(); URI uriObject = UriBuilder.fromPath(uri).build(); this.validateURI(uriObject); QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject); @@ -627,7 +567,7 @@ public class LegacyMoxyConsumer extends RESTAPI { .rawRequestContent(content).build(); List<DBRequest> requests = new ArrayList<>(); requests.add(request); - Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = httpEntry.process(requests, sourceOfTruth); + Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = traversalUriHttpEntry.process(requests, sourceOfTruth); response = responsesTuple.getValue1().get(0).getValue1(); success = responsesTuple.getValue0(); diff --git a/aai-resources/src/main/java/org/onap/aai/rest/URLFromVertexIdConsumer.java b/aai-resources/src/main/java/org/onap/aai/rest/URLFromVertexIdConsumer.java index eb54194..b9e5aa8 100644 --- a/aai-resources/src/main/java/org/onap/aai/rest/URLFromVertexIdConsumer.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/URLFromVertexIdConsumer.java @@ -20,7 +20,6 @@ package org.onap.aai.rest; import java.net.URI; -import java.net.URL; import java.util.Iterator; import javax.servlet.http.HttpServletRequest; @@ -36,11 +35,11 @@ import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; import org.apache.tinkerpop.gremlin.structure.Vertex; - +import org.onap.aai.config.SpringContextAware; import org.onap.aai.dbmap.DBConnectionType; import org.onap.aai.exceptions.AAIException; import org.onap.aai.introspection.ModelType; -import org.onap.aai.introspection.Version; +import org.onap.aai.setup.SchemaVersion; import org.onap.aai.rest.db.HttpEntry; import org.onap.aai.restcore.HttpMethod; import org.onap.aai.restcore.RESTAPI; @@ -48,15 +47,14 @@ import org.onap.aai.serialization.db.DBSerializer; import org.onap.aai.serialization.engines.QueryStyle; import org.onap.aai.serialization.engines.TransactionalGraphEngine; import org.onap.aai.util.AAIConfig; -import org.onap.aai.workarounds.LegacyURITransformer; /** * The Class URLFromVertexIdConsumer. */ -@Path("{version: v[789]|v1[01234]}/generateurl") +@Path("{version: v[1-9][0-9]*|latest}/generateurl") public class URLFromVertexIdConsumer extends RESTAPI { private ModelType introspectorFactoryType = ModelType.MOXY; - private QueryStyle queryStyle = QueryStyle.TRAVERSAL; + private QueryStyle queryStyle = QueryStyle.TRAVERSAL_URI; private final String ID_ENDPOINT = "/id/{vertexid: \\d+}"; @@ -73,20 +71,21 @@ public class URLFromVertexIdConsumer extends RESTAPI { */ @GET @Path(ID_ENDPOINT) - @Produces({ MediaType.TEXT_PLAIN }) + @Produces({ MediaType.WILDCARD }) public Response generateUrlFromVertexId(String content, @PathParam("version")String versionParam, @PathParam("vertexid")long vertexid, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) { String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId"); String realTime = headers.getRequestHeaders().getFirst("Real-Time"); - Version version = Version.valueOf(versionParam); + SchemaVersion version = new SchemaVersion(versionParam); StringBuilder result = new StringBuilder(); Response response = null; TransactionalGraphEngine dbEngine = null; try { DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime); - HttpEntry httpEntry = new HttpEntry(version, introspectorFactoryType, queryStyle, type); - dbEngine = httpEntry.getDbEngine(); + HttpEntry resourceHttpEntry = SpringContextAware.getBean("traversalUriHttpEntry", HttpEntry.class); + resourceHttpEntry.setHttpEntryProperties(version, type); + dbEngine = resourceHttpEntry.getDbEngine(); DBSerializer serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth); @@ -100,14 +99,6 @@ public class URLFromVertexIdConsumer extends RESTAPI { result.append(uri.getRawPath()); result.insert(0, version); result.insert(0, AAIConfig.get("aai.server.url.base")); - LegacyURITransformer urlTransformer = LegacyURITransformer.getInstance(); - URI output = new URI(result.toString()); - /*if (version.compareTo(Version.v2) == 0) { - output = urlTransformer.getLegacyURI(output); - result = new StringBuilder(); - result.append(output.toString()); - }*/ - response = Response.ok().entity(result.toString()).status(Status.OK).type(MediaType.TEXT_PLAIN).build(); } catch (AAIException e) { //TODO check that the details here are sensible diff --git a/aai-resources/src/main/java/org/onap/aai/rest/VertexIdConsumer.java b/aai-resources/src/main/java/org/onap/aai/rest/VertexIdConsumer.java index 94a6a68..3451528 100644 --- a/aai-resources/src/main/java/org/onap/aai/rest/VertexIdConsumer.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/VertexIdConsumer.java @@ -41,7 +41,7 @@ import javax.ws.rs.core.UriInfo; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.javatuples.Pair; - +import org.onap.aai.config.SpringContextAware; import org.onap.aai.db.props.AAIProperties; import org.onap.aai.dbmap.DBConnectionType; import org.onap.aai.exceptions.AAIException; @@ -49,7 +49,6 @@ import org.onap.aai.introspection.Introspector; import org.onap.aai.introspection.Loader; import org.onap.aai.introspection.MarshallerProperties; import org.onap.aai.introspection.ModelType; -import org.onap.aai.introspection.Version; import org.onap.aai.parsers.query.QueryParser; import org.onap.aai.rest.db.DBRequest; import org.onap.aai.rest.db.HttpEntry; @@ -58,18 +57,21 @@ import org.onap.aai.restcore.RESTAPI; import org.onap.aai.serialization.db.DBSerializer; import org.onap.aai.serialization.engines.QueryStyle; import org.onap.aai.serialization.engines.TransactionalGraphEngine; +import org.onap.aai.setup.SchemaVersion; /** * The Class VertexIdConsumer. */ -@Path("{version: v[789]|v1[01234]}/resources") +@Path("{version: v[1-9][0-9]*|latest}/resources") public class VertexIdConsumer extends RESTAPI { - + private ModelType introspectorFactoryType = ModelType.MOXY; - private QueryStyle queryStyle = QueryStyle.TRAVERSAL; + private QueryStyle queryStyle = QueryStyle.TRAVERSAL_URI; private final String ID_ENDPOINT = "/id/{vertexid: \\d+}"; + private HttpEntry resourceHttpEntry; + /** * Gets the by vertex id. * @@ -91,7 +93,7 @@ public class VertexIdConsumer extends RESTAPI { String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId"); String transId = headers.getRequestHeaders().getFirst("X-TransactionId"); String realTime = headers.getRequestHeaders().getFirst("Real-Time"); - Version version = Version.valueOf(versionParam); + SchemaVersion version = new SchemaVersion(versionParam); Status status = Status.NOT_FOUND; String result = ""; Response response = null; @@ -99,9 +101,10 @@ public class VertexIdConsumer extends RESTAPI { try { int depth = setDepth(depthParam); DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime); - HttpEntry httpEntry = new HttpEntry(version, introspectorFactoryType, queryStyle, type); - dbEngine = httpEntry.getDbEngine(); - Loader loader = httpEntry.getLoader(); + resourceHttpEntry = SpringContextAware.getBean("traversalUriHttpEntry", HttpEntry.class); + resourceHttpEntry.setHttpEntryProperties(version, type); + dbEngine = resourceHttpEntry.getDbEngine(); + Loader loader = resourceHttpEntry.getLoader(); DBSerializer serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth); @@ -127,7 +130,7 @@ public class VertexIdConsumer extends RESTAPI { List<DBRequest> requests = new ArrayList<>(); requests.add(request); - Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = httpEntry.process(requests, sourceOfTruth); + Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = resourceHttpEntry.process(requests, sourceOfTruth); response = responsesTuple.getValue1().get(0).getValue1(); } catch (AAIException e){ response = consumerExceptionResponseGenerator(headers, info, HttpMethod.GET, e); diff --git a/aai-resources/src/main/java/org/onap/aai/rest/bulk/BulkOperation.java b/aai-resources/src/main/java/org/onap/aai/rest/bulk/BulkOperation.java index dfd0f1d..82a706f 100644 --- a/aai-resources/src/main/java/org/onap/aai/rest/bulk/BulkOperation.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/bulk/BulkOperation.java @@ -1,87 +1,101 @@ -/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-package org.onap.aai.rest.bulk;
-
-import java.net.URI;
-import java.util.List;
-import java.util.Map.Entry;
-
-import javax.ws.rs.core.UriInfo;
-
-import org.onap.aai.introspection.Introspector;
-import org.onap.aai.restcore.HttpMethod;
-import org.springframework.util.MultiValueMap;
-
-public class BulkOperation {
-
- private URI uri = null;
- private Introspector introspector = null;
- private HttpMethod httpMethod = null;
- private String rawReq = "";
- private UriInfo uriInfo = new BulkUriInfo();
-
- public UriInfo getUriInfo() {
- return uriInfo;
- }
-
- public String getRawReq() {
- return rawReq;
- }
-
- public void setRawReq(String rawReq) {
- this.rawReq = rawReq;
- }
-
- public URI getUri() {
- return uri;
- }
-
- public void setUri(URI uri) {
- this.uri = uri;
- }
-
- public Introspector getIntrospector() {
- return introspector;
- }
-
- public void setIntrospector(Introspector introspector) {
- this.introspector = introspector;
- }
-
- public HttpMethod getHttpMethod() {
- return httpMethod;
- }
-
- public void setHttpMethod(HttpMethod httpMethod) {
- this.httpMethod = httpMethod;
- }
-
- public void addUriInfoQueryParams(MultiValueMap<String, String> queryParams) {
-
- BulkUriInfo bui = new BulkUriInfo();
-
- for (Entry<String, List<String>> entry : queryParams.entrySet()) {
- bui.addParams(entry.getKey(), entry.getValue());
- }
-
- this.uriInfo = bui;
- }
-
-}
+/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.rest.bulk; + +import java.net.URI; +import java.util.List; +import java.util.Map.Entry; + +import javax.ws.rs.core.UriInfo; + +import org.onap.aai.introspection.Introspector; +import org.onap.aai.parsers.query.QueryParser; +import org.onap.aai.restcore.HttpMethod; +import org.springframework.util.MultiValueMap; + +public class BulkOperation { + + private URI uri = null; + private QueryParser uriQuery = null; + private Introspector introspector = null; + private HttpMethod httpMethod = null; + private String rawReq = ""; + private UriInfo uriInfo = new BulkUriInfo(); + + public UriInfo getUriInfo() { + return uriInfo; + } + + public String getRawReq() { + return rawReq; + } + + public void setRawReq(String rawReq) { + this.rawReq = rawReq; + } + + public URI getUri() { + return uri; + } + + public void setUri(URI uri) { + this.uri = uri; + } + + public QueryParser getUriQuery() { + return uriQuery; + } + + public void setUriQuery(QueryParser uriQuery) { + this.uriQuery = uriQuery; + } + + public Introspector getIntrospector() { + return introspector; + } + + public void setIntrospector(Introspector introspector) { + this.introspector = introspector; + } + + public HttpMethod getHttpMethod() { + return httpMethod; + } + + public void setHttpMethod(HttpMethod httpMethod) { + this.httpMethod = httpMethod; + } + + public void addUriInfoQueryParams(MultiValueMap<String, String> queryParams) { + + BulkUriInfo bui = new BulkUriInfo(); + + for (Entry<String, List<String>> entry : queryParams.entrySet()) { + bui.addParams(entry.getKey(), entry.getValue()); + } + + this.uriInfo = bui; + } + + public void addUriInfo(UriInfo uriInfo){ + this.uriInfo = uriInfo; + } + +} diff --git a/aai-resources/src/main/java/org/onap/aai/rest/bulk/BulkOperationResponse.java b/aai-resources/src/main/java/org/onap/aai/rest/bulk/BulkOperationResponse.java index d5c53fd..130ab1c 100644 --- a/aai-resources/src/main/java/org/onap/aai/rest/bulk/BulkOperationResponse.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/bulk/BulkOperationResponse.java @@ -1,89 +1,89 @@ -/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-package org.onap.aai.rest.bulk;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.ws.rs.core.Response;
-
-import org.javatuples.Pair;
-import org.onap.aai.restcore.HttpMethod;
-
-public class BulkOperationResponse {
-
- private URI uri = null;
- private Response response = null;
- private HttpMethod httpMethod = null;
-
- private BulkOperationResponse() {
-
- }
-
- private BulkOperationResponse(HttpMethod httpMethod, Pair<URI, Response> pair) {
- this.httpMethod = httpMethod;
- this.response = pair.getValue1();
- this.uri = pair.getValue0();
- }
-
- public BulkOperationResponse(HttpMethod httpMethod, URI uri, Response response) {
- this.httpMethod = httpMethod;
- this.response = response;
- this.uri = uri;
- }
-
- public URI getUri() {
- return uri;
- }
-
- public void setUri(URI uri) {
- this.uri = uri;
- }
-
- public Response getResponse() {
- return response;
- }
-
- public void setResponse(Response response) {
- this.response = response;
- }
-
- public HttpMethod getHttpMethod() {
- return httpMethod;
- }
-
- public void setHttpMethod(HttpMethod httpMethod) {
- this.httpMethod = httpMethod;
- }
-
- public static List<BulkOperationResponse> processPairList(HttpMethod httpMethod, List<Pair<URI, Response>> pairList) {
-
- List<BulkOperationResponse> borList = new ArrayList<>();
- BulkOperationResponse bor;
-
- for (Pair<URI, Response> pair: pairList) {
- bor = new BulkOperationResponse(httpMethod, pair);
- borList.add(bor);
- }
-
- return borList;
- }
-}
+/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.rest.bulk; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.core.Response; + +import org.javatuples.Pair; +import org.onap.aai.restcore.HttpMethod; + +public class BulkOperationResponse { + + private URI uri = null; + private Response response = null; + private HttpMethod httpMethod = null; + + private BulkOperationResponse() { + + } + + private BulkOperationResponse(HttpMethod httpMethod, Pair<URI, Response> pair) { + this.httpMethod = httpMethod; + this.response = pair.getValue1(); + this.uri = pair.getValue0(); + } + + public BulkOperationResponse(HttpMethod httpMethod, URI uri, Response response) { + this.httpMethod = httpMethod; + this.response = response; + this.uri = uri; + } + + public URI getUri() { + return uri; + } + + public void setUri(URI uri) { + this.uri = uri; + } + + public Response getResponse() { + return response; + } + + public void setResponse(Response response) { + this.response = response; + } + + public HttpMethod getHttpMethod() { + return httpMethod; + } + + public void setHttpMethod(HttpMethod httpMethod) { + this.httpMethod = httpMethod; + } + + public static List<BulkOperationResponse> processPairList(HttpMethod httpMethod, List<Pair<URI, Response>> pairList) { + + List<BulkOperationResponse> borList = new ArrayList<>(); + BulkOperationResponse bor; + + for (Pair<URI, Response> pair: pairList) { + bor = new BulkOperationResponse(httpMethod, pair); + borList.add(bor); + } + + return borList; + } +} diff --git a/aai-resources/src/main/java/org/onap/aai/rest/bulk/BulkSingleTransactionConsumer.java b/aai-resources/src/main/java/org/onap/aai/rest/bulk/BulkSingleTransactionConsumer.java new file mode 100644 index 0000000..1e6ab0c --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/rest/bulk/BulkSingleTransactionConsumer.java @@ -0,0 +1,414 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.rest.bulk; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.javatuples.Pair; +import org.onap.aai.config.SpringContextAware; +import org.onap.aai.dbmap.DBConnectionType; +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.introspection.Introspector; +import org.onap.aai.introspection.Loader; +import org.onap.aai.logging.ErrorLogHelper; +import org.onap.aai.logging.LoggingContext; +import org.onap.aai.rest.bulk.pojos.Operation; +import org.onap.aai.rest.bulk.pojos.OperationResponse; +import org.onap.aai.rest.bulk.pojos.Transaction; +import org.onap.aai.rest.bulk.pojos.TransactionResponse; +import org.onap.aai.rest.db.DBRequest; +import org.onap.aai.rest.db.HttpEntry; +import org.onap.aai.restcore.HttpMethod; +import org.onap.aai.restcore.MediaType; +import org.onap.aai.restcore.RESTAPI; +import org.onap.aai.serialization.engines.TransactionalGraphEngine; +import org.onap.aai.setup.SchemaVersion; +import org.onap.aai.util.AAIConfig; +import org.onap.aai.util.AAIConstants; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.*; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.util.*; + +@Path(value = "{version: v[1-9][0-9]*|latest}/bulk/single-transaction") +public class BulkSingleTransactionConsumer extends RESTAPI { + + private static final String TARGET_ENTITY = "aai-resources"; + private static final Set<String> validOperations = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("put", "patch", "delete"))); + private int allowedOperationCount = 30; + private TransactionalGraphEngine dbEngine = null; + + @POST + @Consumes(value = javax.ws.rs.core.MediaType.APPLICATION_JSON) + @Produces(value = javax.ws.rs.core.MediaType.APPLICATION_JSON) + public Response process(String content, @PathParam(value = "version")String versionParam, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req){ + + String transId = headers.getRequestHeaders().getFirst("X-TransactionId"); + String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId"); + String realTime = headers.getRequestHeaders().getFirst("Real-Time"); + SchemaVersion version = new SchemaVersion(versionParam); + DBConnectionType type; + + initLogging(req, transId, sourceOfTruth); + + try { + type = this.determineConnectionType(sourceOfTruth, realTime); + + // unmarshall the payload. + Gson gson = new Gson(); + Transaction transaction; + try { + transaction = gson.fromJson(content, Transaction.class); + } catch (Exception e) { + throw new AAIException("AAI_6111", "Input payload does not follow bulk/single-transaction interface"); + } + + //set the operation count limit + setOperationCount(headers); + //validate + validate(transaction); + + //generate bulkoperations + List<BulkOperation> bulkOperations = generateBulkOperations(transaction); + + //init http entry + HttpEntry resourceHttpEntry = SpringContextAware.getBean("traversalUriHttpEntry", HttpEntry.class); + resourceHttpEntry.setHttpEntryProperties(version, type); + Loader loader = resourceHttpEntry.getLoader(); + TransactionalGraphEngine dbEngine = resourceHttpEntry.getDbEngine(); + + //populate uri query + populateUriQuery(bulkOperations, dbEngine); + + //populate introspector for operations + populateIntrospectors(bulkOperations, loader); + + //generate db process from bulk operation + List<DBRequest> dbRequests = bulkOperationToDbRequests(headers, transId, bulkOperations); + + //process db requests + Pair<Boolean, List<Pair<URI, Response>>> results = resourceHttpEntry.process(dbRequests, sourceOfTruth, this.enableResourceVersion()); + + //process result of db requests + TransactionResponse transactionResponse = buildTransactionResponse(transaction, results.getValue1()); + + //commit/rollback based on results + if (results.getValue0()) { //everything was processed without error + dbEngine.commit(); + } else { //something failed + dbEngine.rollback(); + } + + return Response + .status(Response.Status.CREATED) + .entity(new GsonBuilder().serializeNulls().create().toJson(transactionResponse)) + .build(); + + } catch (AAIException e) { + return consumerExceptionResponseGenerator(headers, info, javax.ws.rs.HttpMethod.POST, e); + } finally { + if (dbEngine != null) { + dbEngine.rollback(); + } + } + + } + + + /** + * Builds the response + * @param transaction the input transactions + * @param results the response of all of he operations + * @return TansactionResponse obj representing the result of the transaction + * @throws AAIException thrown if there is a failure in the result. Msg contains the details of the first failure. + */ + private TransactionResponse buildTransactionResponse(Transaction transaction, List<Pair<URI, Response>> results) throws AAIException { + TransactionResponse transactionResponse = new TransactionResponse(); + transactionResponse.setOperationResponses(new ArrayList<>(transaction.getOperations().size())); + final String failureInResponse = "Operation %s failed with status code (%s) and msg (%s)"; + for (int i = 0; i < transaction.getOperations().size(); i++) { + if (!Response.Status.Family.familyOf(results.get(i).getValue1().getStatus()) + .equals(Response.Status.Family.SUCCESSFUL)) { + throw new AAIException("AAI_3000", + String.format( + failureInResponse, + i, + results.get(i).getValue1().getStatus(), + results.get(i).getValue1().getEntity())); + } + OperationResponse operationResponse = new OperationResponse(); + operationResponse.setResponseStatusCode(results.get(i).getValue1().getStatus()); + operationResponse.setAction(transaction.getOperations().get(i).getAction()); + operationResponse.setUri(transaction.getOperations().get(i).getUri()); + operationResponse.setBody(results.get(i).getValue1().getEntity()); + transactionResponse.getOperationResponsess().add(i, operationResponse); + } + return transactionResponse; + } + + /** + * Generate one DBRequest per BulkOperation + * @param headers request headers + * @param transId transaction id + * @param bulkOperations operations to convert + * @return One DBRequest per BulkOperation + * @throws AAIException thrown if there are any issues with the transform + */ + private List<DBRequest> bulkOperationToDbRequests(@Context HttpHeaders headers, String transId, List<BulkOperation> bulkOperations) throws AAIException { + List<DBRequest> requests = new ArrayList<>(); + for (int i = 0; i < bulkOperations.size(); i++) { + try { + BulkOperation bulkOperation = bulkOperations.get(i); + DBRequest request = new DBRequest.Builder( + bulkOperation.getHttpMethod(), + bulkOperation.getUri(), + bulkOperation.getUriQuery(), + bulkOperation.getIntrospector(), + headers, + bulkOperation.getUriInfo(), + transId + ).rawRequestContent(bulkOperation.getRawReq()).build(); + requests.add(request); + } catch (Exception e) { + throw new AAIException("AAI_3000", "Error with operation " + i + ": " +e.getMessage()); + } + } + return requests; + } + + /** + * Sets the uriquery for each bulk operation + * @param bulkOperations operations to generate queries for + * @param dbEngine engine for query builder generation + * @throws AAIException thrown for issues with generating uri query + */ + private void populateUriQuery(List<BulkOperation> bulkOperations, TransactionalGraphEngine dbEngine) throws AAIException { + for (int i = 0; i < bulkOperations.size(); i++) { + try { + bulkOperations.get(i).setUriQuery(dbEngine.getQueryBuilder().createQueryFromURI(bulkOperations.get(i).getUri())); + } catch (AAIException e) { + throw new AAIException(e.getCode(), "Error with operation " + i + ": " +e.getMessage()); + } catch (UnsupportedEncodingException e) { + throw new AAIException("AAI_3000", "Error with operation " + i + ": " +e.getMessage()); + } + } + } + + /** + * Sets the introspector for each bulk operation. requires that uriquery is set per operation + * @param bulkOperations operations to generate introspector for + * @param loader Loader for generating introspector + * @throws AAIException thrown for issues with generating introspector + */ + private void populateIntrospectors(List<BulkOperation> bulkOperations, Loader loader) throws AAIException { + + final String objectUnMarshallMsg = "Body of operation %s could not be unmarshalled: %s"; + Introspector obj; + for (int i = 0; i < bulkOperations.size(); i++) { + BulkOperation bulkOperation = bulkOperations.get(i); + try { + if (bulkOperation.getHttpMethod().equals(HttpMethod.PUT_EDGE) + || bulkOperation.getHttpMethod().equals(HttpMethod.DELETE_EDGE)) { + obj = loader.unmarshal("relationship", bulkOperation.getRawReq(), MediaType.APPLICATION_JSON_TYPE); + bulkOperation.setIntrospector(obj); + } else { + String objName = bulkOperation.getUriQuery().getResultType(); + if (bulkOperation.getHttpMethod().equals(HttpMethod.DELETE)) { + obj = loader.introspectorFromName(objName); + } else { + obj = loader.unmarshal(objName, bulkOperation.getRawReq(), MediaType.APPLICATION_JSON_TYPE); + this.validateIntrospector(obj, loader, bulkOperation.getUri(), bulkOperation.getHttpMethod()); + } + bulkOperation.setIntrospector(obj); + } + } catch (UnsupportedEncodingException e) { + throw new AAIException("AAI_3000", String.format(objectUnMarshallMsg, i, bulkOperation.getRawReq())); + } + } + + } + + /** + * Sets the allowedOperationCount to one of the following + * - Integer.MAX_VALUE if override limit is configured + * - Property in aaiconfig + * - 30 by default + * @param headers request header + */ + private void setOperationCount(HttpHeaders headers) { + try { + String overrideLimit = headers.getRequestHeaders().getFirst("X-OverrideLimit"); + boolean isOverride = overrideLimit != null && !AAIConfig.get(AAIConstants.AAI_BULKCONSUMER_OVERRIDE_LIMIT).equals("false") + && overrideLimit.equals(AAIConfig.get(AAIConstants.AAI_BULKCONSUMER_OVERRIDE_LIMIT)); + if (isOverride) { + allowedOperationCount = Integer.MAX_VALUE; + } else { + allowedOperationCount = AAIConfig.getInt(AAIConstants.AAI_BULKCONSUMER_LIMIT); + } + } catch (AAIException e) { + allowedOperationCount = 30; + } + } + + /** + * Converts the request transaction into a list of bulk operations + * @param transaction transaction to extract bulk operations from + * @return list of bulk operations + */ + private List<BulkOperation> generateBulkOperations(Transaction transaction) { + List<BulkOperation> bulkOperations = new ArrayList<>(transaction.getOperations().size()); + + BulkOperation bulkOperation; + for (int i = 0; i < transaction.getOperations().size(); i++) { + final Operation operation = transaction.getOperations().get(i); + bulkOperation = new BulkOperation(); + + UriComponents uriComponents = UriComponentsBuilder.fromUriString(operation.getUri()).build(); + bulkOperation.setUri(UriBuilder.fromPath(uriComponents.getPath()).build()); + bulkOperation.addUriInfoQueryParams(uriComponents.getQueryParams()); + bulkOperation.setHttpMethod(getHttpMethod(operation.getAction(), bulkOperation.getUri())); + bulkOperation.setRawReq(operation.getBody().toString()); + bulkOperations.add(bulkOperation); + } + + return bulkOperations; + } + + /** + * Map action to httpmethod + * @param action action to be mapped + * @param uri uri of the action + * @return HttpMethod thats action/uri maps to + */ + private HttpMethod getHttpMethod(String action, URI uri) { + HttpMethod method = HttpMethod.GET; + switch (action) { + case "put": + method = HttpMethod.PUT; + break; + case "delete": + method = HttpMethod.DELETE; + break; + case "patch": + method = HttpMethod.MERGE_PATCH; + break; + } + if (uri.getPath().endsWith("/relationship-list/relationship")) { + if (method.equals(HttpMethod.PUT)) { + method = HttpMethod.PUT_EDGE; + } else if (method.equals(HttpMethod.DELETE)) { + method = HttpMethod.DELETE_EDGE; + } + } + + return method; + } + + + /** + * For each operation validates: + * - action is provided and correct. + * - uri exists + * - body exists + * @param transaction parsed payload + * @throws AAIException with the violations in the msg + */ + private void validate(Transaction transaction) throws AAIException { + if (transaction == null) { + throw new AAIException("AAI_6111", "input payload does not follow /bulk/single-transaction interface"); + } + + if (transaction.getOperations() == null + || transaction.getOperations().isEmpty()) { + throw new AAIException("AAI_6118", " Payload has no objects to operate on"); + } else if (transaction.getOperations().size() > allowedOperationCount){ + throw new AAIException("AAI_6147", " Allowed limit = " + allowedOperationCount); + } + + final String missingFieldMsgFormat = "Operation %s missing '%s'"; + final String invalidActionMsgFormat = "Operation %s has invalid action '%s'"; + List<String> msgs = new ArrayList<>(); + for (int i = 0; i < transaction.getOperations().size(); i++) { + final Operation operation = transaction.getOperations().get(i); + if (operation.getAction() == null || operation.getAction().isEmpty()) { + msgs.add(String.format(missingFieldMsgFormat, i, "action")); + } else if (!validOperations.contains(operation.getAction())) { + msgs.add(String.format(invalidActionMsgFormat, i, operation.getAction())); + } + if (operation.getUri() == null || operation.getUri().isEmpty()) { + msgs.add(String.format(missingFieldMsgFormat, i, "uri")); + } + if (operation.getBody() == null) { + msgs.add(String.format(missingFieldMsgFormat, i, "body")); + } + } + if (!msgs.isEmpty()) { + throw new AAIException("AAI_6111", "input payload missing required properties. [" + String.join(", ", msgs) + "]"); + } + + } + + /** + * Initialize logging context + * @param req requestContext + * @param transId transaction id + * @param sourceOfTruth application source + */ + private void initLogging(@Context HttpServletRequest req, String transId, String sourceOfTruth) { + String serviceName = req.getMethod() + " " + req.getRequestURI().toString(); + LoggingContext.requestId(transId); + LoggingContext.partnerName(sourceOfTruth); + LoggingContext.serviceName(serviceName); + LoggingContext.targetEntity(TARGET_ENTITY); + LoggingContext.targetServiceName(serviceName); + } + + protected boolean enableResourceVersion() { + return true; + } + + + /** + * Consumer exception response generator. + * + * @param headers the headers + * @param info the info + * @param action type of request + * @param e the e + * @return the response + */ + protected Response consumerExceptionResponseGenerator(HttpHeaders headers, UriInfo info, String action, AAIException e) { + ArrayList<String> templateVars = new ArrayList<>(); + templateVars.add(action); //GET, PUT, etc + templateVars.add(info.getPath()); + templateVars.addAll(e.getTemplateVars()); + + ErrorLogHelper.logException(e); + return Response + .status(e.getErrorObject().getHTTPResponseCode()) + .entity(ErrorLogHelper.getRESTAPIErrorResponseWithLogging(headers.getAcceptableMediaTypes(), e, templateVars)) + .build(); + } +} diff --git a/aai-resources/src/main/java/org/onap/aai/rest/bulk/BulkUriInfo.java b/aai-resources/src/main/java/org/onap/aai/rest/bulk/BulkUriInfo.java index 41cdd85..50b218f 100644 --- a/aai-resources/src/main/java/org/onap/aai/rest/bulk/BulkUriInfo.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/bulk/BulkUriInfo.java @@ -1,130 +1,130 @@ -/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-package org.onap.aai.rest.bulk;
-
-import java.net.URI;
-import java.util.List;
-
-import javax.ws.rs.core.*;
-
-
-public class BulkUriInfo implements UriInfo {
-
- private MultivaluedMap<String, String> queryParams= new MultivaluedHashMap<>();
-
- @Override
- public String getPath() {
- return null;
- }
-
- @Override
- public String getPath(boolean decode) {
- return null;
- }
-
- @Override
- public List<PathSegment> getPathSegments() {
- return null;
- }
-
- @Override
- public List<PathSegment> getPathSegments(boolean decode) {
- return null;
- }
-
- @Override
- public URI getRequestUri() {
- return null;
- }
-
- @Override
- public UriBuilder getRequestUriBuilder() {
- return null;
- }
-
- @Override
- public URI getAbsolutePath() {
- return null;
- }
-
- @Override
- public UriBuilder getAbsolutePathBuilder() {
- return null;
- }
-
- @Override
- public URI getBaseUri() {
- return null;
- }
-
- @Override
- public UriBuilder getBaseUriBuilder() {
- return null;
- }
-
- @Override
- public MultivaluedMap<String, String> getPathParameters() {
- return null;
- }
-
- @Override
- public MultivaluedMap<String, String> getPathParameters(boolean decode) {
- return null;
- }
-
- @Override
- public MultivaluedMap<String, String> getQueryParameters() {
- return this.queryParams;
- }
-
- @Override
- public MultivaluedMap<String, String> getQueryParameters(boolean decode) {
- return this.queryParams;
- }
-
- @Override
- public List<String> getMatchedURIs() {
- return null;
- }
-
- @Override
- public List<String> getMatchedURIs(boolean decode) {
- return null;
- }
-
- @Override
- public List<Object> getMatchedResources() {
- return null;
- }
-
- @Override
- public URI resolve(URI uri) {
- return null;
- }
-
- @Override
- public URI relativize(URI uri) {
- return null;
- }
-
- public void addParams(String key, List<String> list) {
- this.queryParams.put(key, list);
- }
-}
+/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.rest.bulk; + +import java.net.URI; +import java.util.List; + +import javax.ws.rs.core.*; + + +public class BulkUriInfo implements UriInfo { + + private MultivaluedMap<String, String> queryParams= new MultivaluedHashMap<>(); + + @Override + public String getPath() { + return null; + } + + @Override + public String getPath(boolean decode) { + return null; + } + + @Override + public List<PathSegment> getPathSegments() { + return null; + } + + @Override + public List<PathSegment> getPathSegments(boolean decode) { + return null; + } + + @Override + public URI getRequestUri() { + return null; + } + + @Override + public UriBuilder getRequestUriBuilder() { + return null; + } + + @Override + public URI getAbsolutePath() { + return null; + } + + @Override + public UriBuilder getAbsolutePathBuilder() { + return null; + } + + @Override + public URI getBaseUri() { + return null; + } + + @Override + public UriBuilder getBaseUriBuilder() { + return null; + } + + @Override + public MultivaluedMap<String, String> getPathParameters() { + return null; + } + + @Override + public MultivaluedMap<String, String> getPathParameters(boolean decode) { + return null; + } + + @Override + public MultivaluedMap<String, String> getQueryParameters() { + return this.queryParams; + } + + @Override + public MultivaluedMap<String, String> getQueryParameters(boolean decode) { + return this.queryParams; + } + + @Override + public List<String> getMatchedURIs() { + return null; + } + + @Override + public List<String> getMatchedURIs(boolean decode) { + return null; + } + + @Override + public List<Object> getMatchedResources() { + return null; + } + + @Override + public URI resolve(URI uri) { + return null; + } + + @Override + public URI relativize(URI uri) { + return null; + } + + public void addParams(String key, List<String> list) { + this.queryParams.put(key, list); + } +} diff --git a/aai-resources/src/main/java/org/onap/aai/migration/MigrationPriority.java b/aai-resources/src/main/java/org/onap/aai/rest/bulk/pojos/Operation.java index 974b9c6..183f0ad 100644 --- a/aai-resources/src/main/java/org/onap/aai/migration/MigrationPriority.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/bulk/pojos/Operation.java @@ -17,25 +17,48 @@ * limitations under the License. * ============LICENSE_END========================================================= */ -package org.onap.aai.migration; +package org.onap.aai.rest.bulk.pojos; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import com.google.gson.*; +import com.google.gson.annotations.SerializedName; +public class Operation { -/** - * Used to enable a migration to be picked up by the {@link com.openecomp.aai.migration.MigrationControllerInternal MigrationController} - * - * The priority of the migration. - * - * Lower number has higher priority - */ -@Target(ElementType.TYPE) -@Retention(value = RetentionPolicy.RUNTIME) -public @interface MigrationPriority { + @SerializedName("action") + private String action; + @SerializedName("uri") + private String uri; + @SerializedName("body") + private JsonObject body; + + public Operation(String action, String uri, JsonObject body) { + this.action = action; + this.uri = uri; + this.body = body; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public JsonObject getBody() { + return body; + } + + public void setBody(JsonObject body) { + this.body = body; + } + + public String getUri() { + return uri; + } - int value(); + public void setUri(String uri) { + this.uri = uri; + } } diff --git a/aai-resources/src/main/java/org/onap/aai/rest/bulk/pojos/OperationResponse.java b/aai-resources/src/main/java/org/onap/aai/rest/bulk/pojos/OperationResponse.java new file mode 100644 index 0000000..007e434 --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/rest/bulk/pojos/OperationResponse.java @@ -0,0 +1,76 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.rest.bulk.pojos; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.annotations.SerializedName; + +public class OperationResponse { + + @SerializedName("action") + private String action; + @SerializedName("uri") + private String uri; + @SerializedName("response-status-code") + private int responseStatusCode; + @SerializedName("response-body") + private JsonObject body; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public JsonObject getBody() { + return body; + } + + public void setBody(JsonObject body) { + this.body = body; + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public int getResponseStatusCode() { + return responseStatusCode; + } + + public void setResponseStatusCode(int responseStatusCode) { + this.responseStatusCode = responseStatusCode; + } + + public void setBody(Object s) { + if (s == null) { + this.body = null; + } else { + this.body = new JsonParser().parse(s.toString()).getAsJsonObject(); + } + } +} diff --git a/aai-resources/src/main/java/org/onap/aai/transforms/LowerCamelToLowerHyphenConverter.java b/aai-resources/src/main/java/org/onap/aai/rest/bulk/pojos/Transaction.java index aae42b5..20329d7 100644 --- a/aai-resources/src/main/java/org/onap/aai/transforms/LowerCamelToLowerHyphenConverter.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/bulk/pojos/Transaction.java @@ -17,17 +17,23 @@ * limitations under the License. * ============LICENSE_END========================================================= */ -package org.onap.aai.transforms; +package org.onap.aai.rest.bulk.pojos; -import com.google.common.base.CaseFormat; +import com.google.gson.annotations.SerializedName; -public class LowerCamelToLowerHyphenConverter implements Converter { +import java.util.List; - @Override - public String convert(String input) { - if(input == null){ - return null; - } - return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, input); +public class Transaction { + + @SerializedName("operations") + private List<Operation> operations; + + public List<Operation> getOperations() { + return operations; } + + public void setOperations(List<Operation> operations) { + this.operations = operations; + } + } diff --git a/aai-resources/src/main/java/org/onap/aai/migration/Enabled.java b/aai-resources/src/main/java/org/onap/aai/rest/bulk/pojos/TransactionResponse.java index 8a2ef68..ce5462c 100644 --- a/aai-resources/src/main/java/org/onap/aai/migration/Enabled.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/bulk/pojos/TransactionResponse.java @@ -17,19 +17,23 @@ * limitations under the License. * ============LICENSE_END========================================================= */ -package org.onap.aai.migration; +package org.onap.aai.rest.bulk.pojos; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import com.google.gson.annotations.SerializedName; +import java.util.List; -/** - * Used to enable a migration to be picked up by the {@link com.openecomp.aai.migration.MigrationControllerInternal MigrationController} - */ -@Target(ElementType.TYPE) -@Retention(value = RetentionPolicy.RUNTIME) -public @interface Enabled { +public class TransactionResponse { + + @SerializedName("operation-responses") + private List<OperationResponse> operationResponses; + + public List<OperationResponse> getOperationResponsess() { + return operationResponses; + } + + public void setOperationResponses(List<OperationResponse> operationResponses) { + this.operationResponses = operationResponses; + } } diff --git a/aai-resources/src/main/java/org/onap/aai/rest/retired/RetiredConsumer.java b/aai-resources/src/main/java/org/onap/aai/rest/retired/RetiredConsumer.java deleted file mode 100644 index 808b8bc..0000000 --- a/aai-resources/src/main/java/org/onap/aai/rest/retired/RetiredConsumer.java +++ /dev/null @@ -1,141 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.rest.retired; - -import java.util.ArrayList; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriInfo; - -import io.swagger.jaxrs.PATCH; -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.logging.ErrorLogHelper; -import org.onap.aai.restcore.RESTAPI; -import org.onap.aai.util.AAIConfig; - -/** - * The Class RetiredConsumer. - */ -public abstract class RetiredConsumer extends RESTAPI { - - /** - * Creates the message get. - * - * @param versionParam the version param - * @param headers the headers - * @param info the info - * @param req the req - * @return the response - */ - @GET - @Path("/{uri:.*}") - public Response createMessageGet(@PathParam("version")String versionParam, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) { - return createMessage(versionParam, headers, info, req); - } - - /** - * Creates the message delete. - * - * @param versionParam the version param - * @param headers the headers - * @param info the info - * @param req the req - * @return the response - */ - @DELETE - @Path("/{uri:.*}") - public Response createMessageDelete(@PathParam("version")String versionParam, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) { - return createMessage(versionParam, headers, info, req); - } - - /** - * Creates the message post. - * - * @param versionParam the version param - * @param headers the headers - * @param info the info - * @param req the req - * @return the response - */ - @POST - @Path("/{uri:.*}") - public Response createMessagePost(@PathParam("version")String versionParam, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) { - return createMessage(versionParam, headers, info, req); - } - - @PATCH - @Path("/{uri:.*}") - public Response createMessagePatch(@PathParam("version")String versionParam, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) { - return createMessage(versionParam, headers, info, req); - } - /** - * Creates the message put. - * - * @param versionParam the version param - * @param headers the headers - * @param info the info - * @param req the req - * @return the response - */ - @PUT - @Path("/{uri:.*}") - public Response createMessagePut(@PathParam("version")String versionParam, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) { - return createMessage(versionParam, headers, info, req); - } - - - /** - * Creates the message. - * - * @param versionParam the version param - * @param headers the headers - * @param info the info - * @param req the req - * @return the response - */ - private Response createMessage(String versionParam, HttpHeaders headers, UriInfo info, HttpServletRequest req) { - AAIException e = new AAIException("AAI_3007"); - - ArrayList<String> templateVars = new ArrayList<String>(); - - if (templateVars.size() == 0) { - templateVars.add("PUT"); - templateVars.add(info.getPath().toString()); - templateVars.add(versionParam); - templateVars.add(AAIConfig.get("aai.default.api.version", "")); - } - - Response response = Response - .status(e.getErrorObject().getHTTPResponseCode()) - .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, - templateVars)).build(); - - return response; - } -} diff --git a/aai-resources/src/main/java/org/onap/aai/rest/retired/V3ThroughV7Consumer.java b/aai-resources/src/main/java/org/onap/aai/rest/retired/V3ThroughV7Consumer.java deleted file mode 100644 index 1a590bb..0000000 --- a/aai-resources/src/main/java/org/onap/aai/rest/retired/V3ThroughV7Consumer.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.rest.retired; - -import javax.ws.rs.Path; - -@Path("{version: v[3-6]}") //TODO re-add v7 when we fix our env issues AAI-8567 -public class V3ThroughV7Consumer extends RetiredConsumer { - -} diff --git a/aai-resources/src/main/java/org/onap/aai/rest/tools/ModelVersionTransformer.java b/aai-resources/src/main/java/org/onap/aai/rest/tools/ModelVersionTransformer.java deleted file mode 100644 index 15596d0..0000000 --- a/aai-resources/src/main/java/org/onap/aai/rest/tools/ModelVersionTransformer.java +++ /dev/null @@ -1,410 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.rest.tools; - -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.Encoded; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; -import javax.ws.rs.core.UriInfo; - -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.onap.aai.db.props.AAIProperties; -import org.onap.aai.dbmap.DBConnectionType; -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.Introspector; -import org.onap.aai.introspection.Loader; -import org.onap.aai.introspection.MarshallerProperties; -import org.onap.aai.introspection.ModelType; -import org.onap.aai.introspection.Version; -import org.onap.aai.introspection.exceptions.AAIUnknownObjectException; -import org.onap.aai.logging.ErrorLogHelper; -import org.onap.aai.logging.LogFormatTools; -import org.onap.aai.rest.db.HttpEntry; -import org.onap.aai.rest.exceptions.AAIInvalidXMLNamespace; -import org.onap.aai.rest.util.ValidateEncoding; -import org.onap.aai.restcore.RESTAPI; -import org.onap.aai.serialization.db.EdgeType; -import org.onap.aai.serialization.db.exceptions.NoEdgeRuleFoundException; -import org.onap.aai.serialization.engines.QueryStyle; -import org.onap.aai.serialization.engines.TransactionalGraphEngine; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; -import com.google.common.base.Joiner; - - -/** - * The Class ModelVersionTransformer. - */ -@Path("tools") -public class ModelVersionTransformer extends RESTAPI { - - private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(ModelVersionTransformer.class.getName()); - protected static String authPolicyFunctionName = "REST"; - private ModelType introspectorFactoryType = ModelType.MOXY; - private QueryStyle queryStyle = QueryStyle.TRAVERSAL; - protected static String MODEL_ELEMENTS = "model-elements"; - private static final String RELATIONSHIP="relationship"; - - - /** - * POST for model transformation. - * - * @param content the content - * @param uri the uri - * @param headers the headers - * @param info the info - * @param req the req - * @return the transformed model - * @Path("/{uri: modeltransform}") - * @throws UnsupportedEncodingException - */ - @POST - @Path("/{uri: modeltransform}") - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - public Response modelTransform (String content, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) throws UnsupportedEncodingException { - Response response = null; - TransactionalGraphEngine dbEngine = null; - Loader loader = null; - MediaType mediaType = headers.getMediaType(); - String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId"); - String transId = headers.getRequestHeaders().getFirst("X-TransactionId"); - String realTime = headers.getRequestHeaders().getFirst("Real-Time"); - Boolean success = true; - AAIException ex; - - try { - validateRequest(info); - - DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime); - HttpEntry httpEntry = new HttpEntry(Version.v8, introspectorFactoryType, queryStyle, type); - loader = httpEntry.getLoader(); - dbEngine = httpEntry.getDbEngine(); - if (content.length() == 0) { - if (mediaType.toString().contains(MediaType.APPLICATION_JSON)) { - content = "{}"; - } else { - content = "<empty/>"; - } - } - - //Unmarshall the received model and store properties and values in a map. - Introspector obj = loader.unmarshal("Model", content, org.onap.aai.restcore.MediaType.getEnum(this.getInputMediaType(mediaType))); - if (obj == null) { - throw new AAIException("AAI_3000", "object could not be unmarshalled:" + content); - } - - if (mediaType.toString().contains(MediaType.APPLICATION_XML) && !content.equals("<empty/>") && isEmptyObject(obj)) { - throw new AAIInvalidXMLNamespace(content); - } - - Set<String> properties = obj.getProperties(); - java.util.Iterator<String> propItr = properties.iterator(); - - Map<String, Object> v8PropMap = new HashMap<String, Object>(); - while (propItr.hasNext()){ - String property = propItr.next(); - Object propertyValue = obj.getValue(property); - if (propertyValue != null) { - v8PropMap.put(propItr.next(), propertyValue); - } - } - // Get the current models and create a map of model-ver to model keys, this allows us - // to easily figure out and construct the relationships on the supplied v8 model - Map<String,String> modelVersionIdToModelInvariantIdMap = getCurrentModelsFromGraph(headers, transId, info); - - // Build the v10 - TODO - HttpEntry newHttpEntry = new HttpEntry(Version.v10, introspectorFactoryType, queryStyle, type); - Loader newLoader = newHttpEntry.getLoader(); - Introspector newModelObj = newLoader.introspectorFromName("Model"); - - // pull the attributes we need to apply to the model + model-ver objects - // model specific attrs - String oldModelInvariantId = obj.getValue("model-id"); - String oldModelType = obj.getValue("model-type"); - // model-ver specific - String oldModelName = obj.getValue("model-name"); - String oldModelVersionId = obj.getValue("model-name-version-id"); - String oldModelVersion = obj.getValue("model-version"); - - // copy attributes from the v8 model object to the v10 model object - newModelObj.setValue("model-invariant-id", oldModelInvariantId); - newModelObj.setValue("model-type", oldModelType); - - Introspector modelVersObj = newModelObj.newIntrospectorInstanceOfProperty("model-vers"); - - newModelObj.setValue("model-vers", modelVersObj.getUnderlyingObject()); - - List<Object> modelVerList = (List<Object>)modelVersObj.getValue("model-ver"); - - //create a model-ver object - Introspector modelVerObj = newLoader.introspectorFromName("ModelVer"); - // load attributes from the v8 model object into the v10 model-ver object - modelVerObj.setValue("model-version-id", oldModelVersionId); - modelVerObj.setValue("model-name", oldModelName); - modelVerObj.setValue("model-version", oldModelVersion); - - - if (obj.hasProperty(MODEL_ELEMENTS)) { - Introspector oldModelElements = obj.getWrappedValue(MODEL_ELEMENTS); - if (oldModelElements != null) { - Introspector newModelElements = modelVerObj.newIntrospectorInstanceOfProperty(MODEL_ELEMENTS); - modelVerObj.setValue(MODEL_ELEMENTS, newModelElements.getUnderlyingObject()); - repackModelElements(oldModelElements, newModelElements, modelVersionIdToModelInvariantIdMap); - } - } - - modelVerList.add(modelVerObj.getUnderlyingObject()); - - String outputMediaType = getMediaType(headers.getAcceptableMediaTypes()); - MarshallerProperties marshallerProperties = - new MarshallerProperties.Builder(org.onap.aai.restcore.MediaType.getEnum(outputMediaType)).build(); - - String result = newModelObj.marshal(marshallerProperties); - response = Response.ok(result).build(); - - } catch (AAIException e) { - - ArrayList<String> templateVars = new ArrayList<String>(2); - templateVars.add("POST modeltransform"); - templateVars.add("model-ver.model-version-id"); - response = Response - .status(e.getErrorObject().getHTTPResponseCode()) - .entity(ErrorLogHelper.getRESTAPIErrorResponse( - headers.getAcceptableMediaTypes(), e, - templateVars)).build(); - success = false; - } catch (Exception e) { - ArrayList<String> templateVars = new ArrayList<String>(2); - templateVars.add("POST modeltransform"); - templateVars.add("model-ver.model-version-id"); - ex = new AAIException("AAI_4000", e); - response = Response - .status(Status.INTERNAL_SERVER_ERROR) - .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars)) - .build(); - LOGGER.error("Internal server error", e); - success = false; - } finally { - if (dbEngine != null) { - if (success) { - dbEngine.commit(); - } else { - dbEngine.rollback(); - } - } - } - return response; - } - - - private void repackModelElements(Introspector oldModelElements, Introspector newModelElements, Map<String, String> modelVersionIdToModelInvariantIdMap) - throws AAIUnknownObjectException, AAIException { - - List<Introspector> oldModelElementList = oldModelElements.getWrappedListValue("model-element"); - List<Object> newModelElementList = (List<Object>)newModelElements.getValue("model-element"); - - for (Introspector oldModelElement : oldModelElementList) { - Introspector newModelElement = newModelElements.getLoader().introspectorFromName("model-element"); - - ArrayList<String> attrs = new ArrayList<String>(); - - attrs.add("model-element-uuid"); - attrs.add("new-data-del-flag"); - attrs.add("cardinality"); - attrs.add("linkage-points"); - - for (String attr : attrs) { - if (oldModelElement.hasProperty(attr)) { - newModelElement.setValue(attr, oldModelElement.getValue(attr)); - } - } - - if (oldModelElement.hasProperty("relationship-list")) { - - Introspector oldRelationshipList = oldModelElement.getWrappedValue("relationship-list"); - Introspector newRelationshipList = newModelElements.getLoader().introspectorFromName("relationship-list"); - newModelElement.setValue("relationship-list", newRelationshipList.getUnderlyingObject()); - - List<Introspector> oldRelationshipListList = oldRelationshipList.getWrappedListValue(RELATIONSHIP); - List<Object> newRelationshipListList = (List<Object>)newRelationshipList.getValue(RELATIONSHIP); - - for (Introspector oldRelationship : oldRelationshipListList) { - - Introspector newRelationship = newModelElements.getLoader().introspectorFromName(RELATIONSHIP); - newRelationshipListList.add(newRelationship.getUnderlyingObject()); - - List<Introspector> oldRelationshipData = oldRelationship.getWrappedListValue("relationship-data"); - List<Object> newRelationshipData = (List<Object>)newRelationship.getValue("relationship-data"); - - newRelationship.setValue("related-to", "model-ver"); - - for (Introspector oldRelationshipDatum : oldRelationshipData) { - - String oldProp = null; - String oldVal = null; - - if (oldRelationshipDatum.hasProperty("relationship-key")) { - oldProp = oldRelationshipDatum.getValue("relationship-key"); - } - if (oldRelationshipDatum.hasProperty("relationship-value")) { - oldVal = oldRelationshipDatum.getValue("relationship-value"); - } - - if ("model.model-name-version-id".equals(oldProp)) { - // make two new relationshipDatum for use w/ the new style model - - // you should have the model in the list of models we collected earlier - if (modelVersionIdToModelInvariantIdMap.containsKey(oldVal)) { - Introspector newRelationshipDatum1 = newModelElements.getLoader().introspectorFromName("relationship-data"); - Introspector newRelationshipDatum2 = newModelElements.getLoader().introspectorFromName("relationship-data"); - - String modelId = modelVersionIdToModelInvariantIdMap.get(oldVal); - - // the first one points at the model-invariant-id of found model - newRelationshipDatum1.setValue("relationship-key", "model.model-invariant-id"); - newRelationshipDatum1.setValue("relationship-value", modelId); - - // the second one points at the model-version-id which corresponds to the old model-name-version-id - newRelationshipDatum2.setValue("relationship-key", "model-ver.model-version-id"); - newRelationshipDatum2.setValue("relationship-value", oldVal); - - newRelationshipData.add(newRelationshipDatum1.getUnderlyingObject()); - newRelationshipData.add(newRelationshipDatum2.getUnderlyingObject()); - } else { - throw new AAIException("AAI_6114", "No model-ver found using model-ver.model-version-id=" + oldVal); - } - } - } - - } - } - - if (oldModelElement.hasProperty(MODEL_ELEMENTS)) { - Introspector nextOldModelElements = oldModelElement.getWrappedValue(MODEL_ELEMENTS); - if (nextOldModelElements != null) { - Introspector nextNewModelElements = newModelElement.newIntrospectorInstanceOfProperty(MODEL_ELEMENTS); - newModelElement.setValue(MODEL_ELEMENTS, nextNewModelElements.getUnderlyingObject()); - repackModelElements(nextOldModelElements, nextNewModelElements, modelVersionIdToModelInvariantIdMap); - } - } - newModelElementList.add(newModelElement.getUnderlyingObject()); - } - return; - - } - - private Map<String, String> getCurrentModelsFromGraph(HttpHeaders headers, String transactionId, UriInfo info) throws NoEdgeRuleFoundException, AAIException { - - TransactionalGraphEngine dbEngine = null; - Map<String, String> modelVerModelMap = new HashMap<String,String>() ; - try { - - Version version = AAIProperties.LATEST; - DBConnectionType type = DBConnectionType.REALTIME; - - final HttpEntry httpEntry = new HttpEntry(version, introspectorFactoryType, queryStyle, type); - dbEngine = httpEntry.getDbEngine(); - - List<Vertex> modelVertices = dbEngine.asAdmin().getTraversalSource().V().has(AAIProperties.NODE_TYPE,"model").toList(); - for (Vertex modelVtx : modelVertices) { - - List<Vertex> modelVerVerts = dbEngine.getQueryBuilder(modelVtx).createEdgeTraversal(EdgeType.TREE, "model", "model-ver").toList(); - for (Vertex v : modelVerVerts) { - modelVerModelMap.put(v.value("model-version-id"), modelVtx.value("model-invariant-id")); - } - } - } catch (NoSuchElementException e) { - throw new NoSuchElementException(); - } catch (Exception e1) { - LOGGER.error("Exception while getting current models from graph"+ LogFormatTools.getStackTop(e1)); - } - return modelVerModelMap; - - } - - /** - * Validate request. - * - * @param uri the uri - * @param headers the headers - * @param req the req - * @param action the action - * @param info the info - * @throws AAIException the AAI exception - * @throws UnsupportedEncodingException the unsupported encoding exception - */ - private void validateRequest(UriInfo info) throws AAIException, UnsupportedEncodingException { - - if (!ValidateEncoding.getInstance().validate(info)) { - throw new AAIException("AAI_3008", "uri=" + getPath(info)); - } - } - - /** - * Gets the path. - * - * @param info the info - * @return the path - */ - private String getPath(UriInfo info) { - String path = info.getPath(false); - MultivaluedMap<String, String> map = info.getQueryParameters(false); - String params = "?"; - List<String> parmList = new ArrayList<>(); - for (String key : map.keySet()) { - for (String value : map.get(key)) { - parmList.add(key + "=" + value); - } - } - String queryParams = Joiner.on("&").join(parmList); - if (map.keySet().isEmpty()) { - path += params + queryParams; - } - - return path; - - } - - protected boolean isEmptyObject(Introspector obj) { - return "{}".equals(obj.marshal(false)); - } - - -} diff --git a/aai-resources/src/main/java/org/onap/aai/rest/retired/V7V8Models.java b/aai-resources/src/main/java/org/onap/aai/rest/util/LogFormatTools.java index b023827..931ab0b 100644 --- a/aai-resources/src/main/java/org/onap/aai/rest/retired/V7V8Models.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/util/LogFormatTools.java @@ -17,11 +17,19 @@ * limitations under the License. * ============LICENSE_END========================================================= */ -package org.onap.aai.rest.retired; +package org.onap.aai.rest.util; -import javax.ws.rs.Path; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; -@Path("{version: v[78]}/service-design-and-creation/models") -public class V7V8Models extends RetiredConsumer { +public class LogFormatTools { + private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; + private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern(DATE_FORMAT) + .withZone(ZoneOffset.UTC); + + public static String getCurrentDateTime() { + return DTF.format(ZonedDateTime.now()); + } } diff --git a/aai-resources/src/main/java/org/onap/aai/rest/util/ValidateEncoding.java b/aai-resources/src/main/java/org/onap/aai/rest/util/ValidateEncoding.java index 3b4ea73..7d04bf7 100644 --- a/aai-resources/src/main/java/org/onap/aai/rest/util/ValidateEncoding.java +++ b/aai-resources/src/main/java/org/onap/aai/rest/util/ValidateEncoding.java @@ -133,6 +133,9 @@ public class ValidateEncoding { valid = false; } for (String item : params.get(key)) { + if(item.contains("+")){ + item = item.replaceAll("\\+", "%20"); + } if (!this.checkEncoding(item)) { valid = false; } diff --git a/aai-resources/src/main/java/org/onap/aai/service/AuthorizationService.java b/aai-resources/src/main/java/org/onap/aai/service/AuthorizationService.java index 616bb9c..d2597d0 100644 --- a/aai-resources/src/main/java/org/onap/aai/service/AuthorizationService.java +++ b/aai-resources/src/main/java/org/onap/aai/service/AuthorizationService.java @@ -22,7 +22,9 @@ package org.onap.aai.service; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; import org.eclipse.jetty.util.security.Password; +import org.onap.aai.Profiles; import org.onap.aai.util.AAIConstants; +import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; @@ -35,6 +37,7 @@ import java.util.HashMap; import java.util.Map; import java.util.stream.Stream; +@Profile(Profiles.ONE_WAY_SSL) @Service public class AuthorizationService { diff --git a/aai-resources/src/main/java/org/onap/aai/service/RetiredService.java b/aai-resources/src/main/java/org/onap/aai/service/RetiredService.java new file mode 100644 index 0000000..5989e31 --- /dev/null +++ b/aai-resources/src/main/java/org/onap/aai/service/RetiredService.java @@ -0,0 +1,67 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.service; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +@Service +@PropertySource("classpath:retired.properties") +@PropertySource(value = "file:${server.local.startpath}/retired.properties") +public class RetiredService { + + private String retiredPatterns; + + private String retiredAllVersions; + + private List<Pattern> retiredPatternsList; + private List<Pattern> retiredAllVersionList; + + @PostConstruct + public void initialize(){ + this.retiredPatternsList = Arrays.stream(retiredPatterns.split(",")).map(Pattern::compile).collect(Collectors.toList()); + this.retiredAllVersionList = Arrays.stream(retiredAllVersions.split(",")).map(Pattern::compile).collect(Collectors.toList()); + } + + @Value("${retired.api.pattern.list}") + public void setRetiredPatterns(String retiredPatterns){ + this.retiredPatterns = retiredPatterns; + } + + public List<Pattern> getRetiredPatterns(){ + return retiredPatternsList; + } + + @Value("${retired.api.all.versions}") + public void setRetiredAllVersions(String retiredPatterns){ + this.retiredAllVersions = retiredPatterns; + } + + public List<Pattern> getRetiredAllVersionList(){ + return retiredAllVersionList; + } +} diff --git a/aai-resources/src/main/java/org/onap/aai/transforms/Converter.java b/aai-resources/src/main/java/org/onap/aai/transforms/Converter.java deleted file mode 100644 index 676c910..0000000 --- a/aai-resources/src/main/java/org/onap/aai/transforms/Converter.java +++ /dev/null @@ -1,24 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.transforms; - -public interface Converter { - String convert(String input); -} diff --git a/aai-resources/src/main/java/org/onap/aai/transforms/LowerHyphenToLowerCamelConverter.java b/aai-resources/src/main/java/org/onap/aai/transforms/LowerHyphenToLowerCamelConverter.java deleted file mode 100644 index b4baa0c..0000000 --- a/aai-resources/src/main/java/org/onap/aai/transforms/LowerHyphenToLowerCamelConverter.java +++ /dev/null @@ -1,80 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.transforms; - -/** - * <b>LowerHyphenToLowerCamelConverter</b> is the converter to use - * for converting from the lower hyphen to lower camel case - * <p> - * Examples: - * lower-test => lowerTest - * lower-Test => lowerTest - * lowerTest => lowerTest - * lower-test-val => lowerTestVal - * <p> - * - */ -public class LowerHyphenToLowerCamelConverter implements Converter { - - /** - * Converts the dash formatted string into a camel case string - * Ensure that the capitalization is not lost during this conversion - * <p> - * Loops through each character in the string - * checks if the current character is '-' and if it is then sets the - * boolean isPreviousCharDash to true and continues to the next iteration - * If the character is not '-', then checks if the previous character is dash - * If it is, then it will upper case the current character and appends to the builder - * Otherwise, it will just append the current character without any modification - * - * @param input the input string to convert to camel case - * @return a string that is converted to camel case - * if the input is null, then it returns null - */ - @Override - public String convert(String input) { - if(input == null){ - return null; - } - - int size = input.length(); - StringBuilder builder = new StringBuilder(size); - - boolean isPreviousCharDash = false; - - for(int index = 0; index < size; ++index){ - char ch = input.charAt(index); - - if(ch == '-'){ - isPreviousCharDash = true; - continue; - } - if(isPreviousCharDash){ - builder.append(Character.toUpperCase(ch)); - isPreviousCharDash = false; - } else{ - builder.append(ch); - } - } - - return builder.toString(); - } - -} diff --git a/aai-resources/src/main/java/org/onap/aai/transforms/MapTraverser.java b/aai-resources/src/main/java/org/onap/aai/transforms/MapTraverser.java deleted file mode 100644 index 9091998..0000000 --- a/aai-resources/src/main/java/org/onap/aai/transforms/MapTraverser.java +++ /dev/null @@ -1,86 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.transforms; - - -import joptsimple.internal.Objects; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class MapTraverser { - - private Converter converter; - - public MapTraverser(Converter converter){ - this.converter = converter; - } - - public Map<String, Object> convertKeys(Map<String, Object> map){ - - Objects.ensureNotNull(map); - - Map<String, Object> modifiedMap = new HashMap<String, Object>(); - convertKeys(map, modifiedMap); - - return modifiedMap; - } - - private Map<String, Object> convertKeys(Map<String, Object> original, Map<String, Object> modified){ - - for(Map.Entry<String, Object> entry : original.entrySet()){ - String key = entry.getKey(); - key = converter.convert(key); - Object value = entry.getValue(); - if(value instanceof Map){ - modified.put(key, convertKeys((Map<String, Object>)value, new HashMap<String, Object>())); - } else if(value instanceof List){ - modified.put(key, convertKeys((List<Object>) value)); - } else { - modified.put(key, value); - } - } - - return modified; - } - - public List<Object> convertKeys(List<Object> list){ - - List<Object> modifiedList = new ArrayList<Object>(); - if(list != null && list.size() > 0){ - - for(Object o : list){ - if(o instanceof Map){ - Map<String, Object> map = (Map<String, Object>) o; - modifiedList.add(convertKeys(map)); - } else if(o instanceof List){ - List<Object> l = (List<Object>) o; - modifiedList.add(convertKeys(l)); - } else { - modifiedList.add(o); - } - } - } - - return modifiedList; - } -} diff --git a/aai-resources/src/main/java/org/onap/aai/util/DataConversionHelper.java b/aai-resources/src/main/java/org/onap/aai/util/DataConversionHelper.java deleted file mode 100644 index 0fc9779..0000000 --- a/aai-resources/src/main/java/org/onap/aai/util/DataConversionHelper.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.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.onap.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.onap.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/onap/aai/util/JettyObfuscationConversionCommandLineUtil.java b/aai-resources/src/main/java/org/onap/aai/util/JettyObfuscationConversionCommandLineUtil.java deleted file mode 100644 index 8e1de14..0000000 --- a/aai-resources/src/main/java/org/onap/aai/util/JettyObfuscationConversionCommandLineUtil.java +++ /dev/null @@ -1,98 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.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.onap.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/onap/aai/rest/retired/V7V8NamedQueries.java b/aai-resources/src/main/java/org/onap/aai/util/PositiveNumValidator.java index 9a9c183..ee58f55 100644 --- a/aai-resources/src/main/java/org/onap/aai/rest/retired/V7V8NamedQueries.java +++ b/aai-resources/src/main/java/org/onap/aai/util/PositiveNumValidator.java @@ -17,11 +17,19 @@ * limitations under the License. * ============LICENSE_END========================================================= */ -package org.onap.aai.rest.retired; +package org.onap.aai.util; -import javax.ws.rs.Path; +import com.beust.jcommander.IParameterValidator; +import com.beust.jcommander.ParameterException; -@Path("{version: v[78]}/service-design-and-creation/named-queries") -public class V7V8NamedQueries extends RetiredConsumer { +public class PositiveNumValidator implements IParameterValidator { -} + @Override + public void validate(String name, String value) throws ParameterException { + int num = Integer.parseInt(value); + + if(num < 0) { + throw new ParameterException("Parameter " + name + " should be >= 0"); + } + } +}
\ No newline at end of file diff --git a/aai-resources/src/main/java/org/onap/aai/web/JerseyConfiguration.java b/aai-resources/src/main/java/org/onap/aai/web/JerseyConfiguration.java index 320c9c4..4cd09bf 100644 --- a/aai-resources/src/main/java/org/onap/aai/web/JerseyConfiguration.java +++ b/aai-resources/src/main/java/org/onap/aai/web/JerseyConfiguration.java @@ -21,11 +21,8 @@ package org.onap.aai.web; import org.glassfish.jersey.filter.LoggingFilter; import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.servlet.ServletProperties; import org.onap.aai.rest.*; -import org.onap.aai.rest.retired.V7V8Models; -import org.onap.aai.rest.retired.V7V8NamedQueries; -import org.onap.aai.rest.tools.ModelVersionTransformer; +import org.onap.aai.rest.bulk.BulkSingleTransactionConsumer; import org.onap.aai.rest.util.EchoResponse; import org.reflections.Reflections; import org.springframework.beans.factory.annotation.Autowired; @@ -34,7 +31,6 @@ import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; import javax.annotation.Priority; -import javax.ws.rs.ApplicationPath; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.ContainerResponseFilter; import java.util.List; @@ -43,7 +39,6 @@ import java.util.logging.Logger; import java.util.stream.Collectors; @Component -@ApplicationPath("/aai") public class JerseyConfiguration extends ResourceConfig { private static final Logger log = Logger.getLogger(JerseyConfiguration.class.getName()); @@ -60,19 +55,15 @@ public class JerseyConfiguration extends ResourceConfig { register(ExampleConsumer.class); register(BulkAddConsumer.class); register(BulkProcessConsumer.class); + register(BulkSingleTransactionConsumer.class); register(LegacyMoxyConsumer.class); register(URLFromVertexIdConsumer.class); - register(V7V8Models.class); - register(V7V8NamedQueries.class); - register(ModelVersionTransformer.class); //Request Filters registerFiltersForRequests(); // Response Filters registerFiltersForResponses(); - property(ServletProperties.FILTER_FORWARD_ON_404, true); - // Following registers the request headers and response headers // If the LoggingFilter second argument is set to true, it will print response value as well if ("true".equalsIgnoreCase(env.getProperty("aai.request.logging.enabled"))) { diff --git a/aai-resources/src/main/java/org/onap/aai/web/LocalHostAccessLog.java b/aai-resources/src/main/java/org/onap/aai/web/LocalHostAccessLog.java index 9d0aa9a..4bc3300 100644 --- a/aai-resources/src/main/java/org/onap/aai/web/LocalHostAccessLog.java +++ b/aai-resources/src/main/java/org/onap/aai/web/LocalHostAccessLog.java @@ -22,6 +22,8 @@ package org.onap.aai.web; import ch.qos.logback.access.jetty.RequestLogImpl; import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.server.handler.RequestLogHandler; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.jetty.JettyServerCustomizer; @@ -34,7 +36,11 @@ import java.util.Arrays; public class LocalHostAccessLog { @Bean - public EmbeddedServletContainerFactory jettyConfigBean(){ + public EmbeddedServletContainerFactory jettyConfigBean( + @Value("${jetty.threadPool.maxThreads:200}") final String maxThreads, + @Value("${jetty.threadPool.minThreads:8}") final String minThreads + ){ + JettyEmbeddedServletContainerFactory jef = new JettyEmbeddedServletContainerFactory(); jef.addServerCustomizers((JettyServerCustomizer) server -> { @@ -52,6 +58,10 @@ public class LocalHostAccessLog { requestLogHandler.setRequestLog(requestLogImpl); handlers.addHandler(requestLogHandler); server.setHandler(handlers); + + final QueuedThreadPool threadPool = server.getBean(QueuedThreadPool.class); + threadPool.setMaxThreads(Integer.valueOf(maxThreads)); + threadPool.setMinThreads(Integer.valueOf(minThreads)); }); return jef; } diff --git a/aai-resources/src/main/java/org/onap/aai/web/WebConfiguration.java b/aai-resources/src/main/java/org/onap/aai/web/WebConfiguration.java index 5984734..5300611 100644 --- a/aai-resources/src/main/java/org/onap/aai/web/WebConfiguration.java +++ b/aai-resources/src/main/java/org/onap/aai/web/WebConfiguration.java @@ -19,28 +19,28 @@ */ package org.onap.aai.web; -//import org.springframework.context.annotation.Bean; -//import org.springframework.context.annotation.Configuration; -//import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -//import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -// -//@Configuration -//public class WebConfiguration { -// -// @Bean -// public WebMvcConfigurerAdapter forwardToIndex() { -// return new WebMvcConfigurerAdapter() { -// @Override -// public void addViewControllers(ViewControllerRegistry registry) { -// registry.addViewController("/swagger").setViewName( -// "redirect:/swagger/index.html"); -// registry.addViewController("/swagger/").setViewName( -// "redirect:/swagger/index.html"); -// registry.addViewController("/docs").setViewName( -// "redirect:/docs/html/index.html"); -// registry.addViewController("/docs/").setViewName( -// "redirect:/docs/html/index.html"); -// } -// }; -// } -//} +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +@Configuration +public class WebConfiguration { + + @Bean + public WebMvcConfigurerAdapter forwardToIndex() { + return new WebMvcConfigurerAdapter() { + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/swagger").setViewName( + "redirect:/swagger/index.html"); + registry.addViewController("/swagger/").setViewName( + "redirect:/swagger/index.html"); + registry.addViewController("/docs").setViewName( + "redirect:/docs/html/index.html"); + registry.addViewController("/docs/").setViewName( + "redirect:/docs/html/index.html"); + } + }; + } +}
\ No newline at end of file |