diff options
92 files changed, 1526 insertions, 903 deletions
diff --git a/aai-aaf-auth/pom.xml b/aai-aaf-auth/pom.xml index f0a95f51..8be62915 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.7-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..0a7044fc 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.7-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..f3e22bcc 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.7-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..267fb3d2 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.7-SNAPSHOT</version> </parent> <artifactId>aai-common-images</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.7-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..8b98e471 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.7-SNAPSHOT</version> </parent> <artifactId>aai-haproxy-image</artifactId> - <version>1.14.4-SNAPSHOT</version> + <version>1.14.7-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..c6c629bb 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.7-SNAPSHOT</version> <relativePath>../aai-parent/pom.xml</relativePath> </parent> diff --git a/aai-core/pom.xml b/aai-core/pom.xml index ded8830a..2f5908b4 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.7-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> 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 73bbf7c1..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,6 @@ 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; 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..1ed35424 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 @@ -20,46 +20,45 @@ * ============LICENSE_END========================================================= */ -package org.onap.aai.kafka; + 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.jms.core.JmsTemplate; + import org.json.JSONObject; + import org.onap.aai.config.SpringContextAware; + import org.onap.aai.domain.notificationEvent.NotificationEvent; + import org.onap.aai.util.AAIConfig; + import org.springframework.jms.core.JmsTemplate; + import org.springframework.stereotype.Service; -public class AAIKafkaEventJMSProducer implements MessageProducer { + import com.fasterxml.jackson.core.JsonProcessingException; + import com.fasterxml.jackson.databind.ObjectMapper; + import com.fasterxml.jackson.databind.json.JsonMapper; - private JmsTemplate jmsTemplate; + import lombok.RequiredArgsConstructor; + import lombok.extern.slf4j.Slf4j; - 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")); - } - } + @Slf4j + @Service + @RequiredArgsConstructor + public class AAIKafkaEventJMSProducer implements MessageProducer { - public void sendMessageToDefaultDestination(JSONObject finalJson) { - if (jmsTemplate != null) { - jmsTemplate.convertAndSend(finalJson.toString()); - CachingConnectionFactory ccf = (CachingConnectionFactory) this.jmsTemplate.getConnectionFactory(); - if (ccf != null) { - ccf.destroy(); - } - } - } + private boolean eventsEnabled = "true".equals(AAIConfig.get("aai.jms.enable", "true")); + private JmsTemplate jmsTemplate; + private static final ObjectMapper mapper = new JsonMapper(); - public void sendMessageToDefaultDestination(String msg) { - if (jmsTemplate != null) { - jmsTemplate.convertAndSend(msg); - CachingConnectionFactory ccf = (CachingConnectionFactory) this.jmsTemplate.getConnectionFactory(); - if (ccf != null) { - ccf.destroy(); - } - } - } -} + public AAIKafkaEventJMSProducer(JmsTemplate jmsTemplate) { + this.jmsTemplate = jmsTemplate; + } + + public void sendMessageToDefaultDestination(String msg) { + if (eventsEnabled) { + if(jmsTemplate == null) { + this.jmsTemplate = SpringContextAware.getBean(JmsTemplate.class); + } + jmsTemplate.convertAndSend(msg); + } + } + + public void sendMessageToDefaultDestination(JSONObject finalJson) { + 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/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/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..56a6a857 --- /dev/null +++ b/aai-core/src/test/java/org/onap/aai/kafka/AAIKafkaEventIntegrationTest.java @@ -0,0 +1,162 @@ +/** + * ============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 static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.UriInfo; + +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.Mock; +import org.onap.aai.AAISetup; +import org.onap.aai.PayloadUtil; +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.rest.db.DBRequest; +import org.onap.aai.restcore.HttpMethod; +import org.onap.aai.serialization.engines.TransactionalGraphEngine; +import org.onap.aai.setup.SchemaVersion; +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.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +@Ignore +@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; + + @Mock UriInfo uriInfoMock; + @Mock MultivaluedMap<String, String> queryParamsMock; + @Mock HttpHeaders headersMock; + + @Before + public void setup() { + when(headersMock.getAcceptableMediaTypes()).thenReturn(Collections.singletonList(MediaType.APPLICATION_JSON_TYPE)); + when(uriInfoMock.getQueryParameters(anyBoolean())).thenReturn(queryParamsMock); + when(queryParamsMock.getFirst("depth")).thenReturn("0"); + when(headersMock.getRequestHeader("aai-request-context")).thenReturn(null); + } + + @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); + }); + } + + @Test + @Ignore + // only works when aai.jms.enable=true in aaiconfig.properties + public void thatEventsAreBeingCreated() throws AAIException, IOException { + Consumer<String, String> consumer = consumerFactory.createConsumer(); + consumer.subscribe(Collections.singletonList("AAI-EVENT")); + + traversalUriHttpEntry.setHttpEntryProperties(new SchemaVersion("v14")); + String pserverUri = "/aai/v14/cloud-infrastructure/pservers/pserver/pserver1"; + String entity = new String(Files.readAllBytes(Paths.get("src/test/resources/payloads/templates/pserver.json"))).replace("${hostname}", "pserver1"); + DBRequest dbRequest = createDBRequest(pserverUri, entity); + List<DBRequest> dbRequests = new ArrayList<>(); + dbRequests.add(dbRequest); + + traversalUriHttpEntry.process(dbRequests, "test"); + + ConsumerRecords<String, String> consumerRecords = KafkaTestUtils.getRecords(consumer, 100000); + assertFalse(consumerRecords.isEmpty()); + String expectedResponse = PayloadUtil.getExpectedPayload("pserver-event.json"); + + consumerRecords.forEach(consumerRecord -> { + JSONAssert.assertEquals(expectedResponse, consumerRecord.value(), JSONCompareMode.LENIENT); + }); + } + + @SneakyThrows + private DBRequest createDBRequest(String uri, String entity) { + TransactionalGraphEngine dbEngine = traversalUriHttpEntry.getDbEngine(); + Loader loader = traversalUriHttpEntry.getLoader(); + URI uriObject = new URI(uri); + QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject); + String objName = uriQuery.getResultType(); + Introspector obj = loader.unmarshal(objName, entity, + org.onap.aai.restcore.MediaType.getEnum("application/json")); + return new DBRequest.Builder(HttpMethod.PUT, uriObject, uriQuery, obj, headersMock, uriInfoMock, "someTransaction") + .rawRequestContent(entity) + .build(); + } + +} 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-core/src/test/resources/payloads/expected/pserver-event.json b/aai-core/src/test/resources/payloads/expected/pserver-event.json new file mode 100644 index 00000000..11c1a100 --- /dev/null +++ b/aai-core/src/test/resources/payloads/expected/pserver-event.json @@ -0,0 +1,44 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "severity": "NORMAL", + "entity-type": "pserver", + "top-entity-type": "pserver", + "entity-link": "/aai/v14/cloud-infrastructure/pservers/pserver/pserver1", + "event-type": "AAI-EVENT", + "domain": "devINT1", + "action": "CREATE", + "sequence-number": "0", + "id": "someTransaction", + "source-name": "test", + "version": "v14", + }, + "entity": { + "ptnii-equip-name": "example-ptnii-equip-name-val-36969", + "ipaddress-v6-loopback-0": "example-ipaddress-v6-loopback0-val-17856", + "equip-vendor": "example-equip-vendor-val-37452", + "purpose": "example-purpose-val-90218", + "pserver-selflink": "example-pserver-selflink-val-10125", + "number-of-cpus": 62220, + "ipaddress-v6-aim": "example-ipaddress-v6-aim-val-6210", + "pserver-name2": "example-pserver-name2-val-53802", + "hostname": "pserver1", + "inv-status": "example-inv-status-val-3682", + "disk-in-gigabytes": 872, + "equip-type": "example-equip-type-val-22986", + "fqdn": "example-fqdn-val-33429", + "serial-number": "example-serial-number-val-12010", + "ipaddress-v6-oam": "example-ipaddress-v6-oam-val-40977", + "pserver-id": "example-pserver-id-val-82142", + "prov-status": "example-prov-status-val-11642", + "ipv4-oam-address": "example-ipv4-oam-address-val-3155", + "ipaddress-v4-loopback-0": "example-ipaddress-v4-loopback0-val-77686", + "equip-model": "example-equip-model-val-14665", + "in-maint": true, + "ram-in-megabytes": 35331, + "ipaddress-v4-aim": "example-ipaddress-v4-aim-val-33665", + "management-option": "example-management-option-val-91111", + "internet-topology": "example-internet-topology-val-56425", + "host-profile": "example-host-profile-val-36247" + } +} diff --git a/aai-els-onap-logging/pom.xml b/aai-els-onap-logging/pom.xml index fa158035..1f7cec5c 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.7-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..14c01b33 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.7-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 92ea06d1..d9a80223 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.7-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.5.0</gremlin.version> - <janusgraph.version>0.6.0</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> @@ -505,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> @@ -803,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> @@ -816,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..a514b11c 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.7-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..cbf128ee 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.7-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..700db49b 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.7-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..a9d4aebe 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.7-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.7-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} |