diff options
author | Kajur, Harish (vk250x) <vk250x@att.com> | 2018-08-12 23:40:04 -0400 |
---|---|---|
committer | Kajur, Harish (vk250x) <vk250x@att.com> | 2018-08-13 02:49:05 -0400 |
commit | 538aad3add38a0ce4ef6ac25333d50bba7b05ac5 (patch) | |
tree | b0155c033b80bb6d6d316bd92cd5f280e4542e56 /aai-resources/src/main/java/org | |
parent | 96b7ed4bff9a2259f1f28f288caa6cc11c97db59 (diff) |
Update resources ms to use ingest library
Change the code to replace ModelIngestor
with the NodeIngestor and replace the EdgeRules
with the EdgeIngestor and EdgeSerializer
Edge Ingestor for getting the rules from json files
Edge Serializer for creating the edges between vertexes
Node Ingestor is responsible for the multiple oxm files
Issue-ID: AAI-1462
Change-Id: I555916911dc4076ac017173d63478b3b76b36e42
Signed-off-by: Kajur, Harish (vk250x) <vk250x@att.com>
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 |