diff options
94 files changed, 2465 insertions, 1982 deletions
diff --git a/aai-aaf-auth/pom.xml b/aai-aaf-auth/pom.xml index f0a95f51..4f50e48a 100644 --- a/aai-aaf-auth/pom.xml +++ b/aai-aaf-auth/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-parent</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> <relativePath>../aai-parent/pom.xml</relativePath> </parent> <artifactId>aai-aaf-auth</artifactId> diff --git a/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafAuthorizationFilter.java b/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafAuthorizationFilter.java index 485fa7e3..fb7a58e6 100644 --- a/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafAuthorizationFilter.java +++ b/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafAuthorizationFilter.java @@ -32,7 +32,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.onap.aai.aaf.auth.ResponseFormatter; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter; import org.springframework.context.annotation.Profile; @@ -59,7 +58,6 @@ public class AafAuthorizationFilter extends OrderedRequestContextFilter { private List<String> advancedKeywordsList; - @Autowired public AafAuthorizationFilter(GremlinFilter gremlinFilter, @Value("${permission.type}") String type, @Value("${permission.instance}") String instance, @Value("${advanced.keywords.list:}") String advancedKeys) { diff --git a/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafCertAuthorizationFilter.java b/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafCertAuthorizationFilter.java index 56799f1c..f19f4b8e 100644 --- a/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafCertAuthorizationFilter.java +++ b/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafCertAuthorizationFilter.java @@ -32,7 +32,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.onap.aai.aaf.auth.AafRequestFilter; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter; import org.springframework.context.annotation.Profile; @@ -60,7 +59,6 @@ public class AafCertAuthorizationFilter extends OrderedRequestContextFilter { private List<String> advancedKeywordsList; - @Autowired public AafCertAuthorizationFilter(@Value("${permission.type}") String type, @Value("${permission.instance}") String instance, @Value("${advanced.keywords.list:}") String advancedKeys, CadiProps cadiProps) { diff --git a/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafCertFilter.java b/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafCertFilter.java index e423dc0a..a3ce12b0 100644 --- a/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafCertFilter.java +++ b/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafCertFilter.java @@ -32,7 +32,6 @@ import org.onap.aaf.cadi.filter.CadiFilter; import org.onap.aai.aaf.auth.AafRequestFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter; import org.springframework.context.annotation.Profile; @@ -57,7 +56,6 @@ public class AafCertFilter extends OrderedRequestContextFilter { private final CadiProps cadiProps; - @Autowired public AafCertFilter(@Value("${aaf.userchain.pattern}") String aafUserChainPattern, CadiProps cadiProps) throws IOException, ServletException { diff --git a/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafFilter.java b/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafFilter.java index 5dbc2e7a..ae3a6ca6 100644 --- a/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafFilter.java +++ b/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/AafFilter.java @@ -32,7 +32,6 @@ import org.onap.aaf.cadi.filter.CadiFilter; import org.onap.aai.aaf.auth.ResponseFormatter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; @@ -49,7 +48,6 @@ public class AafFilter extends OrderedRequestContextFilter { private final CadiFilter cadiFilter; - @Autowired public AafFilter(CadiProps cadiProps) throws IOException, ServletException { cadiFilter = new CadiFilter(new PropAccess((level, element) -> { switch (level) { diff --git a/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/CadiProps.java b/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/CadiProps.java index 4bf9ea82..01b89148 100644 --- a/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/CadiProps.java +++ b/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/CadiProps.java @@ -30,7 +30,6 @@ import javax.annotation.PostConstruct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; @@ -46,7 +45,6 @@ public class CadiProps { private Properties cadiProperties; - @Autowired public CadiProps(@Value("${aaf.cadi.file:./resources/cadi.properties}") String filename) { cadiFileName = filename; cadiProperties = new Properties(); diff --git a/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/GremlinFilter.java b/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/GremlinFilter.java index dffa74ef..f800097f 100644 --- a/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/GremlinFilter.java +++ b/aai-aaf-auth/src/main/java/org/onap/aai/aaf/filters/GremlinFilter.java @@ -33,7 +33,6 @@ import org.apache.commons.io.IOUtils; import org.onap.aai.aaf.auth.ResponseFormatter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; @@ -54,7 +53,6 @@ public class GremlinFilter { private CadiProps cadiProps; - @Autowired public GremlinFilter(@Value("${permission.type}") String type, @Value("${permission.instance}") String instance, CadiProps cadiProps) { this.type = type; diff --git a/aai-annotations/pom.xml b/aai-annotations/pom.xml index cdc8e975..9718c8cf 100644 --- a/aai-annotations/pom.xml +++ b/aai-annotations/pom.xml @@ -27,7 +27,7 @@ <parent> <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-parent</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> <relativePath>../aai-parent/pom.xml</relativePath> </parent> <artifactId>aai-annotations</artifactId> diff --git a/aai-auth/pom.xml b/aai-auth/pom.xml index 85683d8c..b766ffe7 100644 --- a/aai-auth/pom.xml +++ b/aai-auth/pom.xml @@ -27,7 +27,7 @@ <parent> <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-parent</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> <relativePath>../aai-parent/pom.xml</relativePath> </parent> <artifactId>aai-auth</artifactId> diff --git a/aai-common-docker/aai-common-images/pom.xml b/aai-common-docker/aai-common-images/pom.xml index ed0a9c8f..a10bb127 100644 --- a/aai-common-docker/aai-common-images/pom.xml +++ b/aai-common-docker/aai-common-images/pom.xml @@ -25,11 +25,11 @@ <parent> <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-common-docker</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> </parent> <artifactId>aai-common-images</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> <packaging>pom</packaging> <name>aai-aai-common-images</name> <description>Contains dockerfiles for aai-common images (alpine and ubuntu based).</description> diff --git a/aai-common-docker/aai-haproxy-image/pom.xml b/aai-common-docker/aai-haproxy-image/pom.xml index 259c0fe1..bd2b3a45 100644 --- a/aai-common-docker/aai-haproxy-image/pom.xml +++ b/aai-common-docker/aai-haproxy-image/pom.xml @@ -25,11 +25,11 @@ <parent> <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-common-docker</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> </parent> <artifactId>aai-haproxy-image</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> <packaging>pom</packaging> <name>aai-aai-haproxy-image</name> <description>Contains dockerfiles for aai-haproxy image.</description> diff --git a/aai-common-docker/pom.xml b/aai-common-docker/pom.xml index 0a28f3e5..8aaa8c57 100644 --- a/aai-common-docker/pom.xml +++ b/aai-common-docker/pom.xml @@ -26,7 +26,7 @@ <parent> <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-parent</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> <relativePath>../aai-parent/pom.xml</relativePath> </parent> diff --git a/aai-core/pom.xml b/aai-core/pom.xml index aedc7b40..d2aed3a0 100644 --- a/aai-core/pom.xml +++ b/aai-core/pom.xml @@ -26,7 +26,7 @@ limitations under the License. <parent> <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-parent</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> <relativePath>../aai-parent/pom.xml</relativePath> </parent> <artifactId>aai-core</artifactId> @@ -152,14 +152,6 @@ limitations under the License. <version>2.0.0-oss</version> </dependency> <dependency> - <groupId>org.codehaus.jackson</groupId> - <artifactId>jackson-core-asl</artifactId> - </dependency> - <dependency> - <groupId>org.codehaus.jackson</groupId> - <artifactId>jackson-mapper-asl</artifactId> - </dependency> - <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> @@ -272,6 +264,7 @@ limitations under the License. <dependency> <groupId>org.apache.tinkerpop</groupId> <artifactId>gremlin-core</artifactId> + <version>${gremlin.version}</version> </dependency> <dependency> <groupId>org.apache.tinkerpop</groupId> @@ -388,6 +381,11 @@ limitations under the License. <artifactId>spring-jms</artifactId> </dependency> <dependency> + <groupId>javax.jms</groupId> + <artifactId>javax.jms-api</artifactId> + <version>2.0.1</version> + </dependency> + <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> </dependency> @@ -419,6 +417,11 @@ limitations under the License. <version>1.18.30</version> <scope>provided</scope> </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-configuration2</artifactId> + <version>2.7</version> + </dependency> </dependencies> <!-- Plugins and repositories --> diff --git a/aai-core/src/main/java/org/onap/aai/config/IntrospectionConfig.java b/aai-core/src/main/java/org/onap/aai/config/IntrospectionConfig.java index 2a4673c0..a3411076 100644 --- a/aai-core/src/main/java/org/onap/aai/config/IntrospectionConfig.java +++ b/aai-core/src/main/java/org/onap/aai/config/IntrospectionConfig.java @@ -22,10 +22,9 @@ package org.onap.aai.config; -import java.util.*; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.onap.aai.introspection.LoaderFactory; import org.onap.aai.introspection.MoxyLoader; import org.onap.aai.setup.SchemaVersion; import org.onap.aai.setup.SchemaVersions; @@ -37,7 +36,6 @@ import org.springframework.context.annotation.Import; @Import({ConfigConfiguration.class, SchemaServiceConfiguration.class, NodesConfiguration.class, EdgesConfiguration.class}) @Configuration - public class IntrospectionConfig { private Map<SchemaVersion, MoxyLoader> moxyInstanceMap = new ConcurrentHashMap<>(); @@ -46,11 +44,6 @@ public class IntrospectionConfig { NodesConfiguration nodesConfiguration; @Bean - public LoaderFactory loaderFactory(SchemaVersions schemaVersions) { - return new LoaderFactory(moxyLoaderInstance(schemaVersions)); - } - - @Bean public Map<SchemaVersion, MoxyLoader> moxyLoaderInstance(SchemaVersions schemaVersions) { for (SchemaVersion version : schemaVersions.getVersions()) { if (!moxyInstanceMap.containsKey(version)) { diff --git a/aai-core/src/main/java/org/onap/aai/config/SchemaConfiguration.java b/aai-core/src/main/java/org/onap/aai/config/SchemaConfiguration.java index 9247bc77..7547f4f7 100644 --- a/aai-core/src/main/java/org/onap/aai/config/SchemaConfiguration.java +++ b/aai-core/src/main/java/org/onap/aai/config/SchemaConfiguration.java @@ -25,10 +25,7 @@ package org.onap.aai.config; import org.onap.aai.edges.EdgeIngestor; import org.onap.aai.nodes.NodeIngestor; import org.onap.aai.serialization.db.EdgeSerializer; -import org.onap.aai.setup.AAIConfigTranslator; import org.onap.aai.setup.ConfigTranslator; -import org.onap.aai.setup.SchemaConfigVersions; -import org.onap.aai.setup.SchemaLocationsBean; import org.onap.aai.validation.CheckEverythingStrategy; import org.onap.aai.validation.SchemaErrorStrategy; import org.onap.aai.validation.nodes.DefaultDuplicateNodeDefinitionValidationModule; @@ -36,7 +33,10 @@ import org.onap.aai.validation.nodes.DuplicateNodeDefinitionValidationModule; import org.onap.aai.validation.nodes.NodeValidator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.*; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.PropertySource; @Import({NodesConfiguration.class, EdgesConfiguration.class}) @Configuration diff --git a/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraph.java b/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraph.java index 15f57c13..0db67860 100644 --- a/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraph.java +++ b/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraph.java @@ -25,7 +25,7 @@ package org.onap.aai.dbmap; import java.io.FileNotFoundException; import java.util.Properties; -import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.configuration2.Configuration; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.tinkerpop.gremlin.structure.Graph; import org.apache.tinkerpop.gremlin.structure.io.IoCore; @@ -101,7 +101,7 @@ public class AAIGraph { // Graph being opened by JanusGraphFactory is being placed in hashmap to be used later // These graphs shouldn't be closed until the application shutdown try { - PropertiesConfiguration propertiesConfiguration = new AAIGraphConfig.Builder(configPath) + Configuration propertiesConfiguration = new AAIGraphConfig.Builder(configPath) .forService(serviceName).withGraphType("realtime").buildConfiguration(); graph = JanusGraphFactory.open(propertiesConfiguration); diff --git a/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraphConfig.java b/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraphConfig.java index b6afe626..a1c3368a 100644 --- a/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraphConfig.java +++ b/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraphConfig.java @@ -25,8 +25,10 @@ import java.io.FileNotFoundException; import java.lang.management.ManagementFactory; import java.util.Objects; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.configuration2.PropertiesConfiguration; +import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder; +import org.apache.commons.configuration2.builder.fluent.Parameters; +import org.apache.commons.configuration2.ex.ConfigurationException; import org.apache.commons.lang3.StringUtils; import org.janusgraph.diskstorage.configuration.ConfigElement; @@ -59,10 +61,12 @@ public class AAIGraphConfig { throws ConfigurationException, FileNotFoundException { File file = new File(shortcutOrFile); if (file.exists()) { - PropertiesConfiguration propertiesConfiguration = new PropertiesConfiguration(); - propertiesConfiguration.setAutoSave(false); - propertiesConfiguration.load(shortcutOrFile); - return propertiesConfiguration; + FileBasedConfigurationBuilder<PropertiesConfiguration> builder = + new FileBasedConfigurationBuilder<PropertiesConfiguration>(PropertiesConfiguration.class) + .configure(new Parameters() + .properties() + .setFile(file)); + return builder.getConfiguration(); } else { throw new FileNotFoundException(shortcutOrFile); } diff --git a/aai-core/src/main/java/org/onap/aai/dbmap/InMemoryGraph.java b/aai-core/src/main/java/org/onap/aai/dbmap/InMemoryGraph.java index cca11c6d..6e4ce147 100644 --- a/aai-core/src/main/java/org/onap/aai/dbmap/InMemoryGraph.java +++ b/aai-core/src/main/java/org/onap/aai/dbmap/InMemoryGraph.java @@ -29,7 +29,6 @@ import org.apache.tinkerpop.gremlin.structure.io.IoCore; import org.janusgraph.core.JanusGraph; import org.janusgraph.core.JanusGraphFactory; import org.janusgraph.core.JanusGraphTransaction; -import org.janusgraph.core.schema.JanusGraphManagement; import org.onap.aai.dbgen.GraphSONPartialIO; import org.onap.aai.dbgen.SchemaGenerator; import org.onap.aai.logging.LogFormatTools; diff --git a/aai-core/src/main/java/org/onap/aai/introspection/LoaderFactory.java b/aai-core/src/main/java/org/onap/aai/introspection/LoaderFactory.java index dd1bc0f0..e35f5b92 100644 --- a/aai-core/src/main/java/org/onap/aai/introspection/LoaderFactory.java +++ b/aai-core/src/main/java/org/onap/aai/introspection/LoaderFactory.java @@ -23,27 +23,24 @@ package org.onap.aai.introspection; import java.util.Map; import org.onap.aai.setup.SchemaVersion; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +/** + * Factory method that grants access to the globally loaded schema versions. + * There is one {@link MoxyLoader} instance for each api version ({@link SchemaVersion}) that the AAI supports. + */ +@Component public class LoaderFactory { - @Autowired - public Map<SchemaVersion, MoxyLoader> moxyLoaderInstance; + private final Map<SchemaVersion, MoxyLoader> moxyLoaderInstance; public LoaderFactory(Map<SchemaVersion, MoxyLoader> moxyLoaderInstance) { this.moxyLoaderInstance = moxyLoaderInstance; } /** - * Creates a new Loader object. - * - * @param type - * the type - * @param version - * the version - * @param llBuilder - * the ll builder - * @return the loader + * Contrary to the naming, this method does not create a new loader, + * but rather returns an existing loader instance */ public Loader createLoaderForVersion(ModelType type, SchemaVersion version) { @@ -52,7 +49,6 @@ public class LoaderFactory { } return null; - } public Loader getLoaderStrategy(ModelType type, SchemaVersion version) { @@ -61,15 +57,9 @@ public class LoaderFactory { return getMoxyLoaderInstance().get(version); } return null; - } public Map<SchemaVersion, MoxyLoader> getMoxyLoaderInstance() { return moxyLoaderInstance; } - - public void setMoxyLoaderInstance(Map<SchemaVersion, MoxyLoader> moxyLoaderInstance) { - this.moxyLoaderInstance = moxyLoaderInstance; - } - } diff --git a/aai-core/src/main/java/org/onap/aai/introspection/MoxyLoader.java b/aai-core/src/main/java/org/onap/aai/introspection/MoxyLoader.java index 6099e1b4..ec3151b5 100644 --- a/aai-core/src/main/java/org/onap/aai/introspection/MoxyLoader.java +++ b/aai-core/src/main/java/org/onap/aai/introspection/MoxyLoader.java @@ -23,7 +23,7 @@ package org.onap.aai.introspection; import com.google.common.base.CaseFormat; import com.google.common.collect.ImmutableMap; -import java.io.*; +import java.io.StringReader; import java.util.HashSet; import java.util.Map; import java.util.Set; diff --git a/aai-core/src/main/java/org/onap/aai/kafka/AAIKafkaEventJMSConsumer.java b/aai-core/src/main/java/org/onap/aai/kafka/AAIKafkaEventJMSConsumer.java index 731f3dfc..67f6842e 100644 --- a/aai-core/src/main/java/org/onap/aai/kafka/AAIKafkaEventJMSConsumer.java +++ b/aai-core/src/main/java/org/onap/aai/kafka/AAIKafkaEventJMSConsumer.java @@ -20,116 +20,114 @@ * ============LICENSE_END========================================================= */ - package org.onap.aai.kafka; - - import java.util.Map; - import java.util.Objects; - - import javax.jms.JMSException; - import javax.jms.Message; - import javax.jms.MessageListener; - import javax.jms.TextMessage; - - import org.json.JSONException; - import org.json.JSONObject; - import org.onap.aai.aailog.logs.AaiDmaapMetricLog; - import org.onap.aai.exceptions.AAIException; - import org.onap.aai.logging.AaiElsErrorCode; - import org.onap.aai.logging.ErrorLogHelper; - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; - import org.slf4j.MDC; - import org.springframework.core.env.Environment; - import org.springframework.kafka.core.KafkaTemplate; - - public class AAIKafkaEventJMSConsumer implements MessageListener { - - private static final String EVENT_TOPIC = "event-topic"; - - private static final Logger LOGGER = LoggerFactory.getLogger(AAIKafkaEventJMSConsumer.class); - - private Environment environment; - private Map<String, String> mdcCopy; - private KafkaTemplate<String,String> kafkaTemplate; - - public AAIKafkaEventJMSConsumer(Environment environment,KafkaTemplate<String,String> kafkaTemplate) { - super(); - mdcCopy = MDC.getCopyOfContextMap(); - Objects.nonNull(environment); - this.environment = environment; - this.kafkaTemplate=kafkaTemplate; - } - - @Override - public void onMessage(Message message) { - - if (kafkaTemplate == null) { - return; - } - - String jsmMessageTxt = ""; - String aaiEvent = ""; - JSONObject aaiEventHeader; - JSONObject joPayload; - String transactionId = ""; - String serviceName = ""; - String eventName = ""; - String aaiElsErrorCode = AaiElsErrorCode.SUCCESS; - String errorDescription = ""; - - if (mdcCopy != null) { - MDC.setContextMap(mdcCopy); - } - - if (message instanceof TextMessage) { - AaiDmaapMetricLog metricLog = new AaiDmaapMetricLog(); - try { - jsmMessageTxt = ((TextMessage) message).getText(); - JSONObject jo = new JSONObject(jsmMessageTxt); - if (jo.has("aaiEventPayload")) { - joPayload = jo.getJSONObject("aaiEventPayload"); - aaiEvent = joPayload.toString(); - } else { - return; - } - if (jo.getString(EVENT_TOPIC) != null) { - eventName = jo.getString(EVENT_TOPIC); - } - if (joPayload.has("event-header")) { - try { - aaiEventHeader = joPayload.getJSONObject("event-header"); - if (aaiEventHeader.has("id")) { - transactionId = aaiEventHeader.get("id").toString(); - } - if (aaiEventHeader.has("entity-link")) { - serviceName = aaiEventHeader.get("entity-link").toString(); - } - } catch (JSONException jexc) { - // ignore, this is just used for logging - } - } - metricLog.pre(eventName, aaiEvent, transactionId, serviceName); - - - if ("AAI-EVENT".equals(eventName)) { - // restTemplate.exchange(baseUrl + endpoint, HttpMethod.POST, httpEntity, String.class); - kafkaTemplate.send(eventName,aaiEvent); - - } else { - LOGGER.error(String.format("%s|Event Topic invalid.", eventName)); - } - } catch (JMSException | JSONException e) { - aaiElsErrorCode = AaiElsErrorCode.DATA_ERROR; - errorDescription = e.getMessage(); - ErrorLogHelper.logException(new AAIException("AAI_7350")); - } catch (Exception e) { - aaiElsErrorCode = AaiElsErrorCode.AVAILABILITY_TIMEOUT_ERROR; - errorDescription = e.getMessage(); - ErrorLogHelper.logException(new AAIException("AAI_7304", jsmMessageTxt)); - } finally { - metricLog.post(aaiElsErrorCode, errorDescription); - } - } - } - } -
\ No newline at end of file +package org.onap.aai.kafka; + +import java.util.Map; + +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.TextMessage; + +import org.json.JSONException; +import org.json.JSONObject; +import org.onap.aai.aailog.logs.AaiDmaapMetricLog; +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.logging.AaiElsErrorCode; +import org.onap.aai.logging.ErrorLogHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.springframework.kafka.core.KafkaTemplate; + + +public class AAIKafkaEventJMSConsumer implements MessageListener { + + private static final String EVENT_TOPIC = "event-topic"; + + private static final Logger LOGGER = LoggerFactory.getLogger(AAIKafkaEventJMSConsumer.class); + + private Map<String, String> mdcCopy; + private final KafkaTemplate<String, String> kafkaTemplate; + + public AAIKafkaEventJMSConsumer(KafkaTemplate<String, String> kafkaTemplate) { + super(); + mdcCopy = MDC.getCopyOfContextMap(); + this.kafkaTemplate = kafkaTemplate; + } + + @Override + public void onMessage(Message message) { + + if (kafkaTemplate == null) { + return; + } + + String jmsMessageText = ""; + String aaiEvent = ""; + JSONObject aaiEventHeader; + JSONObject aaiEventPayload; + String transactionId = ""; + String serviceName = ""; + String topicName = ""; + String aaiElsErrorCode = AaiElsErrorCode.SUCCESS; + String errorDescription = ""; + + if (mdcCopy != null) { + MDC.setContextMap(mdcCopy); + } + + if (message instanceof TextMessage) { + AaiDmaapMetricLog metricLog = new AaiDmaapMetricLog(); + try { + jmsMessageText = ((TextMessage) message).getText(); + JSONObject jsonObject = new JSONObject(jmsMessageText); + if (jsonObject.has("aaiEventPayload")) { + aaiEventPayload = jsonObject.getJSONObject("aaiEventPayload"); + aaiEvent = aaiEventPayload.toString(); + } else { + return; + } + if (jsonObject.getString(EVENT_TOPIC) != null) { + topicName = jsonObject.getString(EVENT_TOPIC); + } + if (aaiEventPayload.has("event-header")) { + try { + aaiEventHeader = aaiEventPayload.getJSONObject("event-header"); + if (aaiEventHeader.has("id")) { + transactionId = aaiEventHeader.get("id").toString(); + } + if (aaiEventHeader.has("entity-link")) { + serviceName = aaiEventHeader.get("entity-link").toString(); + } + } catch (JSONException jexc) { + // ignore, this is just used for logging + } + } + metricLog.pre(topicName, aaiEvent, transactionId, serviceName); + + if ("AAI-EVENT".equals(topicName)) { + + kafkaTemplate.send(topicName, aaiEvent); + + } else { + LOGGER.error(String.format("%s|Event Topic invalid.", topicName)); + } + } catch (JMSException | JSONException e) { + aaiElsErrorCode = AaiElsErrorCode.DATA_ERROR; + errorDescription = e.getMessage(); + ErrorLogHelper.logException(new AAIException("AAI_7350")); + } catch (Exception e) { + e.printStackTrace(); + // LOGGER.error(); + LOGGER.error(e.getMessage()); + aaiElsErrorCode = AaiElsErrorCode.AVAILABILITY_TIMEOUT_ERROR; + errorDescription = e.getMessage(); + String errorMessage = String.format("Error processing message: %s, message payload: %s", e.getMessage(), jmsMessageText); + ErrorLogHelper.logException(new AAIException("AAI_7304", errorMessage)); + } finally { + metricLog.post(aaiElsErrorCode, errorDescription); + } + } + } +} diff --git a/aai-core/src/main/java/org/onap/aai/kafka/AAIKafkaEventJMSProducer.java b/aai-core/src/main/java/org/onap/aai/kafka/AAIKafkaEventJMSProducer.java index 00cf677f..4e948772 100644 --- a/aai-core/src/main/java/org/onap/aai/kafka/AAIKafkaEventJMSProducer.java +++ b/aai-core/src/main/java/org/onap/aai/kafka/AAIKafkaEventJMSProducer.java @@ -22,44 +22,27 @@ package org.onap.aai.kafka; -import org.apache.activemq.ActiveMQConnectionFactory; -import org.apache.activemq.command.ActiveMQQueue; import org.json.JSONObject; -import org.onap.aai.util.AAIConfig; -import org.springframework.jms.connection.CachingConnectionFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.jms.core.JmsTemplate; +import org.springframework.stereotype.Service; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor public class AAIKafkaEventJMSProducer implements MessageProducer { - private JmsTemplate jmsTemplate; + @Value("${aai.events.enabled:true}") private boolean eventsEnabled; + private final JmsTemplate jmsTemplate; - public AAIKafkaEventJMSProducer() { - if ("true".equals(AAIConfig.get("aai.jms.enable", "true"))) { - this.jmsTemplate = new JmsTemplate(); - String activeMqTcpUrl = System.getProperty("activemq.tcp.url", "tcp://localhost:61547"); - this.jmsTemplate - .setConnectionFactory(new CachingConnectionFactory(new ActiveMQConnectionFactory(activeMqTcpUrl))); - this.jmsTemplate.setDefaultDestination(new ActiveMQQueue("IN_QUEUE")); + public void sendMessageToDefaultDestination(String msg) { + if (eventsEnabled) { + jmsTemplate.convertAndSend(msg); } } public void sendMessageToDefaultDestination(JSONObject finalJson) { - if (jmsTemplate != null) { - jmsTemplate.convertAndSend(finalJson.toString()); - CachingConnectionFactory ccf = (CachingConnectionFactory) this.jmsTemplate.getConnectionFactory(); - if (ccf != null) { - ccf.destroy(); - } - } - } - - public void sendMessageToDefaultDestination(String msg) { - if (jmsTemplate != null) { - jmsTemplate.convertAndSend(msg); - CachingConnectionFactory ccf = (CachingConnectionFactory) this.jmsTemplate.getConnectionFactory(); - if (ccf != null) { - ccf.destroy(); - } - } + sendMessageToDefaultDestination(finalJson.toString()); } } diff --git a/aai-core/src/main/java/org/onap/aai/parsers/relationship/RelationshipToURI.java b/aai-core/src/main/java/org/onap/aai/parsers/relationship/RelationshipToURI.java index 8ed0fcb6..95b1517d 100644 --- a/aai-core/src/main/java/org/onap/aai/parsers/relationship/RelationshipToURI.java +++ b/aai-core/src/main/java/org/onap/aai/parsers/relationship/RelationshipToURI.java @@ -40,7 +40,10 @@ import org.onap.aai.edges.enums.EdgeType; import org.onap.aai.edges.exceptions.AmbiguousRuleChoiceException; import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException; import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.*; +import org.onap.aai.introspection.Introspector; +import org.onap.aai.introspection.IntrospectorFactory; +import org.onap.aai.introspection.Loader; +import org.onap.aai.introspection.ModelType; import org.onap.aai.introspection.exceptions.AAIUnknownObjectException; import org.onap.aai.parsers.exceptions.AAIIdentityMapParseException; import org.onap.aai.parsers.exceptions.AmbiguousMapAAIException; diff --git a/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationConfiguration.java b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationConfiguration.java index 7030cf7d..c1a4f2a7 100644 --- a/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationConfiguration.java +++ b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationConfiguration.java @@ -26,10 +26,9 @@ import org.onap.aai.restclient.RestClient; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -@Profile("pre-validation") @Configuration +@ConditionalOnProperty(name = "aai.notification.validation.enabled", havingValue = "true") public class ValidationConfiguration { @Bean(name = "validationRestClient") diff --git a/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationService.java b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationService.java index 939c8389..093062a9 100644 --- a/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationService.java +++ b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationService.java @@ -43,7 +43,7 @@ import javax.annotation.PostConstruct; import org.apache.http.conn.ConnectTimeoutException; import org.onap.aai.exceptions.AAIException; import org.onap.aai.introspection.Introspector; -import org.onap.aai.rest.ueb.NotificationEvent; +import org.onap.aai.rest.notification.NotificationEvent; import org.onap.aai.restclient.RestClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java b/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java index 198712b7..10f5cbaf 100644 --- a/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java +++ b/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java @@ -1,1074 +1,1074 @@ /** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * * Modifications Copyright © 2024 DEUTSCHE TELEKOM AG. - * ================================================================================ - * 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========================================================= +* ============LICENSE_START======================================================= +* org.onap.aai +* ================================================================================ +* Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. +* ================================================================================ +* * Modifications Copyright © 2024 DEUTSCHE TELEKOM AG. +* ================================================================================ +* 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.query.builder; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyTranslator; +import org.apache.tinkerpop.gremlin.process.traversal.Order; +import org.apache.tinkerpop.gremlin.process.traversal.P; +import org.apache.tinkerpop.gremlin.process.traversal.Path; +import org.apache.tinkerpop.gremlin.process.traversal.Pop; +import org.apache.tinkerpop.gremlin.process.traversal.Scope; +import org.apache.tinkerpop.gremlin.process.traversal.Traversal; +import org.apache.tinkerpop.gremlin.process.traversal.Traversal.Admin; +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.process.traversal.dsl.graph.__; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; +import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper; +import org.apache.tinkerpop.gremlin.structure.Direction; +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.edges.EdgeRule; +import org.onap.aai.edges.EdgeRuleQuery; +import org.onap.aai.edges.enums.EdgeType; +import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException; +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.introspection.Introspector; +import org.onap.aai.introspection.Loader; +import org.onap.aai.query.entities.PaginationResult; +import org.onap.aai.schema.enums.ObjectMetadata; +import org.onap.aai.schema.enums.PropertyMetadata; +import org.onap.aai.serialization.db.exceptions.NoEdgeRuleFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class GraphTraversalBuilder. */ +public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> { + + private static final Logger LOGGER = LoggerFactory.getLogger(GraphTraversalBuilder.class); + + private final GroovyTranslator groovyTranslator = GroovyTranslator.of("source"); + + protected GraphTraversal<Vertex, E> traversal = null; + protected Admin<Vertex, E> completeTraversal = null; + + protected QueryBuilder<E> containerQuery; + protected QueryBuilder<E> parentQuery; + + /** + * Instantiates a new graph traversal builder. + * + * @param loader the loader + */ + public GraphTraversalBuilder(Loader loader, GraphTraversalSource source) { + super(loader, source); + traversal = (GraphTraversal<Vertex, E>) __.<E>start(); + + } + + public GraphTraversalBuilder(Loader loader, GraphTraversalSource source, GraphTraversal<Vertex, E> traversal) { + super(loader, source); + this.traversal = traversal; + + } + + /** + * Instantiates a new graph traversal builder. + * + * @param loader the loader + * @param start the start + */ + public GraphTraversalBuilder(Loader loader, GraphTraversalSource source, Vertex start) { + super(loader, source, start); + + traversal = (GraphTraversal<Vertex, E>) __.__(start); + + } + + /** + * @{inheritDoc} + */ + @Override + public QueryBuilder<Vertex> getVerticesByProperty(String key, Object value) { + + // correct value call because the index is registered as an Integer + this.vertexHas(key, this.correctObjectType(value)); + stepIndex++; + return (QueryBuilder<Vertex>) this; + } + + @Override + protected void vertexHas(String key, Object value) { + traversal.has(key, value); + } + + @Override + protected void vertexHasNot(String key) { + traversal.hasNot(key); + } + + @Override + protected void vertexHas(String key) { + traversal.has(key); + } + + // TODO: Remove this once we test this - at this point i dont thib this is required + // because predicare is an object + /* + * @Override + * protected void vertexHas(final String key, final P<?> predicate) { + * traversal.has(key, predicate); + * } + */ + + /** + * @{inheritDoc} + */ + @Override + public QueryBuilder<Vertex> getVerticesByProperty(final String key, final List<?> values) { + + // this is because the index is registered as an Integer + List<Object> correctedValues = new ArrayList<>(); + for (Object item : values) { + correctedValues.add(this.correctObjectType(item)); + } + + this.vertexHas(key, P.within(correctedValues)); + stepIndex++; + return (QueryBuilder<Vertex>) this; + } + + /** + * @{inheritDoc} + */ + public QueryBuilder<Vertex> getVerticesByCommaSeperatedValue(String key, String value) { + ArrayList<String> values = new ArrayList<>(Arrays.asList(value.split(","))); + int size = values.size(); + for (int i = 0; i < size; i++) { + values.set(i, values.get(i).trim()); + } + this.vertexHas(key, P.within(values)); + + stepIndex++; + return (QueryBuilder<Vertex>) this; + } + + /** + * @{inheritDoc} + */ + @Override + public QueryBuilder<Vertex> getVerticesStartsWithProperty(String key, Object value) { + + // correct value call because the index is registered as an Integer + // TODO Check if this needs to be in QB and add these as internal + this.vertexHas(key, org.janusgraph.core.attribute.Text.textPrefix(value)); + + stepIndex++; + return (QueryBuilder<Vertex>) this; + } + + /** + * @{inheritDoc} + */ + @Override + public QueryBuilder<Vertex> getVerticesByProperty(String key) { + this.vertexHas(key); + stepIndex++; + return (QueryBuilder<Vertex>) this; + } + + /** + * @{inheritDoc} + */ + @Override + public QueryBuilder<Vertex> getVerticesExcludeByProperty(String key) { + this.vertexHasNot(key); + stepIndex++; + return (QueryBuilder<Vertex>) this; + } + + /** + * @{inheritDoc} + */ + @Override + public QueryBuilder<Vertex> getVerticesExcludeByProperty(String key, Object value) { + + // correct value call because the index is registered as an Integer + this.vertexHas(key, P.neq(this.correctObjectType(value))); + stepIndex++; + return (QueryBuilder<Vertex>) this; + } + + /** + * @{inheritDoc} + */ + @Override + public QueryBuilder<Vertex> getVerticesExcludeByProperty(final String key, final List<?> values) { + + // this is because the index is registered as an Integer + List<Object> correctedValues = new ArrayList<>(); + for (Object item : values) { + correctedValues.add(this.correctObjectType(item)); + } + + this.vertexHas(key, P.without(correctedValues)); + stepIndex++; + return (QueryBuilder<Vertex>) this; + } + + @Override + public QueryBuilder<Vertex> getVerticesGreaterThanProperty(final String key, Object value) { + this.vertexHas(key, P.gte(this.correctObjectType(value))); + + stepIndex++; + return (QueryBuilder<Vertex>) this; + } + + @Override + public QueryBuilder<Vertex> getVerticesLessThanProperty(final String key, Object value) { + this.vertexHas(key, P.lte(this.correctObjectType(value))); + + stepIndex++; + return (QueryBuilder<Vertex>) this; + } + + /** + * @{inheritDoc} + */ + @Override + public QueryBuilder<Vertex> getChildVerticesFromParent(String parentKey, String parentValue, String childType) { + traversal.has(parentKey, parentValue).has(AAIProperties.NODE_TYPE, childType); + stepIndex++; + return (QueryBuilder<Vertex>) this; + } + + /** + * @{inheritDoc} + */ + @Override + public QueryBuilder<Vertex> getTypedVerticesByMap(String type, Map<String, String> map) { + + for (Map.Entry<String, String> es : map.entrySet()) { + this.vertexHas(es.getKey(), es.getValue()); + stepIndex++; + } + traversal.has(AAIProperties.NODE_TYPE, type); + stepIndex++; + return (QueryBuilder<Vertex>) this; + } + + @Override + public QueryBuilder<Vertex> getVerticesByBooleanProperty(String key, Object value) { + + if (value != null && !"".equals(value)) { + boolean bValue = false; + + if (value instanceof String) {// "true" + bValue = Boolean.valueOf(value.toString()); + } else if (value instanceof Boolean) {// true + bValue = (Boolean) value; + } + + this.vertexHas(key, bValue); + stepIndex++; + } + return (QueryBuilder<Vertex>) this; + } + + /** + * @{inheritDoc} + */ + @Override + public QueryBuilder<Vertex> createKeyQuery(Introspector obj) { + Set<String> keys = obj.getKeys(); + Object val; + for (String key : keys) { + val = obj.getValue(key); + Optional<String> metadata = obj.getPropertyMetadata(key, PropertyMetadata.DB_ALIAS); + if (metadata.isPresent()) { + // use the db name for the field rather than the object model + key = metadata.get(); + } + if (val != null) { + // this is because the index is registered as an Integer + if (val.getClass().equals(Long.class)) { + this.vertexHas(key, Integer.valueOf(val.toString())); + } else { + this.vertexHas(key, val); + } + stepIndex++; + } + } + return (QueryBuilder<Vertex>) this; + } + + @Override + public QueryBuilder<Vertex> exactMatchQuery(Introspector obj) { + this.createKeyQuery(obj); + allPropertiesQuery(obj); + this.createContainerQuery(obj); + return (QueryBuilder<Vertex>) this; + } + + private void allPropertiesQuery(Introspector obj) { + Set<String> props = obj.getProperties(); + Set<String> keys = obj.getKeys(); + Object val; + for (String prop : props) { + if (obj.isSimpleType(prop) && !keys.contains(prop)) { + val = obj.getValue(prop); + if (val != null) { + Optional<String> metadata = obj.getPropertyMetadata(prop, PropertyMetadata.DB_ALIAS); + if (metadata.isPresent()) { + // use the db name for the field rather than the object model + prop = metadata.get(); + } + // this is because the index is registered as an Integer + if (val.getClass().equals(Long.class)) { + this.vertexHas(prop, Integer.valueOf(val.toString())); + } else { + this.vertexHas(prop, val); + } + stepIndex++; + } + } + } + } + + @Override + public QueryBuilder<Vertex> createContainerQuery(Introspector obj) { + String type = obj.getChildDBName(); + String abstractType = obj.getMetadata(ObjectMetadata.ABSTRACT); + if (abstractType != null) { + String[] inheritors = obj.getMetadata(ObjectMetadata.INHERITORS).split(","); + traversal.has(AAIProperties.NODE_TYPE, P.within(inheritors)); + } else { + traversal.has(AAIProperties.NODE_TYPE, type); + } + stepIndex++; + markContainer(); + return (QueryBuilder<Vertex>) this; + } + + /** + * @throws NoEdgeRuleFoundException + * @throws AAIException + * @{inheritDoc} + */ + @Override + public QueryBuilder<Vertex> createEdgeTraversal(EdgeType type, Introspector parent, Introspector child) + throws AAIException { + createTraversal(type, parent, child, false); + return (QueryBuilder<Vertex>) this; + + } + + @Override + public QueryBuilder<Vertex> createPrivateEdgeTraversal(EdgeType type, Introspector parent, Introspector child) + throws AAIException { + this.createTraversal(type, parent, child, true); + return (QueryBuilder<Vertex>) this; + } + + private void createTraversal(EdgeType type, Introspector parent, Introspector child, boolean isPrivateEdge) + throws AAIException { + String isAbstractType = parent.getMetadata(ObjectMetadata.ABSTRACT); + if ("true".equals(isAbstractType)) { + markParentBoundary(); + traversal.union(handleAbstractEdge(type, parent, child, isPrivateEdge)); + stepIndex++; + } else { + this.edgeQueryToVertex(type, parent, child, null); + } + } + + /** + * @{inheritDoc} + */ + @Override + public QueryBuilder<Vertex> createEdgeTraversalWithLabels(EdgeType type, Introspector out, Introspector in, + List<String> labels) throws AAIException { + this.edgeQueryToVertex(type, out, in, labels); + return (QueryBuilder<Vertex>) this; + } + + private Traversal<Vertex, Vertex>[] handleAbstractEdge(EdgeType type, Introspector abstractParent, + Introspector child, boolean isPrivateEdge) throws AAIException { + String childName = child.getDbName(); + String inheritorMetadata = abstractParent.getMetadata(ObjectMetadata.INHERITORS); + String[] inheritors = inheritorMetadata.split(","); + List<Traversal<Vertex, Vertex>> unionTraversals = new ArrayList<>(inheritors.length); + + for (int i = 0; i < inheritors.length; i++) { + String inheritor = inheritors[i]; + EdgeRuleQuery.Builder qB = new EdgeRuleQuery.Builder(inheritor, childName); + if (edgeRules.hasRule(qB.build())) { + Multimap<String, EdgeRule> rules = ArrayListMultimap.create(); + try { + rules = edgeRules.getRules(qB.edgeType(type).build()); + } catch (EdgeRuleNotFoundException e) { + throw new NoEdgeRuleFoundException(e); + } + + GraphTraversal<Vertex, Vertex> innerTraversal = __.start(); + + final List<String> inLabels = new ArrayList<>(); + final List<String> outLabels = new ArrayList<>(); + + rules.values().forEach(rule -> { + if (rule.getDirection().equals(Direction.IN)) { + inLabels.add(rule.getLabel()); + } else { + outLabels.add(rule.getLabel()); + } + }); + + if (inLabels.isEmpty() && !outLabels.isEmpty()) { + innerTraversal.out(outLabels.toArray(new String[outLabels.size()])); + } else if (outLabels.isEmpty() && !inLabels.isEmpty()) { + innerTraversal.in(inLabels.toArray(new String[inLabels.size()])); + } else { + innerTraversal.union(__.out(outLabels.toArray(new String[outLabels.size()])), + __.in(inLabels.toArray(new String[inLabels.size()]))); + } + + innerTraversal.has(AAIProperties.NODE_TYPE, childName); + unionTraversals.add(innerTraversal); + } + } + + return unionTraversals.toArray(new Traversal[unionTraversals.size()]); + } + + public QueryBuilder<Edge> getEdgesBetweenWithLabels(EdgeType type, String outNodeType, String inNodeType, + List<String> labels) throws AAIException { + Introspector outObj = loader.introspectorFromName(outNodeType); + Introspector inObj = loader.introspectorFromName(inNodeType); + this.edgeQuery(type, outObj, inObj, labels); + + return (QueryBuilder<Edge>) this; + } + + /** + * @{inheritDoc} + */ + @Override + public QueryBuilder<E> union(QueryBuilder... builder) { + GraphTraversal<Vertex, Vertex>[] traversals = new GraphTraversal[builder.length]; + for (int i = 0; i < builder.length; i++) { + traversals[i] = (GraphTraversal<Vertex, Vertex>) builder[i].getQuery(); + } + this.traversal.union(traversals); + stepIndex++; + + return this; + } + + /** + * @{inheritDoc} + */ + @Override + public QueryBuilder<E> where(QueryBuilder... builder) { + for (int i = 0; i < builder.length; i++) { + this.traversal.where((GraphTraversal<Vertex, Vertex>) builder[i].getQuery()); + stepIndex++; + } + + return this; + } + + /** + * @{inheritDoc} + */ + @Override + public QueryBuilder<E> or(QueryBuilder... builder) { + GraphTraversal<Vertex, Vertex>[] traversals = new GraphTraversal[builder.length]; + for (int i = 0; i < builder.length; i++) { + traversals[i] = (GraphTraversal<Vertex, Vertex>) builder[i].getQuery(); + } + this.traversal.or(traversals); + stepIndex++; + + return this; + } - package org.onap.aai.query.builder; - - import com.google.common.collect.ArrayListMultimap; - import com.google.common.collect.Multimap; - - import java.util.ArrayList; - import java.util.Arrays; - import java.util.Collections; - import java.util.List; - import java.util.Map; - import java.util.Optional; - import java.util.Set; - - import org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyTranslator; - import org.apache.tinkerpop.gremlin.process.traversal.Order; - import org.apache.tinkerpop.gremlin.process.traversal.P; - import org.apache.tinkerpop.gremlin.process.traversal.Path; - import org.apache.tinkerpop.gremlin.process.traversal.Pop; - import org.apache.tinkerpop.gremlin.process.traversal.Scope; - import org.apache.tinkerpop.gremlin.process.traversal.Traversal; - import org.apache.tinkerpop.gremlin.process.traversal.Traversal.Admin; - 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.process.traversal.dsl.graph.__; - import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; - import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper; - import org.apache.tinkerpop.gremlin.structure.Direction; - 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.edges.EdgeRule; - import org.onap.aai.edges.EdgeRuleQuery; - import org.onap.aai.edges.enums.EdgeType; - import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException; - import org.onap.aai.exceptions.AAIException; - import org.onap.aai.introspection.Introspector; - import org.onap.aai.introspection.Loader; - import org.onap.aai.query.entities.PaginationResult; - import org.onap.aai.schema.enums.ObjectMetadata; - import org.onap.aai.schema.enums.PropertyMetadata; - import org.onap.aai.serialization.db.exceptions.NoEdgeRuleFoundException; - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; - - /** - * The Class GraphTraversalBuilder. - */ - public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> { - - private static final Logger LOGGER = LoggerFactory.getLogger(GraphTraversalBuilder.class); - - private final GroovyTranslator groovyTranslator = GroovyTranslator.of("source"); - - protected GraphTraversal<Vertex, E> traversal = null; - protected Admin<Vertex, E> completeTraversal = null; - - protected QueryBuilder<E> containerQuery; - protected QueryBuilder<E> parentQuery; - - /** - * Instantiates a new graph traversal builder. - * - * @param loader the loader - */ - public GraphTraversalBuilder(Loader loader, GraphTraversalSource source) { - super(loader, source); - traversal = (GraphTraversal<Vertex, E>) __.<E>start(); - - } - - public GraphTraversalBuilder(Loader loader, GraphTraversalSource source, GraphTraversal<Vertex, E> traversal) { - super(loader, source); - this.traversal = traversal; - - } - - /** - * Instantiates a new graph traversal builder. - * - * @param loader the loader - * @param start the start - */ - public GraphTraversalBuilder(Loader loader, GraphTraversalSource source, Vertex start) { - super(loader, source, start); - - traversal = (GraphTraversal<Vertex, E>) __.__(start); - - } - - /** - * @{inheritDoc} - */ - @Override - public QueryBuilder<Vertex> getVerticesByProperty(String key, Object value) { - - // correct value call because the index is registered as an Integer - this.vertexHas(key, this.correctObjectType(value)); - stepIndex++; - return (QueryBuilder<Vertex>) this; - } - - @Override - protected void vertexHas(String key, Object value) { - traversal.has(key, value); - } - - @Override - protected void vertexHasNot(String key) { - traversal.hasNot(key); - } - - @Override - protected void vertexHas(String key) { - traversal.has(key); - } - - // TODO: Remove this once we test this - at this point i dont thib this is required - // because predicare is an object - /* - * @Override - * protected void vertexHas(final String key, final P<?> predicate) { - * traversal.has(key, predicate); - * } - */ - - /** - * @{inheritDoc} - */ - @Override - public QueryBuilder<Vertex> getVerticesByProperty(final String key, final List<?> values) { - - // this is because the index is registered as an Integer - List<Object> correctedValues = new ArrayList<>(); - for (Object item : values) { - correctedValues.add(this.correctObjectType(item)); - } - - this.vertexHas(key, P.within(correctedValues)); - stepIndex++; - return (QueryBuilder<Vertex>) this; - } - - /** - * @{inheritDoc} - */ - public QueryBuilder<Vertex> getVerticesByCommaSeperatedValue(String key, String value) { - ArrayList<String> values = new ArrayList<>(Arrays.asList(value.split(","))); - int size = values.size(); - for (int i = 0; i < size; i++) { - values.set(i, values.get(i).trim()); - } - this.vertexHas(key, P.within(values)); - - stepIndex++; - return (QueryBuilder<Vertex>) this; - } - - /** - * @{inheritDoc} - */ - @Override - public QueryBuilder<Vertex> getVerticesStartsWithProperty(String key, Object value) { - - // correct value call because the index is registered as an Integer - // TODO Check if this needs to be in QB and add these as internal - this.vertexHas(key, org.janusgraph.core.attribute.Text.textPrefix(value)); - - stepIndex++; - return (QueryBuilder<Vertex>) this; - } - - /** - * @{inheritDoc} - */ - @Override - public QueryBuilder<Vertex> getVerticesByProperty(String key) { - this.vertexHas(key); - stepIndex++; - return (QueryBuilder<Vertex>) this; - } - - /** - * @{inheritDoc} - */ - @Override - public QueryBuilder<Vertex> getVerticesExcludeByProperty(String key) { - this.vertexHasNot(key); - stepIndex++; - return (QueryBuilder<Vertex>) this; - } - - /** - * @{inheritDoc} - */ - @Override - public QueryBuilder<Vertex> getVerticesExcludeByProperty(String key, Object value) { - - // correct value call because the index is registered as an Integer - this.vertexHas(key, P.neq(this.correctObjectType(value))); - stepIndex++; - return (QueryBuilder<Vertex>) this; - } - - /** - * @{inheritDoc} - */ - @Override - public QueryBuilder<Vertex> getVerticesExcludeByProperty(final String key, final List<?> values) { - - // this is because the index is registered as an Integer - List<Object> correctedValues = new ArrayList<>(); - for (Object item : values) { - correctedValues.add(this.correctObjectType(item)); - } - - this.vertexHas(key, P.without(correctedValues)); - stepIndex++; - return (QueryBuilder<Vertex>) this; - } - - @Override - public QueryBuilder<Vertex> getVerticesGreaterThanProperty(final String key, Object value) { - this.vertexHas(key, P.gte(this.correctObjectType(value))); - - stepIndex++; - return (QueryBuilder<Vertex>) this; - } - - @Override - public QueryBuilder<Vertex> getVerticesLessThanProperty(final String key, Object value) { - this.vertexHas(key, P.lte(this.correctObjectType(value))); - - stepIndex++; - return (QueryBuilder<Vertex>) this; - } - - /** - * @{inheritDoc} - */ - @Override - public QueryBuilder<Vertex> getChildVerticesFromParent(String parentKey, String parentValue, String childType) { - traversal.has(parentKey, parentValue).has(AAIProperties.NODE_TYPE, childType); - stepIndex++; - return (QueryBuilder<Vertex>) this; - } - - /** - * @{inheritDoc} - */ - @Override - public QueryBuilder<Vertex> getTypedVerticesByMap(String type, Map<String, String> map) { - - for (Map.Entry<String, String> es : map.entrySet()) { - this.vertexHas(es.getKey(), es.getValue()); - stepIndex++; - } - traversal.has(AAIProperties.NODE_TYPE, type); - stepIndex++; - return (QueryBuilder<Vertex>) this; - } - - @Override - public QueryBuilder<Vertex> getVerticesByBooleanProperty(String key, Object value) { - - if (value != null && !"".equals(value)) { - boolean bValue = false; - - if (value instanceof String) {// "true" - bValue = Boolean.valueOf(value.toString()); - } else if (value instanceof Boolean) {// true - bValue = (Boolean) value; - } - - this.vertexHas(key, bValue); - stepIndex++; - } - return (QueryBuilder<Vertex>) this; - } - - /** - * @{inheritDoc} - */ - @Override - public QueryBuilder<Vertex> createKeyQuery(Introspector obj) { - Set<String> keys = obj.getKeys(); - Object val; - for (String key : keys) { - val = obj.getValue(key); - Optional<String> metadata = obj.getPropertyMetadata(key, PropertyMetadata.DB_ALIAS); - if (metadata.isPresent()) { - // use the db name for the field rather than the object model - key = metadata.get(); - } - if (val != null) { - // this is because the index is registered as an Integer - if (val.getClass().equals(Long.class)) { - this.vertexHas(key, Integer.valueOf(val.toString())); - } else { - this.vertexHas(key, val); - } - stepIndex++; - } - } - return (QueryBuilder<Vertex>) this; - } - - @Override - public QueryBuilder<Vertex> exactMatchQuery(Introspector obj) { - this.createKeyQuery(obj); - allPropertiesQuery(obj); - this.createContainerQuery(obj); - return (QueryBuilder<Vertex>) this; - } - - private void allPropertiesQuery(Introspector obj) { - Set<String> props = obj.getProperties(); - Set<String> keys = obj.getKeys(); - Object val; - for (String prop : props) { - if (obj.isSimpleType(prop) && !keys.contains(prop)) { - val = obj.getValue(prop); - if (val != null) { - Optional<String> metadata = obj.getPropertyMetadata(prop, PropertyMetadata.DB_ALIAS); - if (metadata.isPresent()) { - // use the db name for the field rather than the object model - prop = metadata.get(); - } - // this is because the index is registered as an Integer - if (val.getClass().equals(Long.class)) { - this.vertexHas(prop, Integer.valueOf(val.toString())); - } else { - this.vertexHas(prop, val); - } - stepIndex++; - } - } - } - } - - @Override - public QueryBuilder<Vertex> createContainerQuery(Introspector obj) { - String type = obj.getChildDBName(); - String abstractType = obj.getMetadata(ObjectMetadata.ABSTRACT); - if (abstractType != null) { - String[] inheritors = obj.getMetadata(ObjectMetadata.INHERITORS).split(","); - traversal.has(AAIProperties.NODE_TYPE, P.within(inheritors)); - } else { - traversal.has(AAIProperties.NODE_TYPE, type); - } - stepIndex++; - markContainer(); - return (QueryBuilder<Vertex>) this; - } - - /** - * @throws NoEdgeRuleFoundException - * @throws AAIException - * @{inheritDoc} - */ - @Override - public QueryBuilder<Vertex> createEdgeTraversal(EdgeType type, Introspector parent, Introspector child) - throws AAIException { - createTraversal(type, parent, child, false); - return (QueryBuilder<Vertex>) this; - - } - - @Override - public QueryBuilder<Vertex> createPrivateEdgeTraversal(EdgeType type, Introspector parent, Introspector child) - throws AAIException { - this.createTraversal(type, parent, child, true); - return (QueryBuilder<Vertex>) this; - } - - private void createTraversal(EdgeType type, Introspector parent, Introspector child, boolean isPrivateEdge) - throws AAIException { - String isAbstractType = parent.getMetadata(ObjectMetadata.ABSTRACT); - if ("true".equals(isAbstractType)) { - markParentBoundary(); - traversal.union(handleAbstractEdge(type, parent, child, isPrivateEdge)); - stepIndex++; - } else { - this.edgeQueryToVertex(type, parent, child, null); - } - } - - /** - * @{inheritDoc} - */ - @Override - public QueryBuilder<Vertex> createEdgeTraversalWithLabels(EdgeType type, Introspector out, Introspector in, - List<String> labels) throws AAIException { - this.edgeQueryToVertex(type, out, in, labels); - return (QueryBuilder<Vertex>) this; - } - - private Traversal<Vertex, Vertex>[] handleAbstractEdge(EdgeType type, Introspector abstractParent, - Introspector child, boolean isPrivateEdge) throws AAIException { - String childName = child.getDbName(); - String inheritorMetadata = abstractParent.getMetadata(ObjectMetadata.INHERITORS); - String[] inheritors = inheritorMetadata.split(","); - List<Traversal<Vertex, Vertex>> unionTraversals = new ArrayList<>(inheritors.length); - - for (int i = 0; i < inheritors.length; i++) { - String inheritor = inheritors[i]; - EdgeRuleQuery.Builder qB = new EdgeRuleQuery.Builder(inheritor, childName); - if (edgeRules.hasRule(qB.build())) { - Multimap<String, EdgeRule> rules = ArrayListMultimap.create(); - try { - rules = edgeRules.getRules(qB.edgeType(type).build()); - } catch (EdgeRuleNotFoundException e) { - throw new NoEdgeRuleFoundException(e); - } - - GraphTraversal<Vertex, Vertex> innerTraversal = __.start(); - - final List<String> inLabels = new ArrayList<>(); - final List<String> outLabels = new ArrayList<>(); - - rules.values().forEach(rule -> { - if (rule.getDirection().equals(Direction.IN)) { - inLabels.add(rule.getLabel()); - } else { - outLabels.add(rule.getLabel()); - } - }); - - if (inLabels.isEmpty() && !outLabels.isEmpty()) { - innerTraversal.out(outLabels.toArray(new String[outLabels.size()])); - } else if (outLabels.isEmpty() && !inLabels.isEmpty()) { - innerTraversal.in(inLabels.toArray(new String[inLabels.size()])); - } else { - innerTraversal.union(__.out(outLabels.toArray(new String[outLabels.size()])), - __.in(inLabels.toArray(new String[inLabels.size()]))); - } - - innerTraversal.has(AAIProperties.NODE_TYPE, childName); - unionTraversals.add(innerTraversal); - } - } - - return unionTraversals.toArray(new Traversal[unionTraversals.size()]); - } - - public QueryBuilder<Edge> getEdgesBetweenWithLabels(EdgeType type, String outNodeType, String inNodeType, - List<String> labels) throws AAIException { - Introspector outObj = loader.introspectorFromName(outNodeType); - Introspector inObj = loader.introspectorFromName(inNodeType); - this.edgeQuery(type, outObj, inObj, labels); - - return (QueryBuilder<Edge>) this; - } - - /** - * @{inheritDoc} - */ - @Override - public QueryBuilder<E> union(QueryBuilder... builder) { - GraphTraversal<Vertex, Vertex>[] traversals = new GraphTraversal[builder.length]; - for (int i = 0; i < builder.length; i++) { - traversals[i] = (GraphTraversal<Vertex, Vertex>) builder[i].getQuery(); - } - this.traversal.union(traversals); - stepIndex++; - - return this; - } - - /** - * @{inheritDoc} - */ - @Override - public QueryBuilder<E> where(QueryBuilder... builder) { - for (int i = 0; i < builder.length; i++) { - this.traversal.where((GraphTraversal<Vertex, Vertex>) builder[i].getQuery()); - stepIndex++; - } - - return this; - } - - /** - * @{inheritDoc} - */ - @Override - public QueryBuilder<E> or(QueryBuilder... builder) { - GraphTraversal<Vertex, Vertex>[] traversals = new GraphTraversal[builder.length]; - for (int i = 0; i < builder.length; i++) { - traversals[i] = (GraphTraversal<Vertex, Vertex>) builder[i].getQuery(); - } - this.traversal.or(traversals); - stepIndex++; - - return this; - } - - @Override - public QueryBuilder<E> store(String name) { - - this.traversal.store(name); - stepIndex++; - - return this; - } - - @Override - public QueryBuilder<E> cap(String name) { - this.traversal.cap(name); - stepIndex++; - - return this; - } - - @Override - public QueryBuilder<E> unfold() { - this.traversal.unfold(); - stepIndex++; - - return this; - } - - @Override - public QueryBuilder<E> dedup() { - - this.traversal.dedup(); - stepIndex++; - - return this; - } - - @Override - public QueryBuilder<E> emit() { - - this.traversal.emit(); - stepIndex++; - - return this; - - } - - @Override - public QueryBuilder<E> repeat(QueryBuilder<E> builder) { - - this.traversal.repeat((GraphTraversal<Vertex, E>) builder.getQuery()); - stepIndex++; - - return this; - } - - @Override - public QueryBuilder<E> until(QueryBuilder<E> builder) { - this.traversal.until((GraphTraversal<Vertex, E>) builder.getQuery()); - stepIndex++; - - return this; - } - - @Override - public QueryBuilder<E> groupCount() { - this.traversal.groupCount(); - stepIndex++; - - return this; - } - - @Override - public QueryBuilder<E> both() { - this.traversal.both(); - stepIndex++; - - return this; - } - - @Override - public QueryBuilder<Tree> tree() { - - this.traversal.tree(); - stepIndex++; - - return (QueryBuilder<Tree>) this; - } - - @Override - public QueryBuilder<E> by(String name) { - this.traversal.by(name); - stepIndex++; - - return this; - } + @Override + public QueryBuilder<E> store(String name) { - @Override - public QueryBuilder<E> valueMap() { - this.traversal.valueMap(); - stepIndex++; - - return this; - } - - @Override - public QueryBuilder<E> valueMap(String... names) { - this.traversal.valueMap(names); - stepIndex++; - - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public QueryBuilder<E> simplePath() { - this.traversal.simplePath(); - stepIndex++; - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public QueryBuilder<Path> path() { - this.traversal.path(); - stepIndex++; - return (QueryBuilder<Path>) this; - } - - @Override - public QueryBuilder<Edge> outE() { - this.traversal.outE(); - stepIndex++; - return (QueryBuilder<Edge>) this; - } - - @Override - public QueryBuilder<Edge> inE() { - this.traversal.inE(); - stepIndex++; - return (QueryBuilder<Edge>) this; - } - - @Override - public QueryBuilder<Vertex> outV() { - this.traversal.outV(); - stepIndex++; - return (QueryBuilder<Vertex>) this; - } - - @Override - public QueryBuilder<Vertex> inV() { - this.traversal.inV(); - stepIndex++; - return (QueryBuilder<Vertex>) this; - } - - @Override - public QueryBuilder<E> as(String name) { - this.traversal.as(name); - - stepIndex++; - return this; - } - - @Override - public QueryBuilder<E> not(QueryBuilder<E> builder) { - this.traversal.not(builder.getQuery()); - - stepIndex++; - return this; - } - - @Override - public QueryBuilder<E> select(String name) { - this.traversal.select(name); - - stepIndex++; - - return this; - } - - @Override - public QueryBuilder<E> select(Pop pop, String name) { - this.traversal.select(pop, name); - - stepIndex++; - - return this; - } - - @Override - public QueryBuilder<E> select(String... names) { - if (names.length == 1) { - this.traversal.select(names[0]); - } else if (names.length == 2) { - this.traversal.select(names[0], names[1]); - } else if (names.length > 2) { - String[] otherNames = Arrays.copyOfRange(names, 2, names.length); - this.traversal.select(names[0], names[1], otherNames); - } - - stepIndex++; - - return this; - } - - /** - * Edge query. - * - * @param outObj the out type - * @param inObj the in type - * @throws NoEdgeRuleFoundException - * @throws AAIException - */ - private void edgeQueryToVertex(EdgeType type, Introspector outObj, Introspector inObj, List<String> labels) - throws AAIException { - String outType = outObj.getDbName(); - String inType = inObj.getDbName(); - - if (outObj.isContainer()) { - outType = outObj.getChildDBName(); - } - if (inObj.isContainer()) { - inType = inObj.getChildDBName(); - } - markParentBoundary(); - Multimap<String, EdgeRule> rules = ArrayListMultimap.create(); - EdgeRuleQuery.Builder qB = new EdgeRuleQuery.Builder(outType, inType).edgeType(type); - - if (labels == null) { - try { - rules.putAll(edgeRules.getRules(qB.build())); - } catch (EdgeRuleNotFoundException e) { - // is ok per original functioning of this section - // TODO add "best try" sort of flag to the EdgeRuleQuery - // to indicate if the exception should be thrown or not - } - } else { - for (String label : labels) { - try { - rules.putAll(edgeRules.getRules(qB.label(label).build())); - } catch (EdgeRuleNotFoundException e) { - throw new NoEdgeRuleFoundException(e); - } - } - if (rules.isEmpty()) { - throw new NoEdgeRuleFoundException( - "No edge rules found for " + outType + " and " + inType + " of type " + type.toString()); - } - } - - final List<String> inLabels = new ArrayList<>(); - final List<String> outLabels = new ArrayList<>(); - - for (EdgeRule rule : rules.values()) { - if (labels != null && !labels.contains(rule.getLabel())) { - return; - } else { - if (Direction.IN.equals(rule.getDirection())) { - inLabels.add(rule.getLabel()); - } else { - outLabels.add(rule.getLabel()); - } - } - } - - if (inLabels.isEmpty() && !outLabels.isEmpty()) { - traversal.out(outLabels.toArray(new String[outLabels.size()])); - } else if (outLabels.isEmpty() && !inLabels.isEmpty()) { - traversal.in(inLabels.toArray(new String[inLabels.size()])); - } else { - traversal.union(__.out(outLabels.toArray(new String[outLabels.size()])), - __.in(inLabels.toArray(new String[inLabels.size()]))); - } - - stepIndex++; - - this.createContainerQuery(inObj); - - } - - /** - * Edge query. - * - * @param outObj the out type - * @param inObj the in type - * @throws NoEdgeRuleFoundException - * @throws AAIException - */ - private void edgeQuery(EdgeType type, Introspector outObj, Introspector inObj, List<String> labels) - throws AAIException { - String outType = outObj.getDbName(); - String inType = inObj.getDbName(); - - if (outObj.isContainer()) { - outType = outObj.getChildDBName(); - } - if (inObj.isContainer()) { - inType = inObj.getChildDBName(); - } - - markParentBoundary(); - Multimap<String, EdgeRule> rules = ArrayListMultimap.create(); - EdgeRuleQuery.Builder qB = new EdgeRuleQuery.Builder(outType, inType).edgeType(type); - - try { - if (labels == null) { - rules.putAll(edgeRules.getRules(qB.build())); - } else { - for (String label : labels) { - rules.putAll(edgeRules.getRules(qB.label(label).build())); - } - } - } catch (EdgeRuleNotFoundException e) { - throw new NoEdgeRuleFoundException(e); - } - - final List<String> inLabels = new ArrayList<>(); - final List<String> outLabels = new ArrayList<>(); - - for (EdgeRule rule : rules.values()) { - if (labels != null && !labels.contains(rule.getLabel())) { - return; - } else { - if (Direction.IN.equals(rule.getDirection())) { - inLabels.add(rule.getLabel()); - } else { - outLabels.add(rule.getLabel()); - } - } - } - - if (inLabels.isEmpty() && !outLabels.isEmpty()) { - traversal.outE(outLabels.toArray(new String[outLabels.size()])); - } else if (outLabels.isEmpty() && !inLabels.isEmpty()) { - traversal.inE(inLabels.toArray(new String[inLabels.size()])); - } else { - traversal.union(__.outE(outLabels.toArray(new String[outLabels.size()])), - __.inE(inLabels.toArray(new String[inLabels.size()]))); - } - } - - @Override - public QueryBuilder<E> limit(long amount) { - traversal.limit(amount); - return this; - } - - /** - * @{inheritDoc} - */ - @Override - public <E2> E2 getQuery() { - return (E2) this.traversal; - } - - /** - * @{inheritDoc} - */ - @Override - public QueryBuilder<E> getParentQuery() { - return this.parentQuery != null - ? this.parentQuery - : cloneQueryAtStep(parentStepIndex); - } - - @Override - public QueryBuilder<E> getContainerQuery() { - - if (this.parentStepIndex == 0) { - return removeQueryStepsBetween(0, containerStepIndex); - } else { - return this.containerQuery; - } - } - - /** - * @{inheritDoc} - */ - @Override - public void markParentBoundary() { - this.parentQuery = cloneQueryAtStep(stepIndex); - parentStepIndex = stepIndex; - } - - @Override - public void markContainer() { - this.containerQuery = cloneQueryAtStep(stepIndex); - containerStepIndex = stepIndex; - } - - /** - * @{inheritDoc} - */ - @Override - public Vertex getStart() { - return this.start; - } - - protected int getParentStepIndex() { - return parentStepIndex; - } - - protected int getContainerStepIndex() { - return containerStepIndex; - } - - protected int getStepIndex() { - return stepIndex; - } - - /** - * end is exclusive - * - * @param start - * @param end - * @return - */ - protected abstract QueryBuilder<E> removeQueryStepsBetween(int start, int end); - - protected void executeQuery() { - - Admin<Vertex, Vertex> admin; - if (start != null) { - this.completeTraversal = traversal.asAdmin(); - } else { - boolean queryLoggingEnabled = false; - if(queryLoggingEnabled) { - String query = groovyTranslator.translate(traversal.asAdmin().getBytecode()); - LOGGER.info("Query: {}", query); - } - - admin = source.V().asAdmin(); - TraversalHelper.insertTraversal(admin.getEndStep(), traversal.asAdmin(), admin); - - this.completeTraversal = (Admin<Vertex, E>) admin; - - } - - } - - @Override - public boolean hasNext() { - if (this.completeTraversal == null) { - executeQuery(); - } - - return this.completeTraversal.hasNext(); - } - - @Override - public E next() { - if (this.completeTraversal == null) { - executeQuery(); - } - - return this.completeTraversal.next(); - } - - @Override - public List<E> toList() { - if (this.completeTraversal == null) { - executeQuery(); - } - return this.completeTraversal.toList(); - } - - @Override - public QueryBuilder<E> sort(Sort sort) { - Order order = sort.getDirection() == Sort.Direction.ASC ? Order.asc : Order.desc; - traversal.order().by(sort.getProperty(), order); - stepIndex++; - return this; - } - - public PaginationResult<E> toPaginationResult(Pageable pageable) { - int page = pageable.getPage(); - int pageSize = pageable.getPageSize(); - if(pageable.isIncludeTotalCount()) { - return paginateWithTotalCount(page, pageSize); - } else { - return paginateWithoutTotalCount(page, pageSize); - } - } - - private PaginationResult<E> paginateWithoutTotalCount(int page, int pageSize) { - int startIndex = page * pageSize; - traversal.range(startIndex, startIndex + pageSize); - - if (this.completeTraversal == null) { - executeQuery(); - } - return completeTraversal.hasNext() - ? new PaginationResult<E>(completeTraversal.toList()) - : new PaginationResult<E>(Collections.emptyList()); - } - - private PaginationResult<E> paginateWithTotalCount(int page, int pageSize) { + this.traversal.store(name); + stepIndex++; + + return this; + } + + @Override + public QueryBuilder<E> cap(String name) { + this.traversal.cap(name); + stepIndex++; + + return this; + } + + @Override + public QueryBuilder<E> unfold() { + this.traversal.unfold(); + stepIndex++; + + return this; + } + + @Override + public QueryBuilder<E> dedup() { + + this.traversal.dedup(); + stepIndex++; + + return this; + } + + @Override + public QueryBuilder<E> emit() { + + this.traversal.emit(); + stepIndex++; + + return this; + + } + + @Override + public QueryBuilder<E> repeat(QueryBuilder<E> builder) { + + this.traversal.repeat((GraphTraversal<Vertex, E>) builder.getQuery()); + stepIndex++; + + return this; + } + + @Override + public QueryBuilder<E> until(QueryBuilder<E> builder) { + this.traversal.until((GraphTraversal<Vertex, E>) builder.getQuery()); + stepIndex++; + + return this; + } + + @Override + public QueryBuilder<E> groupCount() { + this.traversal.groupCount(); + stepIndex++; + + return this; + } + + @Override + public QueryBuilder<E> both() { + this.traversal.both(); + stepIndex++; + + return this; + } + + @Override + public QueryBuilder<Tree> tree() { + + this.traversal.tree(); + stepIndex++; + + return (QueryBuilder<Tree>) this; + } + + @Override + public QueryBuilder<E> by(String name) { + this.traversal.by(name); + stepIndex++; + + return this; + } + + @Override + public QueryBuilder<E> valueMap() { + this.traversal.valueMap(); + stepIndex++; + + return this; + } + + @Override + public QueryBuilder<E> valueMap(String... names) { + this.traversal.valueMap(names); + stepIndex++; + + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public QueryBuilder<E> simplePath() { + this.traversal.simplePath(); + stepIndex++; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public QueryBuilder<Path> path() { + this.traversal.path(); + stepIndex++; + return (QueryBuilder<Path>) this; + } + + @Override + public QueryBuilder<Edge> outE() { + this.traversal.outE(); + stepIndex++; + return (QueryBuilder<Edge>) this; + } + + @Override + public QueryBuilder<Edge> inE() { + this.traversal.inE(); + stepIndex++; + return (QueryBuilder<Edge>) this; + } + + @Override + public QueryBuilder<Vertex> outV() { + this.traversal.outV(); + stepIndex++; + return (QueryBuilder<Vertex>) this; + } + + @Override + public QueryBuilder<Vertex> inV() { + this.traversal.inV(); + stepIndex++; + return (QueryBuilder<Vertex>) this; + } + + @Override + public QueryBuilder<E> as(String name) { + this.traversal.as(name); + + stepIndex++; + return this; + } + + @Override + public QueryBuilder<E> not(QueryBuilder<E> builder) { + this.traversal.not(builder.getQuery()); + + stepIndex++; + return this; + } + + @Override + public QueryBuilder<E> select(String name) { + this.traversal.select(name); + + stepIndex++; + + return this; + } + + @Override + public QueryBuilder<E> select(Pop pop, String name) { + this.traversal.select(pop, name); + + stepIndex++; + + return this; + } + + @Override + public QueryBuilder<E> select(String... names) { + if (names.length == 1) { + this.traversal.select(names[0]); + } else if (names.length == 2) { + this.traversal.select(names[0], names[1]); + } else if (names.length > 2) { + String[] otherNames = Arrays.copyOfRange(names, 2, names.length); + this.traversal.select(names[0], names[1], otherNames); + } + + stepIndex++; + + return this; + } + + /** + * Edge query. + * + * @param outObj the out type + * @param inObj the in type + * @throws NoEdgeRuleFoundException + * @throws AAIException + */ + private void edgeQueryToVertex(EdgeType type, Introspector outObj, Introspector inObj, List<String> labels) + throws AAIException { + String outType = outObj.getDbName(); + String inType = inObj.getDbName(); + + if (outObj.isContainer()) { + outType = outObj.getChildDBName(); + } + if (inObj.isContainer()) { + inType = inObj.getChildDBName(); + } + markParentBoundary(); + Multimap<String, EdgeRule> rules = ArrayListMultimap.create(); + EdgeRuleQuery.Builder qB = new EdgeRuleQuery.Builder(outType, inType).edgeType(type); + + if (labels == null) { + try { + rules.putAll(edgeRules.getRules(qB.build())); + } catch (EdgeRuleNotFoundException e) { + // is ok per original functioning of this section + // TODO add "best try" sort of flag to the EdgeRuleQuery + // to indicate if the exception should be thrown or not + } + } else { + for (String label : labels) { + try { + rules.putAll(edgeRules.getRules(qB.label(label).build())); + } catch (EdgeRuleNotFoundException e) { + throw new NoEdgeRuleFoundException(e); + } + } + if (rules.isEmpty()) { + throw new NoEdgeRuleFoundException( + "No edge rules found for " + outType + " and " + inType + " of type " + type.toString()); + } + } + + final List<String> inLabels = new ArrayList<>(); + final List<String> outLabels = new ArrayList<>(); + + for (EdgeRule rule : rules.values()) { + if (labels != null && !labels.contains(rule.getLabel())) { + return; + } else { + if (Direction.IN.equals(rule.getDirection())) { + inLabels.add(rule.getLabel()); + } else { + outLabels.add(rule.getLabel()); + } + } + } + + if (inLabels.isEmpty() && !outLabels.isEmpty()) { + traversal.out(outLabels.toArray(new String[outLabels.size()])); + } else if (outLabels.isEmpty() && !inLabels.isEmpty()) { + traversal.in(inLabels.toArray(new String[inLabels.size()])); + } else { + traversal.union(__.out(outLabels.toArray(new String[outLabels.size()])), + __.in(inLabels.toArray(new String[inLabels.size()]))); + } + + stepIndex++; + + this.createContainerQuery(inObj); + + } + + /** + * Edge query. + * + * @param outObj the out type + * @param inObj the in type + * @throws NoEdgeRuleFoundException + * @throws AAIException + */ + private void edgeQuery(EdgeType type, Introspector outObj, Introspector inObj, List<String> labels) + throws AAIException { + String outType = outObj.getDbName(); + String inType = inObj.getDbName(); + + if (outObj.isContainer()) { + outType = outObj.getChildDBName(); + } + if (inObj.isContainer()) { + inType = inObj.getChildDBName(); + } + + markParentBoundary(); + Multimap<String, EdgeRule> rules = ArrayListMultimap.create(); + EdgeRuleQuery.Builder qB = new EdgeRuleQuery.Builder(outType, inType).edgeType(type); + + try { + if (labels == null) { + rules.putAll(edgeRules.getRules(qB.build())); + } else { + for (String label : labels) { + rules.putAll(edgeRules.getRules(qB.label(label).build())); + } + } + } catch (EdgeRuleNotFoundException e) { + throw new NoEdgeRuleFoundException(e); + } + + final List<String> inLabels = new ArrayList<>(); + final List<String> outLabels = new ArrayList<>(); + + for (EdgeRule rule : rules.values()) { + if (labels != null && !labels.contains(rule.getLabel())) { + return; + } else { + if (Direction.IN.equals(rule.getDirection())) { + inLabels.add(rule.getLabel()); + } else { + outLabels.add(rule.getLabel()); + } + } + } + + if (inLabels.isEmpty() && !outLabels.isEmpty()) { + traversal.outE(outLabels.toArray(new String[outLabels.size()])); + } else if (outLabels.isEmpty() && !inLabels.isEmpty()) { + traversal.inE(inLabels.toArray(new String[inLabels.size()])); + } else { + traversal.union(__.outE(outLabels.toArray(new String[outLabels.size()])), + __.inE(inLabels.toArray(new String[inLabels.size()]))); + } + } + + @Override + public QueryBuilder<E> limit(long amount) { + traversal.limit(amount); + return this; + } + + /** + * @{inheritDoc} + */ + @Override + public <E2> E2 getQuery() { + return (E2) this.traversal; + } + + /** + * @{inheritDoc} + */ + @Override + public QueryBuilder<E> getParentQuery() { + return this.parentQuery != null + ? this.parentQuery + : cloneQueryAtStep(parentStepIndex); + } + + @Override + public QueryBuilder<E> getContainerQuery() { + + if (this.parentStepIndex == 0) { + return removeQueryStepsBetween(0, containerStepIndex); + } else { + return this.containerQuery; + } + } + + /** + * @{inheritDoc} + */ + @Override + public void markParentBoundary() { + this.parentQuery = cloneQueryAtStep(stepIndex); + parentStepIndex = stepIndex; + } + + @Override + public void markContainer() { + this.containerQuery = cloneQueryAtStep(stepIndex); + containerStepIndex = stepIndex; + } + + /** + * @{inheritDoc} + */ + @Override + public Vertex getStart() { + return this.start; + } + + protected int getParentStepIndex() { + return parentStepIndex; + } + + protected int getContainerStepIndex() { + return containerStepIndex; + } + + protected int getStepIndex() { + return stepIndex; + } + + /** + * end is exclusive + * + * @param start + * @param end + * @return + */ + protected abstract QueryBuilder<E> removeQueryStepsBetween(int start, int end); + + protected void executeQuery() { + + Admin<Vertex, Vertex> admin; + if (start != null) { + this.completeTraversal = traversal.asAdmin(); + } else { + boolean queryLoggingEnabled = false; + if(queryLoggingEnabled) { + String query = groovyTranslator.translate(traversal.asAdmin().getBytecode()).getScript(); + LOGGER.info("Query: {}", query); + } + + admin = source.V().asAdmin(); + TraversalHelper.insertTraversal(admin.getEndStep(), traversal.asAdmin(), admin); + + this.completeTraversal = (Admin<Vertex, E>) admin; + + } + + } + + @Override + public boolean hasNext() { + if (this.completeTraversal == null) { + executeQuery(); + } + + return this.completeTraversal.hasNext(); + } + + @Override + public E next() { + if (this.completeTraversal == null) { + executeQuery(); + } + + return this.completeTraversal.next(); + } + + @Override + public List<E> toList() { + if (this.completeTraversal == null) { + executeQuery(); + } + return this.completeTraversal.toList(); + } + + @Override + public QueryBuilder<E> sort(Sort sort) { + Order order = sort.getDirection() == Sort.Direction.ASC ? Order.asc : Order.desc; + traversal.order().by(sort.getProperty(), order); + stepIndex++; + return this; + } + + public PaginationResult<E> toPaginationResult(Pageable pageable) { + int page = pageable.getPage(); + int pageSize = pageable.getPageSize(); + if(pageable.isIncludeTotalCount()) { + return paginateWithTotalCount(page, pageSize); + } else { + return paginateWithoutTotalCount(page, pageSize); + } + } + + private PaginationResult<E> paginateWithoutTotalCount(int page, int pageSize) { int startIndex = page * pageSize; - traversal.fold().as("results","count") - .select("results","count"). - by(__.range(Scope.local, startIndex, startIndex + pageSize)). - by(__.count(Scope.local)); + traversal.range(startIndex, startIndex + pageSize); if (this.completeTraversal == null) { executeQuery(); } - try { - return mapPaginationResult((Map<String,Object>) completeTraversal.next()); - // .next() will throw an IllegalArguementException if there are no vertices of the given type - } catch (IllegalArgumentException e) { - return new PaginationResult<>(Collections.emptyList(), 0L); + return completeTraversal.hasNext() + ? new PaginationResult<E>(completeTraversal.toList()) + : new PaginationResult<E>(Collections.emptyList()); + } + + private PaginationResult<E> paginateWithTotalCount(int page, int pageSize) { + int startIndex = page * pageSize; + traversal.fold().as("results","count") + .select("results","count"). + by(__.range(Scope.local, startIndex, startIndex + pageSize)). + by(__.count(Scope.local)); + + if (this.completeTraversal == null) { + executeQuery(); + } + try { + return mapPaginationResult((Map<String,Object>) completeTraversal.next()); + // .next() will throw an IllegalArguementException if there are no vertices of the given type + } catch (IllegalArgumentException e) { + return new PaginationResult<>(Collections.emptyList(), 0L); + } + } + + private PaginationResult<E> mapPaginationResult(Map<String,Object> result) { + Object objCount = result.get("count"); + Object vertices = result.get("results"); + if(vertices == null) { + return new PaginationResult<E>(Collections.emptyList() ,0L); } - } - - private PaginationResult<E> mapPaginationResult(Map<String,Object> result) { - Object objCount = result.get("count"); - Object vertices = result.get("results"); - if(vertices == null) { - return new PaginationResult<E>(Collections.emptyList() ,0L); - } - List<E> results = null; - if(vertices instanceof List) { - results = (List<E>) vertices; - } else if (vertices instanceof Vertex) { - results = Collections.singletonList((E) vertices); - } else { - String msg = String.format("Results must be a list or a vertex, but was %s", vertices.getClass().getName()); - LOGGER.error(msg); - throw new IllegalArgumentException(msg); - } - long totalCount = parseCount(objCount); - return new PaginationResult<E>(results, totalCount); - } - - private long parseCount(Object count) { - if(count instanceof String) { - return Long.parseLong((String) count); - } else if(count instanceof Integer) { - return Long.valueOf((int) count); - } else if (count instanceof Long) { - return (long) count; - } else { - throw new IllegalArgumentException("Count must be a string, integer, or long"); - } - } - - protected QueryBuilder<Edge> has(String key, String value) { - traversal.has(key, value); - - return (QueryBuilder<Edge>) this; - } - - } + List<E> results = null; + if(vertices instanceof List) { + results = (List<E>) vertices; + } else if (vertices instanceof Vertex) { + results = Collections.singletonList((E) vertices); + } else { + String msg = String.format("Results must be a list or a vertex, but was %s", vertices.getClass().getName()); + LOGGER.error(msg); + throw new IllegalArgumentException(msg); + } + long totalCount = parseCount(objCount); + return new PaginationResult<E>(results, totalCount); + } + + private long parseCount(Object count) { + if(count instanceof String) { + return Long.parseLong((String) count); + } else if(count instanceof Integer) { + return Long.valueOf((int) count); + } else if (count instanceof Long) { + return (long) count; + } else { + throw new IllegalArgumentException("Count must be a string, integer, or long"); + } + } + + protected QueryBuilder<Edge> has(String key, String value) { + traversal.has(key, value); + + return (QueryBuilder<Edge>) this; + } + +} diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/GremlinUnique.java b/aai-core/src/main/java/org/onap/aai/query/builder/GremlinUnique.java index 58495201..2b117c49 100644 --- a/aai-core/src/main/java/org/onap/aai/query/builder/GremlinUnique.java +++ b/aai-core/src/main/java/org/onap/aai/query/builder/GremlinUnique.java @@ -35,7 +35,6 @@ import org.onap.aai.introspection.Loader; import org.onap.aai.parsers.query.QueryParser; import org.onap.aai.parsers.query.TraversalStrategy; import org.onap.aai.parsers.query.UniqueStrategy; -import org.onap.aai.query.entities.PaginationResult; /** * The Class GremlinUnique. diff --git a/aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java b/aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java index 85c87667..94dc63aa 100644 --- a/aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java +++ b/aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java @@ -54,7 +54,8 @@ import org.onap.aai.parsers.query.QueryParser; import org.onap.aai.prevalidation.ValidationService; import org.onap.aai.query.builder.QueryOptions; import org.onap.aai.query.entities.PaginationResult; -import org.onap.aai.rest.ueb.UEBNotification; +import org.onap.aai.rest.notification.NotificationService; +import org.onap.aai.rest.notification.UEBNotification; import org.onap.aai.restcore.HttpMethod; import org.onap.aai.schema.enums.ObjectMetadata; import org.onap.aai.serialization.db.DBSerializer; @@ -70,7 +71,6 @@ import org.onap.aai.setup.SchemaVersions; import org.onap.aai.transforms.XmlFormatTransformer; import org.onap.aai.util.AAIConfig; import org.onap.aai.util.AAIConstants; -import org.onap.aai.util.delta.DeltaEvents; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -84,17 +84,11 @@ public class HttpEntry { private static final Logger LOGGER = LoggerFactory.getLogger(HttpEntry.class); private ModelType introspectorFactoryType; - private QueryStyle queryStyle; - private SchemaVersion version; - private Loader loader; - private TransactionalGraphEngine dbEngine; - private boolean processSingle = true; - @Autowired private NodeIngestor nodeIngestor; @@ -104,25 +98,17 @@ public class HttpEntry { @Autowired private SchemaVersions schemaVersions; + @Autowired + private NotificationService notificationService; + @Value("${schema.uri.base.path}") private String basePath; - @Value("${delta.events.enabled:false}") - private boolean isDeltaEventsEnabled; - private String serverBase; @Autowired private XmlFormatTransformer xmlFormatTransformer; - /** - * Inject the validation service if the profile pre-valiation is enabled, - * Otherwise this variable will be set to null and thats why required=false - * so that it can continue even if pre validation isn't enabled - */ - @Autowired(required = false) - private ValidationService validationService; - private UEBNotification notification; private int notificationDepth; @@ -292,7 +278,7 @@ public class HttpEntry { if (cleanUp == null) { cleanUp = "false"; } - if (vertices.size() > 1 && processSingle + if (vertices.size() > 1 && !(method.equals(HttpMethod.GET) || method.equals(HttpMethod.GET_RELATIONSHIP))) { if (method.equals(HttpMethod.DELETE)) { @@ -539,7 +525,7 @@ public class HttpEntry { */ if (isDelVerticesPresent) { - this.buildNotificationEvent(sourceOfTruth, status, transactionId, notification, + notificationService.buildNotificationEvent(sourceOfTruth, status, transactionId, notification, deleteObjects, uriMap, deleteRelatedObjects, basePath); } break; @@ -624,7 +610,7 @@ public class HttpEntry { } if (success) { - generateEvents(sourceOfTruth, serializer, transactionId, queryEngine, mainVertexesToNotifyOn); + notificationService.generateEvents(notification, notificationDepth, sourceOfTruth, serializer, transactionId, queryEngine, mainVertexesToNotifyOn, version); } else { notification.clearEvents(); } @@ -655,104 +641,6 @@ public class HttpEntry { : query.getQueryBuilder().toPaginationResult(queryOptions.getPageable()); } - /** - * Generate notification events for the resulting db requests. - */ - private void generateEvents(String sourceOfTruth, DBSerializer serializer, String transactionId, - QueryEngine queryEngine, Set<Vertex> mainVertexesToNotifyOn) throws AAIException { - if (notificationDepth == AAIProperties.MINIMUM_DEPTH) { - serializer.getUpdatedVertexes().entrySet().stream().filter(Map.Entry::getValue).map(Map.Entry::getKey) - .forEach(mainVertexesToNotifyOn::add); - } - Set<Vertex> edgeVertexes = serializer.touchStandardVertexPropertiesForEdges().stream() - .filter(v -> !mainVertexesToNotifyOn.contains(v)).collect(Collectors.toSet()); - try { - createNotificationEvents(mainVertexesToNotifyOn, sourceOfTruth, serializer, transactionId, queryEngine, - notificationDepth); - if ("true".equals(AAIConfig.get("aai.notification.both.sides.enabled", "true"))) { - createNotificationEvents(edgeVertexes, sourceOfTruth, serializer, transactionId, queryEngine, - AAIProperties.MINIMUM_DEPTH); - } - } catch (UnsupportedEncodingException e) { - LOGGER.warn("Encountered exception generating events", e); - } - - // Since @Autowired required is set to false, we need to do a null check - // for the existence of the validationService since its only enabled if profile is enabled - if (validationService != null) { - validationService.validate(notification.getEvents()); - } - notification.triggerEvents(); - if (isDeltaEventsEnabled) { - try { - DeltaEvents deltaEvents = - new DeltaEvents(transactionId, sourceOfTruth, version.toString(), serializer.getObjectDeltas()); - deltaEvents.triggerEvents(); - } catch (Exception e) { - LOGGER.error("Error sending Delta Events", e); - } - } - } - - /** - * Generate notification events for provided set of vertexes at the specified depth - */ - private void createNotificationEvents(Set<Vertex> vertexesToNotifyOn, String sourceOfTruth, DBSerializer serializer, - String transactionId, QueryEngine queryEngine, int eventDepth) - throws AAIException, UnsupportedEncodingException { - for (Vertex vertex : vertexesToNotifyOn) { - if (canGenerateEvent(vertex)) { - boolean isCurVertexNew = - vertex.value(AAIProperties.CREATED_TS).equals(vertex.value(AAIProperties.LAST_MOD_TS)); - Status curObjStatus = (isCurVertexNew) ? Status.CREATED : Status.OK; - - Introspector curObj = serializer.getLatestVersionView(vertex, eventDepth); - String aaiUri = vertex.<String>property(AAIProperties.AAI_URI).value(); - String uri = String.format("%s/%s%s", basePath, version, aaiUri); - HashMap<String, Introspector> curRelatedObjs = new HashMap<>(); - if (!curObj.isTopLevel()) { - curRelatedObjs = serializer.getRelatedObjects(queryEngine, vertex, curObj, this.loader); - } - notification.createNotificationEvent(transactionId, sourceOfTruth, curObjStatus, URI.create(uri), - curObj, curRelatedObjs, basePath); - } - } - } - - /** - * Verifies that vertex has needed properties to generate on - * - * @param vertex Vertex to be verified - * @return <code>true</code> if vertex has necessary properties and exists - */ - private boolean canGenerateEvent(Vertex vertex) { - boolean canGenerate = true; - try { - if (!vertex.property(AAIProperties.AAI_URI).isPresent()) { - LOGGER.debug("Encountered an vertex {} with missing aai-uri", vertex.id()); - canGenerate = false; - } else if (!vertex.property(AAIProperties.CREATED_TS).isPresent() - || !vertex.property(AAIProperties.LAST_MOD_TS).isPresent()) { - LOGGER.debug("Encountered an vertex {} with missing timestamp", vertex.id()); - canGenerate = false; - } - } catch (IllegalStateException e) { - if (e.getMessage().contains(" was removed")) { - LOGGER.warn("Attempted to generate event for non existent vertex", e); - } else { - LOGGER.warn("Encountered exception generating events", e); - } - canGenerate = false; - } - return canGenerate; - } - - /** - * Gets the media type. - * - * @param mediaTypeList the media type list - * @return the media type - */ private String getMediaType(List<MediaType> mediaTypeList) { String mediaType = MediaType.APPLICATION_JSON; // json is the default for (MediaType mt : mediaTypeList) { @@ -763,28 +651,6 @@ public class HttpEntry { return mediaType; } - /** - * Gets the object from db. - * - * @param serializer the serializer - * @param query the query - * @param obj the obj - * @param uri the uri - * @param depth the depth - * @param cleanUp the clean up - * @return the object from db - * @throws AAIException the AAI exception - * @throws IllegalAccessException the illegal access exception - * @throws IllegalArgumentException the illegal argument exception - * @throws InvocationTargetException the invocation target exception - * @throws SecurityException the security exception - * @throws InstantiationException the instantiation exception - * @throws NoSuchMethodException the no such method exception - * @throws UnsupportedEncodingException the unsupported encoding exception - * @throws MalformedURLException the malformed URL exception - * @throws AAIUnknownObjectException - * @throws URISyntaxException - */ private Introspector getObjectFromDb(List<Vertex> results, DBSerializer serializer, QueryParser query, Introspector obj, URI uri, int depth, boolean nodeOnly, String cleanUp) throws AAIException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, @@ -801,29 +667,6 @@ public class HttpEntry { } - /** - * Gets the object from db. - * - * @param serializer the serializer - * @param query the query - * @param obj the obj - * @param uri the uri - * @param depth the depth - * @param cleanUp the clean up - * @param isSkipRelatedTo include related to flag - * @return the object from db - * @throws AAIException the AAI exception - * @throws IllegalAccessException the illegal access exception - * @throws IllegalArgumentException the illegal argument exception - * @throws InvocationTargetException the invocation target exception - * @throws SecurityException the security exception - * @throws InstantiationException the instantiation exception - * @throws NoSuchMethodException the no such method exception - * @throws UnsupportedEncodingException the unsupported encoding exception - * @throws MalformedURLException the malformed URL exception - * @throws AAIUnknownObjectException - * @throws URISyntaxException - */ private Introspector getObjectFromDb(List<Vertex> results, DBSerializer serializer, QueryParser query, Introspector obj, URI uri, int depth, boolean nodeOnly, String cleanUp, boolean isSkipRelatedTo) throws AAIException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, @@ -840,25 +683,6 @@ public class HttpEntry { } - /** - * Gets the object from db. - * - * @param serializer the serializer - * @param query the query - * @param uri the uri - * @return the object from db - * @throws AAIException the AAI exception - * @throws IllegalAccessException the illegal access exception - * @throws IllegalArgumentException the illegal argument exception - * @throws InvocationTargetException the invocation target exception - * @throws SecurityException the security exception - * @throws InstantiationException the instantiation exception - * @throws NoSuchMethodException the no such method exception - * @throws UnsupportedEncodingException the unsupported encoding exception - * @throws MalformedURLException the malformed URL exception - * @throws AAIUnknownObjectException - * @throws URISyntaxException - */ private Introspector getRelationshipObjectFromDb(List<Vertex> results, DBSerializer serializer, QueryParser query, URI uri, boolean isSkipRelatedTo) throws AAIException, IllegalArgumentException, SecurityException, UnsupportedEncodingException, AAIUnknownObjectException { @@ -877,36 +701,15 @@ public class HttpEntry { return serializer.dbToRelationshipObject(v, isSkipRelatedTo); } - /** - * Creates the not found message. - * - * @param resultType the result type - * @param uri the uri - * @return the string - */ private String createNotFoundMessage(String resultType, URI uri) { return "No Node of type " + resultType + " found at: " + uri.getPath(); } - /** - * Creates the not found message. - * - * @param resultType the result type - * @param uri the uri - * @return the string - */ private String createRelationshipNotFoundMessage(String resultType, URI uri) { return "No relationship found of type " + resultType + " at the given URI: " + uri.getPath() + "/relationship-list"; } - /** - * Sets the depth. - * - * @param depthParam the depth param - * @return the int - * @throws AAIException the AAI exception - */ protected int setDepth(Introspector obj, String depthParam) throws AAIException { int depth = AAIProperties.MAXIMUM_DEPTH; @@ -1003,25 +806,4 @@ public class HttpEntry { return relatedObjectsMap; } - - private void buildNotificationEvent(String sourceOfTruth, Status status, String transactionId, - UEBNotification notification, Map<Vertex, Introspector> deleteObjects, Map<String, URI> uriMap, - Map<String, HashMap<String, Introspector>> deleteRelatedObjects, String basePath) { - for (Map.Entry<Vertex, Introspector> entry : deleteObjects.entrySet()) { - try { - if (null != entry.getValue()) { - String vertexObjectId = entry.getValue().getObjectId(); - - if (uriMap.containsKey(vertexObjectId) && deleteRelatedObjects.containsKey(vertexObjectId)) { - notification.createNotificationEvent(transactionId, sourceOfTruth, status, - uriMap.get(vertexObjectId), entry.getValue(), deleteRelatedObjects.get(vertexObjectId), - basePath); - } - } - } catch (UnsupportedEncodingException | AAIException e) { - - LOGGER.warn("Error in sending notification"); - } - } - } } diff --git a/aai-core/src/main/java/org/onap/aai/rest/ueb/NotificationEvent.java b/aai-core/src/main/java/org/onap/aai/rest/notification/NotificationEvent.java index b8e93c5b..17f09b19 100644 --- a/aai-core/src/main/java/org/onap/aai/rest/ueb/NotificationEvent.java +++ b/aai-core/src/main/java/org/onap/aai/rest/notification/NotificationEvent.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.aai.rest.ueb; +package org.onap.aai.rest.notification; import org.onap.aai.exceptions.AAIException; import org.onap.aai.introspection.Introspector; diff --git a/aai-core/src/main/java/org/onap/aai/rest/notification/NotificationService.java b/aai-core/src/main/java/org/onap/aai/rest/notification/NotificationService.java new file mode 100644 index 00000000..9c3dde15 --- /dev/null +++ b/aai-core/src/main/java/org/onap/aai/rest/notification/NotificationService.java @@ -0,0 +1,188 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom. 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.notification; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.ws.rs.core.Response.Status; + +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.LoaderFactory; +import org.onap.aai.prevalidation.ValidationService; +import org.onap.aai.serialization.db.DBSerializer; +import org.onap.aai.serialization.engines.query.QueryEngine; +import org.onap.aai.setup.SchemaVersion; +import org.onap.aai.util.AAIConfig; +import org.onap.aai.util.delta.DeltaEvents; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.lang.Nullable; +import org.springframework.stereotype.Service; + +@Service +public class NotificationService { + + public static final Logger LOGGER = LoggerFactory.getLogger(NotificationService.class); + + private final ValidationService validationService; + private final LoaderFactory loaderFactory; + private final boolean isDeltaEventsEnabled; + private final String basePath; + + public NotificationService( + @Nullable ValidationService validationService, + LoaderFactory loaderFactory, + @Value("${schema.uri.base.path}") String basePath, + @Value("${delta.events.enabled:false}") boolean isDeltaEventsEnabled) { + this.validationService = validationService; + this.loaderFactory = loaderFactory; + this.basePath = basePath; + this.isDeltaEventsEnabled = isDeltaEventsEnabled; + } + + /** + * Generate notification events for the resulting db requests. + */ + public void generateEvents(UEBNotification notification, int notificationDepth, String sourceOfTruth, DBSerializer serializer, + String transactionId, + QueryEngine queryEngine, Set<Vertex> mainVertexesToNotifyOn, SchemaVersion schemaVersion) throws AAIException { + if (notificationDepth == AAIProperties.MINIMUM_DEPTH) { + serializer.getUpdatedVertexes().entrySet().stream() + .filter(Map.Entry::getValue) + .map(Map.Entry::getKey) + .forEach(mainVertexesToNotifyOn::add); + } + Set<Vertex> edgeVertexes = serializer.touchStandardVertexPropertiesForEdges().stream() + .filter(v -> !mainVertexesToNotifyOn.contains(v)) + .collect(Collectors.toSet()); + + try { + createNotificationEvents(mainVertexesToNotifyOn, notification, sourceOfTruth, serializer, transactionId, queryEngine, + notificationDepth, schemaVersion); + if ("true".equals(AAIConfig.get("aai.notification.both.sides.enabled", "true"))) { + createNotificationEvents(edgeVertexes, notification, sourceOfTruth, serializer, transactionId, queryEngine, + AAIProperties.MINIMUM_DEPTH, schemaVersion); + } + } catch (UnsupportedEncodingException e) { + LOGGER.warn("Encountered exception generating events", e); + } + + // validation is configurable via aai.notification.validation.enabled + if (validationService != null) { + validationService.validate(notification.getEvents()); + } + + notification.triggerEvents(); + if (isDeltaEventsEnabled) { + try { + DeltaEvents deltaEvents = new DeltaEvents(transactionId, sourceOfTruth, schemaVersion.toString(), + serializer.getObjectDeltas()); + deltaEvents.triggerEvents(); + } catch (Exception e) { + LOGGER.error("Error sending Delta Events", e); + } + } + } + + /** + * Generate notification events for provided set of vertexes at the specified + * depth + */ + private void createNotificationEvents(Set<Vertex> vertexesToNotifyOn, UEBNotification notification, String sourceOfTruth, DBSerializer serializer, + String transactionId, QueryEngine queryEngine, int eventDepth, SchemaVersion schemaVersion) + throws AAIException, UnsupportedEncodingException { + for (Vertex vertex : vertexesToNotifyOn) { + if (canGenerateEvent(vertex)) { + boolean isVertexNew = vertex.value(AAIProperties.CREATED_TS).equals(vertex.value(AAIProperties.LAST_MOD_TS)); + Status curObjStatus = isVertexNew ? Status.CREATED : Status.OK; + + Introspector curObj = serializer.getLatestVersionView(vertex, eventDepth); + String aaiUri = vertex.<String>property(AAIProperties.AAI_URI).value(); + String uri = String.format("%s/%s%s", basePath, schemaVersion, aaiUri); + HashMap<String, Introspector> curRelatedObjs = new HashMap<>(); + if (!curObj.isTopLevel()) { + curRelatedObjs = serializer.getRelatedObjects(queryEngine, vertex, curObj, loaderFactory.getMoxyLoaderInstance().get(schemaVersion)); + } + notification.createNotificationEvent(transactionId, sourceOfTruth, curObjStatus, URI.create(uri), + curObj, curRelatedObjs, basePath); + } + } + } + + /** + * Verifies that vertex has needed properties to generate on + * + * @param vertex Vertex to be verified + * @return <code>true</code> if vertex has necessary properties and exists + */ + private boolean canGenerateEvent(Vertex vertex) { + boolean canGenerate = true; + try { + if (!vertex.property(AAIProperties.AAI_URI).isPresent()) { + LOGGER.debug("Encountered an vertex {} with missing aai-uri", vertex.id()); + canGenerate = false; + } else if (!vertex.property(AAIProperties.CREATED_TS).isPresent() + || !vertex.property(AAIProperties.LAST_MOD_TS).isPresent()) { + LOGGER.debug("Encountered an vertex {} with missing timestamp", vertex.id()); + canGenerate = false; + } + } catch (IllegalStateException e) { + if (e.getMessage().contains(" was removed")) { + LOGGER.warn("Attempted to generate event for non existent vertex", e); + } else { + LOGGER.warn("Encountered exception generating events", e); + } + canGenerate = false; + } + return canGenerate; + } + + public void buildNotificationEvent(String sourceOfTruth, Status status, String transactionId, + UEBNotification notification, Map<Vertex, Introspector> deleteObjects, Map<String, URI> uriMap, + Map<String, HashMap<String, Introspector>> deleteRelatedObjects, String basePath) { + for (Map.Entry<Vertex, Introspector> entry : deleteObjects.entrySet()) { + try { + if (null != entry.getValue()) { + String vertexObjectId = entry.getValue().getObjectId(); + + if (uriMap.containsKey(vertexObjectId) && deleteRelatedObjects.containsKey(vertexObjectId)) { + notification.createNotificationEvent(transactionId, sourceOfTruth, status, + uriMap.get(vertexObjectId), entry.getValue(), deleteRelatedObjects.get(vertexObjectId), + basePath); + } + } + } catch (UnsupportedEncodingException | AAIException e) { + + LOGGER.warn("Error in sending notification"); + } + } + } + +} diff --git a/aai-core/src/main/java/org/onap/aai/rest/ueb/UEBNotification.java b/aai-core/src/main/java/org/onap/aai/rest/notification/UEBNotification.java index 0c8fde62..83a446b2 100644 --- a/aai-core/src/main/java/org/onap/aai/rest/ueb/UEBNotification.java +++ b/aai-core/src/main/java/org/onap/aai/rest/notification/UEBNotification.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.aai.rest.ueb; +package org.onap.aai.rest.notification; import java.io.UnsupportedEncodingException; import java.net.URI; diff --git a/aai-core/src/main/java/org/onap/aai/serialization/db/EdgeSerializer.java b/aai-core/src/main/java/org/onap/aai/serialization/db/EdgeSerializer.java index 0c58717e..0d491c9d 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/db/EdgeSerializer.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/db/EdgeSerializer.java @@ -20,9 +20,6 @@ package org.onap.aai.serialization.db; -import java.util.EnumMap; -import java.util.Map; -import java.util.Map.Entry; import java.util.Optional; import java.util.UUID; diff --git a/aai-core/src/main/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngine.java b/aai-core/src/main/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngine.java index c96e8d22..264a054e 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngine.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngine.java @@ -91,7 +91,7 @@ public class GraphTraversalQueryEngine extends QueryEngine { try { StopWatch.conditionalStart(); final GraphTraversal<Vertex, Vertex> pipe = - this.g.V().has(AAIProperties.AAI_URI, P.within(uris)).order().by(AAIProperties.AAI_URI, Order.decr); + this.g.V().has(AAIProperties.AAI_URI, P.within(uris)).order().by(AAIProperties.AAI_URI, Order.desc); return pipe.toList(); } finally { dbTimeMsecs += StopWatch.stopIfStarted(); diff --git a/aai-core/src/main/java/org/onap/aai/util/PojoUtils.java b/aai-core/src/main/java/org/onap/aai/util/PojoUtils.java index f974ba14..4c2ce942 100644 --- a/aai-core/src/main/java/org/onap/aai/util/PojoUtils.java +++ b/aai-core/src/main/java/org/onap/aai/util/PojoUtils.java @@ -27,6 +27,7 @@ import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule; import com.google.common.base.CaseFormat; import com.google.common.collect.Multimap; @@ -124,12 +125,15 @@ public class PojoUtils { */ public <T> String getJsonFromObject(T clazz, boolean wrapRoot, boolean indent) throws JsonGenerationException, JsonMappingException, IOException { - ObjectMapper mapper = JsonMapper.builder().serializationInclusion(JsonInclude.Include.NON_NULL) + ObjectMapper mapper = JsonMapper.builder() + .addModule(new JaxbAnnotationModule()) + .addModule(new JavaTimeModule()) + .serializationInclusion(JsonInclude.Include.NON_NULL) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) .configure(SerializationFeature.INDENT_OUTPUT, indent) .configure(SerializationFeature.WRAP_ROOT_VALUE, wrapRoot) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) - .configure(DeserializationFeature.UNWRAP_ROOT_VALUE, wrapRoot).addModule(new JaxbAnnotationModule()) + .configure(DeserializationFeature.UNWRAP_ROOT_VALUE, wrapRoot) .build(); return mapper.writeValueAsString(clazz); diff --git a/aai-core/src/main/java/org/onap/aai/util/StoreNotificationEvent.java b/aai-core/src/main/java/org/onap/aai/util/StoreNotificationEvent.java index 6f3e8883..127cf538 100644 --- a/aai-core/src/main/java/org/onap/aai/util/StoreNotificationEvent.java +++ b/aai-core/src/main/java/org/onap/aai/util/StoreNotificationEvent.java @@ -39,14 +39,18 @@ import org.onap.aai.kafka.AAIKafkaEventJMSProducer; import org.onap.aai.kafka.MessageProducer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.core.env.Environment; +import org.springframework.jms.core.JmsTemplate; public class StoreNotificationEvent { private static final Logger LOGGER = LoggerFactory.getLogger(StoreNotificationEvent.class); - private MessageProducer messageProducer; + @Autowired JmsTemplate jmsTemplate; + + private final MessageProducer messageProducer; private String fromAppId = ""; private String transId = ""; private final String transactionId; @@ -59,12 +63,12 @@ public class StoreNotificationEvent { * Instantiates a new store notification event. */ public StoreNotificationEvent(String transactionId, String sourceOfTruth) { - this.messageProducer = new AAIKafkaEventJMSProducer(); + this.messageProducer = new AAIKafkaEventJMSProducer(jmsTemplate); this.transactionId = transactionId; this.sourceOfTruth = sourceOfTruth; } - public StoreNotificationEvent(AAIKafkaEventJMSProducer producer, String transactionId, String sourceOfTruth) { + public StoreNotificationEvent(MessageProducer producer, String transactionId, String sourceOfTruth) { this.messageProducer = producer; this.transactionId = transactionId; this.sourceOfTruth = sourceOfTruth; diff --git a/aai-core/src/main/java/org/onap/aai/util/delta/DeltaEvents.java b/aai-core/src/main/java/org/onap/aai/util/delta/DeltaEvents.java index 6fbc297b..39a03777 100644 --- a/aai-core/src/main/java/org/onap/aai/util/delta/DeltaEvents.java +++ b/aai-core/src/main/java/org/onap/aai/util/delta/DeltaEvents.java @@ -20,7 +20,6 @@ package org.onap.aai.util.delta; -import com.google.gson.*; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -28,38 +27,33 @@ import java.util.Date; import java.util.Map; import org.onap.aai.db.props.AAIProperties; -import org.onap.aai.kafka.AAIKafkaEventJMSProducer; import org.onap.aai.kafka.MessageProducer; import org.onap.aai.util.AAIConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; -public class DeltaEvents { +import com.google.gson.FieldNamingPolicy; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; - private static final Logger LOGGER = LoggerFactory.getLogger(DeltaEvents.class); +public class DeltaEvents { private static final Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES).create(); + private static final String eventVersion = "v1"; - private String transId; - private String sourceName; - private String eventVersion = "v1"; - private String schemaVersion; - private Map<String, ObjectDelta> objectDeltas; + private final String transId; + private final String sourceName; + private final String schemaVersion; + private final Map<String, ObjectDelta> objectDeltas; - private MessageProducer messageProducer; + @Autowired private MessageProducer messageProducer; public DeltaEvents(String transId, String sourceName, String schemaVersion, Map<String, ObjectDelta> objectDeltas) { - this(transId, sourceName, schemaVersion, objectDeltas, new AAIKafkaEventJMSProducer()); - } - - public DeltaEvents(String transId, String sourceName, String schemaVersion, Map<String, ObjectDelta> objectDeltas, - MessageProducer messageProducer) { - this.transId = transId; - this.sourceName = sourceName; - this.schemaVersion = schemaVersion; - this.objectDeltas = objectDeltas; - this.messageProducer = messageProducer; + this.transId = transId; + this.sourceName = sourceName; + this.schemaVersion = schemaVersion; + this.objectDeltas = objectDeltas; } public boolean triggerEvents() { @@ -98,7 +92,7 @@ public class DeltaEvents { header.addProperty("source-name", this.sourceName); header.addProperty("domain", this.getDomain()); header.addProperty("event-type", this.getEventType()); - header.addProperty("event-version", this.eventVersion); + header.addProperty("event-version", eventVersion); header.addProperty("schema-version", this.schemaVersion); header.addProperty("action", first.getAction().toString()); header.addProperty("entity-type", this.getEntityType(first)); @@ -126,7 +120,7 @@ public class DeltaEvents { /** * Given Long timestamp convert to format YYYYMMdd-HH:mm:ss:SSS - * + * * @param timestamp milliseconds since epoc * @return long timestamp in format YYYYMMdd-HH:mm:ss:SSS */ diff --git a/aai-core/src/main/java/org/onap/aai/web/KafkaConfig.java b/aai-core/src/main/java/org/onap/aai/web/KafkaConfig.java index 71ae5b6b..c1e8357d 100644 --- a/aai-core/src/main/java/org/onap/aai/web/KafkaConfig.java +++ b/aai-core/src/main/java/org/onap/aai/web/KafkaConfig.java @@ -18,158 +18,168 @@ * ============LICENSE_END========================================================= */ - package org.onap.aai.web; - - import java.util.HashMap; - import java.util.Map; - - import javax.annotation.PostConstruct; - - import org.apache.activemq.ActiveMQConnectionFactory; - import org.apache.activemq.broker.BrokerService; - import org.apache.activemq.command.ActiveMQQueue; - import org.apache.kafka.clients.producer.ProducerConfig; +package org.onap.aai.web; + +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.PostConstruct; +import javax.jms.ConnectionFactory; +import javax.jms.MessageListener; +import javax.jms.Queue; + +import org.apache.activemq.ActiveMQConnectionFactory; +import org.apache.activemq.broker.BrokerService; +import org.apache.activemq.command.ActiveMQQueue; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.onap.aai.introspection.LoaderFactory; import org.onap.aai.kafka.AAIKafkaEventJMSConsumer; import org.onap.aai.kafka.AAIKafkaEventJMSProducer; +import org.onap.aai.kafka.MessageProducer; +import org.onap.aai.rest.notification.NotificationService; import org.slf4j.Logger; - import org.slf4j.LoggerFactory; - import org.springframework.beans.factory.annotation.Autowired; - import org.springframework.beans.factory.annotation.Value; - import org.springframework.context.ApplicationContext; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import org.springframework.context.annotation.Profile; - import org.springframework.jms.connection.CachingConnectionFactory; - import org.springframework.jms.core.JmsTemplate; - import org.springframework.jms.listener.DefaultMessageListenerContainer; - import org.springframework.kafka.core.DefaultKafkaProducerFactory; - import org.springframework.kafka.core.KafkaTemplate; - import org.springframework.kafka.core.ProducerFactory; - - @Profile("kafka") - @Configuration - public class KafkaConfig { - - @Autowired - private ApplicationContext ctx; - - - @Value("${jms.bind.address}") - private String bindAddress; - - @Value("${spring.kafka.producer.bootstrap-servers}") - private String bootstrapServers; - - @Value("${spring.kafka.producer.properties.security.protocol}") - private String securityProtocol; - - @Value("${spring.kafka.producer.properties.sasl.mechanism}") - private String saslMechanism; - - @Value("${spring.kafka.producer.properties.sasl.jaas.config}") - private String saslJaasConfig; - - @Value("${spring.kafka.producer.retries}") - private Integer retries; - - private static final Logger logger = LoggerFactory.getLogger(KafkaConfig.class); - - @PostConstruct - public void init() { - System.setProperty("activemq.tcp.url", bindAddress); - } - - @Bean(destroyMethod = "stop") - public BrokerService brokerService() throws Exception { - - BrokerService broker = new BrokerService(); - broker.addConnector(bindAddress); - broker.setPersistent(false); - broker.setUseJmx(false); - broker.setSchedulerSupport(false); - broker.start(); - - return broker; - } - - @Bean(name = "connectionFactory") - public ActiveMQConnectionFactory activeMQConnectionFactory() { - return new ActiveMQConnectionFactory(bindAddress); - } - - @Bean - public CachingConnectionFactory cachingConnectionFactory() { - return new CachingConnectionFactory(activeMQConnectionFactory()); - } - - @Bean(name = "destinationQueue") - public ActiveMQQueue activeMQQueue() { - return new ActiveMQQueue("IN_QUEUE"); - } - - @Bean - public JmsTemplate jmsTemplate() { - JmsTemplate jmsTemplate = new JmsTemplate(); - - jmsTemplate.setConnectionFactory(activeMQConnectionFactory()); - jmsTemplate.setDefaultDestination(activeMQQueue()); - - return jmsTemplate; - } - - @Bean - public AAIKafkaEventJMSProducer jmsProducer() { - return new AAIKafkaEventJMSProducer(); - } - - @Bean(name = "jmsConsumer") - public AAIKafkaEventJMSConsumer jmsConsumer() throws Exception { - return new AAIKafkaEventJMSConsumer(ctx.getEnvironment(),kafkaTemplate()); - } - - @Bean - public DefaultMessageListenerContainer defaultMessageListenerContainer() throws Exception { - - DefaultMessageListenerContainer messageListenerContainer = new DefaultMessageListenerContainer(); - - messageListenerContainer.setConnectionFactory(cachingConnectionFactory()); - messageListenerContainer.setDestinationName("IN_QUEUE"); - messageListenerContainer.setMessageListener(jmsConsumer()); - - return messageListenerContainer; - } - - @Bean - public ProducerFactory<String, String> producerFactory() throws Exception { - Map<String, Object> props = new HashMap<>(); - if(bootstrapServers == null){ - logger.error("Environment Variable " + bootstrapServers + " is missing"); - throw new Exception("Environment Variable " + bootstrapServers + " is missing"); - } - else{ - props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); - } - if(saslJaasConfig == null){ - logger.info("Not using any authentication for kafka interaction"); - } - else{ - logger.info("Using authentication provided by kafka interaction"); - // Strimzi Kafka security properties - props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); - props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); - props.put("security.protocol", securityProtocol); - props.put("sasl.mechanism", saslMechanism); - props.put("sasl.jaas.config", saslJaasConfig); - props.put(ProducerConfig.RETRIES_CONFIG, Integer.toString(retries)); - props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION,"5"); - } - - return new DefaultKafkaProducerFactory<>(props); - } - - @Bean - public KafkaTemplate<String, String> kafkaTemplate() throws Exception { - return new KafkaTemplate<>(producerFactory()); - } - } -
\ No newline at end of file +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.jms.connection.CachingConnectionFactory; +import org.springframework.jms.core.JmsTemplate; +import org.springframework.jms.listener.DefaultMessageListenerContainer; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; + +@Profile("kafka") +@Configuration +public class KafkaConfig { + + @Value("${jms.bind.address}") + private String bindAddress; + + @Value("${spring.kafka.producer.bootstrap-servers}") + private String bootstrapServers; + + @Value("${spring.kafka.producer.properties.security.protocol}") + private String securityProtocol; + + @Value("${spring.kafka.producer.properties.sasl.mechanism}") + private String saslMechanism; + + @Value("${spring.kafka.producer.properties.sasl.jaas.config}") + private String saslJaasConfig; + + @Value("${spring.kafka.producer.retries}") + private String retries; + + private static final Logger logger = LoggerFactory.getLogger(KafkaConfig.class); + + @PostConstruct + public void init() { + System.setProperty("activemq.tcp.url", bindAddress); + } + + @Bean(destroyMethod = "stop") + public BrokerService brokerService() throws Exception { + + BrokerService broker = new BrokerService(); + broker.addConnector(bindAddress); + broker.setPersistent(false); + broker.setUseJmx(false); + broker.setSchedulerSupport(false); + broker.start(); + + return broker; + } + + @ConditionalOnMissingBean + @Bean(name = "connectionFactory") + public ConnectionFactory activeMQConnectionFactory() { + return new ActiveMQConnectionFactory(bindAddress); + } + + @Bean + @ConditionalOnMissingBean + public CachingConnectionFactory cachingConnectionFactory(ConnectionFactory targetConnectionFactory) { + return new CachingConnectionFactory(targetConnectionFactory); + } + + @Bean(name = "destinationQueue") + public Queue activeMQQueue() { + return new ActiveMQQueue("IN_QUEUE"); + } + + @Bean + public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory, Queue queue) { + JmsTemplate jmsTemplate = new JmsTemplate(); + + jmsTemplate.setConnectionFactory(connectionFactory); + jmsTemplate.setDefaultDestination(queue); + + return jmsTemplate; + } + + @Bean(name = "jmsConsumer") + public MessageListener jmsConsumer(KafkaTemplate<String, String> kafkaTemplate) throws Exception { + return new AAIKafkaEventJMSConsumer(kafkaTemplate); + } + + @Bean + public DefaultMessageListenerContainer defaultMessageListenerContainer(ConnectionFactory connectionFactory, MessageListener messageListener) + throws Exception { + + DefaultMessageListenerContainer messageListenerContainer = new DefaultMessageListenerContainer(); + + messageListenerContainer.setConnectionFactory(connectionFactory); + messageListenerContainer.setDestinationName("IN_QUEUE"); + messageListenerContainer.setMessageListener(messageListener); + + return messageListenerContainer; + } + + @Bean + public ProducerFactory<String, String> producerFactory() throws Exception { + Map<String, Object> props = new HashMap<>(); + if (bootstrapServers == null) { + logger.error("Environment Variable " + bootstrapServers + " is missing"); + throw new Exception("Environment Variable " + bootstrapServers + " is missing"); + } else { + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); + } + props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + props.put(ProducerConfig.RETRIES_CONFIG, retries); + props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "5"); + + if (saslJaasConfig == null) { + logger.info("Not using any authentication for kafka interaction"); + } else { + logger.info("Using authentication provided by kafka interaction"); + // Strimzi Kafka security properties + props.put("security.protocol", securityProtocol); + props.put("sasl.mechanism", saslMechanism); + props.put("sasl.jaas.config", saslJaasConfig); + } + + return new DefaultKafkaProducerFactory<>(props); + } + + @Bean + public KafkaTemplate<String, String> kafkaTemplate(ProducerFactory<String, String> producerFactory) throws Exception { + return new KafkaTemplate<>(producerFactory); + } + + @Bean + public MessageProducer messageProducer(JmsTemplate jmsTemplate) { + return new AAIKafkaEventJMSProducer(jmsTemplate); + } + + @Bean + @ConditionalOnMissingBean + public NotificationService notificationService(LoaderFactory loaderFactory, + @Value("${schema.uri.base.path}") String basePath, + @Value("${delta.events.enabled:false}") boolean isDeltaEventsEnabled) { + return new NotificationService(null, loaderFactory, basePath, isDeltaEventsEnabled); + } +} diff --git a/aai-core/src/main/resources/logback.xml b/aai-core/src/main/resources/logback.xml index fc66b32e..ba5b3de8 100644 --- a/aai-core/src/main/resources/logback.xml +++ b/aai-core/src/main/resources/logback.xml @@ -166,7 +166,7 @@ <pattern>${eelfTransLogPattern}</pattern> </encoder> </appender> - + <appender name="asynctranslog" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>1000</queueSize> <includeCallerData>true</includeCallerData> @@ -258,7 +258,7 @@ <logger name="ajsc.UserDefinedBeansDefService" level="WARN" /> <logger name="ajsc.LoggingConfigurationService" level="WARN" /> - <!-- AJSC related loggers (DME2 Registration, csi logging, restlet, servlet + <!-- AJSC related loggers (DME2 Registration, csi logging, restlet, servlet logging) --> <logger name="org.codehaus.groovy" level="WARN" /> <logger name="com.att.scamper" level="WARN" /> @@ -282,7 +282,7 @@ <logger name="org.apache.coyote" level="WARN" /> <logger name="org.apache.jasper" level="WARN" /> - <!-- Camel Related Loggers (including restlet/servlet/jaxrs/cxf logging. + <!-- Camel Related Loggers (including restlet/servlet/jaxrs/cxf logging. May aid in troubleshooting) --> <logger name="org.apache.camel" level="WARN" /> <logger name="org.apache.cxf" level="WARN" /> @@ -366,9 +366,7 @@ </logger> <logger name="org.onap.aai.kafka" level="DEBUG" additivity="false"> - <appender-ref ref="kafkaAAIEventConsumer" /> - <appender-ref ref="kafkaAAIEventConsumerDebug" /> - <appender-ref ref="kafkaAAIEventConsumerMetric" /> + <appender-ref ref="STDOUT" /> </logger> <logger name="org.apache" level="OFF" /> diff --git a/aai-core/src/test/java/org/onap/aai/AAISetup.java b/aai-core/src/test/java/org/onap/aai/AAISetup.java index e1fc351f..08a0e91b 100644 --- a/aai-core/src/test/java/org/onap/aai/AAISetup.java +++ b/aai-core/src/test/java/org/onap/aai/AAISetup.java @@ -33,12 +33,14 @@ import org.onap.aai.nodes.NodeIngestor; import org.onap.aai.prevalidation.ValidationConfiguration; import org.onap.aai.prevalidation.ValidationService; import org.onap.aai.rest.db.HttpEntry; +import org.onap.aai.rest.notification.NotificationService; import org.onap.aai.serialization.db.EdgeSerializer; import org.onap.aai.serialization.queryformats.QueryFormatTestHelper; import org.onap.aai.setup.AAIConfigTranslator; import org.onap.aai.setup.SchemaVersion; import org.onap.aai.setup.SchemaVersions; import org.onap.aai.util.AAIConstants; +import org.onap.aai.web.KafkaConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.test.context.ContextConfiguration; @@ -51,7 +53,8 @@ import org.springframework.test.context.web.WebAppConfiguration; @ContextConfiguration( classes = {ConfigConfiguration.class, AAIConfigTranslator.class, EdgeIngestor.class, EdgeSerializer.class, NodeIngestor.class, SpringContextAware.class, IntrospectionConfig.class, RestBeanConfig.class, - XmlFormatTransformerConfiguration.class, ValidationService.class, ValidationConfiguration.class}) + XmlFormatTransformerConfiguration.class, ValidationService.class, ValidationConfiguration.class, + KafkaConfig.class, LoaderFactory.class, NotificationService.class}) @TestPropertySource( properties = {"schema.uri.base.path = /aai", "schema.xsd.maxoccurs = 5000", "schema.translator.list=config", "schema.nodes.location=src/test/resources/onap/oxm", diff --git a/aai-core/src/test/java/org/onap/aai/DataLinkSetup.java b/aai-core/src/test/java/org/onap/aai/DataLinkSetup.java index b8782045..b38a5c69 100644 --- a/aai-core/src/test/java/org/onap/aai/DataLinkSetup.java +++ b/aai-core/src/test/java/org/onap/aai/DataLinkSetup.java @@ -31,6 +31,7 @@ import org.onap.aai.introspection.LoaderFactory; import org.onap.aai.introspection.MoxyLoader; import org.onap.aai.nodes.NodeIngestor; import org.onap.aai.rest.db.HttpEntry; +import org.onap.aai.rest.notification.NotificationService; import org.onap.aai.serialization.db.EdgeSerializer; import org.onap.aai.serialization.queryformats.QueryFormatTestHelper; import org.onap.aai.setup.SchemaVersion; @@ -48,7 +49,7 @@ import org.springframework.test.context.junit4.rules.SpringMethodRule; @ContextConfiguration( classes = {ConfigConfiguration.class, TestUtilConfigTranslatorforDataLink.class, EdgeIngestor.class, EdgeSerializer.class, NodeIngestor.class, SpringContextAware.class, IntrospectionConfig.class, - RestBeanConfig.class, XmlFormatTransformerConfiguration.class}) + RestBeanConfig.class, XmlFormatTransformerConfiguration.class, LoaderFactory.class, NotificationService.class}) @TestPropertySource( properties = {"schema.uri.base.path = /aai", "schema.xsd.maxoccurs = 5000", "schema.version.api.default = v4", "schema.version.edge.label.start = v4", "schema.version.depth.start = v3", diff --git a/aai-core/src/test/java/org/onap/aai/HttpTestUtil.java b/aai-core/src/test/java/org/onap/aai/HttpTestUtil.java index 07764ecc..49524c4e 100644 --- a/aai-core/src/test/java/org/onap/aai/HttpTestUtil.java +++ b/aai-core/src/test/java/org/onap/aai/HttpTestUtil.java @@ -52,7 +52,7 @@ import org.onap.aai.parsers.query.QueryParser; import org.onap.aai.parsers.uri.URIToObject; import org.onap.aai.rest.db.DBRequest; import org.onap.aai.rest.db.HttpEntry; -import org.onap.aai.rest.ueb.UEBNotification; +import org.onap.aai.rest.notification.UEBNotification; import org.onap.aai.restcore.HttpMethod; import org.onap.aai.restcore.RESTAPI; import org.onap.aai.serialization.engines.QueryStyle; diff --git a/aai-core/src/test/java/org/onap/aai/db/DbMethHelperTest.java b/aai-core/src/test/java/org/onap/aai/db/DbMethHelperTest.java index c79b9148..7bea305e 100644 --- a/aai-core/src/test/java/org/onap/aai/db/DbMethHelperTest.java +++ b/aai-core/src/test/java/org/onap/aai/db/DbMethHelperTest.java @@ -36,7 +36,6 @@ import org.apache.commons.io.IOUtils; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; import org.apache.tinkerpop.gremlin.structure.Graph; import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; import org.janusgraph.core.JanusGraphFactory; import org.junit.After; import org.junit.AfterClass; diff --git a/aai-core/src/test/java/org/onap/aai/domain/model/AAIResourceTest.java b/aai-core/src/test/java/org/onap/aai/domain/model/AAIResourceTest.java index 3ef1befa..5eb0d99c 100644 --- a/aai-core/src/test/java/org/onap/aai/domain/model/AAIResourceTest.java +++ b/aai-core/src/test/java/org/onap/aai/domain/model/AAIResourceTest.java @@ -23,7 +23,9 @@ package org.onap.aai.domain.model; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import org.junit.Assert; import org.junit.Before; diff --git a/aai-core/src/test/java/org/onap/aai/introspection/sideeffect/DataLinkTest.java b/aai-core/src/test/java/org/onap/aai/introspection/sideeffect/DataLinkTest.java index 138723aa..368a9466 100644 --- a/aai-core/src/test/java/org/onap/aai/introspection/sideeffect/DataLinkTest.java +++ b/aai-core/src/test/java/org/onap/aai/introspection/sideeffect/DataLinkTest.java @@ -218,7 +218,7 @@ public class DataLinkTest extends DataLinkSetup { } - /** + /** * This is more directly testing the modification mechanism (see verifyModificationOfVertex test) */ @Test @@ -229,7 +229,7 @@ public class DataLinkTest extends DataLinkSetup { URI uri = new URI("/network/vpn-bindings/vpn-binding/modifyKey/route-targets/route-target/modifyTargetKey2/modifyRoleKey2"); MultivaluedMap<String, String> map = URITools.getQueryMap(uri); GraphTraversal<Vertex, Vertex> traversal = __.<Vertex>start(); - + QueryParser uriQuery = dbEngine.getQueryBuilder(this.queryStyle, loader, source, traversal).createQueryFromURI(uri, map); List<Vertex> results = uriQuery.getQueryBuilder().toList(); @@ -390,4 +390,3 @@ public class DataLinkTest extends DataLinkSetup { } } -
\ No newline at end of file diff --git a/aai-core/src/test/java/org/onap/aai/introspection/tools/CreateUUIDTest.java b/aai-core/src/test/java/org/onap/aai/introspection/tools/CreateUUIDTest.java index 6d8508ce..49baf789 100644 --- a/aai-core/src/test/java/org/onap/aai/introspection/tools/CreateUUIDTest.java +++ b/aai-core/src/test/java/org/onap/aai/introspection/tools/CreateUUIDTest.java @@ -26,7 +26,10 @@ import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; import org.onap.aai.AAISetup; -import org.onap.aai.introspection.*; +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.springframework.test.annotation.DirtiesContext; diff --git a/aai-core/src/test/java/org/onap/aai/introspection/tools/DefaultFieldsTest.java b/aai-core/src/test/java/org/onap/aai/introspection/tools/DefaultFieldsTest.java index 664a69c5..704f02a1 100644 --- a/aai-core/src/test/java/org/onap/aai/introspection/tools/DefaultFieldsTest.java +++ b/aai-core/src/test/java/org/onap/aai/introspection/tools/DefaultFieldsTest.java @@ -28,7 +28,10 @@ import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; import org.onap.aai.AAISetup; -import org.onap.aai.introspection.*; +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.springframework.test.annotation.DirtiesContext; diff --git a/aai-core/src/test/java/org/onap/aai/introspection/tools/InjectKeysFromURITest.java b/aai-core/src/test/java/org/onap/aai/introspection/tools/InjectKeysFromURITest.java index cd5bdb93..15ba9a5e 100644 --- a/aai-core/src/test/java/org/onap/aai/introspection/tools/InjectKeysFromURITest.java +++ b/aai-core/src/test/java/org/onap/aai/introspection/tools/InjectKeysFromURITest.java @@ -31,7 +31,10 @@ import java.net.URI; import org.junit.Before; import org.junit.Test; import org.onap.aai.AAISetup; -import org.onap.aai.introspection.*; +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.springframework.test.annotation.DirtiesContext; diff --git a/aai-core/src/test/java/org/onap/aai/introspection/tools/RemoveNonVisiblePropertyTest.java b/aai-core/src/test/java/org/onap/aai/introspection/tools/RemoveNonVisiblePropertyTest.java index a3380ee2..2ca97007 100644 --- a/aai-core/src/test/java/org/onap/aai/introspection/tools/RemoveNonVisiblePropertyTest.java +++ b/aai-core/src/test/java/org/onap/aai/introspection/tools/RemoveNonVisiblePropertyTest.java @@ -27,7 +27,10 @@ import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; import org.onap.aai.AAISetup; -import org.onap.aai.introspection.*; +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.springframework.test.annotation.DirtiesContext; diff --git a/aai-core/src/test/java/org/onap/aai/introspection/validation/IntrospectorValidationTest.java b/aai-core/src/test/java/org/onap/aai/introspection/validation/IntrospectorValidationTest.java index 88e148f1..374ee558 100644 --- a/aai-core/src/test/java/org/onap/aai/introspection/validation/IntrospectorValidationTest.java +++ b/aai-core/src/test/java/org/onap/aai/introspection/validation/IntrospectorValidationTest.java @@ -29,7 +29,10 @@ import org.junit.Ignore; import org.junit.Test; import org.onap.aai.AAISetup; import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.*; +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.tools.IntrospectorValidator; import org.onap.aai.introspection.tools.Issue; import org.onap.aai.introspection.tools.IssueType; diff --git a/aai-core/src/test/java/org/onap/aai/kafka/AAIKafkaEventIntegrationTest.java b/aai-core/src/test/java/org/onap/aai/kafka/AAIKafkaEventIntegrationTest.java new file mode 100644 index 00000000..0f5f47ad --- /dev/null +++ b/aai-core/src/test/java/org/onap/aai/kafka/AAIKafkaEventIntegrationTest.java @@ -0,0 +1,87 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom. 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.kafka; + +import static org.junit.jupiter.api.Assertions.assertFalse; + +import java.util.Collections; + +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.junit.Test; +import org.mockito.Mock; +import org.onap.aai.AAISetup; +import org.onap.aai.PayloadUtil; +import org.skyscreamer.jsonassert.JSONAssert; +import org.skyscreamer.jsonassert.JSONCompareMode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Import; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@ActiveProfiles("kafka") +@Import(KafkaTestConfiguration.class) +@EmbeddedKafka(partitions = 1, topics = { "AAI-EVENT" }) +@TestPropertySource( + properties = { + "jms.bind.address=tcp://localhost:61647", + "aai.events.enabled=true", + "spring.kafka.producer.retries=0", + "spring.kafka.producer.properties.sasl.jaas.config=#{null}", + "spring.kafka.producer.bootstrap-servers=${spring.embedded.kafka.brokers}" + }) +public class AAIKafkaEventIntegrationTest extends AAISetup { + + @Mock + private KafkaTemplate<String, String> kafkaTemplate; + + @Autowired + MessageProducer messageProducer; + + @Autowired + private ConsumerFactory<String, String> consumerFactory; + + @Test + public void onMessage_shouldSendMessageToKafkaTopic_whenAAIEventReceived() + throws Exception { + Consumer<String, String> consumer = consumerFactory.createConsumer(); + + consumer.subscribe(Collections.singletonList("AAI-EVENT")); + + String payload = PayloadUtil.getResourcePayload("aai-event.json"); + String expectedResponse = PayloadUtil.getExpectedPayload("aai-event.json"); + messageProducer.sendMessageToDefaultDestination(payload); + + ConsumerRecords<String, String> consumerRecords = KafkaTestUtils.getRecords(consumer, 10000); + assertFalse(consumerRecords.isEmpty()); + consumerRecords.forEach(consumerRecord -> { + JSONAssert.assertEquals(expectedResponse, consumerRecord.value(), JSONCompareMode.NON_EXTENSIBLE); + }); + } + +} diff --git a/aai-core/src/test/java/org/onap/aai/kafka/AAIKafkaEventJMSConsumerTest.java b/aai-core/src/test/java/org/onap/aai/kafka/AAIKafkaEventJMSConsumerTest.java deleted file mode 100644 index c72499c4..00000000 --- a/aai-core/src/test/java/org/onap/aai/kafka/AAIKafkaEventJMSConsumerTest.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.onap.aai.kafka; - -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import javax.jms.TextMessage; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; -import org.onap.aai.PayloadUtil; -import org.springframework.core.env.Environment; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.kafka.test.context.EmbeddedKafka; -import org.springframework.test.util.ReflectionTestUtils; - -@RunWith(MockitoJUnitRunner.class) -@EmbeddedKafka(partitions = 1, brokerProperties = { "listeners=PLAINTEXT://localhost:9092", "port=9092" }) -public class AAIKafkaEventJMSConsumerTest { - - @Mock - private Environment environment; - - @Mock - private KafkaTemplate<String,String> kafkaTemplate; - - private AAIKafkaEventJMSConsumer aaiKafkaEventJMSConsumer; - - @Before - public void setUp(){ - aaiKafkaEventJMSConsumer = new AAIKafkaEventJMSConsumer(environment,kafkaTemplate); - } - - @Test - public void onMessage_shouldSendMessageToKafkaTopic_whenAAIEventReceived() - throws Exception - { - TextMessage mockTextMessage = mock(TextMessage.class); - String payload = PayloadUtil.getResourcePayload("aai-event.json"); - - when(mockTextMessage.getText()).thenReturn(payload); - aaiKafkaEventJMSConsumer.onMessage(mockTextMessage); - verify(kafkaTemplate, times(1)).send(eq("AAI-EVENT"), anyString()); - } - - @Test - public void onMessage_shouldNotSendMessageToKafkaTopic_whenInvalidEventReceived() throws Exception{ - TextMessage mockTextMessage = mock(TextMessage.class); - String payload = PayloadUtil.getResourcePayload("aai-invalid-event.json"); - when(mockTextMessage.getText()).thenReturn(payload); - aaiKafkaEventJMSConsumer.onMessage(mockTextMessage); - } - - - @Test - public void onMessage_shouldHandleJSONException() throws Exception { - // Arrange - AAIKafkaEventJMSConsumer consumer = new AAIKafkaEventJMSConsumer(null, kafkaTemplate); - TextMessage mockTextMessage = mock(TextMessage.class); - ReflectionTestUtils.setField(consumer, "kafkaTemplate", null); // Simulate null kafkaTemplate - - // Act - consumer.onMessage(mockTextMessage); - - // Assert - // Verify that exception is logged - } - - @Test - public void onMessage_shouldHandleGenericException() throws Exception { - // Arrange - AAIKafkaEventJMSConsumer consumer = new AAIKafkaEventJMSConsumer(null, kafkaTemplate); - TextMessage mockTextMessage = mock(TextMessage.class); - when(mockTextMessage.getText()).thenReturn("{\"event-topic\":\"AAI-EVENT\",\"aaiEventPayload\":{}}"); // Valid JSON but missing required fields - - // Act - consumer.onMessage(mockTextMessage); - - // Assert - // Verify that exception is logged - } - -} diff --git a/aai-core/src/test/java/org/onap/aai/kafka/KafkaTestConfiguration.java b/aai-core/src/test/java/org/onap/aai/kafka/KafkaTestConfiguration.java new file mode 100644 index 00000000..e77f21af --- /dev/null +++ b/aai-core/src/test/java/org/onap/aai/kafka/KafkaTestConfiguration.java @@ -0,0 +1,76 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom. 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.kafka; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.kafka.clients.admin.AdminClientConfig; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.KafkaAdmin; + +@TestConfiguration +public class KafkaTestConfiguration { + + @Value("${spring.embedded.kafka.brokers}") private String bootstrapAddress; + + private String groupId = "test-consumer"; + + @Bean + public KafkaAdmin kafkaAdmin() { + Map<String, Object> configs = new HashMap<>(); + configs.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress); + return new KafkaAdmin(configs); + } + + @Bean + public ConsumerFactory<String, String> consumerFactory() { + Map<String, Object> props = new HashMap<>(); + props.put( + ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, + bootstrapAddress); + props.put( + ConsumerConfig.GROUP_ID_CONFIG, + groupId); + props.put( + ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, + StringDeserializer.class); + props.put( + ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, + StringDeserializer.class); + props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + return new DefaultKafkaConsumerFactory<>(props); + } + + @Bean + public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory(ConsumerFactory<String, String> consumerFactory) { + + ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(consumerFactory); + return factory; + } +} diff --git a/aai-core/src/test/java/org/onap/aai/parsers/query/GraphTraversalTest.java b/aai-core/src/test/java/org/onap/aai/parsers/query/GraphTraversalTest.java index 04a29916..7651d409 100644 --- a/aai-core/src/test/java/org/onap/aai/parsers/query/GraphTraversalTest.java +++ b/aai-core/src/test/java/org/onap/aai/parsers/query/GraphTraversalTest.java @@ -52,8 +52,6 @@ import org.onap.aai.TinkerpopUpgrade; import org.onap.aai.db.props.AAIProperties; import org.onap.aai.exceptions.AAIException; import org.onap.aai.introspection.ModelType; -import org.onap.aai.query.builder.Pageable; -import org.onap.aai.query.builder.QueryBuilder; import org.onap.aai.rest.RestTokens; import org.onap.aai.serialization.engines.JanusGraphDBEngine; import org.onap.aai.serialization.engines.QueryStyle; diff --git a/aai-core/src/test/java/org/onap/aai/parsers/query/RelationshipGremlinQueryTest.java b/aai-core/src/test/java/org/onap/aai/parsers/query/RelationshipGremlinQueryTest.java index 96a22d4e..2675045c 100644 --- a/aai-core/src/test/java/org/onap/aai/parsers/query/RelationshipGremlinQueryTest.java +++ b/aai-core/src/test/java/org/onap/aai/parsers/query/RelationshipGremlinQueryTest.java @@ -40,7 +40,10 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.onap.aai.AAISetup; import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.*; +import org.onap.aai.introspection.Introspector; +import org.onap.aai.introspection.IntrospectorFactory; +import org.onap.aai.introspection.LoaderFactory; +import org.onap.aai.introspection.ModelType; import org.onap.aai.nodes.NodeIngestor; import org.onap.aai.serialization.engines.JanusGraphDBEngine; import org.onap.aai.serialization.engines.QueryStyle; diff --git a/aai-core/src/test/java/org/onap/aai/parsers/query/RelationshipQueryTest.java b/aai-core/src/test/java/org/onap/aai/parsers/query/RelationshipQueryTest.java index b0f6b240..accb471c 100644 --- a/aai-core/src/test/java/org/onap/aai/parsers/query/RelationshipQueryTest.java +++ b/aai-core/src/test/java/org/onap/aai/parsers/query/RelationshipQueryTest.java @@ -37,7 +37,10 @@ import org.junit.Ignore; import org.junit.Test; import org.onap.aai.AAISetup; import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.*; +import org.onap.aai.introspection.Introspector; +import org.onap.aai.introspection.IntrospectorFactory; +import org.onap.aai.introspection.LoaderFactory; +import org.onap.aai.introspection.ModelType; import org.onap.aai.serialization.engines.JanusGraphDBEngine; import org.onap.aai.serialization.engines.QueryStyle; import org.onap.aai.serialization.engines.TransactionalGraphEngine; diff --git a/aai-core/src/test/java/org/onap/aai/parsers/query/UniqueRelationshipQueryTest.java b/aai-core/src/test/java/org/onap/aai/parsers/query/UniqueRelationshipQueryTest.java index 68fc4376..a2f04c76 100644 --- a/aai-core/src/test/java/org/onap/aai/parsers/query/UniqueRelationshipQueryTest.java +++ b/aai-core/src/test/java/org/onap/aai/parsers/query/UniqueRelationshipQueryTest.java @@ -40,7 +40,10 @@ import org.junit.Ignore; import org.junit.Test; import org.onap.aai.AAISetup; import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.*; +import org.onap.aai.introspection.Introspector; +import org.onap.aai.introspection.IntrospectorFactory; +import org.onap.aai.introspection.LoaderFactory; +import org.onap.aai.introspection.ModelType; import org.onap.aai.nodes.NodeIngestor; import org.onap.aai.serialization.engines.JanusGraphDBEngine; import org.onap.aai.serialization.engines.QueryStyle; diff --git a/aai-core/src/test/java/org/onap/aai/parsers/uri/URIParserTest.java b/aai-core/src/test/java/org/onap/aai/parsers/uri/URIParserTest.java index 74914cce..ebef3cc3 100644 --- a/aai-core/src/test/java/org/onap/aai/parsers/uri/URIParserTest.java +++ b/aai-core/src/test/java/org/onap/aai/parsers/uri/URIParserTest.java @@ -23,20 +23,13 @@ package org.onap.aai.parsers.uri; import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import java.io.UnsupportedEncodingException; import java.net.URI; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; import javax.annotation.PostConstruct; import javax.ws.rs.core.MultivaluedHashMap; @@ -47,14 +40,12 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.ArgumentCaptor; -import org.mockito.InOrder; import org.onap.aai.AAISetup; import org.onap.aai.edges.enums.EdgeType; 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.exceptions.AAIUnknownObjectException; import org.onap.aai.setup.SchemaVersion; diff --git a/aai-core/src/test/java/org/onap/aai/parsers/uri/URIToDBKeyTest.java b/aai-core/src/test/java/org/onap/aai/parsers/uri/URIToDBKeyTest.java index f9055b1d..4bac547d 100644 --- a/aai-core/src/test/java/org/onap/aai/parsers/uri/URIToDBKeyTest.java +++ b/aai-core/src/test/java/org/onap/aai/parsers/uri/URIToDBKeyTest.java @@ -36,7 +36,9 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.onap.aai.AAISetup; import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.*; +import org.onap.aai.introspection.Loader; +import org.onap.aai.introspection.LoaderFactory; +import org.onap.aai.introspection.ModelType; import org.onap.aai.parsers.exceptions.DoesNotStartWithValidNamespaceException; public class URIToDBKeyTest extends AAISetup { diff --git a/aai-core/src/test/java/org/onap/aai/parsers/uri/URIToObjectTest.java b/aai-core/src/test/java/org/onap/aai/parsers/uri/URIToObjectTest.java index 52aa470d..2aad37a0 100644 --- a/aai-core/src/test/java/org/onap/aai/parsers/uri/URIToObjectTest.java +++ b/aai-core/src/test/java/org/onap/aai/parsers/uri/URIToObjectTest.java @@ -38,7 +38,10 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.onap.aai.AAISetup; import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.*; +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.SchemaVersion; import org.springframework.test.annotation.DirtiesContext; diff --git a/aai-core/src/test/java/org/onap/aai/parsers/uri/URIToRelationshipObjectTest.java b/aai-core/src/test/java/org/onap/aai/parsers/uri/URIToRelationshipObjectTest.java index ee8cce21..f94d9241 100644 --- a/aai-core/src/test/java/org/onap/aai/parsers/uri/URIToRelationshipObjectTest.java +++ b/aai-core/src/test/java/org/onap/aai/parsers/uri/URIToRelationshipObjectTest.java @@ -38,7 +38,10 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.onap.aai.AAISetup; import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.*; +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.setup.SchemaVersion; import org.springframework.test.annotation.DirtiesContext; diff --git a/aai-core/src/test/java/org/onap/aai/query/builder/QueryBuilderTestAbstraction.java b/aai-core/src/test/java/org/onap/aai/query/builder/QueryBuilderTestAbstraction.java index 6d10115a..8f4a209b 100644 --- a/aai-core/src/test/java/org/onap/aai/query/builder/QueryBuilderTestAbstraction.java +++ b/aai-core/src/test/java/org/onap/aai/query/builder/QueryBuilderTestAbstraction.java @@ -52,6 +52,7 @@ import org.onap.aai.introspection.Loader; import org.onap.aai.introspection.LoaderFactory; import org.onap.aai.introspection.ModelType; import org.onap.aai.nodes.NodeIngestor; +import org.onap.aai.rest.notification.NotificationService; import org.onap.aai.serialization.db.EdgeSerializer; import org.onap.aai.serialization.db.exceptions.NoEdgeRuleFoundException; import org.onap.aai.serialization.queryformats.QueryFormatTestHelper; @@ -67,7 +68,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @ContextConfiguration( classes = {ConfigConfiguration.class, QueryTestsConfigTranslator.class, NodeIngestor.class, EdgeIngestor.class, EdgeSerializer.class, SpringContextAware.class, IntrospectionConfig.class, - XmlFormatTransformerConfiguration.class}) + XmlFormatTransformerConfiguration.class, LoaderFactory.class, NotificationService.class}) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) @TestPropertySource( properties = {"schema.translator.list = config", "schema.nodes.location=src/test/resources/onap/oxm", diff --git a/aai-core/src/test/java/org/onap/aai/rest/ImpliedDeleteIntegrationTest.java b/aai-core/src/test/java/org/onap/aai/rest/ImpliedDeleteIntegrationTest.java index e6664e1a..218c3a24 100644 --- a/aai-core/src/test/java/org/onap/aai/rest/ImpliedDeleteIntegrationTest.java +++ b/aai-core/src/test/java/org/onap/aai/rest/ImpliedDeleteIntegrationTest.java @@ -46,8 +46,8 @@ import org.onap.aai.PayloadUtil; import org.onap.aai.db.props.AAIProperties; import org.onap.aai.dbmap.AAIGraph; import org.onap.aai.introspection.ModelType; -import org.onap.aai.rest.ueb.NotificationEvent; -import org.onap.aai.rest.ueb.UEBNotification; +import org.onap.aai.rest.notification.NotificationEvent; +import org.onap.aai.rest.notification.UEBNotification; import org.onap.aai.serialization.engines.QueryStyle; import org.skyscreamer.jsonassert.JSONAssert; import org.slf4j.Logger; diff --git a/aai-core/src/test/java/org/onap/aai/rest/NotificationDmaapEventTest.java b/aai-core/src/test/java/org/onap/aai/rest/NotificationDmaapEventTest.java index 399ef7e0..4b52462e 100644 --- a/aai-core/src/test/java/org/onap/aai/rest/NotificationDmaapEventTest.java +++ b/aai-core/src/test/java/org/onap/aai/rest/NotificationDmaapEventTest.java @@ -57,8 +57,8 @@ import org.onap.aai.db.props.AAIProperties; import org.onap.aai.dbmap.AAIGraph; import org.onap.aai.exceptions.AAIException; import org.onap.aai.introspection.ModelType; -import org.onap.aai.rest.ueb.NotificationEvent; -import org.onap.aai.rest.ueb.UEBNotification; +import org.onap.aai.rest.notification.NotificationEvent; +import org.onap.aai.rest.notification.UEBNotification; import org.onap.aai.serialization.engines.QueryStyle; import org.skyscreamer.jsonassert.JSONAssert; import org.springframework.test.annotation.DirtiesContext; diff --git a/aai-core/src/test/java/org/onap/aai/rest/RestHandlerTest.java b/aai-core/src/test/java/org/onap/aai/rest/RestHandlerTest.java index 494d7e4e..b408940e 100644 --- a/aai-core/src/test/java/org/onap/aai/rest/RestHandlerTest.java +++ b/aai-core/src/test/java/org/onap/aai/rest/RestHandlerTest.java @@ -22,7 +22,8 @@ package org.onap.aai.rest; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; import org.junit.Test; diff --git a/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryNotificationIntegrationTest.java b/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryNotificationIntegrationTest.java new file mode 100644 index 00000000..e8e3d691 --- /dev/null +++ b/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryNotificationIntegrationTest.java @@ -0,0 +1,212 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom. 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.db; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriBuilder; +import javax.ws.rs.core.UriInfo; + +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; +import org.javatuples.Pair; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.onap.aai.AAISetup; +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.parsers.query.QueryParser; +import org.onap.aai.query.builder.QueryOptions; +import org.onap.aai.rest.notification.UEBNotification; +import org.onap.aai.restcore.HttpMethod; +import org.onap.aai.serialization.engines.TransactionalGraphEngine; +import org.springframework.test.annotation.DirtiesContext; + +import com.fasterxml.jackson.databind.ObjectMapper; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) +public class HttpEntryNotificationIntegrationTest extends AAISetup { + + private static final MediaType APPLICATION_JSON = MediaType.valueOf("application/json"); + private Loader loader; + private TransactionalGraphEngine dbEngine; + private GraphTraversalSource traversal; + private HttpHeaders httpHeaders; + private UriInfo uriInfo; + private MultivaluedMap<String, String> headersMultiMap; + private MultivaluedMap<String, String> queryParameters; + private List<String> aaiRequestContextList; + private List<MediaType> outputMediaTypes; + + ObjectMapper mapper = new ObjectMapper(); + + @Before + public void setup() { + + httpHeaders = Mockito.mock(HttpHeaders.class); + uriInfo = Mockito.mock(UriInfo.class); + + headersMultiMap = new MultivaluedHashMap<>(); + queryParameters = Mockito.spy(new MultivaluedHashMap<>()); + + headersMultiMap.add("X-FromAppId", "JUNIT"); + headersMultiMap.add("X-TransactionId", UUID.randomUUID().toString()); + headersMultiMap.add("Real-Time", "true"); + headersMultiMap.add("Accept", "application/json"); + headersMultiMap.add("aai-request-context", ""); + + outputMediaTypes = new ArrayList<>(); + outputMediaTypes.add(APPLICATION_JSON); + + aaiRequestContextList = new ArrayList<>(); + aaiRequestContextList.add(""); + + traversalHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion()); + loader = traversalHttpEntry.getLoader(); + dbEngine = traversalHttpEntry.getDbEngine(); + traversal = dbEngine.tx().traversal(); + + when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes); + when(httpHeaders.getRequestHeaders()).thenReturn(headersMultiMap); + + when(httpHeaders.getRequestHeader("aai-request-context")).thenReturn(aaiRequestContextList); + + when(uriInfo.getQueryParameters()).thenReturn(queryParameters); + when(uriInfo.getQueryParameters(false)).thenReturn(queryParameters); + + // TODO - Check if this is valid since RemoveDME2QueryParameters seems to be + // very unreasonable + Mockito.doReturn(null).when(queryParameters).remove(any()); + + when(httpHeaders.getMediaType()).thenReturn(APPLICATION_JSON); + } + + @After + public void rollback() { + dbEngine.rollback(); + } + + @Test + public void notificationOnRelatedToTest() throws UnsupportedEncodingException, AAIException { + + Loader ld = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDefaultVersion()); + UEBNotification uebNotification = Mockito.spy(new UEBNotification(ld, loaderFactory, schemaVersions)); + traversalHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion(), uebNotification); + + Loader loader = traversalHttpEntry.getLoader(); + TransactionalGraphEngine dbEngine = traversalHttpEntry.getDbEngine(); + // Put pserver + String uri = "/cloud-infrastructure/pservers/pserver/junit-edge-test-pserver"; + String content = "{\"hostname\":\"junit-edge-test-pserver\"}"; + doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, content); + // Put complex + uri = "/cloud-infrastructure/complexes/complex/junit-edge-test-complex"; + content = "{\"physical-location-id\":\"junit-edge-test-complex\",\"physical-location-type\":\"AAIDefault\",\"street1\":\"AAIDefault\",\"city\":\"AAIDefault\",\"state\":\"NJ\",\"postal-code\":\"07748\",\"country\":\"USA\",\"region\":\"US\"}"; + doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, content); + + // PutEdge + uri = "/cloud-infrastructure/complexes/complex/junit-edge-test-complex/relationship-list/relationship"; + content = "{\"related-to\":\"pserver\",\"related-link\":\"/aai/" + schemaVersions.getDefaultVersion().toString() + + "/cloud-infrastructure/pservers/pserver/junit-edge-test-pserver\",\"relationship-label\":\"org.onap.relationships.inventory.LocatedIn\"}"; + + doNothing().when(uebNotification).triggerEvents(); + Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT_EDGE, uri, + content); + + assertEquals("Expected the pserver relationship to be deleted", 200, response.getStatus()); + assertEquals("Two notifications", 2, uebNotification.getEvents().size()); + assertEquals("Notification generated for PUT edge", "UPDATE", + uebNotification.getEvents().get(0).getEventHeader().getValue("action").toString()); + assertThat("Event body for the edge create has the related to", + uebNotification.getEvents().get(0).getObj().marshal(false), + containsString("cloud-infrastructure/pservers/pserver/junit-edge-test-pserver")); + + response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.DELETE_EDGE, uri, content); + assertEquals("Expected the pserver relationship to be deleted", 204, response.getStatus()); + assertEquals("Two notifications", 2, uebNotification.getEvents().size()); + assertEquals("Notification generated for DELETE edge", "UPDATE", + uebNotification.getEvents().get(0).getEventHeader().getValue("action").toString()); + assertThat("Event body for the edge delete does not have the related to", + uebNotification.getEvents().get(0).getObj().marshal(false), + not(containsString("cloud-infrastructure/pservers/pserver/junit-edge-test-pserver"))); + dbEngine.rollback(); + + } + + private Response doRequest(HttpEntry httpEntry, Loader loader, TransactionalGraphEngine dbEngine, HttpMethod method, + String uri, String requestBody) throws UnsupportedEncodingException, AAIException { + return doRequest(httpEntry, loader, dbEngine, method, uri, requestBody, null); + } + + private Response doRequest(HttpEntry httpEntry, Loader loader, TransactionalGraphEngine dbEngine, HttpMethod method, + String uri, String requestBody, QueryOptions queryOptions) throws UnsupportedEncodingException, AAIException { + URI uriObject = UriBuilder.fromPath(uri).build(); + QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject); + String objType; + if (!uriQuery.getContainerType().equals("")) { + objType = uriQuery.getContainerType(); + } else { + objType = uriQuery.getResultType(); + } + if (uri.endsWith("relationship")) { + objType = "relationship"; + } + Introspector obj; + if (method.equals(HttpMethod.GET) || method.equals(HttpMethod.GET_RELATIONSHIP)) { + obj = loader.introspectorFromName(objType); + } else { + obj = loader.unmarshal(objType, requestBody, org.onap.aai.restcore.MediaType.getEnum("application/json")); + } + + DBRequest.Builder builder = new DBRequest.Builder(method, uriObject, uriQuery, obj, httpHeaders, uriInfo, + "JUNIT-TRANSACTION"); + DBRequest dbRequest = requestBody != null + ? builder.rawRequestContent(requestBody).build() + : builder.build(); + + List<DBRequest> dbRequestList = Collections.singletonList(dbRequest); + + Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = httpEntry.process(dbRequestList, "JUNIT", + Collections.emptySet(), true, queryOptions); + return responsesTuple.getValue1().get(0).getValue1(); + } +} diff --git a/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryTest.java b/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryTest.java index 39539988..2578eef4 100644 --- a/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryTest.java +++ b/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryTest.java @@ -24,15 +24,14 @@ import static org.onap.aai.edges.enums.AAIDirection.NONE; import static org.hamcrest.Matchers.containsString; - import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; - import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; - import static org.mockito.Mockito.doNothing; - import static org.mockito.Mockito.times; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -40,8 +39,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; - import com.google.gson.JsonObject; - import com.google.gson.JsonParser; import java.io.UnsupportedEncodingException; import java.net.URI; @@ -69,7 +66,6 @@ import org.json.JSONArray; import org.json.JSONObject; import org.junit.After; - import org.junit.Assert; import org.junit.Before; import org.junit.FixMethodOrder; import org.junit.Test; @@ -84,7 +80,6 @@ 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.parsers.query.QueryParser; import org.onap.aai.prevalidation.ValidationService; import org.onap.aai.query.builder.Pageable; @@ -95,8 +90,8 @@ import org.onap.aai.rest.db.responses.Relationship; import org.onap.aai.rest.db.responses.RelationshipWrapper; import org.onap.aai.rest.db.responses.ServiceException; - import org.onap.aai.rest.ueb.UEBNotification; - import org.onap.aai.restcore.HttpMethod; +import org.onap.aai.rest.notification.NotificationService; +import org.onap.aai.restcore.HttpMethod; import org.onap.aai.serialization.engines.QueryStyle; import org.onap.aai.serialization.engines.TransactionalGraphEngine; import org.onap.aai.util.AAIConfig; @@ -110,6 +105,7 @@ public class HttpEntryTest extends AAISetup { @MockBean ValidationService validationService; + @MockBean NotificationService notificationService; protected static final MediaType APPLICATION_JSON = MediaType.valueOf("application/json"); @@ -213,7 +209,7 @@ JSONAssert.assertEquals(expectedResponseBody, actualResponseBody, JSONCompareMode.NON_EXTENSIBLE); assertEquals("Expected the pserver to be returned", 200, response.getStatus()); - verify(validationService, times(1)).validate(any()); + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test @@ -249,7 +245,7 @@ JSONAssert.assertEquals(expectedResponseBody, actualResponseBody, JSONCompareMode.NON_EXTENSIBLE); assertEquals("Expected the pservers to be returned", 200, response.getStatus()); - verify(validationService, times(1)).validate(any()); + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test @@ -283,7 +279,7 @@ assertNull(response.getHeaderString("total-results")); assertEquals(1, actualResponseBody.getJSONArray("pserver").length()); assertEquals("Expected the pservers to be returned", 200, response.getStatus()); - verify(validationService, times(1)).validate(any()); + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); queryOptions = QueryOptions.builder().pageable(new Pageable(0,5).includeTotalCount()).build(); response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, queryOptions); @@ -307,6 +303,7 @@ assertTrue( response.getEntity().toString().contains("Node Not Found:No Node of type pserver found at: /cloud-infrastructure/pservers")); assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatus()); + verify(notificationService, never()).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @@ -344,7 +341,7 @@ assertEquals(2, Integer.parseInt(totalPages)); assertEquals(1, actualResponseBody.getJSONArray("pserver").length()); assertEquals("Expected the pservers to be returned", 200, response.getStatus()); - verify(validationService, times(1)).validate(any()); + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); queryOptions = QueryOptions.builder().pageable(new Pageable(0, 2)).build(); response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, queryOptions); @@ -392,7 +389,6 @@ actualResponseBody = new JSONObject(response.getEntity().toString()); assertEquals("theEquipType2", actualResponseBody.getJSONArray("pserver").getJSONObject(0).getString("equip-type")); assertEquals("theEquipType", actualResponseBody.getJSONArray("pserver").getJSONObject(1).getString("equip-type")); - } @Test @@ -401,6 +397,7 @@ Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri); assertEquals("The pserver is not found", 404, response.getStatus()); + verify(notificationService, never()).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test @@ -410,7 +407,7 @@ Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody); assertEquals("Expecting the pserver to be created", 201, response.getStatus()); - verify(validationService, times(1)).validate(any()); + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test @@ -428,6 +425,7 @@ assertEquals( "Resource version specified on create:resource-version passed for create of /cloud-infrastructure/pservers/pserver/theHostname", errorResponseEntity.getRequestError().getServiceException().getVariables().get(2)); + verify(notificationService, never()).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test @@ -449,7 +447,7 @@ assertEquals("Expecting the pserver to be updated", 200, response.getStatus()); assertTrue("That old properties are removed", traversal.V().has("hostname", "updatedHostname").hasNot("number-of-cpus").hasNext()); - verify(validationService, times(1)).validate(any()); + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test @@ -473,6 +471,7 @@ assertEquals( "Precondition Failed:resource-version MISMATCH for update of /cloud-infrastructure/pservers/pserver/updatedHostname", errorResponseEntity.getRequestError().getServiceException().getVariables().get(2)); + verify(notificationService, never()).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test @@ -518,7 +517,7 @@ traversal.V().has("aai-node-type", "p-interface").has("aai-uri", uri).has("interface-name", "p1") .out("tosca.relationships.network.BindsTo").has("aai-node-type", "pserver") .has("hostname", "hostname").hasNext()); - verify(validationService, times(1)).validate(any()); + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test @@ -538,7 +537,7 @@ assertTrue("object should be updated while keeping old properties", traversal.V().has("aai-node-type", "pserver").has("hostname", "new-hostname") .has("equip-type", "the-equip-type").hasNext()); - verify(validationService, times(1)).validate(any()); + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test @@ -555,7 +554,7 @@ doDelete(resourceVersion, uri, "pserver").getStatus()); assertTrue("Expecting the pserver to be deleted", !traversal.V().has("aai-node-type", "pserver").has("hostname", "the-hostname").hasNext()); - verify(validationService, times(1)).validate(any()); + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test @@ -605,7 +604,7 @@ .has(EdgeProperty.PREVENT_DELETE.toString(), "IN"); assertTrue("p-server has incoming edge from complex", vertexQuery.hasNext()); assertTrue("Created Edge has expected properties", edgeQuery.hasNext()); - verify(validationService, times(1)).validate(any()); + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test @@ -724,7 +723,7 @@ assertEquals("Expected get to succeed", 200, response.getStatus()); assertThat(responseEntity, containsString("/cloud-infrastructure/pservers/pserver/pserver-1")); assertThat(responseEntity, containsString("/cloud-infrastructure/pservers/pserver/pserver-2")); - verify(validationService, times(1)).validate(any()); + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test @@ -759,7 +758,7 @@ assertEquals("Expected the response to be successful", 200, response.getStatus()); assertThat("Related pserver is returned", response.getEntity().toString(), containsString("\"hostname\":\"related-to-pserver\"")); - verify(validationService, times(1)).validate(any()); + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @@ -788,7 +787,7 @@ Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri); assertThat("Related to pserver is returned.", response.getEntity().toString(), containsString("\"hostname\":\"abstract-pserver\"")); - verify(validationService, times(1)).validate(any()); + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test @@ -833,7 +832,7 @@ relationships[0].getRelatedLink()); assertEquals("complex.physical-location-id", relationships[0].getRelationshipData()[0].getRelationshipKey()); assertEquals("related-to-complex", relationships[0].getRelationshipData()[0].getRelationshipValue()); - verify(validationService, times(1)).validate(any()); + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } @Test @@ -891,53 +890,7 @@ JSONAssert.assertEquals(expectedResponseBody, actualResponseBody, JSONCompareMode.NON_EXTENSIBLE); queryParameters.remove("format"); - verify(validationService, times(1)).validate(any()); - } - - @Test - public void notificationOnRelatedToTest() throws UnsupportedEncodingException, AAIException { - - Loader ld = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDefaultVersion()); - UEBNotification uebNotification = Mockito.spy(new UEBNotification(ld, loaderFactory, schemaVersions)); - traversalHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion(), uebNotification); - - Loader loader = traversalHttpEntry.getLoader(); - TransactionalGraphEngine dbEngine = traversalHttpEntry.getDbEngine(); - // Put pserver - String uri = "/cloud-infrastructure/pservers/pserver/junit-edge-test-pserver"; - String content = "{\"hostname\":\"junit-edge-test-pserver\"}"; - doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, content); - // Put complex - uri = "/cloud-infrastructure/complexes/complex/junit-edge-test-complex"; - content = "{\"physical-location-id\":\"junit-edge-test-complex\",\"physical-location-type\":\"AAIDefault\",\"street1\":\"AAIDefault\",\"city\":\"AAIDefault\",\"state\":\"NJ\",\"postal-code\":\"07748\",\"country\":\"USA\",\"region\":\"US\"}"; - doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, content); - - // PutEdge - uri = "/cloud-infrastructure/complexes/complex/junit-edge-test-complex/relationship-list/relationship"; - content = "{\"related-to\":\"pserver\",\"related-link\":\"/aai/" + schemaVersions.getDefaultVersion().toString() - + "/cloud-infrastructure/pservers/pserver/junit-edge-test-pserver\",\"relationship-label\":\"org.onap.relationships.inventory.LocatedIn\"}"; - - doNothing().when(uebNotification).triggerEvents(); - Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT_EDGE, uri, content); - - assertEquals("Expected the pserver relationship to be deleted", 200, response.getStatus()); - assertEquals("Two notifications", 2, uebNotification.getEvents().size()); - assertEquals("Notification generated for PUT edge", "UPDATE", - uebNotification.getEvents().get(0).getEventHeader().getValue("action").toString()); - assertThat("Event body for the edge create has the related to", - uebNotification.getEvents().get(0).getObj().marshal(false), - containsString("cloud-infrastructure/pservers/pserver/junit-edge-test-pserver")); - - response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.DELETE_EDGE, uri, content); - assertEquals("Expected the pserver relationship to be deleted", 204, response.getStatus()); - assertEquals("Two notifications", 2, uebNotification.getEvents().size()); - assertEquals("Notification generated for DELETE edge", "UPDATE", - uebNotification.getEvents().get(0).getEventHeader().getValue("action").toString()); - assertThat("Event body for the edge delete does not have the related to", - uebNotification.getEvents().get(0).getObj().marshal(false), - not(containsString("cloud-infrastructure/pservers/pserver/junit-edge-test-pserver"))); - dbEngine.rollback(); - + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } private Response doRequest(HttpEntry httpEntry, Loader loader, TransactionalGraphEngine dbEngine, HttpMethod method, @@ -1035,6 +988,6 @@ JSONAssert.assertEquals(expectedResponseBody, actualResponseBody, JSONCompareMode.NON_EXTENSIBLE); assertEquals("Expected the pserver to be returned", 200, response.getStatus()); - verify(validationService, times(1)).validate(any()); + verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any()); } } diff --git a/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryTransactionTest.java b/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryTransactionTest.java new file mode 100644 index 00000000..0c2b22ea --- /dev/null +++ b/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryTransactionTest.java @@ -0,0 +1,126 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom. 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.db; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.UriBuilder; +import javax.ws.rs.core.UriInfo; + +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; +import org.janusgraph.core.JanusGraphException; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.onap.aai.AAISetup; +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.parsers.query.QueryParser; +import org.onap.aai.restcore.HttpMethod; +import org.onap.aai.restcore.MediaType; +import org.onap.aai.serialization.engines.TransactionalGraphEngine; + +import lombok.SneakyThrows; + +public class HttpEntryTransactionTest extends AAISetup { + + @Mock UriInfo uriInfoMock; + @Mock MultivaluedMap<String, String> queryParamsMock; + @Mock HttpHeaders headersMock; + + @Before + public void setup() { + when(uriInfoMock.getQueryParameters(anyBoolean())).thenReturn(queryParamsMock); + when(queryParamsMock.getFirst("depth")).thenReturn("0"); + when(headersMock.getRequestHeader("aai-request-context")).thenReturn(null); + } + + @Test + public void thatDBRequestsAreWritten() throws AAIException, UnsupportedEncodingException { + HttpEntry httpEntry = SpringContextAware.getBean("requestScopedTraversalUriHttpEntry", HttpEntry.class); + httpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion()); + TransactionalGraphEngine dbEngine = httpEntry.getDbEngine(); + Loader loader = httpEntry.getLoader(); + + List<String> hostnames = Arrays.asList("test1", "test2", "test3"); + List<DBRequest> dbRequests = createDbRequests(dbEngine, loader, hostnames); + + httpEntry.process(dbRequests, SERVICE_NAME); + + GraphTraversalSource source = dbEngine.startTransaction().traversal(); + Long pserverCount = source.V().has("aai-node-type","pserver").count().next(); + assertEquals(3, pserverCount.intValue()); + } + + @Test + // same test, only that JanusgraphException is thrown + public void thatDBRequestsAreRolledBack() throws AAIException, UnsupportedEncodingException { + HttpEntry httpEntry = SpringContextAware.getBean("requestScopedTraversalUriHttpEntry", HttpEntry.class); + httpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion()); + TransactionalGraphEngine dbEngine = httpEntry.getDbEngine(); + Loader loader = httpEntry.getLoader(); + + List<String> hostnames = Arrays.asList("test1", "test2", "test3"); + List<DBRequest> dbRequests = createDbRequests(dbEngine, loader, hostnames); + + DBRequest request2Spy = spy(dbRequests.get(1)); + QueryParser uriQuerySpy = spy(dbRequests.get(1).getParser()); + when(request2Spy.getParser()).thenReturn(uriQuerySpy); + dbRequests.set(1, request2Spy); + when(uriQuerySpy.getQueryBuilder()).thenThrow(new JanusGraphException("")); + + httpEntry.process(dbRequests, SERVICE_NAME); + + GraphTraversalSource source = dbEngine.startTransaction().traversal(); + Long pserverCount = source.V().has("aai-node-type","pserver").count().next(); + assertEquals(0, pserverCount.intValue()); + } + + @SneakyThrows + private List<DBRequest> createDbRequests(TransactionalGraphEngine dbEngine, Loader loader, List<String> hostnames) { + List<DBRequest> dbRequests = new ArrayList<>(); + + for(String hostname: hostnames) { + URI uriObject = UriBuilder.fromPath("/cloud-infrastructure/pservers/pserver/" + hostname).build(); + QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject); + String content = "{\"hostname\":\"" + hostname + "\"}"; + Introspector obj = loader.unmarshal(uriQuery.getResultType(), content,MediaType.APPLICATION_JSON_TYPE); + DBRequest request = new DBRequest.Builder(HttpMethod.PUT, uriObject, uriQuery, obj, headersMock, uriInfoMock, "someTransaction") + .rawRequestContent(content).build(); + dbRequests.add(request); + } + + return dbRequests; + } +} diff --git a/aai-core/src/test/java/org/onap/aai/rest/notification/NotificationServiceTest.java b/aai-core/src/test/java/org/onap/aai/rest/notification/NotificationServiceTest.java new file mode 100644 index 00000000..95301c6f --- /dev/null +++ b/aai-core/src/test/java/org/onap/aai/rest/notification/NotificationServiceTest.java @@ -0,0 +1,127 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom. 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.notification; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.ws.rs.core.Response.Status; + +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex; +import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.aai.AAISetup; +import org.onap.aai.db.props.AAIProperties; +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.introspection.Introspector; +import org.onap.aai.introspection.LoaderFactory; +import org.onap.aai.prevalidation.ValidationService; +import org.onap.aai.serialization.db.DBSerializer; +import org.onap.aai.serialization.engines.query.QueryEngine; +import org.onap.aai.setup.SchemaVersion; +import org.onap.aai.setup.SchemaVersions; + +public class NotificationServiceTest extends AAISetup { + + @Mock LoaderFactory loaderFactory; + @Mock SchemaVersions schemaVersions; + @Mock UEBNotification uebNotification; + @Mock ValidationService validationService; + @Mock DBSerializer dbSerializer; + @Mock QueryEngine queryEngine; + @Mock Introspector introspector; + + boolean isDeltaEventsEnabled = false; + String basePath = "/aai"; + NotificationService notificationService; + + @Before + public void setup() throws UnsupportedEncodingException, AAIException { + MockitoAnnotations.openMocks(this); + + when(dbSerializer.touchStandardVertexPropertiesForEdges()).thenReturn(Collections.emptySet()); + when(dbSerializer.getLatestVersionView(any(),anyInt())).thenReturn(introspector); + + notificationService = new NotificationService(validationService, loaderFactory, basePath, isDeltaEventsEnabled); + when(schemaVersions.getDefaultVersion()).thenReturn(new SchemaVersion("v29")); + doNothing().when(uebNotification).createNotificationEvent(any(),any(),any(),any(),any(),any(),any()); + } + + @Test + public void thatNotificationsCanBeCreatedWithoutEdges() throws AAIException, UnsupportedEncodingException { + + Map<String, Object> properties = new HashMap<>(); + properties.put(AAIProperties.NODE_TYPE, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "pserver", new HashMap<>()))); + properties.put(AAIProperties.AAI_URI, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "/pservers/pserver/hostname", new HashMap<>()))); + properties.put(AAIProperties.CREATED_TS, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "12", new HashMap<>()))); + properties.put(AAIProperties.LAST_MOD_TS, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "34", new HashMap<>()))); + + Vertex vertex = new DetachedVertex("1","label", properties); + Set<Vertex> mainVertexesToNotifyOn = new HashSet<>(); + mainVertexesToNotifyOn.add(vertex); + SchemaVersion schemaVersion = new SchemaVersion("v29"); + when(dbSerializer.getUpdatedVertexes()).thenReturn(Collections.emptyMap()); + + notificationService.generateEvents(uebNotification, AAIProperties.MINIMUM_DEPTH, "sourceOfTruth", dbSerializer, "transactionId", queryEngine, mainVertexesToNotifyOn, schemaVersion); + + verify(uebNotification, times(1)).createNotificationEvent(eq("transactionId"), eq("sourceOfTruth"), eq(Status.OK), eq(URI.create("/aai/v29/pservers/pserver/hostname")), eq(introspector), any(), eq("/aai")); + verify(validationService, times(1)).validate(anyList()); + verify(uebNotification, times(1)).triggerEvents(); + } + + @Test + public void thatValidationCanBeDisabled() throws AAIException, UnsupportedEncodingException { + + Map<String, Object> properties = new HashMap<>(); + properties.put(AAIProperties.NODE_TYPE, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "pserver", new HashMap<>()))); + properties.put(AAIProperties.AAI_URI, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "/pservers/pserver/hostname", new HashMap<>()))); + properties.put(AAIProperties.CREATED_TS, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "12", new HashMap<>()))); + properties.put(AAIProperties.LAST_MOD_TS, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "34", new HashMap<>()))); + + Vertex vertex = new DetachedVertex("1","label", properties); + Set<Vertex> mainVertexesToNotifyOn = new HashSet<>(); + mainVertexesToNotifyOn.add(vertex); + SchemaVersion schemaVersion = new SchemaVersion("v29"); + when(dbSerializer.getUpdatedVertexes()).thenReturn(Collections.emptyMap()); + + notificationService = new NotificationService(null, loaderFactory, basePath, isDeltaEventsEnabled); + notificationService.generateEvents(uebNotification, AAIProperties.MINIMUM_DEPTH, "sourceOfTruth", dbSerializer, "transactionId", queryEngine, mainVertexesToNotifyOn, schemaVersion); + + verify(uebNotification, times(1)).triggerEvents(); + } +} diff --git a/aai-core/src/test/java/org/onap/aai/rest/ueb/UEBNotificationTest.java b/aai-core/src/test/java/org/onap/aai/rest/notification/UEBNotificationTest.java index efa43250..229abae4 100644 --- a/aai-core/src/test/java/org/onap/aai/rest/ueb/UEBNotificationTest.java +++ b/aai-core/src/test/java/org/onap/aai/rest/notification/UEBNotificationTest.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.aai.rest.ueb; +package org.onap.aai.rest.notification; import static org.junit.Assert.assertEquals; diff --git a/aai-core/src/test/java/org/onap/aai/serialization/db/DbSerializer_needsFakeRulesTest.java b/aai-core/src/test/java/org/onap/aai/serialization/db/DbSerializer_needsFakeRulesTest.java index ead83917..7dca441e 100644 --- a/aai-core/src/test/java/org/onap/aai/serialization/db/DbSerializer_needsFakeRulesTest.java +++ b/aai-core/src/test/java/org/onap/aai/serialization/db/DbSerializer_needsFakeRulesTest.java @@ -53,6 +53,7 @@ import org.onap.aai.introspection.LoaderFactory; import org.onap.aai.introspection.ModelType; import org.onap.aai.nodes.NodeIngestor; import org.onap.aai.parsers.query.QueryParser; +import org.onap.aai.rest.notification.NotificationService; import org.onap.aai.serialization.engines.JanusGraphDBEngine; import org.onap.aai.serialization.engines.QueryStyle; import org.onap.aai.serialization.engines.TransactionalGraphEngine; @@ -70,7 +71,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @ContextConfiguration( classes = {ConfigConfiguration.class, AAICoreFakeEdgesConfigTranslator.class, NodeIngestor.class, EdgeIngestor.class, EdgeSerializer.class, SpringContextAware.class, IntrospectionConfig.class, - XmlFormatTransformerConfiguration.class}) + XmlFormatTransformerConfiguration.class, LoaderFactory.class, NotificationService.class}) @TestPropertySource( properties = {"schema.translator.list = config", "schema.nodes.location=src/test/resources/onap/oxm", "schema.edges.location=src/test/resources/onap/dbedgerules"}) diff --git a/aai-core/src/test/java/org/onap/aai/serialization/db/EdgeRulesTest.java b/aai-core/src/test/java/org/onap/aai/serialization/db/EdgeRulesTest.java index 5dfa12b7..517a43a7 100644 --- a/aai-core/src/test/java/org/onap/aai/serialization/db/EdgeRulesTest.java +++ b/aai-core/src/test/java/org/onap/aai/serialization/db/EdgeRulesTest.java @@ -27,7 +27,9 @@ import static org.junit.Assert.assertEquals; import com.google.common.collect.Multimap; -import java.util.*; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; import org.apache.tinkerpop.gremlin.structure.Direction; import org.junit.Rule; diff --git a/aai-core/src/test/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngineTest.java b/aai-core/src/test/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngineTest.java index 738953d5..dff741ec 100644 --- a/aai-core/src/test/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngineTest.java +++ b/aai-core/src/test/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngineTest.java @@ -301,7 +301,7 @@ public class GraphTraversalQueryEngineTest extends AAISetup { /** * convenience helper method to make it easier to check the contents of the tree against * a list of expected results - * + * * @param tree - the tree whose contents you want in collection form * @return set of the contents of the tree */ diff --git a/aai-core/src/test/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngine_needsFakeEdgeRulesTest.java b/aai-core/src/test/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngine_needsFakeEdgeRulesTest.java index 6ae32f39..6a22aee1 100644 --- a/aai-core/src/test/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngine_needsFakeEdgeRulesTest.java +++ b/aai-core/src/test/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngine_needsFakeEdgeRulesTest.java @@ -20,7 +20,7 @@ package org.onap.aai.serialization.engines.query; -import static org.junit.Assert.*; +import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Arrays; diff --git a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/FormatTest.java b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/FormatTest.java index 965e7157..78b8a5aa 100644 --- a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/FormatTest.java +++ b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/FormatTest.java @@ -20,7 +20,7 @@ package org.onap.aai.serialization.queryformats; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import org.junit.Rule; import org.junit.Test; diff --git a/aai-core/src/test/java/org/onap/aai/util/PojoUtilsTest.java b/aai-core/src/test/java/org/onap/aai/util/PojoUtilsTest.java index 68f01962..a6a8c33d 100644 --- a/aai-core/src/test/java/org/onap/aai/util/PojoUtilsTest.java +++ b/aai-core/src/test/java/org/onap/aai/util/PojoUtilsTest.java @@ -100,18 +100,8 @@ public class PojoUtilsTest { LocalDateTime date = LocalDateTime.of(2017, Month.SEPTEMBER, 18, 10, 55, 0, 300); String res = pojoUtils.getJsonFromObject(date); - + assertEquals("\"2017-09-18T10:55:00.0000003\"", res); assertNotNull(res); - assertTrue(res.contains("\"dayOfMonth\" : 18")); - assertTrue(res.contains("\"dayOfWeek\" : \"MONDAY\"")); - assertTrue(res.contains("\"dayOfYear\" : 261")); - assertTrue(res.contains("\"hour\" : 10")); - assertTrue(res.contains("\"minute\" : 55")); - assertTrue(res.contains("\"month\" : \"SEPTEMBER\"")); - assertTrue(res.contains("\"monthValue\" : 9")); - assertTrue(res.contains("\"nano\" : 300")); - assertTrue(res.contains("\"second\" : 0")); - assertTrue(res.contains("\"year\" : 2017")); } @Test diff --git a/aai-core/src/test/resources/logback.xml b/aai-core/src/test/resources/logback.xml index 4c82c0bf..6acc77f0 100644 --- a/aai-core/src/test/resources/logback.xml +++ b/aai-core/src/test/resources/logback.xml @@ -163,7 +163,7 @@ <pattern>${eelfTransLogPattern}</pattern> </encoder> </appender> - + <appender name="asynctranslog" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>1000</queueSize> <includeCallerData>true</includeCallerData> @@ -255,7 +255,7 @@ <logger name="ajsc.UserDefinedBeansDefService" level="WARN" /> <logger name="ajsc.LoggingConfigurationService" level="WARN" /> - <!-- AJSC related loggers (DME2 Registration, csi logging, restlet, servlet + <!-- AJSC related loggers (DME2 Registration, csi logging, restlet, servlet logging) --> <logger name="org.codehaus.groovy" level="WARN" /> <logger name="com.att.scamper" level="WARN" /> @@ -279,7 +279,7 @@ <logger name="org.apache.coyote" level="WARN" /> <logger name="org.apache.jasper" level="WARN" /> - <!-- Camel Related Loggers (including restlet/servlet/jaxrs/cxf logging. + <!-- Camel Related Loggers (including restlet/servlet/jaxrs/cxf logging. May aid in troubleshooting) --> <logger name="org.apache.camel" level="WARN" /> <logger name="org.apache.cxf" level="WARN" /> @@ -363,9 +363,7 @@ </logger> <logger name="org.onap.aai.kafka" level="DEBUG" additivity="false"> - <appender-ref ref="kafkaAAIEventConsumer" /> - <appender-ref ref="kafkaAAIEventConsumerDebug" /> - <appender-ref ref="kafkaAAIEventConsumerMetric" /> + <appender-ref ref="STDOUT" /> </logger> <logger name="org.apache" level="WARN" /> diff --git a/aai-core/src/test/resources/payloads/expected/aai-event.json b/aai-core/src/test/resources/payloads/expected/aai-event.json new file mode 100644 index 00000000..86c67992 --- /dev/null +++ b/aai-core/src/test/resources/payloads/expected/aai-event.json @@ -0,0 +1,61 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "severity": "NORMAL", + "entity-type": "object-group", + "top-entity-type": "object-group", + "entity-link": "/aai/v28/common/object-groups/object-group/ric_cluster", + "event-type": "AAI-EVENT", + "domain": "dev", + "action": "UPDATE", + "sequence-number": "0", + "id": "23f12123-c326-48a7-b57e-e48746c295ea", + "source-name": "postman-api", + "version": "v28", + "timestamp": "20231207-12:14:44:757" + }, + "entity": { + "relationship-list": { + "relationship": [ + { + "related-to": "cell", + "relationship-data": [ + { + "relationship-value": "445611193273958916", + "relationship-key": "cell.cell-id" + } + ], + "related-link": "/aai/v28/network/cells/cell/445611193273958916", + "relationship-label": "org.onap.relationships.inventory.MemberOf", + "related-to-property": [ + { + "property-key": "cell.cell-name", + "property-value": "MY6885_M-Schwere-Reiter-Str-440460_GU2_84079913" + } + ] + }, + { + "related-to": "cell", + "relationship-data": [ + { + "relationship-value": "445611193272330241", + "relationship-key": "cell.cell-id" + } + ], + "related-link": "/aai/v28/network/cells/cell/445611193272330241", + "relationship-label": "org.onap.relationships.inventory.MemberOf", + "related-to-property": [ + { + "property-key": "cell.cell-name", + "property-value": "MY6885_M-Schwere-Reiter-Str-440460_GTC2_84003803" + } + ] + } + ] + }, + "group-name": "Urban", + "resource-version": "1701951284582", + "group-type": "cell", + "object-group-id": "ric_cluster" + } +} diff --git a/aai-els-onap-logging/pom.xml b/aai-els-onap-logging/pom.xml index fa158035..6b24e1f4 100644 --- a/aai-els-onap-logging/pom.xml +++ b/aai-els-onap-logging/pom.xml @@ -4,7 +4,7 @@ <parent> <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-parent</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> <relativePath>../aai-parent/pom.xml</relativePath> </parent> <artifactId>aai-els-onap-logging</artifactId> diff --git a/aai-failover/pom.xml b/aai-failover/pom.xml index f892b117..240fd071 100644 --- a/aai-failover/pom.xml +++ b/aai-failover/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-parent</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> <relativePath>../aai-parent/pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/aai-parent/pom.xml b/aai-parent/pom.xml index 5ff0c693..3fe7b3f4 100644 --- a/aai-parent/pom.xml +++ b/aai-parent/pom.xml @@ -27,7 +27,7 @@ limitations under the License. <parent> <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-common</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> </parent> <artifactId>aai-parent</artifactId> <name>aai-parent</name> @@ -47,12 +47,11 @@ limitations under the License. <aaf.version>2.1.15</aaf.version> <antlr.version>4.11.1</antlr.version> <activemq.version>5.16.1</activemq.version> - <codehaus.jackson.version>1.9.13</codehaus.jackson.version> <commons.beanutils.version>1.9.4</commons.beanutils.version> <commons.cli.version>1.5.0</commons.cli.version> - <commons.compress.version>1.21</commons.compress.version> + <commons.compress.version>1.27.0</commons.compress.version> <commons.configuration.version>1.10</commons.configuration.version> - <commons.io.version>2.11.0</commons.io.version> + <commons.io.version>2.16.1</commons.io.version> <commons.lang3.version>3.9</commons.lang3.version> <commons.net.version>3.8.0</commons.net.version> <commons.text.version>1.10.0</commons.text.version> @@ -62,13 +61,12 @@ limitations under the License. <eelf.core.version>2.0.0-oss</eelf.core.version> <freemarker.version>2.3.31</freemarker.version> <google.guava.version>31.1-jre</google.guava.version> - <gremlin.version>3.4.13</gremlin.version> - <janusgraph.version>0.5.3</janusgraph.version> + <gremlin.version>3.5.8</gremlin.version> + <janusgraph.version>0.6.4</janusgraph.version> <groovy.version>2.5.15</groovy.version> <gson.version>2.9.1</gson.version> <hamcrest.junit.version>2.0.0.0</hamcrest.junit.version> <hamcrest.core.version>2.2</hamcrest.core.version> - <jackson.bom.version>2.11.4</jackson.bom.version> <javatuples.version>1.2</javatuples.version> <jaxb.version>2.3.1</jaxb.version> <old.jaxb.version>2.3.0.1</old.jaxb.version> @@ -91,8 +89,8 @@ limitations under the License. Please don't upgrade to 2.3.0 or above for nexus iq or security scans as it could potentially break our code --> - <spring.boot.version>2.4.13</spring.boot.version> - <spring.version>5.3.13</spring.version> + <spring.boot.version>2.5.15</spring.boot.version> + <spring.version>5.3.39</spring.version> <spring.jms.version>5.2.25.RELEASE</spring.jms.version> <spring.test.version>${spring.version}</spring.test.version> <json.path.version>2.2.0</json.path.version> @@ -139,13 +137,6 @@ limitations under the License. <dependencyManagement> <dependencies> <dependency> - <groupId>com.fasterxml.jackson</groupId> - <artifactId>jackson-bom</artifactId> - <version>${jackson.bom.version}</version> - <type>pom</type> - <scope>import</scope> - </dependency> - <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring.boot.version}</version> @@ -175,7 +166,7 @@ limitations under the License. <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> - <version>5.3.31</version> + <version>5.3.39</version> </dependency> @@ -223,12 +214,6 @@ limitations under the License. </dependency> <dependency> - <groupId>commons-configuration</groupId> - <artifactId>commons-configuration</artifactId> - <version>${commons.configuration.version}</version> - </dependency> - - <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>${commons.lang3.version}</version> @@ -319,15 +304,6 @@ limitations under the License. <version>${janusgraph.version}</version> </dependency> - - <!-- https://docs.datastax.com/en/developer/java-driver/3.5/manual/metrics/index.html#metrics-4-compatibility --> - <!-- remove this for janusgraph >= 0.6.0 --> - <dependency> - <groupId>io.dropwizard.metrics</groupId> - <artifactId>metrics-core</artifactId> - <version>3.2.6</version> - </dependency> - <dependency> <groupId>org.janusgraph</groupId> <artifactId>janusgraph-inmemory</artifactId> @@ -520,12 +496,6 @@ limitations under the License. </dependency> <dependency> - <groupId>org.codehaus.jackson</groupId> - <artifactId>jackson-core-asl</artifactId> - <version>${codehaus.jackson.version}</version> - </dependency> - - <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-core</artifactId> <version>${jersey.version}</version> @@ -818,7 +788,7 @@ limitations under the License. <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> - <version>3.0.0-M4</version> + <version>3.1.2</version> <configuration> <!-- Sets the VM argument line used when unit tests are run. --> <argLine>${surefireArgLine}</argLine> @@ -831,7 +801,7 @@ limitations under the License. <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> - <version>3.0.0-M4</version> + <version>3.1.2</version> <executions> <!-- Ensures that both integration-test and verify goals of the Failsafe Maven plugin are executed. --> diff --git a/aai-rest/pom.xml b/aai-rest/pom.xml index 298783d3..9af589ff 100644 --- a/aai-rest/pom.xml +++ b/aai-rest/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-parent</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> <relativePath>../aai-parent/pom.xml</relativePath> </parent> <artifactId>aai-rest</artifactId> diff --git a/aai-schema-abstraction/pom.xml b/aai-schema-abstraction/pom.xml index 52db4c3b..c89cf6eb 100644 --- a/aai-schema-abstraction/pom.xml +++ b/aai-schema-abstraction/pom.xml @@ -28,7 +28,7 @@ <parent> <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-parent</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> <relativePath>../aai-parent/pom.xml</relativePath> </parent> @@ -86,14 +86,6 @@ <artifactId>logback-access</artifactId> </dependency> <dependency> - <groupId>org.codehaus.jackson</groupId> - <artifactId>jackson-core-asl</artifactId> - </dependency> - <dependency> - <groupId>org.codehaus.jackson</groupId> - <artifactId>jackson-mapper-asl</artifactId> - </dependency> - <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/RelationshipSchema.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/RelationshipSchema.java index 921cff33..32350779 100644 --- a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/RelationshipSchema.java +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/RelationshipSchema.java @@ -23,6 +23,7 @@ package org.onap.aai.schemaif.oxm; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Multimap; import java.io.IOException; @@ -35,7 +36,6 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import org.codehaus.jackson.map.ObjectMapper; import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.edges.EdgeRule; import org.onap.aai.schemaif.SchemaProviderException; diff --git a/aai-schema-ingest/pom.xml b/aai-schema-ingest/pom.xml index 326082da..56305a9a 100644 --- a/aai-schema-ingest/pom.xml +++ b/aai-schema-ingest/pom.xml @@ -26,7 +26,7 @@ limitations under the License. <parent> <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-parent</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> <relativePath>../aai-parent/pom.xml</relativePath> </parent> <artifactId>aai-schema-ingest</artifactId> diff --git a/aai-schema-ingest/src/main/java/org/onap/aai/validation/VersionValidator.java b/aai-schema-ingest/src/main/java/org/onap/aai/validation/VersionValidator.java index 375bec0f..a1e95557 100644 --- a/aai-schema-ingest/src/main/java/org/onap/aai/validation/VersionValidator.java +++ b/aai-schema-ingest/src/main/java/org/onap/aai/validation/VersionValidator.java @@ -1,4 +1,4 @@ -/** +/** * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -21,6 +21,7 @@ package org.onap.aai.validation; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; /** @@ -28,6 +29,7 @@ import org.springframework.stereotype.Component; * all required versions */ @Component +@ConditionalOnProperty(name = "schema.translator.list", havingValue = "config", matchIfMissing = true) public class VersionValidator { private SchemaErrorStrategy strat; private VersionValidationModule verMod; diff --git a/aai-schema-ingest/src/main/java/org/onap/aai/validation/edges/EdgeRuleValidator.java b/aai-schema-ingest/src/main/java/org/onap/aai/validation/edges/EdgeRuleValidator.java index 4eedaa07..620bc726 100644 --- a/aai-schema-ingest/src/main/java/org/onap/aai/validation/edges/EdgeRuleValidator.java +++ b/aai-schema-ingest/src/main/java/org/onap/aai/validation/edges/EdgeRuleValidator.java @@ -1,4 +1,4 @@ -/** +/** * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -31,12 +31,14 @@ import org.onap.aai.setup.ConfigTranslator; import org.onap.aai.setup.SchemaVersion; import org.onap.aai.validation.SchemaErrorStrategy; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; /** * Runs all validations against the ingested schema */ @Component +@ConditionalOnProperty(name = "schema.translator.list", havingValue = "config", matchIfMissing = true) public class EdgeRuleValidator { private Map<SchemaVersion, List<DocumentContext>> versionJsonFilesMap; private final SchemaErrorStrategy strat; diff --git a/aai-schema-ingest/src/main/java/org/onap/aai/validation/nodes/NodeValidator.java b/aai-schema-ingest/src/main/java/org/onap/aai/validation/nodes/NodeValidator.java index ac9ecbdd..13de6715 100644 --- a/aai-schema-ingest/src/main/java/org/onap/aai/validation/nodes/NodeValidator.java +++ b/aai-schema-ingest/src/main/java/org/onap/aai/validation/nodes/NodeValidator.java @@ -1,4 +1,4 @@ -/** +/** * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -27,9 +27,11 @@ import org.onap.aai.setup.ConfigTranslator; import org.onap.aai.setup.SchemaVersion; import org.onap.aai.validation.SchemaErrorStrategy; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; @Component +@ConditionalOnProperty(name = "schema.translator.list", havingValue = "config", matchIfMissing = true) public class NodeValidator { private ConfigTranslator translator; diff --git a/aai-utils/pom.xml b/aai-utils/pom.xml index 56d14a26..af541a21 100644 --- a/aai-utils/pom.xml +++ b/aai-utils/pom.xml @@ -27,7 +27,7 @@ <parent> <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-parent</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> <relativePath>../aai-parent/pom.xml</relativePath> </parent> <artifactId>aai-utils</artifactId> diff --git a/docs/_static/logo_onap_2024.png b/docs/_static/logo_onap_2024.png Binary files differnew file mode 100644 index 00000000..55d307fc --- /dev/null +++ b/docs/_static/logo_onap_2024.png diff --git a/docs/conf.py b/docs/conf.py index a9c42b67..8b63262d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -11,7 +11,7 @@ html_theme = "sphinx_rtd_theme" html_theme_options = { "style_nav_header_background": "white", "sticky_navigation": "False" } -html_logo = "_static/logo_onap_2017.png" +html_logo = "_static/logo_onap_2024.png" html_favicon = "_static/favicon.ico" html_static_path = ["_static"] html_show_sphinx = False @@ -30,7 +30,7 @@ <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-common</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.6-SNAPSHOT</version> <packaging>pom</packaging> <name>aai-aai-common</name> <description>Contains all of the common code for resources and traversal repos</description> diff --git a/releases/1.14.5-maven-release.yaml b/releases/1.14.5-maven-release.yaml new file mode 100644 index 00000000..96ddb776 --- /dev/null +++ b/releases/1.14.5-maven-release.yaml @@ -0,0 +1,4 @@ +distribution_type: maven +log_dir: aai-aai-common-maven-stage-master/1461/ +project: aai-common +version: 1.14.5 diff --git a/releases/1.14.6-maven-release.yaml b/releases/1.14.6-maven-release.yaml new file mode 100644 index 00000000..d6503ca1 --- /dev/null +++ b/releases/1.14.6-maven-release.yaml @@ -0,0 +1,4 @@ +distribution_type: maven +log_dir: aai-aai-common-maven-stage-master/1462/ +project: aai-common +version: 1.14.6 diff --git a/version.properties b/version.properties index 82f9610a..cae43c29 100644 --- a/version.properties +++ b/version.properties @@ -5,7 +5,7 @@ major_version=1 minor_version=14 -patch_version=4 +patch_version=6 base_version=${major_version}.${minor_version}.${patch_version} |