diff options
Diffstat (limited to 'aai-core')
58 files changed, 1233 insertions, 2352 deletions
diff --git a/aai-core/pom.xml b/aai-core/pom.xml index d2aed3a0..4ce7f76d 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.6-SNAPSHOT</version> + <version>1.15.2-SNAPSHOT</version> <relativePath>../aai-parent/pom.xml</relativePath> </parent> <artifactId>aai-core</artifactId> @@ -36,7 +36,6 @@ limitations under the License. <springframework.version>4.3.24.RELEASE</springframework.version> <jacoco.line.coverage.limit>0.50</jacoco.line.coverage.limit> - <groovy.version>2.5.15</groovy.version> <mockito.core.version>3.4.0</mockito.core.version> <!-- Start of Default ONAP Schema Properties --> <aai.wiki.link>https://wiki.onap.org/</aai.wiki.link> @@ -115,10 +114,6 @@ limitations under the License. </dependency> <dependency> <groupId>org.onap.aai.aai-common</groupId> - <artifactId>aai-aaf-auth</artifactId> - </dependency> - <dependency> - <groupId>org.onap.aai.aai-common</groupId> <artifactId>aai-annotations</artifactId> </dependency> <dependency> @@ -176,6 +171,11 @@ limitations under the License. <artifactId>guava</artifactId> </dependency> <dependency> + <groupId>org.glassfish</groupId> + <artifactId>javax.json</artifactId> + <version>1.1.4</version> + </dependency> + <dependency> <groupId>org.janusgraph</groupId> <artifactId>janusgraph-core</artifactId> <exclusions> @@ -213,16 +213,12 @@ limitations under the License. <artifactId>json-simple</artifactId> </dependency> <dependency> - <groupId>javax.xml.bind</groupId> - <artifactId>jaxb-api</artifactId> - </dependency> - <dependency> - <groupId>com.sun.xml.bind</groupId> - <artifactId>jaxb-impl</artifactId> + <groupId>jakarta.xml.bind</groupId> + <artifactId>jakarta.xml.bind-api</artifactId> </dependency> <dependency> - <groupId>com.sun.xml.bind</groupId> - <artifactId>jaxb-core</artifactId> + <groupId>org.glassfish.jaxb</groupId> + <artifactId>jaxb-runtime</artifactId> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> @@ -250,16 +246,12 @@ limitations under the License. <artifactId>jackson-module-jaxb-annotations</artifactId> </dependency> <dependency> - <groupId>com.sun.jersey</groupId> - <artifactId>jersey-core</artifactId> - </dependency> - <dependency> - <groupId>com.sun.jersey</groupId> + <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-client</artifactId> </dependency> <dependency> - <groupId>com.sun.jersey</groupId> - <artifactId>jersey-json</artifactId> + <groupId>org.glassfish.jersey.media</groupId> + <artifactId>jersey-media-json-jackson</artifactId> </dependency> <dependency> <groupId>org.apache.tinkerpop</groupId> @@ -300,14 +292,6 @@ limitations under the License. <artifactId>logback-access</artifactId> </dependency> <dependency> - <groupId>org.apache.activemq</groupId> - <artifactId>activemq-broker</artifactId> - </dependency> - <dependency> - <groupId>org.apache.activemq</groupId> - <artifactId>activemq-openwire-legacy</artifactId> - </dependency> - <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> </dependency> @@ -316,12 +300,6 @@ limitations under the License. <artifactId>json-patch</artifactId> </dependency> <dependency> - <groupId>org.codehaus.groovy</groupId> - <artifactId>groovy</artifactId> - <version>${groovy.version}</version> - <classifier>indy</classifier> - </dependency> - <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> @@ -369,21 +347,6 @@ limitations under the License. <dependency> <groupId>org.apache.tinkerpop</groupId> <artifactId>gremlin-groovy</artifactId> - <exclusions> - <exclusion> - <groupId>org.codehaus.groovy</groupId> - <artifactId>groovy</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>org.springframework</groupId> - <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> @@ -414,14 +377,9 @@ limitations under the License. <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> - <version>1.18.30</version> + <version>1.18.34</version> <scope>provided</scope> </dependency> - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-configuration2</artifactId> - <version>2.7</version> - </dependency> </dependencies> <!-- Plugins and repositories --> diff --git a/aai-core/src/main/java/org/onap/aai/concurrent/AaiCallable.java b/aai-core/src/main/java/org/onap/aai/concurrent/AaiCallable.java index 2703bdc4..9451e32e 100644 --- a/aai-core/src/main/java/org/onap/aai/concurrent/AaiCallable.java +++ b/aai-core/src/main/java/org/onap/aai/concurrent/AaiCallable.java @@ -35,7 +35,6 @@ public abstract class AaiCallable<T> implements Callable<T> { /** * The constructor. */ - @SuppressWarnings("unchecked") public AaiCallable() { mdcCopy = MDC.getCopyOfContextMap(); } diff --git a/aai-core/src/main/java/org/onap/aai/config/KafkaConfig.java b/aai-core/src/main/java/org/onap/aai/config/KafkaConfig.java new file mode 100644 index 00000000..7a81d9d2 --- /dev/null +++ b/aai-core/src/main/java/org/onap/aai/config/KafkaConfig.java @@ -0,0 +1,120 @@ +/** + * ============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.config; + +import java.util.Map; +import java.util.HashMap; + +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.common.serialization.StringSerializer; +import org.onap.aai.domain.deltaEvent.DeltaEvent; +import org.onap.aai.domain.notificationEvent.NotificationEvent; +import org.onap.aai.kafka.DeltaProducer; +import org.onap.aai.kafka.DeltaProducerService; +import org.onap.aai.kafka.NotificationProducer; +import org.onap.aai.kafka.NotificationProducerService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; +import org.springframework.kafka.support.serializer.JsonSerializer; + +@Configuration +public class KafkaConfig { + + private static final Logger logger = LoggerFactory.getLogger(KafkaConfig.class); + + @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:#{null}}") + private String saslJaasConfig; + + @Value("${spring.kafka.producer.retries:3}") + private String retries; + + private Map<String, Object> buildKafkaProperties() 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(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + 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 props; + } + + @Bean + public KafkaTemplate<String, NotificationEvent> kafkaNotificationEventTemplate(ProducerFactory<String, NotificationEvent> producerFactory) throws Exception { + return new KafkaTemplate<>(producerFactory); + } + + @Bean + public NotificationProducer notificationProducer(KafkaTemplate<String,NotificationEvent> kafkaTemplate) { + return new NotificationProducerService(kafkaTemplate); + } + + @Bean + public ProducerFactory<String, NotificationEvent> notificationEventProducerFactory() throws Exception { + Map<String, Object> props = buildKafkaProperties(); + return new DefaultKafkaProducerFactory<>(props); + } + + @Bean + public ProducerFactory<String, DeltaEvent> deltaEventProducerFactory() throws Exception { + Map<String, Object> props = buildKafkaProperties(); + return new DefaultKafkaProducerFactory<>(props); + } + + @Bean + public KafkaTemplate<String, DeltaEvent> kafkaDeltaEventTemplate(ProducerFactory<String, DeltaEvent> producerFactory) throws Exception { + return new KafkaTemplate<>(producerFactory); + } + + @Bean + public DeltaProducer deltaProducer(KafkaTemplate<String,DeltaEvent> kafkaTemplate) { + return new DeltaProducerService(kafkaTemplate); + } +} diff --git a/aai-core/src/main/java/org/onap/aai/config/RestBeanConfig.java b/aai-core/src/main/java/org/onap/aai/config/RestBeanConfig.java index c04e4e3c..3cc1719c 100644 --- a/aai-core/src/main/java/org/onap/aai/config/RestBeanConfig.java +++ b/aai-core/src/main/java/org/onap/aai/config/RestBeanConfig.java @@ -32,8 +32,19 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import org.springframework.web.context.annotation.RequestScope; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule; + @Configuration public class RestBeanConfig { + + @Bean + public ObjectMapper objectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JaxbAnnotationModule()); + return objectMapper; + } + @Bean(name = "traversalUriHttpEntry") @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE) public HttpEntry traversalUriHttpEntry() { diff --git a/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java b/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java index 6430df50..055a70e3 100644 --- a/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java +++ b/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java @@ -26,12 +26,10 @@ import com.google.common.collect.Multimap; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletableFuture; @@ -49,10 +47,10 @@ import org.janusgraph.core.PropertyKey; import org.janusgraph.core.schema.ConsistencyModifier; import org.janusgraph.core.schema.JanusGraphIndex; import org.janusgraph.core.schema.JanusGraphManagement; -import org.janusgraph.core.schema.JanusGraphManagement.IndexJobFuture; import org.janusgraph.core.schema.RelationTypeIndex; import org.janusgraph.core.schema.SchemaAction; import org.janusgraph.core.schema.SchemaStatus; +import org.janusgraph.diskstorage.keycolumnvalue.scan.ScanJobFuture; import org.janusgraph.graphdb.database.StandardJanusGraph; import org.janusgraph.graphdb.database.management.ManagementSystem; import org.janusgraph.graphdb.database.management.RelationIndexStatusReport; @@ -109,7 +107,7 @@ public class SchemaGenerator { final Map<String, Introspector> objs = LoaderUtil.getLatestVersion().getAllObjects(); final Map<String, PropertyKey> seenProps = new HashMap<>(); - + for (Introspector obj : objs.values()) { createSchemaForObject(graphMgmt, seenProps, obj); } @@ -340,7 +338,7 @@ public class SchemaGenerator { private static void awaitRelationIndexStatus(JanusGraph graph, Collection<String> labels, SchemaStatus newStatus) { LOGGER.info("Awaiting index status [{}]", newStatus);; CompletableFuture<RelationIndexStatusReport>[] awaits = labels.stream() - .map(label -> + .map(label -> CompletableFuture.supplyAsync(() -> { try { return ManagementSystem @@ -365,8 +363,8 @@ public class SchemaGenerator { private static void updateRelationIndexes(JanusGraph graph, Collection<String> labels, SchemaAction updateAction) { JanusGraphManagement graphMgmt = graph.openManagement(); - CompletableFuture<IndexJobFuture>[] awaits = labels.stream() - .map(label -> + CompletableFuture<ScanJobFuture>[] awaits = labels.stream() + .map(label -> CompletableFuture.supplyAsync(() -> { EdgeLabel relation = graphMgmt.getEdgeLabel(label); RelationTypeIndex index = graphMgmt.getRelationIndex(relation, label); @@ -398,7 +396,7 @@ public class SchemaGenerator { LOGGER.debug("Closing open transaction [{}] before schema generation", transaction.toString()); transaction.rollback(); }); - + final JanusGraphManagement graphMgtForClosing = graph.openManagement(); Set<String> instances = graphMgtForClosing.getOpenInstances(); diff --git a/aai-core/src/main/java/org/onap/aai/config/AuthorizationConfiguration.java b/aai-core/src/main/java/org/onap/aai/domain/deltaEvent/DeltaEvent.java index 24e7ec5a..b8c37744 100644 --- a/aai-core/src/main/java/org/onap/aai/config/AuthorizationConfiguration.java +++ b/aai-core/src/main/java/org/onap/aai/domain/deltaEvent/DeltaEvent.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * 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. @@ -18,23 +18,22 @@ * ============LICENSE_END========================================================= */ -package org.onap.aai.config; +package org.onap.aai.domain.deltaEvent; -import org.onap.aai.aaf.auth.AAIAuthCore; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; +import java.util.Collection; -@Profile("two-way-ssl") -@Configuration -public class AuthorizationConfiguration { +import org.onap.aai.domain.notificationEvent.NotificationEvent.EventHeader; +import org.onap.aai.util.delta.ObjectDelta; - @Value("${schema.uri.base.path}") - private String basePath; +import com.fasterxml.jackson.annotation.JsonProperty; - @Bean - public AAIAuthCore aaiAuthCore() { - return new AAIAuthCore(basePath); - } +import lombok.Data; + +@Data +public class DeltaEvent { + @JsonProperty("cambria.partition") + protected String cambriaPartition; + @JsonProperty("event-header") + protected EventHeader eventHeader; + Collection<ObjectDelta> entities; } diff --git a/aai-core/src/main/java/org/onap/aai/domain/notificationEvent/NotificationEvent.java b/aai-core/src/main/java/org/onap/aai/domain/notificationEvent/NotificationEvent.java index dad35669..e349009e 100644 --- a/aai-core/src/main/java/org/onap/aai/domain/notificationEvent/NotificationEvent.java +++ b/aai-core/src/main/java/org/onap/aai/domain/notificationEvent/NotificationEvent.java @@ -17,188 +17,35 @@ * limitations under the License. * ============LICENSE_END========================================================= */ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.01.06 at 05:38:00 PM EST -// - package org.onap.aai.domain.notificationEvent; import javax.xml.bind.annotation.*; -import org.w3c.dom.Element; +import com.fasterxml.jackson.annotation.JsonProperty; -/** - * <p> - * Java class for anonymous complex type. - * - * <p> - * The following schema fragment specifies the expected content contained within this class. - * - * <pre> - * <complexType> - * <complexContent> - * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> - * <sequence> - * <element name="cambria.partition" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="event-header" minOccurs="0"> - * <complexType> - * <complexContent> - * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> - * <sequence> - * <element name="id" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="timestamp" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="source-name" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="domain" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="sequence-number" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="severity" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="event-type" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="version" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="action" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="entity-type" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="top-entity-type" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="entity-link" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="status" type="{http://www.w3.org/2001/XMLSchema}string"/> - * </sequence> - * </restriction> - * </complexContent> - * </complexType> - * </element> - * <any processContents='lax' namespace='##other' minOccurs="0"/> - * </sequence> - * </restriction> - * </complexContent> - * </complexType> - * </pre> - * - * - */ +import lombok.Data; + +@Data @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = {"cambriaPartition", "eventHeader", "entity"}) @XmlRootElement(name = "NotificationEvent") public class NotificationEvent { @XmlElement(name = "cambria.partition") + @JsonProperty("cambria.partition") protected String cambriaPartition; @XmlElement(name = "event-header") + @JsonProperty("event-header") protected EventHeader eventHeader; @XmlAnyElement(lax = true) protected Object entity; - /** - * Gets the value of the eventHeader property. - * - * @return - * possible object is - * {@link EventHeader } - * - */ - public EventHeader getEventHeader() { - return eventHeader; - } - - /** - * Sets the value of the eventHeader property. - * - * @param value - * allowed object is - * {@link EventHeader } - * - */ - public void setEventHeader(EventHeader value) { - this.eventHeader = value; - } - - /** - * Gets the value of the any property. - * - * @return - * possible object is - * {@link Object } - * {@link Element } - * - */ - public Object getEntity() { - return entity; - } - - /** - * Sets the value of the any property. - * - * @param value - * allowed object is - * {@link Object } - * {@link Element } - * - */ - public void setEntity(Object value) { - this.entity = value; - } - - /** - * Gets the value of the cambriaPartition property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getCambriaPartition() { - return cambriaPartition; - } - - /** - * Sets the value of the cambriaPartition property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setCambriaPartition(String value) { - this.cambriaPartition = value; - } - - /** - * <p> - * Java class for anonymous complex type. - * - * <p> - * The following schema fragment specifies the expected content contained within this class. - * - * <pre> - * <complexType> - * <complexContent> - * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> - * <sequence> - * <element name="id" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="timestamp" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="source-name" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="domain" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="sequence-number" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="severity" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="event-type" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="version" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="action" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="entity-type" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="top-entity-type" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="entity-link" type="{http://www.w3.org/2001/XMLSchema}string"/> - * <element name="status" type="{http://www.w3.org/2001/XMLSchema}string"/> - * </sequence> - * </restriction> - * </complexContent> - * </complexType> - * </pre> - * - * - */ + @Data @XmlAccessorType(XmlAccessType.FIELD) @XmlType( name = "", propOrder = {"id", "timestamp", "sourceName", "domain", "sequenceNumber", "severity", "eventType", - "version", "action", "entityType", "topEntityType", "entityLink", "status"}) + "version", "action", "entityType", "topEntityType", "entityLink","entityUuid"}) public static class EventHeader { @XmlElement(required = true) @@ -206,340 +53,33 @@ public class NotificationEvent { @XmlElement(required = true) protected String timestamp; @XmlElement(name = "source-name", required = true) + @JsonProperty("source-name") protected String sourceName; @XmlElement(required = true) protected String domain; @XmlElement(name = "sequence-number", required = true) + @JsonProperty("sequence-number") protected String sequenceNumber; @XmlElement(required = true) protected String severity; @XmlElement(name = "event-type", required = true) + @JsonProperty("event-type") protected String eventType; @XmlElement(required = true) protected String version; @XmlElement(required = true) protected String action; @XmlElement(name = "entity-type", required = true) + @JsonProperty("entity-type") protected String entityType; @XmlElement(name = "top-entity-type", required = true) + @JsonProperty("top-entity-type") protected String topEntityType; @XmlElement(name = "entity-link", required = true) + @JsonProperty("entity-link") protected String entityLink; - @XmlElement(required = true) - protected String status; - - /** - * Gets the value of the id property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getId() { - return id; - } - - /** - * Sets the value of the id property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setId(String value) { - this.id = value; - } - - /** - * Gets the value of the timestamp property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTimestamp() { - return timestamp; - } - - /** - * Sets the value of the timestamp property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTimestamp(String value) { - this.timestamp = value; - } - - /** - * Gets the value of the sourceName property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSourceName() { - return sourceName; - } - - /** - * Sets the value of the sourceName property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSourceName(String value) { - this.sourceName = value; - } - - /** - * Gets the value of the domain property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getDomain() { - return domain; - } - - /** - * Sets the value of the domain property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setDomain(String value) { - this.domain = value; - } - - /** - * Gets the value of the sequenceNumber property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSequenceNumber() { - return sequenceNumber; - } - - /** - * Sets the value of the sequenceNumber property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSequenceNumber(String value) { - this.sequenceNumber = value; - } - - /** - * Gets the value of the severity property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSeverity() { - return severity; - } - - /** - * Sets the value of the severity property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSeverity(String value) { - this.severity = value; - } - - /** - * Gets the value of the eventType property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getEventType() { - return eventType; - } - - /** - * Sets the value of the eventType property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setEventType(String value) { - this.eventType = value; - } - - /** - * Gets the value of the version property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getVersion() { - return version; - } - - /** - * Sets the value of the version property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setVersion(String value) { - this.version = value; - } - - /** - * Gets the value of the action property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAction() { - return action; - } - - /** - * Sets the value of the action property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAction(String value) { - this.action = value; - } - - /** - * Gets the value of the entityType property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getEntityType() { - return entityType; - } - - /** - * Sets the value of the entityType property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setEntityType(String value) { - this.entityType = value; - } - - /** - * Gets the value of the topEntityType property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTopEntityType() { - return topEntityType; - } - - /** - * Sets the value of the topEntityType property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTopEntityType(String value) { - this.topEntityType = value; - } - - /** - * Gets the value of the entityLink property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getEntityLink() { - return entityLink; - } - - /** - * Sets the value of the entityLink property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setEntityLink(String value) { - this.entityLink = value; - } - - /** - * Gets the value of the status property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getStatus() { - return status; - } - - /** - * Sets the value of the status property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setStatus(String value) { - this.status = value; - } - + @JsonProperty("entity-uuid") + protected String entityUuid; } } diff --git a/aai-core/src/main/java/org/onap/aai/introspection/Introspector.java b/aai-core/src/main/java/org/onap/aai/introspection/Introspector.java index 87983d8d..cde99db4 100644 --- a/aai-core/src/main/java/org/onap/aai/introspection/Introspector.java +++ b/aai-core/src/main/java/org/onap/aai/introspection/Introspector.java @@ -20,6 +20,8 @@ package org.onap.aai.introspection; +import com.fasterxml.jackson.annotation.JsonRawValue; +import com.fasterxml.jackson.annotation.JsonValue; import com.google.common.base.CaseFormat; import java.io.UnsupportedEncodingException; @@ -620,6 +622,12 @@ public abstract class Introspector implements Cloneable { return marshal(properties); } + @JsonValue + @JsonRawValue + public String toString() { + return marshal(false); + } + public String makeSingular(String word) { String result = word; diff --git a/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/SideEffect.java b/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/SideEffect.java index bec46520..ce802c7a 100644 --- a/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/SideEffect.java +++ b/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/SideEffect.java @@ -136,7 +136,7 @@ public abstract class SideEffect { } private Optional<String> resolveRelativePath(Optional<String> populatedUri) throws UnsupportedEncodingException { - if (!populatedUri.isPresent()) { + if (populatedUri.isEmpty()) { return Optional.empty(); } else { return Optional.of(populatedUri.get().replaceFirst("\\./", this.serializer.getURIForVertex(self) + "/")); 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 deleted file mode 100644 index 67f6842e..00000000 --- a/aai-core/src/main/java/org/onap/aai/kafka/AAIKafkaEventJMSConsumer.java +++ /dev/null @@ -1,133 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Modifications Copyright © 2018 IBM. - * ================================================================================ - * 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.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/DeltaProducer.java b/aai-core/src/main/java/org/onap/aai/kafka/DeltaProducer.java new file mode 100644 index 00000000..d1b74fd2 --- /dev/null +++ b/aai-core/src/main/java/org/onap/aai/kafka/DeltaProducer.java @@ -0,0 +1,29 @@ +/** + * ============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 org.onap.aai.domain.deltaEvent.DeltaEvent; +import org.springframework.stereotype.Service; + +@Service +public interface DeltaProducer { + public void sendNotification(DeltaEvent notificationEvent); +} diff --git a/aai-core/src/main/java/org/onap/aai/kafka/AAIKafkaEventJMSProducer.java b/aai-core/src/main/java/org/onap/aai/kafka/DeltaProducerService.java index 4e948772..bdf02316 100644 --- a/aai-core/src/main/java/org/onap/aai/kafka/AAIKafkaEventJMSProducer.java +++ b/aai-core/src/main/java/org/onap/aai/kafka/DeltaProducerService.java @@ -2,15 +2,13 @@ * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Modifications Copyright © 2018 IBM. + * 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 + * 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, @@ -22,27 +20,25 @@ package org.onap.aai.kafka; -import org.json.JSONObject; +import org.onap.aai.domain.deltaEvent.DeltaEvent; import org.springframework.beans.factory.annotation.Value; -import org.springframework.jms.core.JmsTemplate; +import org.springframework.kafka.core.KafkaTemplate; import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; @Service @RequiredArgsConstructor -public class AAIKafkaEventJMSProducer implements MessageProducer { - - @Value("${aai.events.enabled:true}") private boolean eventsEnabled; - private final JmsTemplate jmsTemplate; +public class DeltaProducerService implements DeltaProducer { - public void sendMessageToDefaultDestination(String msg) { - if (eventsEnabled) { - jmsTemplate.convertAndSend(msg); - } - } + private final KafkaTemplate<String,DeltaEvent> kafkaTemplate; + @Value("${aai.notifications.enabled:true}") + boolean notificationsEnabled; - public void sendMessageToDefaultDestination(JSONObject finalJson) { - sendMessageToDefaultDestination(finalJson.toString()); + @Override + public void sendNotification(DeltaEvent deltaEvent) { + if(notificationsEnabled) { + kafkaTemplate.send("DELTA", deltaEvent); } + } } diff --git a/aai-core/src/main/java/org/onap/aai/kafka/MessageProducer.java b/aai-core/src/main/java/org/onap/aai/kafka/MessageProducer.java index d6a491ef..09fc68a2 100644 --- a/aai-core/src/main/java/org/onap/aai/kafka/MessageProducer.java +++ b/aai-core/src/main/java/org/onap/aai/kafka/MessageProducer.java @@ -22,6 +22,12 @@ package org.onap.aai.kafka; import org.json.JSONObject; +/** + * MessageProducer interface based on untyped messages + * + * @deprecated use {@link org.onap.aai.kafka.NotificationProducer} instead + */ +@Deprecated public interface MessageProducer { void sendMessageToDefaultDestination(JSONObject finalJson); diff --git a/aai-core/src/main/java/org/onap/aai/kafka/NotificationProducer.java b/aai-core/src/main/java/org/onap/aai/kafka/NotificationProducer.java new file mode 100644 index 00000000..3c739174 --- /dev/null +++ b/aai-core/src/main/java/org/onap/aai/kafka/NotificationProducer.java @@ -0,0 +1,31 @@ +/** + * ============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 org.onap.aai.domain.notificationEvent.NotificationEvent; +import org.onap.aai.rest.notification.UEBNotification; +import org.springframework.stereotype.Service; + +@Service +public interface NotificationProducer { + public void sendNotification(NotificationEvent notificationEvent); + public void sendUEBNotification(UEBNotification uebNotification); +} diff --git a/aai-core/src/main/java/org/onap/aai/kafka/NotificationProducerService.java b/aai-core/src/main/java/org/onap/aai/kafka/NotificationProducerService.java new file mode 100644 index 00000000..44a03ba1 --- /dev/null +++ b/aai-core/src/main/java/org/onap/aai/kafka/NotificationProducerService.java @@ -0,0 +1,48 @@ +/** + * ============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 org.onap.aai.domain.notificationEvent.NotificationEvent; +import org.onap.aai.rest.notification.UEBNotification; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class NotificationProducerService implements NotificationProducer { + + private final KafkaTemplate<String,NotificationEvent> kafkaTemplate; + @Value("${aai.notifications.enabled:true}") boolean notificationsEnabled; + + public void sendNotification(NotificationEvent notificationEvent) { + if(notificationsEnabled) { + kafkaTemplate.send("AAI-EVENT", notificationEvent); + } + } + + public void sendUEBNotification(UEBNotification uebNotification) { + uebNotification.getEvents().stream() + .forEach(this::sendNotification); + } +} 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 95b1517d..af9d8aa1 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 @@ -112,12 +112,12 @@ public class RelationshipToURI { try { if (loader.getVersion().compareTo(schemaVersions.getRelatedLinkVersion()) >= 0) { result = processRelatedLink(relatedLink); - if (!result.isPresent()) { + if (result.isEmpty()) { result = processRelationshipData(); } } else { result = processRelationshipData(); - if (!result.isPresent()) { + if (result.isEmpty()) { result = processRelatedLink(relatedLink); } } diff --git a/aai-core/src/main/java/org/onap/aai/parsers/uri/URIToObject.java b/aai-core/src/main/java/org/onap/aai/parsers/uri/URIToObject.java index 186f2ee9..11a028bf 100644 --- a/aai-core/src/main/java/org/onap/aai/parsers/uri/URIToObject.java +++ b/aai-core/src/main/java/org/onap/aai/parsers/uri/URIToObject.java @@ -24,6 +24,7 @@ import java.io.UnsupportedEncodingException; import java.net.URI; import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.ws.rs.core.MultivaluedMap; @@ -37,27 +38,21 @@ import org.onap.aai.setup.SchemaVersion; /** * Given a URI this class returns an object, or series of nested objects * with their keys populated based off the values in the URI. - * + * * It populates the keys in the order they are listed in the model. */ public class URIToObject implements Parsable { + private final SchemaVersion version; + private final Loader loader; + private final Map<String, Introspector> relatedObjects; private Introspector topEntity = null; - private String topEntityName = null; - private String entityName = null; - private Introspector entity = null; - private Introspector previous = null; - private List<Object> parentList = null; - private SchemaVersion version = null; - private Loader loader = null; - private final HashMap<String, Introspector> relatedObjects; - /** * Instantiates a new URI to object. * @@ -77,7 +72,7 @@ public class URIToObject implements Parsable { this.version = loader.getVersion(); } - public URIToObject(Loader loader, URI uri, HashMap<String, Introspector> relatedObjects) + public URIToObject(Loader loader, URI uri, Map<String, Introspector> relatedObjects) throws AAIException, UnsupportedEncodingException { URIParser parser = new URIParser(loader, uri); 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 093062a9..9d8f5fdb 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 @@ -22,8 +22,8 @@ package org.onap.aai.prevalidation; -import com.google.gson.Gson; -import com.google.gson.JsonSyntaxException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import java.net.ConnectException; import java.net.SocketTimeoutException; @@ -41,9 +41,10 @@ import java.util.stream.Collectors; import javax.annotation.PostConstruct; import org.apache.http.conn.ConnectTimeoutException; +import org.onap.aai.domain.notificationEvent.NotificationEvent; +import org.onap.aai.domain.notificationEvent.NotificationEvent.EventHeader; import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.Introspector; -import org.onap.aai.rest.notification.NotificationEvent; + import org.onap.aai.restclient.RestClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -74,22 +75,19 @@ public class ValidationService { static final String VALIDATION_HEALTH_ENDPOINT = "/v1/info"; private static final Logger LOGGER = LoggerFactory.getLogger(ValidationService.class); - private static final String ENTITY_TYPE = "entity-type"; - private static final String ACTION = "action"; - private static final String SOURCE_NAME = "source-name"; private static final String DELETE = "DELETE"; private final RestClient validationRestClient; private final String appName; private final Set<String> validationNodeTypes; - private final Gson gson; - - private List<Pattern> exclusionList; + private final ObjectMapper mapper; + private final List<Pattern> exclusionList; public ValidationService(@Qualifier("validationRestClient") RestClient validationRestClient, @Value("${spring.application.name}") String appName, @Value("${validation.service.node-types}") String validationNodes, - @Value("${validation.service.exclusion-regexes:#{null}}") String exclusionRegexes) { + @Value("${validation.service.exclusion-regexes:#{null}}") String exclusionRegexes, + ObjectMapper mapper) { this.validationRestClient = validationRestClient; this.appName = appName; @@ -101,7 +99,7 @@ public class ValidationService { this.exclusionList = Arrays.stream(exclusionRegexes.split(",")).map(Pattern::compile).collect(Collectors.toList()); } - this.gson = new Gson(); + this.mapper = mapper; LOGGER.info("Successfully initialized the pre validation service"); } @@ -119,7 +117,7 @@ public class ValidationService { ResponseEntity<String> healthCheckResponse = null; try { healthCheckResponse = - validationRestClient.execute(VALIDATION_HEALTH_ENDPOINT, HttpMethod.GET, httpHeaders, null); + validationRestClient.execute(VALIDATION_HEALTH_ENDPOINT, HttpMethod.GET, httpHeaders); } catch (Exception ex) { AAIException validationException = new AAIException("AAI_4021", ex); throw validationException; @@ -142,7 +140,7 @@ public class ValidationService { } for (NotificationEvent event : notificationEvents) { - Introspector eventHeader = event.getEventHeader(); + EventHeader eventHeader = event.getEventHeader(); if (eventHeader == null) { // Should I skip processing the request and let it continue // or fail the request and cause client impact @@ -156,10 +154,10 @@ public class ValidationService { if (isDelete(eventHeader)) { continue; } - String entityType = eventHeader.getValue(ENTITY_TYPE); + String entityType = eventHeader.getEntityType(); if (this.shouldValidate(entityType)) { - List<String> violations = preValidate(event.getNotificationEvent()); + List<String> violations = preValidate(event); if (!violations.isEmpty()) { AAIException aaiException = new AAIException("AAI_4019"); aaiException.getTemplateVars().addAll(violations); @@ -172,8 +170,8 @@ public class ValidationService { /** * Determine if event is of type delete */ - private boolean isDelete(Introspector eventHeader) { - String action = eventHeader.getValue(ACTION); + private boolean isDelete(EventHeader eventHeader) { + String action = eventHeader.getAction(); return DELETE.equalsIgnoreCase(action); } @@ -186,15 +184,15 @@ public class ValidationService { // Get the first notification and if the source of that notification // is in one of the regexes then we skip sending it to validation NotificationEvent notification = notificationEvents.get(0); - Introspector eventHeader = notification.getEventHeader(); + EventHeader eventHeader = notification.getEventHeader(); if (eventHeader != null) { - String source = eventHeader.getValue(SOURCE_NAME); + String source = eventHeader.getSourceName(); return exclusionList.stream().anyMatch(pattern -> pattern.matcher(source).matches()); } return false; } - public List<String> preValidate(String body) throws AAIException { + public List<String> preValidate(NotificationEvent notificationEvent) throws AAIException { Map<String, String> httpHeaders = new HashMap<>(); httpHeaders.put("X-FromAppId", appName); httpHeaders.put("X-TransactionID", UUID.randomUUID().toString()); @@ -203,7 +201,8 @@ public class ValidationService { List<String> violations = new ArrayList<>(); ResponseEntity<String> responseEntity; try { - responseEntity = validationRestClient.execute(VALIDATION_ENDPOINT, HttpMethod.POST, httpHeaders, body); + String requestBody = mapper.writeValueAsString(notificationEvent); + responseEntity = validationRestClient.execute(VALIDATION_ENDPOINT, HttpMethod.POST, httpHeaders, requestBody); Object responseBody = responseEntity.getBody(); if (isSuccess(responseEntity)) { LOGGER.debug("Validation Service returned following response status code {} and body {}", @@ -242,8 +241,8 @@ public class ValidationService { private Validation getValidation(Object responseBody) { Validation validation = null; try { - validation = gson.fromJson(responseBody.toString(), Validation.class); - } catch (JsonSyntaxException jsonException) { + validation = mapper.readValue(responseBody.toString(), Validation.class); + } catch (JsonProcessingException jsonException) { LOGGER.warn("Unable to convert the response body {}", jsonException.getMessage()); } return validation; diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java b/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java index 10f5cbaf..4ea0c074 100644 --- a/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java +++ b/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java @@ -30,10 +30,11 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Optional; import java.util.Set; -import org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyTranslator; +import org.apache.tinkerpop.gremlin.process.traversal.translator.GroovyTranslator; import org.apache.tinkerpop.gremlin.process.traversal.Order; import org.apache.tinkerpop.gremlin.process.traversal.P; import org.apache.tinkerpop.gremlin.process.traversal.Path; @@ -519,7 +520,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> { @Override public QueryBuilder<E> store(String name) { - this.traversal.store(name); + this.traversal.aggregate(Scope.local , name); stepIndex++; return this; @@ -1028,7 +1029,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> { try { return mapPaginationResult((Map<String,Object>) completeTraversal.next()); // .next() will throw an IllegalArguementException if there are no vertices of the given type - } catch (IllegalArgumentException e) { + } catch (NoSuchElementException | IllegalArgumentException e) { return new PaginationResult<>(Collections.emptyList(), 0L); } } 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 94dc63aa..c481e2cd 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 @@ -130,7 +130,7 @@ public class HttpEntry { this.dbEngine = new JanusGraphDBEngine(queryStyle, loader); getDbEngine().startTransaction(); - this.notification = new UEBNotification(loader, loaderFactory, schemaVersions); + this.notification = new UEBNotification(loaderFactory, schemaVersions); if ("true".equals(AAIConfig.get("aai.notification.depth.all.enabled", "true"))) { this.notificationDepth = AAIProperties.MAXIMUM_DEPTH; } else { @@ -196,7 +196,6 @@ public class HttpEntry { Set<String> groups, boolean enableResourceVersion, QueryOptions queryOptions) throws AAIException { DBSerializer serializer = null; - if (serverBase != null) { serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth, groups, notificationDepth, serverBase); @@ -205,45 +204,29 @@ public class HttpEntry { notificationDepth); } - Response response; - Introspector obj; - QueryParser query; - URI uri; - String transactionId = null; - int depth; - Format format = null; - List<Pair<URI, Response>> responses = new ArrayList<>(); - MultivaluedMap<String, String> params; - HttpMethod method; - String uriTemp; - boolean success = true; - QueryEngine queryEngine = dbEngine.getQueryEngine(); Set<Vertex> mainVertexesToNotifyOn = new LinkedHashSet<>(); - AaiDBMetricLog metricLog = new AaiDBMetricLog(AAIConstants.AAI_RESOURCES_MS); String outputMediaType = null; - if (requests != null && !requests.isEmpty()) { HttpHeaders headers = requests.get(0).getHeaders(); outputMediaType = getMediaType(headers.getAcceptableMediaTypes()); } + String transactionId = requests.get(0).getTransactionId(); + boolean success = true; + QueryEngine queryEngine = dbEngine.getQueryEngine(); + List<Pair<URI, Response>> responses = new ArrayList<>(); for (DBRequest request : requests) { - response = null; + Response response = null; Status status = Status.NOT_FOUND; - method = request.getMethod(); + HttpMethod method = request.getMethod(); metricLog.pre(request); try { try { + String uriTemp = request.getUri().getRawPath().replaceFirst("^v\\d+/", ""); - obj = request.getIntrospector(); - query = request.getParser(); - transactionId = request.getTransactionId(); - uriTemp = request.getUri().getRawPath().replaceFirst("^v\\d+/", ""); - uri = UriBuilder.fromPath(uriTemp).build(); - - boolean groupsAvailable = serializer.getGroups() != null && !serializer.getGroups().isEmpty(); + QueryParser query = request.getParser(); List<Vertex> queryResult; PaginationResult<Vertex> paginationResult = null; if(queryOptions != null && queryOptions.getPageable() != null) { @@ -253,28 +236,22 @@ public class HttpEntry { queryResult = executeQuery(query, queryOptions); } + boolean groupsAvailable = serializer.getGroups() != null && !serializer.getGroups().isEmpty(); List<Vertex> vertices = groupsAvailable ? queryResult.stream() .filter(vertex -> OwnerCheck.isAuthorized(groups, vertex)) .collect(Collectors.toList()) : queryResult; - boolean isNewVertex; - HttpHeaders headers = request.getHeaders(); - outputMediaType = getMediaType(headers.getAcceptableMediaTypes()); - String result = null; - params = request.getInfo().getQueryParameters(false); - depth = setDepth(obj, params.getFirst("depth")); + MultivaluedMap<String, String> params = request.getInfo().getQueryParameters(false); + Introspector obj = request.getIntrospector(); + int depth = setDepth(obj, params.getFirst("depth")); + Format format = null; if (params.containsKey("format")) { format = Format.getFormat(params.getFirst("format")); } - String cleanUp = params.getFirst("cleanup"); - String requestContext = ""; - List<String> requestContextList = request.getHeaders().getRequestHeader("aai-request-context"); - if (requestContextList != null) { - requestContext = requestContextList.get(0); - } + String cleanUp = params.getFirst("cleanup"); if (cleanUp == null) { cleanUp = "false"; } @@ -287,6 +264,7 @@ public class HttpEntry { throw new AAIException("AAI_6137"); } } + boolean isNewVertex; if (method.equals(HttpMethod.PUT)) { String resourceVersion = obj.getValue(AAIProperties.RESOURCE_VERSION); if (vertices.isEmpty()) { @@ -337,6 +315,16 @@ public class HttpEntry { HashMap<String, Introspector> relatedObjects = new HashMap<>(); String nodeOnly = params.getFirst("nodes-only"); boolean isNodeOnly = nodeOnly != null; + + String requestContext = ""; + List<String> requestContextList = request.getHeaders().getRequestHeader("aai-request-context"); + if (requestContextList != null) { + requestContext = requestContextList.get(0); + } + URI uri = UriBuilder.fromPath(uriTemp).build(); + HttpHeaders headers = request.getHeaders(); + outputMediaType = getMediaType(headers.getAcceptableMediaTypes()); + String result = null; switch (method) { case GET: @@ -384,7 +372,7 @@ public class HttpEntry { if (obj != null) { status = Status.OK; MarshallerProperties properties; - if (!request.getMarshallerProperties().isPresent()) { + if (request.getMarshallerProperties().isEmpty()) { properties = new MarshallerProperties.Builder( org.onap.aai.restcore.MediaType.getEnum(outputMediaType)).build(); } else { diff --git a/aai-core/src/main/java/org/onap/aai/rest/notification/EntityConverter.java b/aai-core/src/main/java/org/onap/aai/rest/notification/EntityConverter.java new file mode 100644 index 00000000..e939f323 --- /dev/null +++ b/aai-core/src/main/java/org/onap/aai/rest/notification/EntityConverter.java @@ -0,0 +1,66 @@ +/** + * ============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.util.List; + +import org.onap.aai.introspection.Introspector; +import org.onap.aai.introspection.exceptions.AAIUnmarshallingException; +import org.onap.aai.parsers.uri.URIToObject; + +import lombok.Value; + +@Value +public class EntityConverter { + + final URIToObject parser; + + public Introspector convert(Introspector obj) throws AAIUnmarshallingException { + List<Object> parentList = parser.getParentList(); + parentList.clear(); + + if (!parser.getTopEntity().equals(parser.getEntity())) { + Introspector child = obj; + if (!parser.getLoader().getVersion().equals(obj.getVersion())) { + String json = obj.marshal(false); + child = parser.getLoader().unmarshal(parser.getEntity().getName(), json); + } + + // wrap the child object in its parents + parentList.add(child.getUnderlyingObject()); + } + + final Introspector eventObject; + if (parser.getTopEntity().equals(parser.getEntity())) { + // take the top level parent object passed in + eventObject = obj; + } else { + // take the wrapped child objects (ogres are like onions) + eventObject = parser.getTopEntity(); + } + + return eventObject; + } + + public String getTopEntityName() { + return parser.getTopEntityName(); + } +} diff --git a/aai-core/src/main/java/org/onap/aai/rest/notification/NotificationEvent.java b/aai-core/src/main/java/org/onap/aai/rest/notification/NotificationEvent.java deleted file mode 100644 index 17f09b19..00000000 --- a/aai-core/src/main/java/org/onap/aai/rest/notification/NotificationEvent.java +++ /dev/null @@ -1,101 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.aai.rest.notification; - -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.Introspector; -import org.onap.aai.introspection.Loader; -import org.onap.aai.setup.SchemaVersion; -import org.onap.aai.util.StoreNotificationEvent; - -/** - * The Class NotificationEvent. - */ -public class NotificationEvent { - - private final Loader loader; - - private final Introspector eventHeader; - - private final Introspector obj; - private final String transactionId; - private final String sourceOfTruth; - - /** - * Instantiates a new notification event. - * - * @param eventHeader the event header - * @param obj the obj - */ - public NotificationEvent(Loader loader, Introspector eventHeader, Introspector obj, String transactionId, - String sourceOfTruth) { - this.loader = loader; - this.eventHeader = eventHeader; - this.obj = obj; - this.transactionId = transactionId; - this.sourceOfTruth = sourceOfTruth; - } - - /** - * Trigger. - * - * @throws AAIException the AAI exception - */ - public void trigger() throws AAIException { - - StoreNotificationEvent sne = new StoreNotificationEvent(transactionId, sourceOfTruth); - - sne.storeEventAndSendToJms(loader, eventHeader, obj); - - } - - public String getNotificationEvent() throws AAIException { - return new StoreNotificationEvent(transactionId, sourceOfTruth).storeEventOnly(loader, eventHeader, obj); - } - - /** - * Gets the notification version. - * - * @return the notification version - */ - public SchemaVersion getNotificationVersion() { - return loader.getVersion(); - } - - /** - * Gets the event header. - * - * @return the event header - */ - public Introspector getEventHeader() { - return eventHeader; - } - - /** - * Gets the obj. - * - * @return the obj - */ - public Introspector getObj() { - return obj; - } - -} 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 index 9c3dde15..c2770692 100644 --- 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 @@ -34,6 +34,7 @@ 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.kafka.NotificationProducer; import org.onap.aai.prevalidation.ValidationService; import org.onap.aai.serialization.db.DBSerializer; import org.onap.aai.serialization.engines.query.QueryEngine; @@ -52,6 +53,7 @@ public class NotificationService { public static final Logger LOGGER = LoggerFactory.getLogger(NotificationService.class); private final ValidationService validationService; + private final NotificationProducer notificationProducer; private final LoaderFactory loaderFactory; private final boolean isDeltaEventsEnabled; private final String basePath; @@ -60,11 +62,13 @@ public class NotificationService { @Nullable ValidationService validationService, LoaderFactory loaderFactory, @Value("${schema.uri.base.path}") String basePath, - @Value("${delta.events.enabled:false}") boolean isDeltaEventsEnabled) { + @Value("${delta.events.enabled:false}") boolean isDeltaEventsEnabled, + NotificationProducer notificationProducer) { this.validationService = validationService; this.loaderFactory = loaderFactory; this.basePath = basePath; this.isDeltaEventsEnabled = isDeltaEventsEnabled; + this.notificationProducer = notificationProducer; } /** @@ -99,7 +103,7 @@ public class NotificationService { validationService.validate(notification.getEvents()); } - notification.triggerEvents(); + notificationProducer.sendUEBNotification(notification); if (isDeltaEventsEnabled) { try { DeltaEvents deltaEvents = new DeltaEvents(transactionId, sourceOfTruth, schemaVersion.toString(), diff --git a/aai-core/src/main/java/org/onap/aai/rest/notification/UEBNotification.java b/aai-core/src/main/java/org/onap/aai/rest/notification/UEBNotification.java index 83a446b2..61be76c8 100644 --- a/aai-core/src/main/java/org/onap/aai/rest/notification/UEBNotification.java +++ b/aai-core/src/main/java/org/onap/aai/rest/notification/UEBNotification.java @@ -4,6 +4,8 @@ * ================================================================================ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. * ================================================================================ + * Modifications Copyright © 2024 Deutsche Telekom. + * ================================================================================ * 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 @@ -30,6 +32,8 @@ import java.util.Map; import javax.ws.rs.core.Response.Status; +import org.onap.aai.domain.notificationEvent.NotificationEvent; +import org.onap.aai.domain.notificationEvent.NotificationEvent.EventHeader; import org.onap.aai.exceptions.AAIException; import org.onap.aai.introspection.Introspector; import org.onap.aai.introspection.Loader; @@ -41,59 +45,31 @@ import org.onap.aai.logging.LogFormatTools; import org.onap.aai.parsers.uri.URIToObject; import org.onap.aai.setup.SchemaVersion; import org.onap.aai.setup.SchemaVersions; +import org.onap.aai.util.AAIConfig; +import org.onap.aai.util.AAIConstants; +import org.onap.aai.util.FormatDate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** - * The Class UEBNotification. - */ public class UEBNotification { private static final Logger LOGGER = LoggerFactory.getLogger(UEBNotification.class); + private static final FormatDate FORMAT_DATE = new FormatDate("YYYYMMdd-HH:mm:ss:SSS"); + private static final String EVENT_TYPE = "AAI-EVENT"; - private Loader currentVersionLoader = null; - protected Map<String, NotificationEvent> events = null; - private SchemaVersion notificationVersion = null; - - /** - * Instantiates a new UEB notification. - * - * @param loader the loader - */ - public UEBNotification(Loader loader, LoaderFactory loaderFactory, SchemaVersions schemaVersions) { - events = new LinkedHashMap<>(); - SchemaVersion defaultVersion = schemaVersions.getDefaultVersion(); - currentVersionLoader = loaderFactory.createLoaderForVersion(loader.getModelType(), defaultVersion); - notificationVersion = defaultVersion; - } + private final String domain = AAIConfig.get("aai.notificationEvent.default.domain", "UNK"); + private final String sequenceNumber = AAIConfig.get("aai.notificationEvent.default.sequenceNumber", "UNK"); + private final String severity = AAIConfig.get("aai.notificationEvent.default.severity", "UNK"); + private final Map<String, NotificationEvent> events; + private final Loader currentVersionLoader; + private final SchemaVersion notificationVersion; - /** - * Instantiates a new UEB notification. - * - * @param modelType - Model type - * @param loaderFactory - the loader factory - * @param schemaVersions the schema versions bean - */ - public UEBNotification(ModelType modelType, LoaderFactory loaderFactory, SchemaVersions schemaVersions) { + public UEBNotification(LoaderFactory loaderFactory, SchemaVersions schemaVersions) { events = new LinkedHashMap<>(); - SchemaVersion defaultVersion = schemaVersions.getDefaultVersion(); - currentVersionLoader = loaderFactory.createLoaderForVersion(modelType, defaultVersion); - notificationVersion = defaultVersion; + notificationVersion = schemaVersions.getDefaultVersion(); + currentVersionLoader = loaderFactory.createLoaderForVersion(ModelType.MOXY, notificationVersion); } - /** - * Creates the notification event. - * - * @param transactionId the X-TransactionId - * @param sourceOfTruth - * @param status the status - * @param uri the uri - * @param obj the obj - * @param basePath base URI path - * @throws AAIException the AAI exception - * @throws IllegalArgumentException the illegal argument exception - * @throws UnsupportedEncodingException the unsupported encoding exception - */ public void createNotificationEvent(String transactionId, String sourceOfTruth, Status status, URI uri, Introspector obj, HashMap<String, Introspector> relatedObjects, String basePath) throws AAIException, UnsupportedEncodingException { @@ -101,60 +77,32 @@ public class UEBNotification { String action = getAction(status); try { - Introspector eventHeader = currentVersionLoader.introspectorFromName("notification-event-header"); - URIToObject parser = new URIToObject(currentVersionLoader, uri, relatedObjects); + EntityConverter entityConverter = new EntityConverter(new URIToObject(currentVersionLoader, uri, relatedObjects)); + EventHeader eventHeader = new EventHeader(); basePath = formatBasePath(basePath); - String entityLink = formatEntityLink(uri, basePath); - - eventHeader.setValue("entity-link", entityLink); - eventHeader.setValue("action", action); - eventHeader.setValue("entity-type", obj.getDbName()); - eventHeader.setValue("top-entity-type", parser.getTopEntityName()); - eventHeader.setValue("source-name", sourceOfTruth); - eventHeader.setValue("version", notificationVersion.toString()); - eventHeader.setValue("id", transactionId); - - List<Object> parentList = parser.getParentList(); - parentList.clear(); - - if (!parser.getTopEntity().equals(parser.getEntity())) { - Introspector child = obj; - if (!parser.getLoader().getVersion().equals(obj.getVersion())) { - String json = obj.marshal(false); - child = parser.getLoader().unmarshal(parser.getEntity().getName(), json); - } - - // wrap the child object in its parents - parentList.add(child.getUnderlyingObject()); - } - - final Introspector eventObject; - - // convert to most resent version - if (!parser.getLoader().getVersion().equals(currentVersionLoader.getVersion())) { - String json = ""; - if (parser.getTopEntity().equals(parser.getEntity())) { - // convert the parent object passed in - json = obj.marshal(false); - eventObject = currentVersionLoader.unmarshal(obj.getName(), json); - } else { - // convert the object created in the parser - json = parser.getTopEntity().marshal(false); - eventObject = currentVersionLoader.unmarshal(parser.getTopEntity().getName(), json); - } - } else { - if (parser.getTopEntity().equals(parser.getEntity())) { - // take the top level parent object passed in - eventObject = obj; - } else { - // take the wrapped child objects (ogres are like onions) - eventObject = parser.getTopEntity(); - } - } - final NotificationEvent event = - new NotificationEvent(currentVersionLoader, eventHeader, eventObject, transactionId, sourceOfTruth); + eventHeader.setEntityLink(entityLink); + eventHeader.setAction(action); + eventHeader.setEntityType(obj.getDbName()); + eventHeader.setTopEntityType(entityConverter.getTopEntityName()); + eventHeader.setSourceName(sourceOfTruth); + eventHeader.setVersion(notificationVersion.toString()); + eventHeader.setId(transactionId); + + // default values + eventHeader.setTimestamp(FORMAT_DATE.getDateTime()); + eventHeader.setEventType(EVENT_TYPE); + eventHeader.setDomain(domain); + eventHeader.setSequenceNumber(sequenceNumber); + eventHeader.setSeverity(severity); + + Introspector entity = entityConverter.convert(obj); + + final NotificationEvent event = new NotificationEvent(); + event.setEventHeader(eventHeader); + event.setCambriaPartition(AAIConstants.UEB_PUB_PARTITION_AAI); + event.setEntity(entity); events.put(uri.toString(), event); } catch (AAIUnknownObjectException e) { throw new RuntimeException("Fatal error - notification-event-header object not found!"); @@ -206,26 +154,10 @@ public class UEBNotification { return action; } - /** - * Trigger events. - * - * @throws AAIException the AAI exception - */ - public void triggerEvents() throws AAIException { - for (NotificationEvent event : events.values()) { - event.trigger(); - } - clearEvents(); - } - public List<NotificationEvent> getEvents() { return new ArrayList<>(this.events.values()); } - public Map<String, NotificationEvent> getEventsMap() { - return this.events; - } - private String getUri(String uri, String basePath) { if (uri == null || uri.isEmpty()) { return ""; 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 0d491c9d..ce3891ee 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 @@ -112,7 +112,7 @@ public class EdgeSerializer { if (message.isPresent() && !isBestEffort) { throw new EdgeMultiplicityException(message.get()); } - if (!message.isPresent()) { + if (message.isEmpty()) { if (rule.getDirection().equals(Direction.OUT)) { e = aVertex.addEdge(rule.getLabel(), bVertex); } else if (rule.getDirection().equals(Direction.IN)) { @@ -185,7 +185,7 @@ public class EdgeSerializer { if (message.isPresent() && !isBestEffort) { throw new EdgeMultiplicityException(message.get()); } - if (!message.isPresent()) { + if (message.isEmpty()) { if (rule.getDirection().equals(Direction.OUT)) { e = aVertex.addEdge(rule.getLabel(), bVertex); } else if (rule.getDirection().equals(Direction.IN)) { diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Aggregate.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Aggregate.java index 71f7bc78..54fc4eb0 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Aggregate.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Aggregate.java @@ -177,7 +177,7 @@ public class Aggregate extends MultiFormatMapper { } return Optional.<JsonObject>empty(); - }).filter(Optional::isPresent).map(Optional::get).forEach(json -> { + }).flatMap(Optional::stream).forEach(json -> { if (isParallel) { synchronized (body) { body.add(json); diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Count.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Count.java index 216d021d..c736eab8 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Count.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Count.java @@ -44,7 +44,7 @@ public class Count implements FormatMapper { final JsonObject countResult = new JsonObject(); - list.stream().map(this::getCount).filter(Optional::isPresent).map(Optional::get) + list.stream().map(this::getCount).flatMap(Optional::stream) .collect(Collectors.toConcurrentMap(Pair::getValue0, Pair::getValue1, Long::sum)) .forEach(countResult::addProperty); diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Formatter.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Formatter.java index da5d5425..10f1edc4 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Formatter.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Formatter.java @@ -102,7 +102,7 @@ public class Formatter { } return Optional.<JsonObject>empty(); - }).filter(Optional::isPresent).map(Optional::get).forEach(json -> { + }).flatMap(Optional::stream).forEach(json -> { if (isParallel) { synchronized (body) { body.add(json); diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/GraphSON.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/GraphSON.java index 89970e24..9c7c4a44 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/GraphSON.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/GraphSON.java @@ -54,7 +54,7 @@ public class GraphSON implements FormatMapper { private static final GraphSONVersion version = GraphSONVersion.V1_0; private final GraphSONMapper mapper = - GraphSONMapper.build().version(version).addRegistry(JanusGraphIoRegistry.getInstance()).create(); + GraphSONMapper.build().version(version).addRegistry(JanusGraphIoRegistry.instance()).create(); private final GraphSONWriter writer = GraphSONWriter.build().mapper(mapper).create(); @Override diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/LifecycleFormat.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/LifecycleFormat.java index 74742c98..fbe74e28 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/LifecycleFormat.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/LifecycleFormat.java @@ -267,7 +267,7 @@ public class LifecycleFormat extends HistoryFormat { } return Optional.<JsonObject>empty(); - }).filter(Optional::isPresent).map(Optional::get).forEach(json -> { + }).flatMap(Optional::stream).forEach(json -> { if (isParallel) { synchronized (body) { body.add(json); diff --git a/aai-core/src/main/java/org/onap/aai/util/HttpsAuthClient.java b/aai-core/src/main/java/org/onap/aai/util/HttpsAuthClient.java index f8f0b65e..b31bfcb8 100644 --- a/aai-core/src/main/java/org/onap/aai/util/HttpsAuthClient.java +++ b/aai-core/src/main/java/org/onap/aai/util/HttpsAuthClient.java @@ -20,13 +20,6 @@ package org.onap.aai.util; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.api.json.JSONConfiguration; -import com.sun.jersey.client.urlconnection.HTTPSProperties; - import java.io.FileInputStream; import java.io.IOException; import java.security.KeyManagementException; @@ -41,8 +34,16 @@ import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; - -import org.onap.aai.aailog.filter.RestControllerClientLoggingInterceptor; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.commons.configuration2.JSONConfiguration; +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.client.ClientProperties; +import org.onap.aai.aailog.filter.RestControllerClientRequestLoggingInterceptor; +import org.onap.aai.aailog.filter.RestControllerClientResponseLoggingInterceptor; import org.onap.aai.exceptions.AAIException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,12 +63,10 @@ public class HttpsAuthClient { System.out.println("Making Jersey https call..."); Client client = HttpsAuthClient.getClient(); - ClientResponse res = client.resource(url).accept("application/json").header("X-TransactionId", "PROV001") - .header("X-FromAppId", "AAI").type("application/json").get(ClientResponse.class); - - // System.out.println("Jersey result: "); - // System.out.println(res.getEntity(String.class).toString()); - + Response res = client.target(url) + .request(MediaType.APPLICATION_JSON) + .header("X-TransactionId", "PROV001") + .header("X-FromAppId", "AAI").get(); } catch (KeyManagementException e) { logger.debug("HttpsAuthClient KeyManagement error : {}", e.getMessage()); } catch (Exception e) { @@ -89,9 +88,9 @@ public class HttpsAuthClient { String keystorePassword) throws KeyManagementException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException { - ClientConfig config = new DefaultClientConfig(); - config.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); - config.getClasses().add(org.onap.aai.restcore.CustomJacksonJaxBJsonProvider.class); + ClientConfig config = new ClientConfig(); + config.register(org.onap.aai.restcore.CustomJacksonJaxBJsonProvider.class); + SSLContext ctx = null; try { System.setProperty("javax.net.ssl.trustStore", truststorePath); @@ -117,20 +116,16 @@ public class HttpsAuthClient { } ctx.init(kmf.getKeyManagers(), null, null); - config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, - new HTTPSProperties(new HostnameVerifier() { - @Override - public boolean verify(String s, SSLSession sslSession) { - return true; - } - }, ctx)); + config.property("jersey.config.client.ssl.context", ctx); + config.property("jersey.config.client.hostname.verifier", (HostnameVerifier) (s, sslSession) -> true); } catch (Exception e) { System.out.println("Error setting up config: exiting " + e.getMessage()); throw e; } - Client client = Client.create(config); - client.addFilter(new RestControllerClientLoggingInterceptor()); + Client client = ClientBuilder.newClient(config); + client.register(new RestControllerClientRequestLoggingInterceptor()); + client.register(new RestControllerClientResponseLoggingInterceptor()); // uncomment this line to get more logging for the request/response // client.addFilter(new LoggingFilter(System.out)); diff --git a/aai-core/src/main/java/org/onap/aai/util/HttpsAuthExternalClient.java b/aai-core/src/main/java/org/onap/aai/util/HttpsAuthExternalClient.java index 53e2d958..1ace66c7 100644 --- a/aai-core/src/main/java/org/onap/aai/util/HttpsAuthExternalClient.java +++ b/aai-core/src/main/java/org/onap/aai/util/HttpsAuthExternalClient.java @@ -20,21 +20,16 @@ package org.onap.aai.util; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.api.json.JSONConfiguration; -import com.sun.jersey.client.urlconnection.HTTPSProperties; - import java.io.FileInputStream; -import java.security.KeyStore; + +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.SslConfigurator; import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManagerFactory; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; public class HttpsAuthExternalClient { @@ -48,63 +43,45 @@ public class HttpsAuthExternalClient { */ public static Client getClient(String keystoreFileName, String keystorePassword) throws Exception { - ClientConfig config = new DefaultClientConfig(); - config.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); - config.getClasses().add(org.onap.aai.restcore.CustomJacksonJaxBJsonProvider.class); - Client client = null; - SSLContext ctx = null; - String truststore_path = AAIConstants.AAI_HOME_ETC_AUTH + AAIConfig.get(AAIConstants.AAI_TRUSTSTORE_FILENAME); - try (FileInputStream tin = new FileInputStream(truststore_path)) { - String truststore_password = AAIConfig.get(AAIConstants.AAI_TRUSTSTORE_PASSWD); - String keystore_path = AAIConstants.AAI_HOME_ETC_AUTH + keystoreFileName; - String keystore_password = keystorePassword; - // System.setProperty("javax.net.ssl.trustStore", truststore_path); - // System.setProperty("javax.net.ssl.trustStorePassword", truststore_password); - HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { - public boolean verify(String string, SSLSession ssls) { - return true; - } - }); + ClientConfig config = new ClientConfig(); + config.register(org.onap.aai.restcore.CustomJacksonJaxBJsonProvider.class); - ctx = SSLContext.getInstance("TLS"); - KeyManagerFactory kmf = null; + SSLContext sslContext = null; + String truststorePath = AAIConstants.AAI_HOME_ETC_AUTH + AAIConfig.get(AAIConstants.AAI_TRUSTSTORE_FILENAME); + try (FileInputStream tin = new FileInputStream(truststorePath)) { + String truststorePassword = AAIConfig.get(AAIConstants.AAI_TRUSTSTORE_PASSWD); + String keystorePath = AAIConstants.AAI_HOME_ETC_AUTH + keystoreFileName; - /**** - * kmf = KeyManagerFactory.getInstance("SunX509"); - * FileInputStream fin = new FileInputStream(keystore_path); - * KeyStore ks = KeyStore.getInstance("PKCS12"); - * char[] pwd = keystore_password.toCharArray(); - * ks.load(fin, pwd); - * kmf.init(ks, pwd); - ***/ + SslConfigurator sslConfig = SslConfigurator.newInstance() + .trustStoreFile(truststorePath) + .trustStorePassword(truststorePassword) + .keyStoreFile(keystorePath) + .keyStorePassword(keystorePassword); - String alg = TrustManagerFactory.getDefaultAlgorithm(); - TrustManagerFactory tmf = TrustManagerFactory.getInstance(alg); + sslContext = sslConfig.createSSLContext(); - KeyStore ts = KeyStore.getInstance("PKCS12"); - char[] tpwd = truststore_password.toCharArray(); - ts.load(tin, tpwd); - tmf.init(ts); + HostnameVerifier hostnameVerifier = new HostnameVerifier() { + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } + }; - // ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); - // Updating key manager to null, to disable two way SSL - ctx.init(null, tmf.getTrustManagers(), null); + Client client = ClientBuilder.newBuilder() + .withConfig(config) + .sslContext(sslContext) + .hostnameVerifier(hostnameVerifier) + .build(); - config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, - new HTTPSProperties(new HostnameVerifier() { - @Override - public boolean verify(String s, SSLSession sslSession) { - return true; - } - }, ctx)); + // Uncomment this line to get more logging for the request/response + // client.register(new + // LoggingFeature(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME), + // Level.INFO, LoggingFeature.Verbosity.PAYLOAD_ANY, 8192)); - client = Client.create(config); - // uncomment this line to get more logging for the request/response - // client.addFilter(new LoggingFilter(System.out)); + return client; } catch (Exception e) { throw e; } - return client; } } diff --git a/aai-core/src/main/java/org/onap/aai/util/RestController.java b/aai-core/src/main/java/org/onap/aai/util/RestController.java index 1b050829..b72b5af5 100644 --- a/aai-core/src/main/java/org/onap/aai/util/RestController.java +++ b/aai-core/src/main/java/org/onap/aai/util/RestController.java @@ -22,9 +22,8 @@ package org.onap.aai.util; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.TypeFactory; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.ClientHandlerException; -import com.sun.jersey.api.client.ClientResponse; + +import javax.ws.rs.client.Entity; import java.io.IOException; import java.lang.reflect.InvocationTargetException; @@ -37,6 +36,11 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; +import javax.ws.rs.ClientErrorException; +import javax.ws.rs.client.Client; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + import org.onap.aai.exceptions.AAIException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,8 +73,7 @@ public class RestController implements RestControllerInterface { public static final String REST_APIPATH_CLOUDREGION = "cloud-infrastructure/cloud-regions/cloud-region/"; public static final String REST_APIPATH_TENANT = "cloud-infrastructure/tenants/tenant/"; - public static final String REST_APIPATH_VIRTUAL_DATA_CENTER = - "cloud-infrastructure/virtual-data-centers/virtual-data-center/"; + public static final String REST_APIPATH_VIRTUAL_DATA_CENTER = "cloud-infrastructure/virtual-data-centers/virtual-data-center/"; public static final String REST_APIPATH_VIRTUAL_DATA_CENTERS = "cloud-infrastructure/virtual-data-centers/"; public static final String REST_APIPATH_GENERIC_VNF = "network/generic-vnfs/generic-vnf/"; public static final String REST_APIPATH_GENERIC_VNFS = "network/generic-vnfs"; @@ -173,8 +176,8 @@ public class RestController implements RestControllerInterface { url = AAIConfig.get(AAIConstants.AAI_OLDSERVER_URL) + path; } else { if (overrideLocalHost == null) { - overrideLocalHost = - AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT); + overrideLocalHost = AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, + AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT); } if (AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT.equals(overrideLocalHost)) { url = String.format(AAIConstants.AAI_LOCAL_REST, port, @@ -185,21 +188,26 @@ public class RestController implements RestControllerInterface { } } LOGGER.debug(url + " for the get REST API"); - ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId) - .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json") - .get(ClientResponse.class); + Response response = client.target(url) + .request(MediaType.APPLICATION_JSON) + .header("X-TransactionId", transId) + .header("X-FromAppId", sourceID) + .header("Real-Time", "true") + .get(); - // System.out.println("cres.EntityInputSream()="+cres.getEntityInputStream().toString()); - // System.out.println("cres.tostring()="+cres.toString()); + // System.out.println("response.EntityInputSream()="+response.getEntityInputStream().toString()); + // System.out.println("response.tostring()="+response.toString()); - if (cres.getStatus() == 200) { + if (response.getStatus() == 200) { // System.out.println(methodName + ": url=" + url); - t = (T) cres.getEntity(t.getClass()); + T entity = response.readEntity((Class<T>) t.getClass()); + restObject.set(entity); restObject.set(t); LOGGER.debug(methodName + "REST api GET was successfull!"); } else { - // System.out.println(methodName + ": url=" + url + " failed with status=" + cres.getStatus()); - throw new AAIException("AAI_7116", methodName + " with status=" + cres.getStatus() + ", url=" + url); + // System.out.println(methodName + ": url=" + url + " failed with status=" + + // response.getStatus()); + throw new AAIException("AAI_7116", methodName + " with status=" + response.getStatus() + ", url=" + url); } } @@ -229,21 +237,25 @@ public class RestController implements RestControllerInterface { url = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE) + apiVersion + "/" + path; LOGGER.debug(url + " for the get REST API"); - ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId) - .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json") - .get(ClientResponse.class); + Response response = client.target(url) + .request(MediaType.APPLICATION_JSON) + .header("X-TransactionId", transId) + .header("X-FromAppId", sourceID) + .header("Real-Time", "true") + .get(); - // System.out.println("cres.EntityInputSream()="+cres.getEntityInputStream().toString()); - // System.out.println("cres.tostring()="+cres.toString()); + // System.out.println("response.EntityInputSream()="+response.getEntityInputStream().toString()); + // System.out.println("response.tostring()="+response.toString()); - if (cres.getStatus() == 200) { + if (response.getStatus() == 200) { // System.out.println(methodName + ": url=" + url); - t = (T) cres.getEntity(t.getClass()); - restObject.set(t); + T entity = response.readEntity((Class<T>) t.getClass()); + restObject.set(entity); LOGGER.debug(methodName + "REST api GET was successfull!"); } else { - // System.out.println(methodName + ": url=" + url + " failed with status=" + cres.getStatus()); - throw new AAIException("AAI_7116", methodName + " with status=" + cres.getStatus() + ", url=" + url); + // System.out.println(methodName + ": url=" + url + " failed with status=" + + // response.getStatus()); + throw new AAIException("AAI_7116", methodName + " with status=" + response.getStatus() + ", url=" + url); } } @@ -318,8 +330,8 @@ public class RestController implements RestControllerInterface { url = AAIConfig.get(AAIConstants.AAI_OLDSERVER_URL) + path; } else { if (overrideLocalHost == null) { - overrideLocalHost = - AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT); + overrideLocalHost = AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, + AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT); } if (AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT.equals(overrideLocalHost)) { url = String.format(AAIConstants.AAI_LOCAL_REST, port, @@ -330,18 +342,21 @@ public class RestController implements RestControllerInterface { } } - ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId) - .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(t) - .put(ClientResponse.class); + Response response = client.target(url) + .request(MediaType.APPLICATION_JSON) + .header("X-TransactionId", transId) + .header("X-FromAppId", sourceID) + .header("Real-Time", "true") + .put(Entity.entity(t, MediaType.APPLICATION_JSON)); - // System.out.println("cres.tostring()="+cres.toString()); + // System.out.println("response.tostring()="+response.toString()); - int statuscode = cres.getStatus(); + int statuscode = response.getStatus(); if (statuscode >= 200 && statuscode <= 299) { LOGGER.debug(methodName + ": url=" + url + ", request=" + path); } else { throw new AAIException("AAI_7116", methodName + " with status=" + statuscode + ", url=" + url + ", msg=" - + cres.getEntity(String.class)); + + response.readEntity(String.class)); } } @@ -365,18 +380,21 @@ public class RestController implements RestControllerInterface { url = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE) + apiVersion + "/" + path; - ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId) - .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(t) - .put(ClientResponse.class); + Response response = client.target(url) + .request(MediaType.APPLICATION_JSON) + .header("X-TransactionId", transId) + .header("X-FromAppId", sourceID) + .header("Real-Time", "true") + .put(Entity.entity(t, MediaType.APPLICATION_JSON)); - // System.out.println("cres.tostring()="+cres.toString()); + // System.out.println("response.tostring()="+response.toString()); - int statuscode = cres.getStatus(); + int statuscode = response.getStatus(); if (statuscode >= 200 && statuscode <= 299) { LOGGER.debug(methodName + ": url=" + url + ", request=" + path); } else { throw new AAIException("AAI_7116", methodName + " with status=" + statuscode + ", url=" + url + ", msg=" - + cres.getEntity(String.class)); + + response.getEntity()); } } @@ -410,16 +428,20 @@ public class RestController implements RestControllerInterface { url = String.format(AAIConstants.AAI_LOCAL_REST_OVERRIDE, overrideLocalHost, AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path; } - ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId) - .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(request) - .delete(ClientResponse.class); - - if (cres.getStatus() == 404) { // resource not found - LOGGER.info("Resource does not exist...: " + cres.getStatus() + ":" + cres.getEntity(String.class)); - } else if (cres.getStatus() == 200 || cres.getStatus() == 204) { + Response response = client.target(url) + .request(MediaType.APPLICATION_JSON) + .header("X-TransactionId", transId) + .header("X-FromAppId", sourceID) + .header("Real-Time", "true") + .delete(); + + if (response.getStatus() == 404) { // resource not found + LOGGER.info( + "Resource does not exist...: " + response.getStatus() + ":" + response.readEntity(String.class)); + } else if (response.getStatus() == 200 || response.getStatus() == 204) { LOGGER.info("Resource " + url + " deleted"); } else { - LOGGER.error("Deleting Resource failed: " + cres.getStatus() + ":" + cres.getEntity(String.class)); + LOGGER.error("Deleting Resource failed: " + response.getStatus() + ":" + response.readEntity(String.class)); throw new AAIException("AAI_7116", "Error during DELETE"); } } @@ -451,17 +473,20 @@ public class RestController implements RestControllerInterface { url = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE) + apiVersion + "/" + path; - ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId) - .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(t) - .post(ClientResponse.class); + Response response = client.target(url) + .request(MediaType.APPLICATION_JSON) + .header("X-TransactionId", transId) + .header("X-FromAppId", sourceID) + .header("Real-Time", "true") + .post(Entity.entity(t, MediaType.APPLICATION_JSON)); - int statuscode = cres.getStatus(); + int statuscode = response.getStatus(); if (statuscode >= 200 && statuscode <= 299) { LOGGER.debug(methodName + "REST api POST was successful!"); - return cres.getEntity(String.class); + return response.readEntity(String.class); } else { throw new AAIException("AAI_7116", methodName + " with status=" + statuscode + ", url=" + url + ", msg=" - + cres.getEntity(String.class)); + + response.readEntity(String.class)); } } catch (AAIException e) { @@ -503,17 +528,17 @@ public class RestController implements RestControllerInterface { */ /* * DoesResourceExist - * + * * To check whether a resource exist or get a copy of the existing version of the resource - * + * * Resourcepath: should contain the qualified resource path (including encoded unique key identifier value), * resourceClassName: is the canonical name of the resource class name, * fromAppId: * transId: - * + * * Will return null (if the resource doesn’t exist) (or) * Will return the specified resource from the Graph. - * + * * Example: * LogicalLink llink = new LogicalLink(); * String resourceClassName = llink.getClass().getCanonicalName(); @@ -536,7 +561,7 @@ public class RestController implements RestControllerInterface { } catch (AAIException e) { - } catch (ClientHandlerException che) { + } catch (ClientErrorException che) { } catch (Exception e) { @@ -560,13 +585,13 @@ public class RestController implements RestControllerInterface { transId += ":" + UUID.randomUUID().toString(); int numRetries = 5; - ClientResponse cres = null; + Response response = null; int statusCode = -1; try { if (overrideLocalHost == null) { - overrideLocalHost = - AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT); + overrideLocalHost = AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, + AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT); } if (AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT.equals(overrideLocalHost)) { url = String.format(AAIConstants.AAI_LOCAL_REST, AAIConstants.AAI_RESOURCES_PORT, @@ -578,11 +603,14 @@ public class RestController implements RestControllerInterface { do { - cres = client.resource(url).accept("application/json").header("X-TransactionId", transId) - .header("X-FromAppId", sourceID).header("X-HTTP-Method-Override", "PATCH") - .type("application/merge-patch+json").entity(t).post(ClientResponse.class); + response = client.target(url) + .request(MediaType.APPLICATION_JSON) + .header("X-TransactionId", transId) + .header("X-FromAppId", sourceID) + .header("X-HTTP-Method-Override", "PATCH") + .post(Entity.entity(t, "application/merge-patch+json")); - statusCode = cres.getStatus(); + statusCode = response.getStatus(); if (statusCode >= 200 && statusCode <= 299) { LOGGER.debug(methodName + "REST api PATCH was successful!"); @@ -598,7 +626,7 @@ public class RestController implements RestControllerInterface { LOGGER.debug(methodName + "Unable to make the patch request to url " + url + " even after trying = " + numRetries + " times."); throw new AAIException("AAI_7116", methodName + " with status=" + statusCode + ", url=" + url + ", msg=" - + cres.getEntity(String.class)); + + response.readEntity(String.class)); } catch (AAIException e) { throw new AAIException("AAI_7116", methodName + " with url=" + url + ", Exception: " + e.toString()); 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 deleted file mode 100644 index 127cf538..00000000 --- a/aai-core/src/main/java/org/onap/aai/util/StoreNotificationEvent.java +++ /dev/null @@ -1,452 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.aai.util; - -import java.io.StringWriter; -import java.util.Iterator; -import java.util.UUID; - -import javax.xml.bind.Marshaller; - -import org.eclipse.persistence.dynamic.DynamicEntity; -import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext; -import org.json.JSONException; -import org.json.JSONObject; -import org.onap.aai.domain.notificationEvent.NotificationEvent; -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.introspection.Introspector; -import org.onap.aai.introspection.Loader; -import org.onap.aai.introspection.exceptions.AAIUnknownObjectException; -import org.onap.aai.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); - - @Autowired JmsTemplate jmsTemplate; - - private final MessageProducer messageProducer; - private String fromAppId = ""; - private String transId = ""; - private final String transactionId; - private final String sourceOfTruth; - - private ApplicationContext context; - private Environment env; - - /** - * Instantiates a new store notification event. - */ - public StoreNotificationEvent(String transactionId, String sourceOfTruth) { - this.messageProducer = new AAIKafkaEventJMSProducer(jmsTemplate); - this.transactionId = transactionId; - this.sourceOfTruth = sourceOfTruth; - } - - public StoreNotificationEvent(MessageProducer producer, String transactionId, String sourceOfTruth) { - this.messageProducer = producer; - this.transactionId = transactionId; - this.sourceOfTruth = sourceOfTruth; - } - - /** - * Store event. - * - * @param eh - * the eh - * @param obj - * the obj - * @throws AAIException - * the AAI exception - */ - public String storeEventAndSendToJms(NotificationEvent.EventHeader eh, Object obj) throws AAIException { - - if (obj == null) { - throw new AAIException("AAI_7350"); - } - - org.onap.aai.domain.notificationEvent.ObjectFactory factory = - new org.onap.aai.domain.notificationEvent.ObjectFactory(); - - org.onap.aai.domain.notificationEvent.NotificationEvent ne = factory.createNotificationEvent(); - - if (eh.getId() == null) { - eh.setId(genDate2() + "-" + UUID.randomUUID().toString()); - } - if (eh.getTimestamp() == null) { - eh.setTimestamp(genDate()); - } - - // there's no default, but i think we want to put this in hbase? - - if (eh.getEntityLink() == null) { - eh.setEntityLink("UNK"); - } - - if (eh.getAction() == null) { - eh.setAction("UNK"); - } - - if (eh.getEventType() == null) { - eh.setEventType(AAIConfig.get("aai.notificationEvent.default.eventType", "UNK")); - } - - if (eh.getDomain() == null) { - eh.setDomain(AAIConfig.get("aai.notificationEvent.default.domain", "UNK")); - } - - if (eh.getSourceName() == null) { - eh.setSourceName(AAIConfig.get("aai.notificationEvent.default.sourceName", "UNK")); - } - - if (eh.getSequenceNumber() == null) { - eh.setSequenceNumber(AAIConfig.get("aai.notificationEvent.default.sequenceNumber", "UNK")); - } - - if (eh.getSeverity() == null) { - eh.setSeverity(AAIConfig.get("aai.notificationEvent.default.severity", "UNK")); - } - - if (eh.getVersion() == null) { - eh.setVersion(AAIConfig.get("aai.notificationEvent.default.version", "UNK")); - } - - ne.setCambriaPartition(AAIConstants.UEB_PUB_PARTITION_AAI); - ne.setEventHeader(eh); - ne.setEntity(obj); - - try { - PojoUtils pu = new PojoUtils(); - String entityJson = pu.getJsonFromObject(ne); - sendToKafkaJmsQueue(entityJson); - return entityJson; - } catch (Exception e) { - throw new AAIException("AAI_7350", e); - } - } - - /** - * Store dynamic event. - * - * @param notificationJaxbContext - * the notification jaxb context - * @param notificationVersion - * the notification version - * @param eventHeader - * the event header - * @param obj - * the obj - * @throws AAIException - * the AAI exception - */ - public void storeDynamicEvent(DynamicJAXBContext notificationJaxbContext, String notificationVersion, - DynamicEntity eventHeader, DynamicEntity obj) throws AAIException { - - if (obj == null) { - throw new AAIException("AAI_7350"); - } - - DynamicEntity notificationEvent = notificationJaxbContext - .getDynamicType("inventory.aai.onap.org." + notificationVersion + ".NotificationEvent") - .newDynamicEntity(); - - if (eventHeader.get("id") == null) { - eventHeader.set("id", genDate2() + "-" + UUID.randomUUID().toString()); - } - - if (eventHeader.get("timestamp") == null) { - eventHeader.set("timestamp", genDate()); - } - - if (eventHeader.get("entityLink") == null) { - eventHeader.set("entityLink", "UNK"); - } - - if (eventHeader.get("action") == null) { - eventHeader.set("action", "UNK"); - } - - if (eventHeader.get("eventType") == null) { - eventHeader.set("eventType", AAIConfig.get("aai.notificationEvent.default.eventType", "UNK")); - } - - if (eventHeader.get("domain") == null) { - eventHeader.set("domain", AAIConfig.get("aai.notificationEvent.default.domain", "UNK")); - } - - if (eventHeader.get("sourceName") == null) { - eventHeader.set("sourceName", AAIConfig.get("aai.notificationEvent.default.sourceName", "UNK")); - } - - if (eventHeader.get("sequenceNumber") == null) { - eventHeader.set("sequenceNumber", AAIConfig.get("aai.notificationEvent.default.sequenceNumber", "UNK")); - } - - if (eventHeader.get("severity") == null) { - eventHeader.set("severity", AAIConfig.get("aai.notificationEvent.default.severity", "UNK")); - } - - if (eventHeader.get("version") == null) { - eventHeader.set("version", AAIConfig.get("aai.notificationEvent.default.version", "UNK")); - } - - if (notificationEvent.get("cambriaPartition") == null) { - notificationEvent.set("cambriaPartition", AAIConstants.UEB_PUB_PARTITION_AAI); - } - - notificationEvent.set("eventHeader", eventHeader); - notificationEvent.set("entity", obj); - - try { - StringWriter result = new StringWriter(); - - Marshaller marshaller = notificationJaxbContext.createMarshaller(); - marshaller.setProperty(org.eclipse.persistence.jaxb.MarshallerProperties.MEDIA_TYPE, "application/json"); - marshaller.setProperty(org.eclipse.persistence.jaxb.MarshallerProperties.JSON_INCLUDE_ROOT, false); - marshaller.setProperty(org.eclipse.persistence.jaxb.MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, false); - marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false); - marshaller.marshal(notificationEvent, result); - this.sendToKafkaJmsQueue(result.toString()); - - } catch (Exception e) { - throw new AAIException("AAI_7350", e); - } - } - - public String storeEventOnly(Loader loader, Introspector eventHeader, Introspector obj) throws AAIException { - if (obj == null) { - throw new AAIException("AAI_7350"); - } - - try { - final Introspector notificationEvent = loader.introspectorFromName("notification-event"); - - if (eventHeader.getValue("id") == null) { - eventHeader.setValue("id", genDate2() + "-" + UUID.randomUUID().toString()); - } - - if (eventHeader.getValue("timestamp") == null) { - eventHeader.setValue("timestamp", genDate()); - } - - if (eventHeader.getValue("entity-link") == null) { - eventHeader.setValue("entity-link", "UNK"); - } - - if (eventHeader.getValue("action") == null) { - eventHeader.setValue("action", "UNK"); - } - - if (eventHeader.getValue("event-type") == null) { - eventHeader.setValue("event-type", AAIConfig.get("aai.notificationEvent.default.eventType", "UNK")); - } - - if (eventHeader.getValue("domain") == null) { - eventHeader.setValue("domain", AAIConfig.get("aai.notificationEvent.default.domain", "UNK")); - } - - if (eventHeader.getValue("source-name") == null) { - eventHeader.setValue("source-name", AAIConfig.get("aai.notificationEvent.default.sourceName", "UNK")); - } - - if (eventHeader.getValue("sequence-number") == null) { - eventHeader.setValue("sequence-number", - AAIConfig.get("aai.notificationEvent.default.sequenceNumber", "UNK")); - } - - if (eventHeader.getValue("severity") == null) { - eventHeader.setValue("severity", AAIConfig.get("aai.notificationEvent.default.severity", "UNK")); - } - - if (eventHeader.getValue("version") == null) { - eventHeader.setValue("version", AAIConfig.get("aai.notificationEvent.default.version", "UNK")); - } - - if (notificationEvent.getValue("cambria-partition") == null) { - notificationEvent.setValue("cambria-partition", - AAIConfig.get("aai.notificationEvent.default.partition", AAIConstants.UEB_PUB_PARTITION_AAI)); - } - - notificationEvent.setValue("event-header", eventHeader.getUnderlyingObject()); - notificationEvent.setValue("entity", obj.getUnderlyingObject()); - - String entityJson = notificationEvent.marshal(false); - JSONObject entityJsonObject = new JSONObject(entityJson); - - JSONObject entityJsonObjectUpdated = new JSONObject(); - - JSONObject entityHeader = entityJsonObject.getJSONObject("event-header"); - String cambriaPartition = entityJsonObject.getString("cambria.partition"); - - entityJsonObject.remove("event-header"); - entityJsonObject.remove("cambria.partition"); - - entityJsonObjectUpdated.put("event-header", entityHeader); - entityJsonObjectUpdated.put("cambria.partition", cambriaPartition); - - Iterator<String> iter = entityJsonObject.keys(); - JSONObject entity = new JSONObject(); - if (iter.hasNext()) { - entity = entityJsonObject.getJSONObject(iter.next()); - } - - entityJsonObjectUpdated.put("entity", entity); - - return entityJsonObjectUpdated.toString(); - } catch (JSONException e) { - throw new AAIException("AAI_7350", e); - } catch (AAIUnknownObjectException e) { - throw new AAIException("AAI_7350", e); - } - } - - public String storeEventAndSendToJms(Loader loader, Introspector eventHeader, Introspector obj) - throws AAIException { - if (obj == null) { - throw new AAIException("AAI_7350"); - } - - try { - final Introspector notificationEvent = loader.introspectorFromName("notification-event"); - - if (eventHeader.getValue("id") == null) { - eventHeader.setValue("id", genDate2() + "-" + UUID.randomUUID().toString()); - } - - if (eventHeader.getValue("timestamp") == null) { - eventHeader.setValue("timestamp", genDate()); - } - - if (eventHeader.getValue("entity-link") == null) { - eventHeader.setValue("entity-link", "UNK"); - } - - if (eventHeader.getValue("action") == null) { - eventHeader.setValue("action", "UNK"); - } - - if (eventHeader.getValue("event-type") == null) { - eventHeader.setValue("event-type", AAIConfig.get("aai.notificationEvent.default.eventType", "UNK")); - } - - if (eventHeader.getValue("domain") == null) { - eventHeader.setValue("domain", AAIConfig.get("aai.notificationEvent.default.domain", "UNK")); - } - - if (eventHeader.getValue("source-name") == null) { - eventHeader.setValue("source-name", AAIConfig.get("aai.notificationEvent.default.sourceName", "UNK")); - } - - if (eventHeader.getValue("sequence-number") == null) { - eventHeader.setValue("sequence-number", - AAIConfig.get("aai.notificationEvent.default.sequenceNumber", "UNK")); - } - - if (eventHeader.getValue("severity") == null) { - eventHeader.setValue("severity", AAIConfig.get("aai.notificationEvent.default.severity", "UNK")); - } - - if (eventHeader.getValue("version") == null) { - eventHeader.setValue("version", AAIConfig.get("aai.notificationEvent.default.version", "UNK")); - } - - if (notificationEvent.getValue("cambria-partition") == null) { - notificationEvent.setValue("cambria-partition", - AAIConfig.get("aai.notificationEvent.default.partition", AAIConstants.UEB_PUB_PARTITION_AAI)); - } - - notificationEvent.setValue("event-header", eventHeader.getUnderlyingObject()); - notificationEvent.setValue("entity", obj.getUnderlyingObject()); - - String entityJson = notificationEvent.marshal(false); - sendToKafkaJmsQueue(entityJson); - return entityJson; - } catch (JSONException e) { - throw new AAIException("AAI_7350", e); - } catch (AAIUnknownObjectException e) { - throw new AAIException("AAI_7350", e); - } - } - - private void sendToKafkaJmsQueue(String entityString) throws JSONException { - - JSONObject entityJsonObject = new JSONObject(entityString); - - JSONObject entityJsonObjectUpdated = new JSONObject(); - JSONObject finalJson = new JSONObject(); - - JSONObject entityHeader = entityJsonObject.getJSONObject("event-header"); - String cambriaPartition = entityJsonObject.getString("cambria.partition"); - - entityJsonObject.remove("event-header"); - entityJsonObject.remove("cambria.partition"); - - entityJsonObjectUpdated.put("event-header", entityHeader); - entityJsonObjectUpdated.put("cambria.partition", cambriaPartition); - - String transId = entityHeader.getString("id"); - String fromAppId = entityHeader.getString("source-name"); - - Iterator<String> iter = entityJsonObject.keys(); - JSONObject entity = new JSONObject(); - if (iter.hasNext()) { - entity = entityJsonObject.getJSONObject(iter.next()); - } - - entityJsonObjectUpdated.put("entity", entity); - - finalJson.put("event-topic", "AAI-EVENT"); - finalJson.put("transId", transId); - finalJson.put("fromAppId", fromAppId); - finalJson.put("fullId", ""); - finalJson.put("aaiEventPayload", entityJsonObjectUpdated); - - messageProducer.sendMessageToDefaultDestination(finalJson); - } - - /** - * Gen date. - * - * @return the string - */ - public static String genDate() { - FormatDate fd = new FormatDate("YYYYMMdd-HH:mm:ss:SSS"); - return fd.getDateTime(); - } - - /** - * Gen date 2. - * - * @return the string - */ - public static String genDate2() { - FormatDate fd = new FormatDate("YYYYMMddHHmmss"); - return fd.getDateTime(); - } - -} 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 39a03777..b255687d 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 @@ -27,33 +27,25 @@ import java.util.Date; import java.util.Map; import org.onap.aai.db.props.AAIProperties; -import org.onap.aai.kafka.MessageProducer; +import org.onap.aai.domain.deltaEvent.DeltaEvent; +import org.onap.aai.domain.notificationEvent.NotificationEvent.EventHeader; +import org.onap.aai.kafka.DeltaProducer; import org.onap.aai.util.AAIConfig; import org.springframework.beans.factory.annotation.Autowired; -import com.google.gson.FieldNamingPolicy; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; - public class DeltaEvents { - - private static final Gson gson = - new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES).create(); - private static final String eventVersion = "v1"; - private final String transId; private final String sourceName; private final String schemaVersion; private final Map<String, ObjectDelta> objectDeltas; - @Autowired private MessageProducer messageProducer; + @Autowired private DeltaProducer deltaProducer; public DeltaEvents(String transId, String sourceName, String schemaVersion, Map<String, ObjectDelta> objectDeltas) { - this.transId = transId; - this.sourceName = sourceName; - this.schemaVersion = schemaVersion; - this.objectDeltas = objectDeltas; + this.transId = transId; + this.sourceName = sourceName; + this.schemaVersion = schemaVersion; + this.objectDeltas = objectDeltas; } public boolean triggerEvents() { @@ -61,44 +53,35 @@ public class DeltaEvents { return false; } - JsonObject finalJson = new JsonObject(); - finalJson.addProperty("event-topic", "DELTA"); - finalJson.addProperty("transId", transId); - finalJson.addProperty("fromAppId", sourceName); - finalJson.addProperty("fullId", ""); - finalJson.add("aaiEventPayload", buildEvent()); - - this.messageProducer.sendMessageToDefaultDestination(finalJson.toString()); + deltaProducer.sendNotification(buildEvent()); return true; } - private JsonObject buildEvent() { - JsonObject event = new JsonObject(); - event.addProperty("cambria.partition", this.getPartition()); - event.add("event-header", getHeader()); - event.add("entities", gson.toJsonTree(objectDeltas.values())); - return event; + private DeltaEvent buildEvent() { + DeltaEvent deltaEvent = new DeltaEvent(); + deltaEvent.setCambriaPartition(getPartition()); + deltaEvent.setEventHeader(getHeader()); + deltaEvent.setEntities(objectDeltas.values()); + return deltaEvent; } private String getPartition() { return "DELTA"; } - private JsonObject getHeader() { + private EventHeader getHeader() { ObjectDelta first = objectDeltas.values().iterator().next(); - JsonObject header = new JsonObject(); - header.addProperty("id", this.transId); - header.addProperty("timestamp", this.getTimeStamp(first.getTimestamp())); - header.addProperty("source-name", this.sourceName); - header.addProperty("domain", this.getDomain()); - header.addProperty("event-type", this.getEventType()); - header.addProperty("event-version", eventVersion); - header.addProperty("schema-version", this.schemaVersion); - header.addProperty("action", first.getAction().toString()); - header.addProperty("entity-type", this.getEntityType(first)); - header.addProperty("entity-link", first.getUri()); - header.addProperty("entity-uuid", this.getUUID(first)); - + EventHeader header = new EventHeader(); + header.setId(this.transId); + header.setTimestamp(this.getTimeStamp(first.getTimestamp())); + header.setSourceName(this.sourceName); + header.setDomain(this.getDomain()); + header.setEventType(this.getEventType()); + header.setVersion(this.schemaVersion); + header.setAction(first.getAction().toString()); + header.setEntityType(this.getEntityType(first)); + header.setEntityLink(first.getUri()); + header.setEntityUuid(this.getUUID(first)); return header; } diff --git a/aai-core/src/main/java/org/onap/aai/util/delta/ObjectDelta.java b/aai-core/src/main/java/org/onap/aai/util/delta/ObjectDelta.java index 23476675..7af30db9 100644 --- a/aai-core/src/main/java/org/onap/aai/util/delta/ObjectDelta.java +++ b/aai-core/src/main/java/org/onap/aai/util/delta/ObjectDelta.java @@ -20,7 +20,9 @@ package org.onap.aai.util.delta; -import com.google.gson.annotations.SerializedName; +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.Data; import java.util.ArrayList; import java.util.HashMap; @@ -29,24 +31,17 @@ import java.util.Map; import org.apache.commons.lang3.builder.ToStringBuilder; +@Data public class ObjectDelta { - @SerializedName("uri") private String uri; - - @SerializedName("action") private DeltaAction action; - - @SerializedName("source-of-truth") + @JsonProperty("source-of-truth") private String sourceOfTruth; - - @SerializedName("timestamp") private long timestamp; - - @SerializedName("property-deltas") + @JsonProperty("property-deltas") private Map<String, PropertyDelta> propertyDeltas = new HashMap<>(); - - @SerializedName("relationship-deltas") + @JsonProperty("relationship-deltas") private List<RelationshipDelta> relationshipDeltas = new ArrayList<>(); public ObjectDelta(String uri, DeltaAction action, String sourceOfTruth, long timestamp) { @@ -64,54 +59,6 @@ public class ObjectDelta { relationshipDeltas.add(relationshipDelta); } - public String getUri() { - return uri; - } - - public void setUri(String uri) { - this.uri = uri; - } - - public DeltaAction getAction() { - return action; - } - - public void setAction(DeltaAction action) { - this.action = action; - } - - public String getSourceOfTruth() { - return sourceOfTruth; - } - - public void setSourceOfTruth(String sourceOfTruth) { - this.sourceOfTruth = sourceOfTruth; - } - - public long getTimestamp() { - return timestamp; - } - - public void setTimestamp(long timestamp) { - this.timestamp = timestamp; - } - - public void setPropertyDeltas(Map<String, PropertyDelta> propertyDeltas) { - this.propertyDeltas = propertyDeltas; - } - - public void setRelationshipDeltas(List<RelationshipDelta> relationshipDeltas) { - this.relationshipDeltas = relationshipDeltas; - } - - public Map<String, PropertyDelta> getPropertyDeltas() { - return propertyDeltas; - } - - public List<RelationshipDelta> getRelationshipDeltas() { - return relationshipDeltas; - } - @Override public String toString() { return new ToStringBuilder(this).append("uri", uri).append("action", action) diff --git a/aai-core/src/main/java/org/onap/aai/util/delta/PropertyDelta.java b/aai-core/src/main/java/org/onap/aai/util/delta/PropertyDelta.java index 98296d35..62890ffc 100644 --- a/aai-core/src/main/java/org/onap/aai/util/delta/PropertyDelta.java +++ b/aai-core/src/main/java/org/onap/aai/util/delta/PropertyDelta.java @@ -20,19 +20,18 @@ package org.onap.aai.util.delta; -import com.google.gson.annotations.SerializedName; +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.Data; import org.apache.commons.lang3.builder.ToStringBuilder; +@Data public class PropertyDelta { - @SerializedName("action") protected DeltaAction action; - - @SerializedName("value") protected Object value; - - @SerializedName("old-value") + @JsonProperty("old-value") private Object oldValue; public PropertyDelta(DeltaAction action, Object value) { @@ -45,30 +44,6 @@ public class PropertyDelta { this.oldValue = oldValue; } - public DeltaAction getAction() { - return action; - } - - public void setAction(DeltaAction action) { - this.action = action; - } - - public Object getValue() { - return value; - } - - public void setValue(Object value) { - this.value = value; - } - - public Object getOldValue() { - return oldValue; - } - - public void setOldValue(Object oldValue) { - this.oldValue = oldValue; - } - @Override public String toString() { return new ToStringBuilder(this).append("action", action).append("value", value).append("oldValue", oldValue) 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 deleted file mode 100644 index c1e8357d..00000000 --- a/aai-core/src/main/java/org/onap/aai/web/KafkaConfig.java +++ /dev/null @@ -1,185 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.aai.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.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 ba5b3de8..6eb8ea47 100644 --- a/aai-core/src/main/resources/logback.xml +++ b/aai-core/src/main/resources/logback.xml @@ -245,7 +245,6 @@ <logger name="org.springframework" level="WARN" /> <logger name="org.springframework.beans" level="WARN" /> <logger name="org.springframework.web" level="WARN" /> - <logger name="com.blog.spring.jms" level="WARN" /> <logger name="com.jayway.jsonpath" level="WARN" /> <!-- AJSC Services (bootstrap services) --> 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 08a0e91b..5273c6e7 100644 --- a/aai-core/src/test/java/org/onap/aai/AAISetup.java +++ b/aai-core/src/test/java/org/onap/aai/AAISetup.java @@ -40,7 +40,6 @@ 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; @@ -54,11 +53,12 @@ import org.springframework.test.context.web.WebAppConfiguration; classes = {ConfigConfiguration.class, AAIConfigTranslator.class, EdgeIngestor.class, EdgeSerializer.class, NodeIngestor.class, SpringContextAware.class, IntrospectionConfig.class, RestBeanConfig.class, XmlFormatTransformerConfiguration.class, ValidationService.class, ValidationConfiguration.class, - KafkaConfig.class, LoaderFactory.class, NotificationService.class}) + KafkaConfig.class, LoaderFactory.class, NotificationService.class, KafkaConfig.class}) @TestPropertySource( properties = {"schema.uri.base.path = /aai", "schema.xsd.maxoccurs = 5000", "schema.translator.list=config", "schema.nodes.location=src/test/resources/onap/oxm", - "schema.edges.location=src/test/resources/onap/dbedgerules"}) + "schema.edges.location=src/test/resources/onap/dbedgerules", + "aai.notifications.enabled=false"}) public abstract class AAISetup { @ClassRule 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 b38a5c69..5ede5c22 100644 --- a/aai-core/src/test/java/org/onap/aai/DataLinkSetup.java +++ b/aai-core/src/test/java/org/onap/aai/DataLinkSetup.java @@ -49,13 +49,13 @@ 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, LoaderFactory.class, NotificationService.class}) + RestBeanConfig.class, XmlFormatTransformerConfiguration.class, LoaderFactory.class, NotificationService.class, KafkaConfig.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", "schema.version.app.root.start = v4", "schema.version.related.link.start = v4", "schema.version.namespace.change.start = v4", "schema.version.list = v1,v2,v3,v4", - "schema.translator.list = config"}) + "schema.translator.list = config","aai.notifications.enabled = false"}) @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) public abstract class DataLinkSetup { 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 49524c4e..62f63ea3 100644 --- a/aai-core/src/test/java/org/onap/aai/HttpTestUtil.java +++ b/aai-core/src/test/java/org/onap/aai/HttpTestUtil.java @@ -153,14 +153,6 @@ public class HttpTestUtil extends RESTAPI { doReturn(null).when(queryParameters).remove(any()); when(httpHeaders.getMediaType()).thenReturn(APPLICATION_JSON); - - try { - if (notification != null) { - doNothing().when(notification).triggerEvents(); - } - } catch (AAIException e) { - e.printStackTrace(); - } } public Response doPut(String uri, String payload) throws UnsupportedEncodingException, AAIException { diff --git a/aai-core/src/test/java/org/onap/aai/introspection/IntrospectorSerializationTest.java b/aai-core/src/test/java/org/onap/aai/introspection/IntrospectorSerializationTest.java new file mode 100644 index 00000000..60749ddd --- /dev/null +++ b/aai-core/src/test/java/org/onap/aai/introspection/IntrospectorSerializationTest.java @@ -0,0 +1,87 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aai.introspection; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.junit.Before; +import org.junit.Test; +import org.onap.aai.AAISetup; +import org.onap.aai.domain.notificationEvent.NotificationEvent; +import org.onap.aai.domain.notificationEvent.NotificationEvent.EventHeader; +import org.onap.aai.introspection.exceptions.AAIUnmarshallingException; +import org.onap.aai.setup.SchemaVersion; +import org.skyscreamer.jsonassert.JSONAssert; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule; + +public class IntrospectorSerializationTest extends AAISetup { + + ObjectMapper mapper; + Loader loader; + + @Before + public void setup() { + loader = loaderFactory.getMoxyLoaderInstance().get(new SchemaVersion("v14")); + } + + @Test + public void serializePlain() throws IOException, AAIUnmarshallingException { + mapper = new ObjectMapper(); + + String pserver = new String(Files.readAllBytes(Path.of("src/test/resources/payloads/templates/pserver.json"))); + Introspector introspector = loader.unmarshal("pserver", pserver); + String result = mapper.writeValueAsString(introspector); + JSONAssert.assertEquals(pserver, result, false); + } + + @Test + public void serializeNotificationEvent() throws IOException, AAIUnmarshallingException { + mapper = new ObjectMapper(); + mapper.registerModule(new JaxbAnnotationModule()); + + String pserver = new String(Files.readAllBytes(Path.of("src/test/resources/payloads/templates/pserver.json"))).replace("${hostname}", "pserver1"); + Introspector introspector = loader.unmarshal("pserver", pserver); + + NotificationEvent notificationEvent = new NotificationEvent(); + notificationEvent.setCambriaPartition("AAI"); + notificationEvent.setEntity(introspector); + EventHeader eventHeader = new EventHeader(); + eventHeader.setSeverity("NORMAL"); + eventHeader.setEntityType("pserver"); + eventHeader.setTopEntityType("pserver"); + eventHeader.setEntityLink("/aai/v14/cloud-infrastructure/pservers/pserver/pserver1"); + eventHeader.setEventType("AAI-EVENT"); + eventHeader.setDomain("devINT1"); + eventHeader.setAction("CREATE"); + eventHeader.setSequenceNumber("0"); + eventHeader.setId("someTransaction"); + eventHeader.setSourceName("test"); + eventHeader.setVersion("v14"); + notificationEvent.setEventHeader(eventHeader); + String result = mapper.writeValueAsString(notificationEvent); + String expectedEvent = new String(Files.readAllBytes(Path.of("src/test/resources/payloads/expected/pserver-event.json"))); + JSONAssert.assertEquals(expectedEvent, result, false); + } +} 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 index 0f5f47ad..d00fa818 100644 --- a/aai-core/src/test/java/org/onap/aai/kafka/AAIKafkaEventIntegrationTest.java +++ b/aai-core/src/test/java/org/onap/aai/kafka/AAIKafkaEventIntegrationTest.java @@ -20,16 +20,39 @@ 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.Path; +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.ConsumerRecord; 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.domain.notificationEvent.NotificationEvent; +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; @@ -41,6 +64,9 @@ import org.springframework.kafka.test.utils.KafkaTestUtils; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; +import com.fasterxml.jackson.databind.ObjectMapper; + +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @Slf4j @@ -49,11 +75,11 @@ import lombok.extern.slf4j.Slf4j; @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}" + "spring.kafka.producer.bootstrap-servers=${spring.embedded.kafka.brokers}", + "aai.notifications.enabled=true" }) public class AAIKafkaEventIntegrationTest extends AAISetup { @@ -61,12 +87,28 @@ public class AAIKafkaEventIntegrationTest extends AAISetup { private KafkaTemplate<String, String> kafkaTemplate; @Autowired - MessageProducer messageProducer; + ObjectMapper mapper; + + @Autowired + NotificationProducer 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 + @Ignore public void onMessage_shouldSendMessageToKafkaTopic_whenAAIEventReceived() throws Exception { Consumer<String, String> consumer = consumerFactory.createConsumer(); @@ -74,8 +116,9 @@ public class AAIKafkaEventIntegrationTest extends AAISetup { consumer.subscribe(Collections.singletonList("AAI-EVENT")); String payload = PayloadUtil.getResourcePayload("aai-event.json"); + NotificationEvent event = mapper.readValue(payload, NotificationEvent.class); String expectedResponse = PayloadUtil.getExpectedPayload("aai-event.json"); - messageProducer.sendMessageToDefaultDestination(payload); + messageProducer.sendNotification(event); ConsumerRecords<String, String> consumerRecords = KafkaTestUtils.getRecords(consumer, 10000); assertFalse(consumerRecords.isEmpty()); @@ -84,4 +127,41 @@ public class AAIKafkaEventIntegrationTest extends AAISetup { }); } + @Test + 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(Path.of("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/prevalidation/ValidationServiceTest.java b/aai-core/src/test/java/org/onap/aai/prevalidation/ValidationServiceTest.java index 8ef1d706..db9ee961 100644 --- a/aai-core/src/test/java/org/onap/aai/prevalidation/ValidationServiceTest.java +++ b/aai-core/src/test/java/org/onap/aai/prevalidation/ValidationServiceTest.java @@ -24,9 +24,14 @@ import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentCaptor.forClass; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule; import com.google.gson.Gson; import java.io.IOException; @@ -38,10 +43,13 @@ import org.apache.http.conn.ConnectTimeoutException; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.onap.aai.PayloadUtil; +import org.onap.aai.domain.notificationEvent.NotificationEvent; import org.onap.aai.exceptions.AAIException; import org.onap.aai.restclient.RestClient; +import org.skyscreamer.jsonassert.JSONAssert; import org.springframework.boot.test.system.OutputCaptureRule; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; @@ -56,12 +64,15 @@ public class ValidationServiceTest { public OutputCaptureRule capture = new OutputCaptureRule(); private Gson gson; + private ObjectMapper mapper; @Before public void setUp() throws Exception { + mapper = new ObjectMapper(); + mapper.registerModule(new JaxbAnnotationModule()); gson = new Gson(); restClient = Mockito.mock(RestClient.class); - validationService = Mockito.spy(new ValidationService(restClient, "JUNIT", "generic-vnf", null)); + validationService = Mockito.spy(new ValidationService(restClient, "JUNIT", "generic-vnf", null, mapper)); } @Test @@ -81,14 +92,19 @@ public class ValidationServiceTest { throws IOException, AAIException { String pserverRequest = PayloadUtil.getResourcePayload("prevalidation/success-request-with-no-violations.json"); + NotificationEvent notificationEvent = mapper.readValue(pserverRequest, NotificationEvent.class); Mockito.when(restClient.execute(eq(ValidationService.VALIDATION_ENDPOINT), eq(HttpMethod.POST), any(), - eq(pserverRequest))).thenThrow(new RuntimeException(new ConnectException("Connection refused"))); + anyString())).thenThrow(new RuntimeException(new ConnectException("Connection refused"))); - validationService.preValidate(pserverRequest); + validationService.preValidate(notificationEvent); assertThat(capture.toString(), containsString("Connection refused to the validation microservice due to service unreachable")); + ArgumentCaptor<String> bodyCaptor = forClass(String.class); + verify(restClient).execute(eq(ValidationService.VALIDATION_ENDPOINT), eq(HttpMethod.POST), any(), bodyCaptor.capture()); + + JSONAssert.assertEquals(pserverRequest, bodyCaptor.getValue(), false); } @Test @@ -96,15 +112,20 @@ public class ValidationServiceTest { throws IOException, AAIException { String pserverRequest = PayloadUtil.getResourcePayload("prevalidation/success-request-with-no-violations.json"); + NotificationEvent notificationEvent = mapper.readValue(pserverRequest, NotificationEvent.class); Mockito.when(restClient.execute(eq(ValidationService.VALIDATION_ENDPOINT), eq(HttpMethod.POST), any(), - eq(pserverRequest))) + anyString())) .thenThrow(new RuntimeException(new ConnectTimeoutException("Connection timed out"))); - validationService.preValidate(pserverRequest); + validationService.preValidate(notificationEvent); assertThat(capture.toString(), containsString( "Connection timeout to the validation microservice as this could indicate the server is unable to reach port")); + ArgumentCaptor<String> bodyCaptor = forClass(String.class); + verify(restClient).execute(eq(ValidationService.VALIDATION_ENDPOINT), eq(HttpMethod.POST), any(), bodyCaptor.capture()); + + JSONAssert.assertEquals(pserverRequest, bodyCaptor.getValue(), false); } @Test @@ -112,22 +133,28 @@ public class ValidationServiceTest { throws IOException, AAIException { String pserverRequest = PayloadUtil.getResourcePayload("prevalidation/success-request-with-no-violations.json"); + NotificationEvent notificationEvent = mapper.readValue(pserverRequest, NotificationEvent.class); String validationResponse = PayloadUtil.getResourcePayload("prevalidation/success-response-with-empty-violations.json"); ResponseEntity responseEntity = Mockito.mock(ResponseEntity.class, Mockito.RETURNS_DEEP_STUBS); Mockito.when(restClient.execute(eq(ValidationService.VALIDATION_ENDPOINT), eq(HttpMethod.POST), any(), - eq(pserverRequest))).thenReturn(responseEntity); + anyString())).thenReturn(responseEntity); Mockito.when(responseEntity.getStatusCodeValue()).thenReturn(200); Mockito.when(responseEntity.getBody()).thenReturn(validationResponse); Mockito.doReturn(true).when(validationService).isSuccess(responseEntity); - List<String> errorMessages = validationService.preValidate(pserverRequest); + List<String> errorMessages = validationService.preValidate(notificationEvent); assertNotNull("Expected the error messages to be not null", errorMessages); assertThat(errorMessages.size(), is(0)); + + ArgumentCaptor<String> bodyCaptor = forClass(String.class); + verify(restClient).execute(eq(ValidationService.VALIDATION_ENDPOINT), eq(HttpMethod.POST), any(), bodyCaptor.capture()); + + JSONAssert.assertEquals(pserverRequest, bodyCaptor.getValue(), false); } @Test @@ -135,16 +162,21 @@ public class ValidationServiceTest { throws IOException, AAIException { String pserverRequest = PayloadUtil.getResourcePayload("prevalidation/success-request-with-no-violations.json"); + NotificationEvent notificationEvent = mapper.readValue(pserverRequest, NotificationEvent.class); Mockito.when(restClient.execute(eq(ValidationService.VALIDATION_ENDPOINT), eq(HttpMethod.POST), any(), - eq(pserverRequest))) + anyString())) .thenThrow(new RuntimeException( new SocketTimeoutException("Request timed out due to taking longer than client expected"))); - validationService.preValidate(pserverRequest); + validationService.preValidate(notificationEvent); assertThat(capture.toString(), containsString("Request to validation service took longer than the currently set timeout")); + ArgumentCaptor<String> bodyCaptor = forClass(String.class); + verify(restClient).execute(eq(ValidationService.VALIDATION_ENDPOINT), eq(HttpMethod.POST), any(), bodyCaptor.capture()); + + JSONAssert.assertEquals(pserverRequest, bodyCaptor.getValue(), false); } @Test 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 8f4a209b..7685360b 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 @@ -42,6 +42,7 @@ import org.junit.*; import org.junit.runner.RunWith; import org.onap.aai.config.ConfigConfiguration; import org.onap.aai.config.IntrospectionConfig; +import org.onap.aai.config.KafkaConfig; import org.onap.aai.config.SpringContextAware; import org.onap.aai.config.XmlFormatTransformerConfiguration; import org.onap.aai.db.props.AAIProperties; @@ -68,11 +69,12 @@ 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, LoaderFactory.class, NotificationService.class}) + XmlFormatTransformerConfiguration.class, LoaderFactory.class, NotificationService.class, KafkaConfig.class}) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) @TestPropertySource( properties = {"schema.translator.list = config", "schema.nodes.location=src/test/resources/onap/oxm", - "schema.edges.location=src/test/resources/onap/dbedgerules"}) + "schema.edges.location=src/test/resources/onap/dbedgerules", + "aai.notifications.enabled=false"}) public abstract class QueryBuilderTestAbstraction { protected Loader loader; 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 218c3a24..38731288 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 @@ -45,8 +45,9 @@ import org.onap.aai.HttpTestUtil; import org.onap.aai.PayloadUtil; import org.onap.aai.db.props.AAIProperties; import org.onap.aai.dbmap.AAIGraph; +import org.onap.aai.domain.notificationEvent.NotificationEvent; +import org.onap.aai.domain.notificationEvent.NotificationEvent.EventHeader; import org.onap.aai.introspection.ModelType; -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; @@ -73,7 +74,7 @@ public class ImpliedDeleteIntegrationTest extends AAISetup { String uri = "/aai/v12/cloud-infrastructure/pservers/pserver/test-pserver-implied-delete"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle, notification, AAIProperties.MINIMUM_DEPTH); String resource = PayloadUtil.getResourcePayload("pserver-implied-delete.json"); @@ -91,7 +92,7 @@ public class ImpliedDeleteIntegrationTest extends AAISetup { JSONAssert.assertEquals(resource, response.getEntity().toString(), false); jsonObject.getJSONObject("p-interfaces").remove("p-interface"); - notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); httpTestUtil = new HttpTestUtil(queryStyle, notification, AAIProperties.MINIMUM_DEPTH); response = httpTestUtil.doPut(uri, jsonObject.toString()); @@ -100,10 +101,11 @@ public class ImpliedDeleteIntegrationTest extends AAISetup { List<NotificationEvent> notificationEvents = notification.getEvents(); assertThat(notificationEvents.size(), is(5)); - List<String> notificationEventHeaders = notification.getEvents().stream() - .map(event -> event.getEventHeader().marshal(false)).collect(Collectors.toList()); + List<EventHeader> notificationEventHeaders = notification.getEvents().stream() + .map(NotificationEvent::getEventHeader) + .collect(Collectors.toList()); - Long deletedEventsCount = notificationEventHeaders.stream().filter(e -> e.contains("\"DELETE\"")).count(); + Long deletedEventsCount = notificationEventHeaders.stream().filter(e -> "DELETE".equals(e.getAction())).count(); assertThat(deletedEventsCount, is(4L)); 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 4b52462e..0eafdf1c 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 @@ -26,6 +26,7 @@ import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.JsonObject; import com.google.gson.JsonParser; @@ -55,24 +56,29 @@ import org.onap.aai.HttpTestUtil; import org.onap.aai.PayloadUtil; import org.onap.aai.db.props.AAIProperties; import org.onap.aai.dbmap.AAIGraph; +import org.onap.aai.domain.notificationEvent.NotificationEvent; +import org.onap.aai.domain.notificationEvent.NotificationEvent.EventHeader; import org.onap.aai.exceptions.AAIException; import org.onap.aai.introspection.ModelType; -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.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; @RunWith(value = Parameterized.class) @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) public class NotificationDmaapEventTest extends AAISetup { +// ObjectMapper mapper = new ObjectMapper(); + @Autowired private ObjectMapper mapper; + @Parameterized.Parameter public QueryStyle queryStyle; @Parameterized.Parameters(name = "QueryStyle.{0}") public static Collection<Object[]> data() { - return Arrays.asList(new Object[][] {{QueryStyle.TRAVERSAL}, {QueryStyle.TRAVERSAL_URI}}); + return Arrays.asList(new Object[][] {{QueryStyle.TRAVERSAL}}); } @Test @@ -80,7 +86,7 @@ public class NotificationDmaapEventTest extends AAISetup { throws IOException, AAIException { String uri = "/aai/v14/cloud-infrastructure/pservers/pserver/example-hostname-val-85598"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle, notification, AAIProperties.MINIMUM_DEPTH); String resource = PayloadUtil.getResourcePayload("pserver-with-children-for-notification.json"); @@ -97,13 +103,8 @@ public class NotificationDmaapEventTest extends AAISetup { // Verify all the events are create since its a new PUT notification.getEvents().forEach((event) -> { - - String header = event.getEventHeader().marshal(false); - - assertThat(event.getEventHeader().marshal(false), containsString("\"CREATE\"")); - - assertThat(header, containsString("\"top-entity-type\":\"pserver\"")); - + assertEquals("CREATE", event.getEventHeader().getAction()); + assertEquals("pserver", event.getEventHeader().getTopEntityType()); }); response = httpTestUtil.doGet(uri); @@ -116,7 +117,7 @@ public class NotificationDmaapEventTest extends AAISetup { throws IOException, AAIException { String uri = "/aai/v14/cloud-infrastructure/pservers/pserver/example-hostname-val-85598"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle); String pserverResource = PayloadUtil.getResourcePayload("pserver-with-children-for-notification.json"); @@ -147,19 +148,20 @@ public class NotificationDmaapEventTest extends AAISetup { List<NotificationEvent> events = notification.getEvents(); assertThat(events.size(), is(2)); - String notificationEventHeader = events.get(1).getEventHeader().marshal(false); - String notificationEventBody = events.get(1).getObj().marshal(false); + EventHeader notificationEventHeader = events.get(1).getEventHeader(); + String notificationEventBody = events.get(1).getEntity().toString(); - assertThat(notificationEventHeader, containsString("\"action\":\"CREATE\"")); - assertThat(notificationEventHeader, containsString("\"entity-type\":\"p-interface\"")); - assertThat(notificationEventHeader, containsString("\"top-entity-type\":\"pserver\"")); + assertEquals("CREATE", notificationEventHeader.getAction()); + assertEquals("p-interface", notificationEventHeader.getEntityType()); + assertEquals("pserver", notificationEventHeader.getTopEntityType()); String expectedNotificationHeader = PayloadUtil.getResourcePayload( "notification-dmaap-events/depth-zero/expected-notification-header-create-child-on-existing-obj.json"); String expectedNotificationBody = PayloadUtil.getResourcePayload( "notification-dmaap-events/depth-zero/expected-notification-body-create-child-on-existing-obj.json"); - JSONAssert.assertEquals(expectedNotificationHeader, notificationEventHeader, false); + String eventHeaderJson = mapper.writeValueAsString(events.get(1).getEventHeader()); + JSONAssert.assertEquals(expectedNotificationHeader, eventHeaderJson, false); JSONAssert.assertEquals(expectedNotificationBody, notificationEventBody, false); } @@ -168,7 +170,7 @@ public class NotificationDmaapEventTest extends AAISetup { throws IOException, AAIException { String uri = "/aai/v14/cloud-infrastructure/pservers/pserver/example-hostname-val-85598"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle); String pserverResource = PayloadUtil.getResourcePayload("pserver-with-children-for-notification.json"); @@ -200,19 +202,19 @@ public class NotificationDmaapEventTest extends AAISetup { List<NotificationEvent> events = notification.getEvents(); assertThat(events.size(), is(1)); - String notificationEventHeader = events.get(0).getEventHeader().marshal(false); - String notificationEventBody = events.get(0).getObj().marshal(false); - - assertThat(notificationEventHeader, containsString("\"action\":\"UPDATE\"")); - assertThat(notificationEventHeader, containsString("\"entity-type\":\"pserver\"")); - assertThat(notificationEventHeader, containsString("\"top-entity-type\":\"pserver\"")); + EventHeader notificationEventHeader = events.get(0).getEventHeader(); + String notificationEventBody = events.get(0).getEntity().toString(); + assertEquals("UPDATE", notificationEventHeader.getAction()); + assertEquals("pserver", notificationEventHeader.getEntityType()); + assertEquals("pserver", notificationEventHeader.getTopEntityType()); String expectedNotificationHeader = PayloadUtil.getResourcePayload( "notification-dmaap-events/depth-all/expected-notification-header-create-child-on-existing-obj.json"); String expectedNotificationBody = PayloadUtil.getResourcePayload( "notification-dmaap-events/depth-all/expected-notification-body-create-child-on-existing-obj.json"); - JSONAssert.assertEquals(expectedNotificationHeader, notificationEventHeader, false); + String eventHeaderJson = mapper.writeValueAsString(events.get(0).getEventHeader()); + JSONAssert.assertEquals(expectedNotificationHeader, eventHeaderJson, false); JSONAssert.assertEquals(expectedNotificationBody, notificationEventBody, false); response = httpTestUtil.doGet(uri, "0"); @@ -235,7 +237,7 @@ public class NotificationDmaapEventTest extends AAISetup { String cloudRegionUri = "/aai/v14/cloud-infrastructure/cloud-regions/cloud-region/random-cloud-region-owner/random-cloud-region-id"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle, notification, AAIProperties.MINIMUM_DEPTH); Map<String, String> uriPayload = new LinkedHashMap<>(); @@ -252,8 +254,7 @@ public class NotificationDmaapEventTest extends AAISetup { assertThat("Expecting the number of dmaap events to be 2", numberOfEventsActual, is(expectedEvents)); notification.getEvents().forEach((event) -> { - String notificationEventHeader = event.getEventHeader().marshal(false); - assertThat(notificationEventHeader, containsString("\"CREATE\"")); + assertEquals("CREATE", event.getEventHeader().getAction()); }); } @@ -265,7 +266,7 @@ public class NotificationDmaapEventTest extends AAISetup { String cloudRegionUri = "/aai/v14/cloud-infrastructure/cloud-regions/cloud-region/random-cloud-region-owner/random-cloud-region-id"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle, notification, AAIProperties.MAXIMUM_DEPTH); Map<String, String> uriPayload = new LinkedHashMap<>(); @@ -282,8 +283,7 @@ public class NotificationDmaapEventTest extends AAISetup { assertThat("Expecting the number of dmaap events to be 2", numberOfEventsActual, is(expectedEvents)); notification.getEvents().forEach((event) -> { - String notificationEventHeader = event.getEventHeader().marshal(false); - assertThat(notificationEventHeader, containsString("\"CREATE\"")); + assertEquals("CREATE", event.getEventHeader().getAction()); }); } @@ -291,7 +291,7 @@ public class NotificationDmaapEventTest extends AAISetup { public void testDeleteOnExistingPserverAndCheckIfNotificationDepthIsZeroThatAllEventsHaveDeleteAndThatDepthIsZeroOnEachNotificationEvent() throws IOException, AAIException { String uri = "/aai/v14/cloud-infrastructure/pservers/pserver/example-hostname-val-85598"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle); String pserverResource = PayloadUtil.getResourcePayload("pserver-with-children-for-notification.json"); @@ -316,19 +316,16 @@ public class NotificationDmaapEventTest extends AAISetup { assertThat(notificationEvents.size(), is(17)); notificationEvents.forEach((event) -> { - - String header = event.getEventHeader().marshal(false); - - assertThat(event.getEventHeader().marshal(false), containsString("\"DELETE\"")); - - assertThat(header, containsString("\"top-entity-type\":\"pserver\"")); + EventHeader header = event.getEventHeader(); + assertEquals("DELETE", header.getAction()); + assertEquals("pserver", header.getTopEntityType()); }); } @Test public void testDeleteOnExistingResourceVersionMismatchNoEventGenerated() throws IOException, AAIException { String uri = "/aai/v14/cloud-infrastructure/pservers/pserver/example-hostname-val-85598"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle); String pserverResource = PayloadUtil.getResourcePayload("pserver-with-children-for-notification.json"); @@ -362,7 +359,7 @@ public class NotificationDmaapEventTest extends AAISetup { throws IOException, AAIException { String uri = "/aai/v14/cloud-infrastructure/pservers/pserver/example-hostname-val-85598"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle, notification, AAIProperties.MAXIMUM_DEPTH); String resource = PayloadUtil.getResourcePayload("pserver-with-children-for-notification.json"); @@ -378,20 +375,16 @@ public class NotificationDmaapEventTest extends AAISetup { NotificationEvent notificationEvent = notification.getEvents().get(0); // Verify all the events are create since its a new PUT - String header = notificationEvent.getEventHeader().marshal(false); - - assertThat(header, containsString("\"CREATE\"")); - - assertThat(header, containsString("\"entity-type\":\"pserver\"")); - - assertThat(header, containsString("\"top-entity-type\":\"pserver\"")); - - assertThat(header, containsString("\"entity-link\":\"" + uri + "\"")); + EventHeader eventHeader = notificationEvent.getEventHeader(); + assertEquals("CREATE", eventHeader.getAction()); + assertEquals("pserver", eventHeader.getEntityType()); + assertEquals("pserver", eventHeader.getTopEntityType()); + assertEquals(uri, eventHeader.getEntityLink()); response = httpTestUtil.doGet(uri); assertEquals("Expecting the pserver to be found", 200, response.getStatus()); - JSONAssert.assertEquals(response.getEntity().toString(), notificationEvent.getObj().marshal(false), false); + JSONAssert.assertEquals(response.getEntity().toString(), notificationEvent.getEntity().toString(), false); } @Test @@ -399,7 +392,7 @@ public class NotificationDmaapEventTest extends AAISetup { throws IOException, AAIException { String uri = "/aai/v14/cloud-infrastructure/pservers/pserver/example-hostname-val-85598"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle); String resource = PayloadUtil.getResourcePayload("pserver-with-children-for-notification.json"); @@ -424,7 +417,7 @@ public class NotificationDmaapEventTest extends AAISetup { assertThat(response.getEntity().toString(), containsString("new-equip-patch-type")); assertThat(notification.getEvents().size(), is(1)); - String updateNotificationEvent = notification.getEvents().get(0).getObj().marshal(true); + String updateNotificationEvent = notification.getEvents().get(0).getEntity().toString(); // Check that everything in notification event is also response body // Not comparing the other way as notification only includes parents main properties @@ -436,7 +429,7 @@ public class NotificationDmaapEventTest extends AAISetup { throws IOException, AAIException { String uri = "/aai/v14/cloud-infrastructure/pservers/pserver/example-hostname-val-85598"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle); String resource = PayloadUtil.getResourcePayload("pserver-with-children-for-notification.json"); @@ -461,7 +454,7 @@ public class NotificationDmaapEventTest extends AAISetup { assertThat(response.getEntity().toString(), containsString("new-equip-patch-type")); assertThat(notification.getEvents().size(), is(1)); - String updateNotificationEvent = notification.getEvents().get(0).getObj().marshal(true); + String updateNotificationEvent = notification.getEvents().get(0).getEntity().toString(); // Check that everything in notification event is also response body // Not comparing the other way as notification only includes parents main properties @@ -476,7 +469,7 @@ public class NotificationDmaapEventTest extends AAISetup { throws IOException, AAIException { String uri = "/aai/v14/cloud-infrastructure/pservers/pserver/example-hostname-val-85598"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle); String resource = PayloadUtil.getResourcePayload("pserver-with-children-for-notification.json"); @@ -506,7 +499,7 @@ public class NotificationDmaapEventTest extends AAISetup { assertThat(response.getEntity().toString(), containsString("new-equipment-identifier")); assertThat(notification.getEvents().size(), is(1)); - String updateNotificationEvent = notification.getEvents().get(0).getObj().marshal(true); + String updateNotificationEvent = notification.getEvents().get(0).getEntity().toString(); // Check that everything in notification event is also response body // Not comparing the other way as notification only includes parents main properties @@ -520,7 +513,7 @@ public class NotificationDmaapEventTest extends AAISetup { throws IOException, AAIException { String uri = "/aai/v14/cloud-infrastructure/pservers/pserver/example-hostname-val-85598"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle); String resource = PayloadUtil.getResourcePayload("pserver-with-children-for-notification.json"); @@ -547,7 +540,7 @@ public class NotificationDmaapEventTest extends AAISetup { response = httpTestUtil.doGet(uri); assertThat(notification.getEvents().size(), is(1)); - String updateNotificationEvent = notification.getEvents().get(0).getObj().marshal(true); + String updateNotificationEvent = notification.getEvents().get(0).getEntity().toString(); System.out.println("Update notification " + updateNotificationEvent); // Check that everything in notification event is also response body @@ -564,7 +557,7 @@ public class NotificationDmaapEventTest extends AAISetup { String pserverUri = "/aai/v14/cloud-infrastructure/pservers/pserver/" + hostname; String genericVnfUri = "/aai/v14/network/generic-vnfs/generic-vnf/generic-vnf-notification"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle); String resource = PayloadUtil.getResourcePayload("pserver-with-children-for-notification.json"); @@ -604,9 +597,9 @@ public class NotificationDmaapEventTest extends AAISetup { String expectedNotificationBody = PayloadUtil.getResourcePayload( "notification-dmaap-events/depth-zero/expected-notification-body-create-edge-between-pserver-and-generic-vnf.json"); - JSONAssert.assertEquals(expectedNotificationHeader, notificationEvents.get(0).getEventHeader().marshal(false), + JSONAssert.assertEquals(expectedNotificationHeader, mapper.writeValueAsString(notificationEvents.get(0).getEventHeader()), false); - JSONAssert.assertEquals(expectedNotificationBody, notificationEvents.get(0).getObj().marshal(false), false); + JSONAssert.assertEquals(expectedNotificationBody, notificationEvents.get(0).getEntity().toString(), false); response = httpTestUtil.doGet(genericVnfUri); @@ -623,7 +616,7 @@ public class NotificationDmaapEventTest extends AAISetup { String pserverUri = "/aai/v14/cloud-infrastructure/pservers/pserver/" + hostname; String genericVnfUri = "/aai/v14/network/generic-vnfs/generic-vnf/generic-vnf-notification"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle); String resource = PayloadUtil.getResourcePayload("pserver-with-children-for-notification.json"); @@ -663,10 +656,10 @@ public class NotificationDmaapEventTest extends AAISetup { String expectedNotificationBody = PayloadUtil.getResourcePayload( "notification-dmaap-events/depth-all/expected-notification-body-create-edge-between-pserver-and-generic-vnf.json"); - System.out.println("Notification Body: " + notificationEvents.get(0).getObj().marshal(false)); - JSONAssert.assertEquals(expectedNotificationHeader, notificationEvents.get(0).getEventHeader().marshal(false), + System.out.println("Notification Body: " + notificationEvents.get(0).getEntity().toString()); + JSONAssert.assertEquals(expectedNotificationHeader, mapper.writeValueAsString(notificationEvents.get(0).getEventHeader()), false); - JSONAssert.assertEquals(expectedNotificationBody, notificationEvents.get(0).getObj().marshal(false), false); + JSONAssert.assertEquals(expectedNotificationBody, notificationEvents.get(0).getEntity().toString(), false); response = httpTestUtil.doGet(genericVnfUri); @@ -685,7 +678,7 @@ public class NotificationDmaapEventTest extends AAISetup { String relationship = PayloadUtil.getResourcePayload("pserver-to-gvnf-relationship-notification.json"); - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle); String resource = PayloadUtil.getResourcePayload("pserver-with-children-for-notification.json"); @@ -741,9 +734,9 @@ public class NotificationDmaapEventTest extends AAISetup { String expectedNotificationBody = PayloadUtil.getResourcePayload( "notification-dmaap-events/depth-zero/expected-notification-body-delete-edge-between-pserver-and-generic-vnf.json"); - JSONAssert.assertEquals(expectedNotificationHeader, notificationEvents.get(0).getEventHeader().marshal(false), + JSONAssert.assertEquals(expectedNotificationHeader, mapper.writeValueAsString(notificationEvents.get(0).getEventHeader()), false); - JSONAssert.assertEquals(expectedNotificationBody, notificationEvents.get(0).getObj().marshal(false), false); + JSONAssert.assertEquals(expectedNotificationBody, notificationEvents.get(0).getEntity().toString(), false); } @@ -758,7 +751,7 @@ public class NotificationDmaapEventTest extends AAISetup { String relationship = PayloadUtil.getResourcePayload("pserver-to-gvnf-relationship-notification.json"); - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle); String resource = PayloadUtil.getResourcePayload("pserver-with-children-for-notification.json"); @@ -813,9 +806,9 @@ public class NotificationDmaapEventTest extends AAISetup { String expectedNotificationBody = PayloadUtil.getResourcePayload( "notification-dmaap-events/depth-all/expected-notification-body-delete-edge-between-pserver-and-generic-vnf.json"); - JSONAssert.assertEquals(expectedNotificationHeader, notificationEvents.get(0).getEventHeader().marshal(false), + JSONAssert.assertEquals(expectedNotificationHeader, mapper.writeValueAsString(notificationEvents.get(0).getEventHeader()), false); - JSONAssert.assertEquals(expectedNotificationBody, notificationEvents.get(0).getObj().marshal(false), false); + JSONAssert.assertEquals(expectedNotificationBody, notificationEvents.get(0).getEntity().toString(), false); } @@ -823,7 +816,7 @@ public class NotificationDmaapEventTest extends AAISetup { public void testDeleteOnExistingResourceVersionMismatchNoEventGeneratedFullDepth() throws IOException, AAIException { String uri = "/aai/v14/cloud-infrastructure/pservers/pserver/example-hostname-val-85598"; - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle); String pserverResource = PayloadUtil.getResourcePayload("pserver-with-children-for-notification.json"); @@ -851,7 +844,7 @@ public class NotificationDmaapEventTest extends AAISetup { @Test public void testCreateVnfWithChildrenCreateCustomerWithChildrenAndCousinBetweenVlanAndServiceInstanceThenDeleteCustomerVerifyingVlanRV() throws IOException, AAIException { - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle); String json = PayloadUtil.getResourcePayload( @@ -912,7 +905,7 @@ public class NotificationDmaapEventTest extends AAISetup { @Test public void testBulkCreateOfComplexAndPserverWithRelationshipThenBulkDeleteBoth() throws IOException, AAIException { - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle, notification, AAIProperties.MAXIMUM_DEPTH); JsonObject payloads = JsonParser @@ -945,7 +938,7 @@ public class NotificationDmaapEventTest extends AAISetup { Map<String, Pair<String, String>> deletes = new LinkedHashMap<>(); deletes.put(pserverUri, new Pair<>(pserverRv, null)); deletes.put(complexUri, new Pair<>(complexRV, null)); - notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); httpTestUtil = new HttpTestUtil(queryStyle, notification, AAIProperties.MAXIMUM_DEPTH); httpTestUtil.doDelete(deletes); @@ -958,7 +951,7 @@ public class NotificationDmaapEventTest extends AAISetup { @Test public void testCreateVnfWithChildrenCreateCustomerWithChildrenAndCousinBetweenVlanAndServiceInstanceThenImplicitDeleteVlanVerifyingServiceInstanceRV() throws IOException, AAIException { - UEBNotification notification = Mockito.spy(new UEBNotification(ModelType.MOXY, loaderFactory, schemaVersions)); + UEBNotification notification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); HttpTestUtil httpTestUtil = new HttpTestUtil(queryStyle); String json = PayloadUtil.getResourcePayload( 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 index e8e3d691..6b90782c 100644 --- 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 @@ -61,8 +61,6 @@ 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 { @@ -77,8 +75,6 @@ public class HttpEntryNotificationIntegrationTest extends AAISetup { private List<String> aaiRequestContextList; private List<MediaType> outputMediaTypes; - ObjectMapper mapper = new ObjectMapper(); - @Before public void setup() { @@ -129,7 +125,7 @@ public class HttpEntryNotificationIntegrationTest extends AAISetup { public void notificationOnRelatedToTest() throws UnsupportedEncodingException, AAIException { Loader ld = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDefaultVersion()); - UEBNotification uebNotification = Mockito.spy(new UEBNotification(ld, loaderFactory, schemaVersions)); + UEBNotification uebNotification = Mockito.spy(new UEBNotification(loaderFactory, schemaVersions)); traversalHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion(), uebNotification); Loader loader = traversalHttpEntry.getLoader(); @@ -148,25 +144,24 @@ public class HttpEntryNotificationIntegrationTest extends AAISetup { 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()); + uebNotification.getEvents().get(1).getEventHeader().getAction()); assertThat("Event body for the edge create has the related to", - uebNotification.getEvents().get(0).getObj().marshal(false), + uebNotification.getEvents().get(1).getEntity().toString(), 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()); + uebNotification.getEvents().get(0).getEventHeader().getAction()); assertThat("Event body for the edge delete does not have the related to", - uebNotification.getEvents().get(0).getObj().marshal(false), + uebNotification.getEvents().get(0).getEntity().toString(), not(containsString("cloud-infrastructure/pservers/pserver/junit-edge-test-pserver"))); dbEngine.rollback(); diff --git a/aai-core/src/test/java/org/onap/aai/rest/notification/EntityConverterTest.java b/aai-core/src/test/java/org/onap/aai/rest/notification/EntityConverterTest.java new file mode 100644 index 00000000..cbfedef7 --- /dev/null +++ b/aai-core/src/test/java/org/onap/aai/rest/notification/EntityConverterTest.java @@ -0,0 +1,119 @@ +/** + * ============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.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.List; + + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.aai.introspection.Introspector; +import org.onap.aai.introspection.Loader; +import org.onap.aai.introspection.exceptions.AAIUnmarshallingException; +import org.onap.aai.parsers.uri.URIToObject; +import org.onap.aai.setup.SchemaVersion; + +public class EntityConverterTest { + + @Mock URIToObject parser; + @Mock Introspector introspector; + @Mock Loader loader; + @Mock List<Object> parentList; + + EntityConverter entityConverter; + + @BeforeEach + public void setUp() { + MockitoAnnotations.openMocks(this); + entityConverter = new EntityConverter(parser); + } + + @Test + public void testConvert_topEntitySameAsEntity() throws AAIUnmarshallingException { + when(parser.getParentList()).thenReturn(parentList); + when(parser.getTopEntity()).thenReturn(introspector); + when(parser.getEntity()).thenReturn(introspector); + + Introspector result = entityConverter.convert(introspector); + + assertEquals(introspector, result); + verify(parser.getParentList()).clear(); + } + + @Test + public void testConvert_topEntityDifferentFromEntity_withVersionMismatch() throws AAIUnmarshallingException { + Introspector topEntity = mock(Introspector.class); + Introspector childEntity = mock(Introspector.class); + String json = "{}"; + + when(parser.getParentList()).thenReturn(parentList); + when(parser.getTopEntity()).thenReturn(topEntity); + when(parser.getEntity()).thenReturn(childEntity); + when(childEntity.getName()).thenReturn("smth"); + when(parser.getLoader()).thenReturn(loader); + when(introspector.getVersion()).thenReturn(new SchemaVersion("v1")); + when(loader.getVersion()).thenReturn(new SchemaVersion("v2")); + when(introspector.marshal(false)).thenReturn(json); + when(loader.unmarshal(anyString(), eq(json))).thenReturn(childEntity); + + Introspector result = entityConverter.convert(introspector); + + assertEquals(topEntity, result); + } + + @Test + public void testConvert_topEntityDifferentFromEntity_withoutVersionMismatch() throws AAIUnmarshallingException { + Introspector topEntity = mock(Introspector.class); + Introspector childEntity = mock(Introspector.class); + + when(parser.getParentList()).thenReturn(parentList); + when(parser.getTopEntity()).thenReturn(topEntity); + when(parser.getEntity()).thenReturn(childEntity); + when(parser.getLoader()).thenReturn(loader); + when(introspector.getVersion()).thenReturn(new SchemaVersion("v1")); + when(loader.getVersion()).thenReturn(new SchemaVersion("v1")); + + Introspector result = entityConverter.convert(introspector); + + assertEquals(topEntity, result); + verify(parentList).add(any()); + } + + @Test + public void testGetTopEntityName() { + String topEntityName = "TopEntity"; + when(parser.getTopEntityName()).thenReturn(topEntityName); + + String result = entityConverter.getTopEntityName(); + + assertEquals(topEntityName, result); + } +} 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 index 95301c6f..4fd21497 100644 --- 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 @@ -24,6 +24,7 @@ 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.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -50,6 +51,7 @@ 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.kafka.NotificationProducerService; import org.onap.aai.prevalidation.ValidationService; import org.onap.aai.serialization.db.DBSerializer; import org.onap.aai.serialization.engines.query.QueryEngine; @@ -62,6 +64,7 @@ public class NotificationServiceTest extends AAISetup { @Mock SchemaVersions schemaVersions; @Mock UEBNotification uebNotification; @Mock ValidationService validationService; + @Mock NotificationProducerService notificationProducerService; @Mock DBSerializer dbSerializer; @Mock QueryEngine queryEngine; @Mock Introspector introspector; @@ -77,9 +80,10 @@ public class NotificationServiceTest extends AAISetup { when(dbSerializer.touchStandardVertexPropertiesForEdges()).thenReturn(Collections.emptySet()); when(dbSerializer.getLatestVersionView(any(),anyInt())).thenReturn(introspector); - notificationService = new NotificationService(validationService, loaderFactory, basePath, isDeltaEventsEnabled); + notificationService = new NotificationService(validationService, loaderFactory, basePath, isDeltaEventsEnabled, notificationProducerService); when(schemaVersions.getDefaultVersion()).thenReturn(new SchemaVersion("v29")); doNothing().when(uebNotification).createNotificationEvent(any(),any(),any(),any(),any(),any(),any()); + doNothing().when(notificationProducerService).sendUEBNotification(any()); } @Test @@ -101,7 +105,7 @@ public class NotificationServiceTest extends AAISetup { 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(); + verify(notificationProducerService, times(1)).sendUEBNotification(uebNotification); } @Test @@ -119,9 +123,9 @@ public class NotificationServiceTest extends AAISetup { SchemaVersion schemaVersion = new SchemaVersion("v29"); when(dbSerializer.getUpdatedVertexes()).thenReturn(Collections.emptyMap()); - notificationService = new NotificationService(null, loaderFactory, basePath, isDeltaEventsEnabled); + notificationService = new NotificationService(null, loaderFactory, basePath, isDeltaEventsEnabled, notificationProducerService); notificationService.generateEvents(uebNotification, AAIProperties.MINIMUM_DEPTH, "sourceOfTruth", dbSerializer, "transactionId", queryEngine, mainVertexesToNotifyOn, schemaVersion); - verify(uebNotification, times(1)).triggerEvents(); + verify(notificationProducerService, times(1)).sendUEBNotification(uebNotification); } } diff --git a/aai-core/src/test/java/org/onap/aai/rest/notification/UEBNotificationTest.java b/aai-core/src/test/java/org/onap/aai/rest/notification/UEBNotificationTest.java index 229abae4..e176f1cb 100644 --- a/aai-core/src/test/java/org/onap/aai/rest/notification/UEBNotificationTest.java +++ b/aai-core/src/test/java/org/onap/aai/rest/notification/UEBNotificationTest.java @@ -71,14 +71,14 @@ public class UEBNotificationTest extends AAISetup { Introspector pserver = loader.introspectorFromName("pserver"); pserver.setValue("hostname", "hn"); URI uri = new URI("/cloud-infrastructure/pservers/pserver/hn"); - UEBNotification uebNotification = new UEBNotification(loader, loaderFactory, schemaVersions); + UEBNotification uebNotification = new UEBNotification(loaderFactory, schemaVersions); uebNotification.createNotificationEvent(UUID.randomUUID().toString(), "JUNIT-SOT", Response.Status.CREATED, uri, pserver, new HashMap<>(), BASE_PATH); assertEquals("One event created", 1, uebNotification.getEvents().size()); assertEquals("Uri is correct", BASE_PATH + "/" + schemaVersions.getDefaultVersion() + "/cloud-infrastructure/pservers/pserver/hn", - uebNotification.getEvents().get(0).getEventHeader().getValue("entity-link").toString()); + uebNotification.getEvents().get(0).getEventHeader().getEntityLink()); } @Test @@ -87,13 +87,13 @@ public class UEBNotificationTest extends AAISetup { Introspector pserver = loader.introspectorFromName("pserver"); pserver.setValue("hostname", "hn"); URI uri = new URI(BASE_PATH + "/v12/cloud-infrastructure/pservers/pserver/hn"); - UEBNotification uebNotification = new UEBNotification(loader, loaderFactory, schemaVersions); + UEBNotification uebNotification = new UEBNotification(loaderFactory, schemaVersions); uebNotification.createNotificationEvent(UUID.randomUUID().toString(), "JUNIT-SOT", Response.Status.CREATED, uri, pserver, new HashMap<>(), BASE_PATH); assertEquals("One event created", 1, uebNotification.getEvents().size()); assertEquals("Uri is correct", BASE_PATH + "/" + schemaVersions.getDefaultVersion() + "/cloud-infrastructure/pservers/pserver/hn", - uebNotification.getEvents().get(0).getEventHeader().getValue("entity-link").toString()); + uebNotification.getEvents().get(0).getEventHeader().getEntityLink()); } } 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 7dca441e..6db9e4fa 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 @@ -42,6 +42,7 @@ import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.onap.aai.config.ConfigConfiguration; import org.onap.aai.config.IntrospectionConfig; +import org.onap.aai.config.KafkaConfig; import org.onap.aai.config.SpringContextAware; import org.onap.aai.config.XmlFormatTransformerConfiguration; import org.onap.aai.db.props.AAIProperties; @@ -71,10 +72,11 @@ 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, LoaderFactory.class, NotificationService.class}) + XmlFormatTransformerConfiguration.class, LoaderFactory.class, NotificationService.class, + KafkaConfig.class}) @TestPropertySource( properties = {"schema.translator.list = config", "schema.nodes.location=src/test/resources/onap/oxm", - "schema.edges.location=src/test/resources/onap/dbedgerules"}) + "schema.edges.location=src/test/resources/onap/dbedgerules","aai.notifications.enabled=false"}) public class DbSerializer_needsFakeRulesTest { // to use, set thrown.expect to whatever your test needs diff --git a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/PathedURLTest.java b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/PathedURLTest.java index 6ed42539..cd2c3af3 100644 --- a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/PathedURLTest.java +++ b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/PathedURLTest.java @@ -127,7 +127,7 @@ public class PathedURLTest extends AAISetup { when(urlBuilder.pathed(pserver)).thenReturn("/aai/v14/cloud-infrastructure/pservers/pserver/hostname-1"); Optional<JsonObject> jsonObjectOptional = pathedURL.getJsonFromVertex(pserver); - if (!jsonObjectOptional.isPresent()) { + if (jsonObjectOptional.isEmpty()) { fail("Expecting an json object returned from pathed url but returned none"); } @@ -150,7 +150,7 @@ public class PathedURLTest extends AAISetup { when(urlBuilder.pathed(pserver)).thenReturn("/aai/v14/cloud-infrastructure/pservers/pserver/hostname-1"); Optional<JsonObject> jsonObjectOptional = pathedURL.getJsonFromVertex(pserver); - if (!jsonObjectOptional.isPresent()) { + if (jsonObjectOptional.isEmpty()) { fail("Expecting an json object returned from pathed url but returned none"); } diff --git a/aai-core/src/test/java/org/onap/aai/util/StoreNotificationEventTest.java b/aai-core/src/test/java/org/onap/aai/util/StoreNotificationEventTest.java deleted file mode 100644 index a0c3f639..00000000 --- a/aai-core/src/test/java/org/onap/aai/util/StoreNotificationEventTest.java +++ /dev/null @@ -1,227 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.aai.util; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.databind.JsonMappingException; - -import java.io.IOException; - -import javax.json.Json; -import javax.json.JsonObject; - -import org.eclipse.persistence.dynamic.DynamicEntity; -import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; -import org.mockito.Mockito; -import org.onap.aai.AAISetup; -import org.onap.aai.domain.notificationEvent.NotificationEvent.EventHeader; -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.kafka.AAIKafkaEventJMSProducer; - -public class StoreNotificationEventTest extends AAISetup { - - private static AAIKafkaEventJMSProducer producer; - private static StoreNotificationEvent sne; - - @BeforeClass - public static void setUp() { - producer = Mockito.mock(AAIKafkaEventJMSProducer.class); - // sne = new StoreNotificationEvent(producer, "transiationId", "sourceOfTruth"); - } - - @Before - public void setUpBefore() { - producer = Mockito.mock(AAIKafkaEventJMSProducer.class); - sne = new StoreNotificationEvent(producer, "transiationId", "sourceOfTruth"); - - } - - @Test(expected = AAIException.class) - public void testStoreEventNullObj() throws AAIException { - sne.storeEventAndSendToJms(new EventHeader(), null); - } - - @Test(expected = AAIException.class) - public void testStoreEventInvalidObjForPojoUtils() throws AAIException { - sne.storeEventAndSendToJms(new EventHeader(), new Object()); - } - - @Test - public void testStoreEventEmptyEventHeader() - throws AAIException, JsonGenerationException, JsonMappingException, IOException { - JsonObject object = Json.createObjectBuilder().add("hello", "world").build(); - String res = sne.storeEventAndSendToJms(new EventHeader(), object); - - assertNotNull(res); - assertTrue(res.contains("\"cambria.partition\" : \"" + AAIConstants.UEB_PUB_PARTITION_AAI + "\"")); - assertTrue(res.contains("\"event-header\"")); - assertTrue(res.contains("\"id\"")); - assertTrue(res.contains("\"timestamp\"")); - assertTrue(res - .contains("\"source-name\" : \"" + AAIConfig.get("aai.notificationEvent.default.sourceName") + "\"")); - assertTrue(res.contains("\"domain\" : \"" + AAIConfig.get("aai.notificationEvent.default.domain") + "\"")); - assertTrue(res.contains( - "\"sequence-number\" : \"" + AAIConfig.get("aai.notificationEvent.default.sequenceNumber") + "\"")); - assertTrue(res.contains("\"severity\" : \"" + AAIConfig.get("aai.notificationEvent.default.severity") + "\"")); - assertTrue( - res.contains("\"event-type\" : \"" + AAIConfig.get("aai.notificationEvent.default.eventType") + "\"")); - assertTrue(res.contains("\"version\" : \"" + AAIConfig.get("aai.notificationEvent.default.version") + "\"")); - assertTrue(res.contains("\"action\" : \"UNK\"")); - assertTrue(res.contains("\"entity-link\" : \"UNK\"")); - assertTrue(res.contains("\"entity\"")); - assertTrue(res.contains("\"hello\"")); - assertTrue(res.contains("\"chars\" : \"world\"")); - assertTrue(res.contains("\"string\" : \"world\"")); - assertTrue(res.contains("\"valueType\" : \"STRING\"")); - } - - @Test - public void testStoreEvent() throws AAIException, JsonGenerationException, JsonMappingException, IOException { - JsonObject object = Json.createObjectBuilder().add("hello", "world").build(); - EventHeader eh = new EventHeader(); - eh.setId("123"); - eh.setTimestamp("current-time"); - eh.setEntityLink("entity-link"); - eh.setAction("action!"); - eh.setEventType("surprise"); - eh.setDomain("PROD"); - eh.setSourceName("source"); - eh.setSequenceNumber("23"); - eh.setSeverity("ALERT"); - eh.setVersion("v12"); - - String res = sne.storeEventAndSendToJms(eh, object); - - assertNotNull(res); - assertTrue(res.contains("\"cambria.partition\" : \"" + AAIConstants.UEB_PUB_PARTITION_AAI + "\"")); - assertTrue(res.contains("\"event-header\"")); - assertTrue(res.contains("\"id\" : \"123\"")); - assertTrue(res.contains("\"timestamp\" : \"current-time\"")); - assertTrue(res.contains("\"source-name\" : \"source\"")); - assertTrue(res.contains("\"domain\" : \"PROD\"")); - assertTrue(res.contains("\"sequence-number\" : \"23\"")); - assertTrue(res.contains("\"severity\" : \"ALERT\"")); - assertTrue(res.contains("\"event-type\" : \"surprise\"")); - assertTrue(res.contains("\"version\" : \"v12\"")); - assertTrue(res.contains("\"action\" : \"action!\"")); - assertTrue(res.contains("\"entity-link\" : \"entity-link\"")); - assertTrue(res.contains("\"entity\"")); - assertTrue(res.contains("\"hello\"")); - assertTrue(res.contains("\"chars\" : \"world\"")); - assertTrue(res.contains("\"string\" : \"world\"")); - assertTrue(res.contains("\"valueType\" : \"STRING\"")); - } - - @Test(expected = AAIException.class) - public void testStoreDynamicEventNullObj() throws AAIException { - DynamicEntity eventHeader = Mockito.mock(DynamicEntity.class); - DynamicJAXBContext notificationJaxbContext = - nodeIngestor.getContextForVersion(schemaVersions.getEdgeLabelVersion()); - sne.storeDynamicEvent(notificationJaxbContext, "v12", eventHeader, null); - } - - @Test(expected = Exception.class) - public void testStoreDynamicEventAAIException() throws Exception { - - DynamicJAXBContext notificationJaxbContext = - nodeIngestor.getContextForVersion(schemaVersions.getEdgeLabelVersion()); - DynamicEntity obj = Mockito.mock(DynamicEntity.class); - DynamicEntity eventHeader = Mockito.mock(DynamicEntity.class); - sne.storeDynamicEvent(notificationJaxbContext, "v12", eventHeader, obj); - } - - @Test(expected = AAIException.class) - public void testStoreEventIntrospectorNullObj() throws Exception { - Loader loader = Mockito.mock(Loader.class); - sne.storeEventAndSendToJms(loader, null, null); - } - - @Ignore("Stopped working since the model driven story") - @Test - public void testStoreEvent1Introspector() throws Exception { - Loader loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getEdgeLabelVersion()); - Introspector eventHeader = loader.introspectorFromName("notification-event-header"); - eventHeader.setValue("id", "123"); - eventHeader.setValue("timestamp", "current-time"); - eventHeader.setValue("entity-link", "entity-link"); - eventHeader.setValue("action", "action!"); - eventHeader.setValue("event-type", "surprise"); - eventHeader.setValue("domain", "PROD"); - eventHeader.setValue("source-name", "source"); - eventHeader.setValue("sequence-number", "23"); - eventHeader.setValue("severity", "ALERT"); - eventHeader.setValue("version", "v12"); - Introspector obj = loader.introspectorFromName("notification-event"); - String res = sne.storeEventAndSendToJms(loader, eventHeader, obj); - - assertNotNull(res); - assertTrue(res.contains("\"cambria.partition\":\"" + AAIConstants.UEB_PUB_PARTITION_AAI + "\"")); - assertTrue(res.contains("\"event-header\"")); - assertTrue(res.contains("\"id\":\"123\"")); - assertTrue(res.contains("\"timestamp\":\"current-time\"")); - assertTrue(res.contains("\"source-name\":\"source\"")); - assertTrue(res.contains("\"domain\":\"PROD\"")); - assertTrue(res.contains("\"sequence-number\":\"23\"")); - assertTrue(res.contains("\"severity\":\"ALERT\"")); - assertTrue(res.contains("\"event-type\":\"surprise\"")); - assertTrue(res.contains("\"version\":\"v12\"")); - assertTrue(res.contains("\"action\":\"action!\"")); - assertTrue(res.contains("\"entity-link\":\"entity-link\"")); - assertTrue(res.contains("\"notification-event\"")); - } - - @Ignore("Stopped working since the model driven story") - @Test - public void testStoreEventIntrospectorEmptyEventHeader() throws Exception { - Loader loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getEdgeLabelVersion()); - Introspector eventHeader = loader.introspectorFromName("notification-event-header"); - Introspector obj = loader.introspectorFromName("notification-event"); - - String res = sne.storeEventAndSendToJms(loader, eventHeader, obj); - - assertNotNull(res); - assertTrue(res.contains("\"cambria.partition\":\"" + AAIConstants.UEB_PUB_PARTITION_AAI + "\"")); - assertTrue(res.contains("\"event-header\"")); - assertTrue(res.contains("\"id\"")); - assertTrue(res.contains("\"timestamp\"")); - assertTrue( - res.contains("\"source-name\":\"" + AAIConfig.get("aai.notificationEvent.default.sourceName") + "\"")); - assertTrue(res.contains("\"domain\":\"" + AAIConfig.get("aai.notificationEvent.default.domain") + "\"")); - assertTrue(res.contains( - "\"sequence-number\":\"" + AAIConfig.get("aai.notificationEvent.default.sequenceNumber") + "\"")); - assertTrue(res.contains("\"severity\":\"" + AAIConfig.get("aai.notificationEvent.default.severity") + "\"")); - assertTrue(res.contains("\"event-type\":\"" + AAIConfig.get("aai.notificationEvent.default.eventType") + "\"")); - assertTrue(res.contains("\"version\":\"" + AAIConfig.get("aai.notificationEvent.default.version") + "\"")); - assertTrue(res.contains("\"action\":\"UNK\"")); - assertTrue(res.contains("\"entity-link\":\"UNK\"")); - assertTrue(res.contains("\"notification-event\"")); - } -} diff --git a/aai-core/src/test/resources/bundleconfig-local/etc/appprops/aaiconfig.properties b/aai-core/src/test/resources/bundleconfig-local/etc/appprops/aaiconfig.properties index c7eaad36..40554216 100644 --- a/aai-core/src/test/resources/bundleconfig-local/etc/appprops/aaiconfig.properties +++ b/aai-core/src/test/resources/bundleconfig-local/etc/appprops/aaiconfig.properties @@ -50,8 +50,6 @@ aai.example.int=7748 aai.realtime.clients=RO,SDNC,SO -aai.jms.enable=false - aai.rest.getall.depthparam=someuuid aaf.valid.issuer.wildcard=aaf wild card issuer|aafWildCardIssuer|OU=another 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-core/src/test/resources/payloads/resource/aai-event.json b/aai-core/src/test/resources/payloads/resource/aai-event.json index 0fab96da..86c67992 100644 --- a/aai-core/src/test/resources/payloads/resource/aai-event.json +++ b/aai-core/src/test/resources/payloads/resource/aai-event.json @@ -1,64 +1,61 @@ { - "event-topic": "AAI-EVENT", - "aaiEventPayload": { - "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" + "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" + } + ] + } + ] }, - "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" - } + "group-name": "Urban", + "resource-version": "1701951284582", + "group-type": "cell", + "object-group-id": "ric_cluster" } -}
\ No newline at end of file +} |