summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore31
-rw-r--r--Changelog.md8
-rw-r--r--Dockerfile4
-rw-r--r--Makefile24
-rw-r--r--README.md68
-rw-r--r--docker-compose.yml11
-rw-r--r--environment.config13
-rw-r--r--pom.xml235
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/Main.java93
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/config/DistributionClientConfig.java130
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/config/ValidatorProperties.java39
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/exceptions/ArtifactException.java26
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/model/Artifact.java37
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/model/ArtifactValidationResult.java40
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/model/DistributionStatusMessage.java63
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/model/FinalDistributionStatusMessage.java59
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/model/SchemaMap.java48
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/service/ArtifactsCollector.java99
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/service/ClientCallback.java143
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/service/notification/ArtifactsCollectorStatusSender.java93
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/service/notification/FinalStatusSender.java85
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/service/notification/ValidationStatusSender.java89
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/service/serialization/SchemaMapDeserializer.java71
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/service/serialization/VesEventsArtifactDeserializer.java69
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/service/validation/ArtifactsValidator.java35
-rw-r--r--src/main/java/org/onap/ves/openapi/manager/service/validation/SchemaReferenceValidator.java158
-rw-r--r--src/main/resources/application.yml20
-rw-r--r--src/main/resources/schema-map.json58
-rw-r--r--src/test/java/org/onap/ves/openapi/manager/config/DistributionClientConfigTest.java89
-rw-r--r--src/test/java/org/onap/ves/openapi/manager/config/ValidatorPropertiesTest.java60
-rw-r--r--src/test/java/org/onap/ves/openapi/manager/model/DistributionStatusMessageTest.java56
-rw-r--r--src/test/java/org/onap/ves/openapi/manager/service/ServiceFunctionalTest.java94
-rw-r--r--src/test/java/org/onap/ves/openapi/manager/service/notification/ArtifactsCollectorStatusSenderTest.java118
-rw-r--r--src/test/java/org/onap/ves/openapi/manager/service/notification/ArtifactsCollectorTest.java106
-rw-r--r--src/test/java/org/onap/ves/openapi/manager/service/notification/ClientCallbackTest.java153
-rw-r--r--src/test/java/org/onap/ves/openapi/manager/service/notification/ValidationStatusSenderTest.java84
-rw-r--r--src/test/java/org/onap/ves/openapi/manager/service/serialization/SchemaMapDeserializerTest.java84
-rw-r--r--src/test/java/org/onap/ves/openapi/manager/service/serialization/VesEventsArtifactDeserializerTest.java73
-rw-r--r--src/test/java/org/onap/ves/openapi/manager/service/testModel/ArtifactInfo.java121
-rw-r--r--src/test/java/org/onap/ves/openapi/manager/service/testModel/Resource.java161
-rw-r--r--src/test/java/org/onap/ves/openapi/manager/service/testModel/Service.java136
-rw-r--r--src/test/java/org/onap/ves/openapi/manager/service/validation/SchemaReferenceValidatorTest.java120
-rw-r--r--src/test/resources/test-schema-map.json14
-rw-r--r--src/test/resources/ves_artifact_invalid_stndDefined_events.yaml107
-rw-r--r--src/test/resources/ves_artifact_stndDefined_events.yaml107
-rw-r--r--version.properties6
46 files changed, 3538 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..dd9be1b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,31 @@
+# See https://help.github.com/ignore-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+
+# testing
+/coverage
+
+# production
+/build
+/artifactInfos
+
+# misc
+.DS_Store
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+
+# dependencies
+target
+*.iml
+.idea
+node_modules
+package-lock.json
+build \ No newline at end of file
diff --git a/Changelog.md b/Changelog.md
new file mode 100644
index 0000000..812816c
--- /dev/null
+++ b/Changelog.md
@@ -0,0 +1,8 @@
+# Change Log
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/)
+and this project adheres to [Semantic Versioning](http://semver.org/).
+
+## [1.0.0] - 09/02/2020
+ - [DCAEGEN2-2572](https://jira.onap.org/browse/DCAEGEN2-2572) - Add ves-openapi-manager implementation
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..67275d9
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,4 @@
+FROM onap/integration-java11:8.0.0
+COPY ./src/main/resources/schema-map.json /app/schema-map.json
+COPY target/ves-openapi-manager.jar /app/
+ENTRYPOINT java -jar /app/ves-openapi-manager.jar \ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..fcf3f44
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,24 @@
+include environment.config
+
+all: build docker run cleanup
+
+port-forward:
+ @echo "Forwarding ports. To cancel forwarding press CTRL+C."
+ @$(SSH) -L 3904:$(WORKER_IP):$(MESSAGE_ROUTER_PORT) ubuntu@$(RKE_IP) -i $(SSH_LAB_KEY_PATH) -N
+
+build:
+ @echo "Building ves-openapi-manager"
+ @$(MVN) clean package
+
+docker:
+ @echo "Building ves-openapi-manager docker image"
+ @$(DOCKER) build --tag ves-openapi-manager:latest .
+
+run:
+ @echo "Starting ves-openapi-manager docker containers"
+ @$(COMPOSE) --file ./docker-compose.yml up
+
+cleanup:
+ @echo "Cleaning up ves-openapi-manager project, removing containers"
+ @rm -rf ./target
+ @$(COMPOSE) --file ./docker-compose.yml down
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7d74f51
--- /dev/null
+++ b/README.md
@@ -0,0 +1,68 @@
+# VES OpenApi Manager
+
+# Description
+This application should partially validate incoming service distributions in SDC. It validates each artifact of type
+VES_EVENT. Its purpose is to check whether schemaReferences of stndDefined events included in VES_EVENT artifacts are
+matching the schemas which VES Collector contains.
+
+# Instructions
+
+## How to prepare environment for local ves-openapi-manager with lab connection
+
+1. Connect to lab and expose ports of message-router service by setting *spec.type* to NodePort.
+
+2. Add to /etc/hosts new entry:
+```
+<lab_worker_node_ip> sdc-be.onap
+```
+
+3. Get exposed port of 3904 internal port of message-router.
+
+ Set up connection configuration in *environment.config* file.
+ - MESSAGE_ROUTER_PORT - exposed port of message-router.
+ - RKE_IP - IP of lab RKE node.
+ - WORKER_IP - IP of lab worker node.
+ - SSH_LAB_KEY_PATH - path to lab SSH key.
+
+4. Local port forwarding is required to set up proper connection from local environment to message-router on the lab.
+
+ Run this to enable port-forwarding (CTRL+C to end):
+ ```
+ make port-forwarding
+ ```
+## How to locally start ves-openapi-manager
+Currently, there are two common ways to run application, both described below.
+
+### Start in IntelliJ
+Right click on Main class, then Run or Debug button.
+
+### Start as Docker container
+Run:
+```
+make all
+```
+
+### Lab connection verification
+Correctly connected to lab application should print logs:
+```
+distribution client initialized successfuly
+```
+and
+```
+distribution client started successfuly
+```
+
+## How to use ves-openapi-manager
+After preparing environment, starting ves-openapi-manager and successful connection to lab, application will listen for
+service distributions taking place in SDC.
+
+1. In SDC UI, create Service with Resource (e.g. PNF) containing VES_EVENT artifact.
+2. (Re)distribute created Service.
+
+When distribution takes place, ves-openapi-manager downloads each VES_EVENT artifact to validate its stndDefined events.
+
+Results of validation are visible in two places:
+- In SDC UI in Service -> Distributions view under specific distribution as component *ves-openapi-manager*.
+ It might take few minutes to show results after service distribution.
+- In logs of ves-openapi-manager, right after validation takes place.
+ \ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..d708fd8
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,11 @@
+version: '3'
+
+services:
+ ves-openapi-manager:
+ image: ves-openapi-manager:latest
+ container_name: ves-openapi-manager
+ hostname: ves-openapi-manager
+ environment:
+ - SCHEMA_MAP_PATH=/app/schema-map.json
+ - ASDC_ADDRESS=sdc-be.onap:30204
+ network_mode: host
diff --git a/environment.config b/environment.config
new file mode 100644
index 0000000..0d34eef
--- /dev/null
+++ b/environment.config
@@ -0,0 +1,13 @@
+# Configuration file for ves-openapi-manager Makefile
+
+# consts
+COMPOSE = docker-compose
+MVN = mvn
+DOCKER = docker
+SSH = ssh
+
+# Port-forwarding configuration
+RKE_IP=10.129.36.103
+WORKER_IP=10.129.36.116
+MESSAGE_ROUTER_PORT=30000
+SSH_LAB_KEY_PATH=~/Scripts/labs_keys/onap-8414.pem
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..93140cd
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.oparent</groupId>
+ <artifactId>oparent</artifactId>
+ <version>3.2.0</version>
+ <relativePath/>
+ </parent>
+
+ <groupId>org.onap.dcaegen2.platform</groupId>
+ <artifactId>ves-openapi-manager</artifactId>
+ <version>1.0.0</version>
+ <packaging>jar</packaging>
+
+ <properties>
+ <sdc-distribution-client.version>1.4.2</sdc-distribution-client.version>
+ <junit-jupiter.version>5.2.0</junit-jupiter.version>
+ <maven.compiler.source>11</maven.compiler.source>
+ <maven.compiler.target>11</maven.compiler.target>
+ <junit5.version>5.2.0</junit5.version>
+ <platform.version>1.2.0</platform.version>
+ <surefire.version>${mockito-core.version}</surefire.version>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ <hibernate-validator.version>6.1.6.Final</hibernate-validator.version>
+ <jackson-databind.version>2.9.4</jackson-databind.version>
+ <mockito-core.version>2.22.0</mockito-core.version>
+ <spring.version>2.4.2</spring.version>
+ <docker-maven-plugin.version>0.31.0</docker-maven-plugin.version>
+ <skipDockerPush>false</skipDockerPush>
+ <nexusproxy>https://nexus.onap.org</nexusproxy>
+ <snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>
+ <releaseNexusPath>/content/repositories/releases/</releaseNexusPath>
+ <stagingNexusPath>/content/repositories/staging/</stagingNexusPath>
+ <docker-image.namespace>onap</docker-image.namespace>
+ <docker-image.name.prefix>org.onap.dcaegen2.platform</docker-image.name.prefix>
+ <maven.build.timestamp.format>yyyyMMdd'T'HHmmss</maven.build.timestamp.format>
+ <maven-compiler-plugin.version>3.5.1</maven-compiler-plugin.version>
+ <bean-matchers.version>0.13</bean-matchers.version>
+ </properties>
+
+ <build>
+ <finalName>ves-openapi-manager</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${surefire.version}</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.junit.platform</groupId>
+ <artifactId>junit-platform-surefire-provider</artifactId>
+ <version>${platform.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <version>${junit5.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${spring.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${maven-compiler-plugin.version}</version>
+ <configuration>
+ <source>${maven.compiler.source}</source>
+ <target>${maven.compiler.target}</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>docker</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <properties>
+ <os.detected.name>linux</os.detected.name>
+ <os.detected.arch>x86_64</os.detected.arch>
+ <os.detected.classifier>${os.detected.name}-${os.detected.arch}</os.detected.classifier>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>io.fabric8</groupId>
+ <artifactId>docker-maven-plugin</artifactId>
+ <version>${docker-maven-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>docker-build-image</id>
+ <phase>package</phase>
+ <goals>
+ <goal>build</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>docker-push-image</id>
+ <phase>deploy</phase>
+ <goals>
+ <goal>push</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <skipPush>${skipDockerPush}</skipPush>
+ <verbose>true</verbose>
+ <imagePullPolicy>IfNotPresent</imagePullPolicy>
+ <images>
+ <image>
+ <alias>${project.artifactId}</alias>
+ <name>${docker-image.namespace}/${docker-image.name.prefix}.${project.artifactId}</name>
+ <registry>${onap.nexus.dockerregistry.daily}</registry>
+ <build>
+ <dockerFileDir>${project.basedir}</dockerFileDir>
+ <tags>
+ <tag>${project.version}-STAGE-${maven.build.timestamp}Z</tag>
+ </tags>
+ </build>
+ </image>
+ </images>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <!-- Import dependency management from Spring Boot -->
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-dependencies</artifactId>
+ <version>${spring.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-configuration-processor</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-validator</artifactId>
+ <version>${hibernate-validator.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.sdc.sdc-distribution-client</groupId>
+ <artifactId>sdc-distribution-client</artifactId>
+ <version>${sdc-distribution-client.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>${jackson-databind.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-yaml</artifactId>
+ <version>${jackson-databind.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.datatype</groupId>
+ <artifactId>jackson-datatype-jsr310</artifactId>
+ <version>${jackson-databind.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>${mockito-core.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.bean-matchers</groupId>
+ <artifactId>bean-matchers</artifactId>
+ <version>${bean-matchers.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <distributionManagement>
+ <repository>
+ <id>ecomp-releases</id>
+ <name>Integration simulators Release Repository</name>
+ <url>${nexusproxy}${releaseNexusPath}</url>
+ </repository>
+ <snapshotRepository>
+ <id>ecomp-snapshots</id>
+ <name>Integration simulators Snapshot Repository</name>
+ <url>${nexusproxy}${snapshotNexusPath}</url>
+ </snapshotRepository>
+ <site>
+ <id>ecomp-site</id>
+ <url>dav:${nexusproxy}${sitePath}</url>
+ </site>
+ </distributionManagement>
+
+</project>
diff --git a/src/main/java/org/onap/ves/openapi/manager/Main.java b/src/main/java/org/onap/ves/openapi/manager/Main.java
new file mode 100644
index 0000000..209c05b
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/Main.java
@@ -0,0 +1,93 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager;
+
+import lombok.extern.log4j.Log4j2;
+import org.onap.sdc.api.results.IDistributionClientResult;
+import org.onap.sdc.http.HttpAsdcClient;
+import org.onap.sdc.http.HttpClientFactory;
+import org.onap.sdc.http.HttpRequestFactory;
+import org.onap.sdc.http.SdcConnectorClient;
+import org.onap.sdc.impl.DistributionClientImpl;
+import org.onap.ves.openapi.manager.config.DistributionClientConfig;
+import org.onap.ves.openapi.manager.service.ArtifactsCollector;
+import org.onap.ves.openapi.manager.service.ClientCallback;
+import org.onap.ves.openapi.manager.service.notification.ArtifactsCollectorStatusSender;
+import org.onap.ves.openapi.manager.service.notification.FinalStatusSender;
+import org.onap.ves.openapi.manager.service.notification.ValidationStatusSender;
+import org.onap.ves.openapi.manager.service.validation.ArtifactsValidator;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+
+import java.util.List;
+
+@Log4j2
+@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
+public class Main {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Main.class, args);
+ }
+
+ /**
+ * Creates bean of SdcConnectorClient
+ * @param clientConfig DistributionClientConfig object with configuration properties
+ * @return SdcConnectorClient
+ */
+ @Bean
+ public SdcConnectorClient getSdcConnectorClient(DistributionClientConfig clientConfig) {
+ HttpRequestFactory requestFactory = new HttpRequestFactory(clientConfig.getUser(), clientConfig.getPassword());
+ HttpClientFactory clientFactory = new HttpClientFactory(clientConfig);
+ return new SdcConnectorClient(clientConfig, new HttpAsdcClient(clientConfig.getAsdcAddress(), clientFactory, requestFactory));
+ }
+
+ /**
+ * Creates bean of DistributionClientImpl
+ * @param clientConfig DistributionClientConfig object with configuration properties
+ * @param validators List of objects implementing ArtifactValidator interface
+ * @param artifactsCollector ArtifactsCollector object which downloads artifacts contents
+ * @return DistributionClientImpl
+ */
+ @Bean
+ public DistributionClientImpl getDistributionClientImpl(DistributionClientConfig clientConfig,
+ List<ArtifactsValidator> validators,
+ ArtifactsCollector artifactsCollector) {
+ DistributionClientImpl client = new DistributionClientImpl();
+ ClientCallback callback = new ClientCallback(validators, artifactsCollector,
+ new ArtifactsCollectorStatusSender(client), new ValidationStatusSender(client),
+ new FinalStatusSender(client));
+
+ log.info(ClientCallback.SEPARATOR);
+ IDistributionClientResult initResult = client.init(clientConfig, callback);
+ log.info(initResult.getDistributionMessageResult());
+ log.info(ClientCallback.SEPARATOR);
+
+ log.info(ClientCallback.SEPARATOR);
+ IDistributionClientResult startResult = client.start();
+ log.info(startResult.getDistributionMessageResult());
+ log.info(ClientCallback.SEPARATOR);
+
+ return client;
+ }
+
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/config/DistributionClientConfig.java b/src/main/java/org/onap/ves/openapi/manager/config/DistributionClientConfig.java
new file mode 100644
index 0000000..188cced
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/config/DistributionClientConfig.java
@@ -0,0 +1,130 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.onap.sdc.api.consumer.IConfiguration;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * DistributionClientConfig - properties required by DistributionClientImpl, values mapped from application.yml
+ */
+@Configuration
+@ConfigurationProperties(prefix = "vesopenapimanager.distribution")
+@Getter
+@Setter
+public class DistributionClientConfig implements IConfiguration {
+
+ public static final String VES_EVENTS_ARTIFACT_TYPE = "VES_EVENTS";
+
+ private String asdcAddress;
+ private String msgBusAddress;
+ private String user;
+ private String password;
+ private Integer pollingInterval;
+ private Integer pollingTimeout;
+ private String consumerGroup;
+ private String environmentName;
+ private String consumerID;
+ private Boolean activateServerTLSAuth;
+ private Boolean isFilterInEmptyResources;
+ private Boolean isUseHttpsWithDmaap;
+
+ @Override
+ public String getAsdcAddress() {
+ return asdcAddress;
+ }
+
+ @Override
+ public List<String> getMsgBusAddress() {
+ return Collections.singletonList(msgBusAddress);
+ }
+
+ @Override
+ public String getUser() {
+ return user;
+ }
+
+ @Override
+ public String getPassword() {
+ return password;
+ }
+
+ @Override
+ public int getPollingInterval() {
+ return pollingInterval;
+ }
+
+ @Override
+ public int getPollingTimeout() {
+ return pollingTimeout;
+ }
+
+ @Override
+ public List<String> getRelevantArtifactTypes() {
+ return Collections.singletonList(VES_EVENTS_ARTIFACT_TYPE);
+ }
+
+ @Override
+ public String getConsumerGroup() {
+ return consumerGroup;
+ }
+
+ @Override
+ public String getEnvironmentName() {
+ return environmentName;
+ }
+
+ @Override
+ public String getConsumerID() {
+ return consumerID;
+ }
+
+ @Override
+ public String getKeyStorePath() {
+ return null;
+ }
+
+ @Override
+ public String getKeyStorePassword() {
+ return null;
+ }
+
+ @Override
+ public boolean activateServerTLSAuth() {
+ return activateServerTLSAuth;
+ }
+
+ @Override
+ public boolean isFilterInEmptyResources() {
+ return isFilterInEmptyResources;
+ }
+
+ @Override
+ public Boolean isUseHttpsWithDmaap() {
+ return isUseHttpsWithDmaap;
+ }
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/config/ValidatorProperties.java b/src/main/java/org/onap/ves/openapi/manager/config/ValidatorProperties.java
new file mode 100644
index 0000000..11beb22
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/config/ValidatorProperties.java
@@ -0,0 +1,39 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * ValidatorProperties - properties required by SchemaReferenceValidator, values mapped from application.yml
+ */
+@Configuration
+@ConfigurationProperties(prefix = "vesopenapimanager.validation")
+@Getter
+@Setter
+public class ValidatorProperties {
+ private String schemaMapPath;
+ private String eventDomainPath;
+ private String eventSchemaReferencePath;
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/exceptions/ArtifactException.java b/src/main/java/org/onap/ves/openapi/manager/exceptions/ArtifactException.java
new file mode 100644
index 0000000..c51face
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/exceptions/ArtifactException.java
@@ -0,0 +1,26 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.exceptions;
+
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+public class ArtifactException extends RuntimeException { }
diff --git a/src/main/java/org/onap/ves/openapi/manager/model/Artifact.java b/src/main/java/org/onap/ves/openapi/manager/model/Artifact.java
new file mode 100644
index 0000000..8cc54ac
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/model/Artifact.java
@@ -0,0 +1,37 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.model;
+
+import lombok.AllArgsConstructor;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import org.onap.sdc.api.notification.IArtifactInfo;
+
+/**
+ * Artifact - model class that contains description and content of artifact
+ */
+@AllArgsConstructor
+@Getter
+@EqualsAndHashCode
+public class Artifact {
+ private final IArtifactInfo description;
+ private final byte[] content;
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/model/ArtifactValidationResult.java b/src/main/java/org/onap/ves/openapi/manager/model/ArtifactValidationResult.java
new file mode 100644
index 0000000..f672bb5
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/model/ArtifactValidationResult.java
@@ -0,0 +1,40 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.model;
+
+import lombok.AllArgsConstructor;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import org.onap.sdc.api.notification.IArtifactInfo;
+import org.onap.ves.openapi.manager.service.validation.ArtifactsValidator;
+
+/**
+ * ArtifactValidationResult - model class for result of artifact validation
+ */
+@AllArgsConstructor
+@Getter
+@EqualsAndHashCode
+public class ArtifactValidationResult {
+ private final IArtifactInfo artifact;
+ private final boolean isValid;
+ private final String message;
+ private final ArtifactsValidator validator;
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/model/DistributionStatusMessage.java b/src/main/java/org/onap/ves/openapi/manager/model/DistributionStatusMessage.java
new file mode 100644
index 0000000..f25e6e0
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/model/DistributionStatusMessage.java
@@ -0,0 +1,63 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.model;
+
+import lombok.AllArgsConstructor;
+import org.onap.sdc.api.consumer.IDistributionStatusMessage;
+import org.onap.sdc.utils.DistributionStatusEnum;
+
+/**
+ * DistributionStatusMessage - model class for operation status sent to SDC
+ */
+@AllArgsConstructor
+public class DistributionStatusMessage implements IDistributionStatusMessage {
+
+ private final String artifactUrl;
+ private final String distributionId;
+ private final String consumerId;
+ private final long timestamp;
+ private final DistributionStatusEnum status;
+
+ @Override
+ public String getArtifactURL() {
+ return artifactUrl;
+ }
+
+ @Override
+ public String getDistributionID() {
+ return distributionId;
+ }
+
+ @Override
+ public String getConsumerID() {
+ return consumerId;
+ }
+
+ @Override
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ @Override
+ public DistributionStatusEnum getStatus() {
+ return status;
+ }
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/model/FinalDistributionStatusMessage.java b/src/main/java/org/onap/ves/openapi/manager/model/FinalDistributionStatusMessage.java
new file mode 100644
index 0000000..de8836d
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/model/FinalDistributionStatusMessage.java
@@ -0,0 +1,59 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.model;
+
+import lombok.AllArgsConstructor;
+import org.onap.sdc.api.consumer.IFinalDistrStatusMessage;
+import org.onap.sdc.utils.DistributionStatusEnum;
+
+
+/**
+ * FinalDistributionStatusMessage - model class for final ves-openapi-manager's validation message sent to SDC
+ */
+@AllArgsConstructor
+public class FinalDistributionStatusMessage implements IFinalDistrStatusMessage {
+
+ private final String distributionId;
+ private final long timestamp;
+ private final DistributionStatusEnum status;
+ private final String consumerId;
+
+ @Override
+ public String getDistributionID() {
+ return distributionId;
+ }
+
+ @Override
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ @Override
+ public DistributionStatusEnum getStatus() {
+ return status;
+ }
+
+ @Override
+ public String getConsumerID() {
+ return consumerId;
+ }
+
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/model/SchemaMap.java b/src/main/java/org/onap/ves/openapi/manager/model/SchemaMap.java
new file mode 100644
index 0000000..b275e7f
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/model/SchemaMap.java
@@ -0,0 +1,48 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * SchemaMap - model class with list of mappings of publicly stored OpenApi schemas to schemas stored locally in VES.
+ */
+@AllArgsConstructor
+@Getter
+public class SchemaMap {
+ private final List<Mapping> mappings;
+
+ /**
+ * Single schemas mapping,
+ * publicURL contains URL to externally located schema,
+ * localURL contains URL located in VES container
+ */
+ @NoArgsConstructor
+ @Getter
+ public static class Mapping {
+ private String publicURL;
+ private String localURL;
+ }
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/service/ArtifactsCollector.java b/src/main/java/org/onap/ves/openapi/manager/service/ArtifactsCollector.java
new file mode 100644
index 0000000..52f1b0e
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/service/ArtifactsCollector.java
@@ -0,0 +1,99 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service;
+
+import lombok.extern.log4j.Log4j2;
+import org.onap.sdc.api.notification.IArtifactInfo;
+import org.onap.sdc.http.SdcConnectorClient;
+import org.onap.sdc.impl.DistributionClientDownloadResultImpl;
+import org.onap.ves.openapi.manager.config.DistributionClientConfig;
+import org.onap.ves.openapi.manager.exceptions.ArtifactException;
+import org.onap.ves.openapi.manager.model.Artifact;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * ArtifactsCollector - Collector of artifact contents from distributed service,
+ * downloads artifacts contents basing on artifacts descriptions
+ */
+@Log4j2
+@Component
+public class ArtifactsCollector {
+
+ private static final String QUOTATION_MARK = "\"";
+ private static final int ARTIFACT_NAME_INDEX_NO_QUOTATION = 0;
+ private static final int ARTIFACT_NAME_INDEX_WITH_QUOTATION = 1;
+ private static final int NAME_WITH_QUOTATION_LENGTH = 2;
+
+ private final SdcConnectorClient sdcConnectorClient;
+
+ /**
+ * Constructor of ArtifactsCollector
+ * @param sdcConnectorClient SdcConnectorClient object
+ */
+ @Autowired
+ public ArtifactsCollector(SdcConnectorClient sdcConnectorClient) {
+ this.sdcConnectorClient = sdcConnectorClient;
+ }
+
+ /**
+ * @param artifacts List of IArtifactInfo objects, which are descriptions of artifacts
+ * @return List of Artifacts, each object contains description and content of artifact
+ */
+ public List<Artifact> pullArtifacts(List<IArtifactInfo> artifacts) {
+ log.info("Downloading artifacts");
+ List<IArtifactInfo> artifactDescriptions = filterVesEventsArtifacts(artifacts);
+ return artifactDescriptions.stream()
+ .map(sdcConnectorClient::downloadArtifact)
+ .map(downloadResult -> mapDownloadResultToArtifactContent(downloadResult, artifactDescriptions))
+ .collect(Collectors.toList());
+ }
+
+ private List<IArtifactInfo> filterVesEventsArtifacts(List<IArtifactInfo> artifacts) {
+ return artifacts.stream()
+ .filter(artifactInfo ->
+ artifactInfo.getArtifactType().equals(DistributionClientConfig.VES_EVENTS_ARTIFACT_TYPE))
+ .collect(Collectors.toList());
+ }
+
+ private Artifact mapDownloadResultToArtifactContent(DistributionClientDownloadResultImpl downloadResult,
+ List<IArtifactInfo> artifactDescriptions) {
+ String artifactName = parseArtifactName(downloadResult);
+ Optional<IArtifactInfo> artifact = findArtifactDescription(artifactDescriptions, artifactName);
+ return artifact.map(artifactInfo ->
+ new Artifact(artifactInfo, downloadResult.getArtifactPayload()))
+ .orElseThrow(ArtifactException::new);
+ }
+
+ private String parseArtifactName(DistributionClientDownloadResultImpl artifact) {
+ String[] name = artifact.getArtifactName().split(QUOTATION_MARK);
+ boolean doesContainQuotationMark = name.length >= NAME_WITH_QUOTATION_LENGTH;
+ return doesContainQuotationMark ? name[ARTIFACT_NAME_INDEX_WITH_QUOTATION] : name[ARTIFACT_NAME_INDEX_NO_QUOTATION];
+ }
+
+ private Optional<IArtifactInfo> findArtifactDescription(List<IArtifactInfo> artifacts, String artifactName) {
+ return artifacts.stream().filter(a -> a.getArtifactName().equals(artifactName)).findFirst();
+ }
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/service/ClientCallback.java b/src/main/java/org/onap/ves/openapi/manager/service/ClientCallback.java
new file mode 100644
index 0000000..720ab8c
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/service/ClientCallback.java
@@ -0,0 +1,143 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service;
+
+import lombok.extern.log4j.Log4j2;
+import org.onap.sdc.api.consumer.INotificationCallback;
+import org.onap.sdc.api.notification.IArtifactInfo;
+import org.onap.sdc.api.notification.INotificationData;
+import org.onap.sdc.api.notification.IResourceInstance;
+import org.onap.ves.openapi.manager.model.Artifact;
+import org.onap.ves.openapi.manager.model.ArtifactValidationResult;
+import org.onap.ves.openapi.manager.service.notification.ArtifactsCollectorStatusSender;
+import org.onap.ves.openapi.manager.service.notification.FinalStatusSender;
+import org.onap.ves.openapi.manager.service.notification.ValidationStatusSender;
+import org.onap.ves.openapi.manager.service.validation.ArtifactsValidator;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Log4j2
+public class ClientCallback implements INotificationCallback {
+
+ public static final String SEPARATOR = "===================================";
+ private final List<ArtifactsValidator> validators;
+ private final ValidationStatusSender validationStatusSender;
+ private final ArtifactsCollectorStatusSender artifactsCollectorStatusSender;
+ private final ArtifactsCollector artifactsCollector;
+ private final FinalStatusSender finalStatusSender;
+
+ /**
+ * Constructor of ClientCallback
+ * @param validators List of objects implementing ArtifactValidator interface
+ * @param artifactsCollector ArtifactsCollector object which downloads artifacts contents
+ * @param artifactsCollectorStatusSender ArtifactsCollectorStatusSender which sends download results back to SDC
+ * @param validationStatusSender ValidationStatusSender which sends validation results to SDC
+ * @param finalStatusSender FinalStatusSender which sends final status of VES OpenApi Manager workflow
+ */
+ public ClientCallback(List<ArtifactsValidator> validators, ArtifactsCollector artifactsCollector,
+ ArtifactsCollectorStatusSender artifactsCollectorStatusSender,
+ ValidationStatusSender validationStatusSender, FinalStatusSender finalStatusSender) {
+ this.validators = validators;
+ this.validationStatusSender = validationStatusSender;
+ this.artifactsCollectorStatusSender = artifactsCollectorStatusSender;
+ this.artifactsCollector = artifactsCollector;
+ this.finalStatusSender = finalStatusSender;
+ }
+
+ /**
+ * Callback method of distribution listener. Each time a service distribution takes place it's executed.
+ * @param service Distributed service information.
+ */
+ @Override
+ public void activateCallback(INotificationData service) {
+ logServiceInfo(service);
+ String distributionID = service.getDistributionID();
+
+ List<Artifact> artifacts = downloadArtifacts(service);
+ List<ArtifactValidationResult> validationResults = validate(distributionID, artifacts);
+ sendFinalStatus(distributionID, validationResults);
+ }
+
+ private void logServiceInfo(INotificationData service) {
+ log.info(SEPARATOR);
+ log.info("Distributed service information");
+ log.info("Service UUID: {}", service.getServiceUUID());
+ log.info("Service name: {}", service.getServiceName());
+ List<IResourceInstance> resources = service.getResources();
+ log.info("Service resources:");
+ resources.forEach(resource -> {
+ log.info(" - Resource: {}", resource.getResourceName());
+ log.info(" Artifacts:");
+ resource.getArtifacts().forEach(artifact -> log.info(" - Name: {}", artifact.getArtifactName()));
+ });
+ log.info(SEPARATOR);
+ }
+
+ private List<Artifact> downloadArtifacts(INotificationData service) {
+ List<IArtifactInfo> artifactInfos = getArtifactInfos(service);
+ List<Artifact> artifacts = artifactsCollector.pullArtifacts(artifactInfos);
+ sendDownloadStatuses(service, artifactInfos, artifacts);
+ return artifacts;
+ }
+
+ private void sendDownloadStatuses(INotificationData service, List<IArtifactInfo> artifactInfos, List<Artifact> artifacts) {
+ Map<Boolean, List<Artifact>> artifactsDownloadResults = artifacts.stream()
+ .collect(Collectors.partitioningBy(this::isContentDownloaded));
+ artifactsDownloadResults.get(Boolean.TRUE).forEach(artifact ->
+ artifactsCollectorStatusSender.sendDownloadOk(service.getDistributionID(), artifactInfos));
+ artifactsDownloadResults.get(Boolean.FALSE).forEach(artifact ->
+ artifactsCollectorStatusSender.sendDownloadError(service.getDistributionID(), artifactInfos));
+ }
+
+ private boolean isContentDownloaded(Artifact artifact) {
+ return artifact.getContent() != null && artifact.getContent().length > 0;
+ }
+
+ private List<IArtifactInfo> getArtifactInfos(INotificationData service) {
+ return service.getResources().stream()
+ .map(IResourceInstance::getArtifacts)
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList());
+ }
+
+ private List<ArtifactValidationResult> validate(String distributionID, List<Artifact> artifacts) {
+ return validators.stream()
+ .map(validator -> {
+ List<ArtifactValidationResult> validationResults = validator.validate(artifacts);
+ validationStatusSender.send(distributionID, validationResults);
+ return validationResults;
+ })
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList());
+ }
+
+ private void sendFinalStatus(String distributionID, List<ArtifactValidationResult> validationResults) {
+ boolean areAllArtifactsValid = validationResults.stream().allMatch(ArtifactValidationResult::isValid);
+ if (areAllArtifactsValid) {
+ finalStatusSender.sendFinalStatusOk(distributionID);
+ } else {
+ finalStatusSender.sendFinalStatusError(distributionID);
+ }
+ }
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/service/notification/ArtifactsCollectorStatusSender.java b/src/main/java/org/onap/ves/openapi/manager/service/notification/ArtifactsCollectorStatusSender.java
new file mode 100644
index 0000000..0829855
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/service/notification/ArtifactsCollectorStatusSender.java
@@ -0,0 +1,93 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.notification;
+
+
+import lombok.extern.log4j.Log4j2;
+import org.onap.sdc.api.notification.IArtifactInfo;
+import org.onap.sdc.api.results.IDistributionClientResult;
+import org.onap.sdc.impl.DistributionClientImpl;
+import org.onap.sdc.utils.DistributionStatusEnum;
+import org.onap.ves.openapi.manager.model.DistributionStatusMessage;
+
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * ArtifactsCollectorStatusSender - sender of DistributionStatusMessage with artifacts download status to SDC
+ */
+@Log4j2
+public class ArtifactsCollectorStatusSender {
+
+ private static final String DOWNLOAD_ERROR_MESSAGE = "Couldn't download artifact";
+ private final DistributionClientImpl distributionClient;
+
+ /**
+ * Constructor of ArtifactsCollectorStatusSender
+ * @param distributionClient DistributionClientImpl object
+ */
+ public ArtifactsCollectorStatusSender(DistributionClientImpl distributionClient) {
+ this.distributionClient = distributionClient;
+ }
+
+ /**
+ * Sends DOWNLOAD_OK status to SDC
+ * @param distributionId Service distribution ID
+ * @param downloadedArtifacts Artifacts which are successfully downloaded
+ * @return List of IDistributionClientResult, results of sending status
+ */
+ public List<IDistributionClientResult> sendDownloadOk(String distributionId, List<IArtifactInfo> downloadedArtifacts) {
+ return downloadedArtifacts.stream()
+ .map(artifact -> {
+ DistributionStatusMessage distributionMessage = getDownloadMessage(distributionId,
+ artifact.getArtifactURL(), DistributionStatusEnum.DOWNLOAD_OK);
+ return distributionClient.sendDownloadStatus(distributionMessage);
+ })
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Sends DOWNLOAD_ERROR status to SDC
+ * @param distributionId Service distribution ID
+ * @param downloadedArtifacts Artifacts which could not be downloaded
+ * @return List of IDistributionClientResult, results of sending status
+ */
+ public List<IDistributionClientResult> sendDownloadError(String distributionId, List<IArtifactInfo> downloadedArtifacts) {
+ return downloadedArtifacts.stream()
+ .map(artifact -> {
+ DistributionStatusMessage distributionMessage = getDownloadMessage(distributionId,
+ artifact.getArtifactURL(), DistributionStatusEnum.DOWNLOAD_ERROR);
+ return distributionClient.sendDownloadStatus(distributionMessage, DOWNLOAD_ERROR_MESSAGE);
+ })
+ .collect(Collectors.toList());
+ }
+
+ private DistributionStatusMessage getDownloadMessage(String distributionId, String artifactURL, DistributionStatusEnum downloadStatus) {
+ return new DistributionStatusMessage(
+ artifactURL,
+ distributionId,
+ distributionClient.getConfiguration().getConsumerID(),
+ LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli(),
+ downloadStatus);
+ }
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/service/notification/FinalStatusSender.java b/src/main/java/org/onap/ves/openapi/manager/service/notification/FinalStatusSender.java
new file mode 100644
index 0000000..e21ab70
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/service/notification/FinalStatusSender.java
@@ -0,0 +1,85 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.notification;
+
+import lombok.extern.log4j.Log4j2;
+import org.onap.sdc.api.results.IDistributionClientResult;
+import org.onap.sdc.impl.DistributionClientImpl;
+import org.onap.sdc.utils.DistributionStatusEnum;
+import org.onap.ves.openapi.manager.model.FinalDistributionStatusMessage;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+
+/**
+ * FinalStatusSender - sender of FinalDistributionStatusMessage with final status to SDC
+ */
+@Log4j2
+@Service
+public class FinalStatusSender {
+
+ private static final String INVALID_ARTIFACTS_MESSAGE = "At least one VES_EVENT artifact is invalid";
+ private final DistributionClientImpl distributionClient;
+
+ /**
+ * Constructor of FinalStatusSender
+ * @param distributionClient DistributionClientImpl object
+ */
+ @Autowired
+ public FinalStatusSender(DistributionClientImpl distributionClient) {
+ this.distributionClient = distributionClient;
+ }
+
+ /**
+ * Sends final message COMPONENT_DONE_OK to SDC
+ * @param distributionId Service distribution ID
+ * @return IDistributionClientResult, result of sending status
+ */
+ public IDistributionClientResult sendFinalStatusOk(String distributionId) {
+ DistributionStatusEnum okStatus = DistributionStatusEnum.COMPONENT_DONE_OK;
+ FinalDistributionStatusMessage message = getMessage(distributionId, okStatus);
+ log.info("All VES_EVENT artifacts are valid, sending final status {}", okStatus.name());
+ return distributionClient.sendFinalDistrStatus(message);
+ }
+
+ /**
+ * Sends final message COMPONENT_DONE_ERROR to SDC
+ * @param distributionId Service distribution ID
+ * @return IDistributionClientResult, result of sending status
+ */
+ public IDistributionClientResult sendFinalStatusError(String distributionId) {
+ DistributionStatusEnum errorStatus = DistributionStatusEnum.COMPONENT_DONE_ERROR;
+ FinalDistributionStatusMessage message = getMessage(distributionId, errorStatus);
+ log.info("At least one VES_EVENT artifact is invalid, sending final status {}", errorStatus.name());
+ return distributionClient.sendFinalDistrStatus(message, INVALID_ARTIFACTS_MESSAGE);
+ }
+
+ private FinalDistributionStatusMessage getMessage(String distributionId, DistributionStatusEnum distributionStatus) {
+ return new FinalDistributionStatusMessage(
+ distributionId,
+ LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli(),
+ distributionStatus,
+ distributionClient.getConfiguration().getConsumerID());
+ }
+
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/service/notification/ValidationStatusSender.java b/src/main/java/org/onap/ves/openapi/manager/service/notification/ValidationStatusSender.java
new file mode 100644
index 0000000..ae11791
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/service/notification/ValidationStatusSender.java
@@ -0,0 +1,89 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.notification;
+
+import lombok.extern.log4j.Log4j2;
+import org.onap.sdc.api.results.IDistributionClientResult;
+import org.onap.sdc.impl.DistributionClientImpl;
+import org.onap.sdc.utils.DistributionStatusEnum;
+import org.onap.ves.openapi.manager.model.ArtifactValidationResult;
+import org.onap.ves.openapi.manager.model.DistributionStatusMessage;
+
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * ValidationStatusSender - sender of DistributionStatusMessage with validation status to SDC
+ */
+@Log4j2
+public class ValidationStatusSender {
+
+ private final DistributionClientImpl distributionClient;
+
+ /**
+ * Constructor of ValidationStatusSender
+ * @param distributionClient DistributionClientImpl object
+ */
+ public ValidationStatusSender(DistributionClientImpl distributionClient) {
+ this.distributionClient = distributionClient;
+ }
+
+ /**
+ * Sends validation result status to SDC
+ * @param distributionId Service distribution ID
+ * @param validationResults Validation results
+ * @return List of IDistributionClientResult, results of sending status
+ */
+ public List<IDistributionClientResult> send(String distributionId, List<ArtifactValidationResult> validationResults) {
+ return validationResults.stream()
+ .map(validationResult -> sendValidationResult(distributionId, validationResult))
+ .collect(Collectors.toList());
+ }
+
+ private IDistributionClientResult sendValidationResult(String distributionId, ArtifactValidationResult validationResult) {
+ DistributionStatusMessage distributionMessage = getDistributionMessage(distributionId, validationResult);
+ String artifactName = validationResult.getArtifact().getArtifactName();
+
+ if (validationResult.isValid()) {
+ log.warn("Artifact {} is valid", artifactName);
+ return distributionClient.sendDeploymentStatus(distributionMessage);
+ } else {
+ String message = validationResult.getMessage();
+ log.warn("Artifact {} is invalid", artifactName);
+ log.warn("Validation message: {}", message);
+ return distributionClient.sendDeploymentStatus(distributionMessage, message);
+ }
+ }
+
+ private DistributionStatusMessage getDistributionMessage(String distributionId, ArtifactValidationResult validationResult) {
+ String artifactURL = validationResult.getArtifact().getArtifactURL();
+ DistributionStatusEnum status = getErrorStatus(validationResult);
+ return new DistributionStatusMessage(artifactURL, distributionId,
+ distributionClient.getConfiguration().getConsumerID(),
+ LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli(), status);
+ }
+
+ private DistributionStatusEnum getErrorStatus(ArtifactValidationResult validationResult) {
+ return validationResult.isValid() ? DistributionStatusEnum.DEPLOY_OK : DistributionStatusEnum.DEPLOY_ERROR;
+ }
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/service/serialization/SchemaMapDeserializer.java b/src/main/java/org/onap/ves/openapi/manager/service/serialization/SchemaMapDeserializer.java
new file mode 100644
index 0000000..8ea434e
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/service/serialization/SchemaMapDeserializer.java
@@ -0,0 +1,71 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.serialization;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.log4j.Log4j2;
+import org.onap.ves.openapi.manager.model.SchemaMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * SchemaMapDeserializer - Deserializer of JSON file contents to SchemaMap objects
+ */
+@Log4j2
+@Service
+public class SchemaMapDeserializer {
+
+ private static final String COULD_NOT_READ_SCHEMA_MAP_MESSAGE = "Couldn't read schema map from path: ";
+ private final ObjectMapper objectMapper;
+
+ /**
+ * Constructor of SchemaMapDeserializer
+ * @param objectMapper ObjectMapper for YAML parsing
+ */
+ @Autowired
+ public SchemaMapDeserializer(ObjectMapper objectMapper) {
+ this.objectMapper = objectMapper;
+ }
+
+ /**
+ * Deserializes file content to SchemaMap object
+ * @param schemaMapPath Path to file containing JSON formatted SchemaMap
+ * @return SchemaMap
+ */
+ public SchemaMap getSchemaMapFromFile(String schemaMapPath) {
+ SchemaMap schemaMap;
+ try {
+ File file = new File(schemaMapPath);
+ List<SchemaMap.Mapping> mappings = Arrays.asList(objectMapper.readValue(file, SchemaMap.Mapping[].class));
+ schemaMap = new SchemaMap(mappings);
+ } catch (IOException e) {
+ schemaMap = new SchemaMap(Collections.emptyList());
+ log.error(COULD_NOT_READ_SCHEMA_MAP_MESSAGE + schemaMapPath, e);
+ }
+ return schemaMap;
+ }
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/service/serialization/VesEventsArtifactDeserializer.java b/src/main/java/org/onap/ves/openapi/manager/service/serialization/VesEventsArtifactDeserializer.java
new file mode 100644
index 0000000..4bd6761
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/service/serialization/VesEventsArtifactDeserializer.java
@@ -0,0 +1,69 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.serialization;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+import com.fasterxml.jackson.dataformat.yaml.YAMLParser;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * VesEventsArtifactDeserializer - Deserializer of byte array of MultiDocument YAML to ObjectNodes
+ */
+@Log4j2
+@Service
+public class VesEventsArtifactDeserializer {
+
+ private static final String COULD_NOT_READ_ARTIFACT_CONTENT_MESSAGE = "Couldn't read artifact content";
+ private final ObjectMapper objectMapper;
+
+ /**
+ * Constructor of VesEventsArtifactDeserializer
+ * @param objectMapper ObjectMapper for YAML parsing
+ */
+ @Autowired
+ public VesEventsArtifactDeserializer(ObjectMapper objectMapper) {
+ this.objectMapper = objectMapper;
+ }
+
+ /**
+ * Deserializes MultiDocument YAML given as byte array
+ * @param data MultiDocument YAML as byte array
+ * @return List of ObjectNodes, each Document is separate ObjectNode
+ */
+ public List<ObjectNode> deserializeMultiDocumentYaml(byte[] data) {
+ List<ObjectNode> events = Collections.emptyList();
+ try {
+ YAMLParser yamlParser = new YAMLFactory().createParser(data);
+ events = objectMapper.readValues(yamlParser, ObjectNode.class).readAll();
+ } catch (IOException e) {
+ log.error(COULD_NOT_READ_ARTIFACT_CONTENT_MESSAGE, e);
+ }
+ return events;
+ }
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/service/validation/ArtifactsValidator.java b/src/main/java/org/onap/ves/openapi/manager/service/validation/ArtifactsValidator.java
new file mode 100644
index 0000000..5963c6b
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/service/validation/ArtifactsValidator.java
@@ -0,0 +1,35 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.validation;
+
+import org.onap.ves.openapi.manager.model.Artifact;
+import org.onap.ves.openapi.manager.model.ArtifactValidationResult;
+
+import java.util.List;
+
+public interface ArtifactsValidator {
+ /**
+ * Validates given VES_EVENT type artifacts
+ * @param artifacts List of artifacts: descriptions and contents
+ * @return List of ArtifactValidationResult, validation results
+ */
+ List<ArtifactValidationResult> validate(List<Artifact> artifacts);
+}
diff --git a/src/main/java/org/onap/ves/openapi/manager/service/validation/SchemaReferenceValidator.java b/src/main/java/org/onap/ves/openapi/manager/service/validation/SchemaReferenceValidator.java
new file mode 100644
index 0000000..dd97b09
--- /dev/null
+++ b/src/main/java/org/onap/ves/openapi/manager/service/validation/SchemaReferenceValidator.java
@@ -0,0 +1,158 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.validation;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import lombok.extern.log4j.Log4j2;
+import org.onap.sdc.api.notification.IArtifactInfo;
+import org.onap.ves.openapi.manager.config.ValidatorProperties;
+import org.onap.ves.openapi.manager.model.Artifact;
+import org.onap.ves.openapi.manager.model.ArtifactValidationResult;
+import org.onap.ves.openapi.manager.model.SchemaMap;
+import org.onap.ves.openapi.manager.service.serialization.SchemaMapDeserializer;
+import org.onap.ves.openapi.manager.service.serialization.VesEventsArtifactDeserializer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+/**
+ * SchemaReferenceValidator - validator of schemaReference field in VES_EVENTS artifacts
+ */
+@Log4j2
+@Service
+public class SchemaReferenceValidator implements ArtifactsValidator {
+
+ private static final String HASH_KEY = "#";
+ private static final String NEW_LINE = "\n";
+ static final String STND_DEFINED_DOMAIN = "stndDefined";
+ static final String SCHEMA_REFERENCE_ERROR_MESSAGE = "Schema reference is not present in VES schema map.";
+
+ private final VesEventsArtifactDeserializer vesEventsArtifactDeserializer;
+ private final SchemaMapDeserializer schemaMapDeserializer;
+ private final ValidatorProperties validatorProperties;
+
+ /**
+ * Constructor of SchemaReferenceValidator
+ * @param vesEventsArtifactDeserializer Deserializer of VES_EVENT type artifact
+ * @param schemaMapDeserializer Deserializer of Schema Map
+ * @param validatorProperties Properties required by validator
+ */
+ @Autowired
+ public SchemaReferenceValidator(VesEventsArtifactDeserializer vesEventsArtifactDeserializer,
+ SchemaMapDeserializer schemaMapDeserializer,
+ ValidatorProperties validatorProperties) {
+ this.vesEventsArtifactDeserializer = vesEventsArtifactDeserializer;
+ this.schemaMapDeserializer = schemaMapDeserializer;
+ this.validatorProperties = validatorProperties;
+ }
+
+ /**
+ * Validates given VES_EVENT type artifacts
+ * @param artifacts List of artifacts: descriptions and contents
+ * @return List of ArtifactValidationResult, validation results
+ */
+ @Override
+ public List<ArtifactValidationResult> validate(List<Artifact> artifacts) {
+ return artifacts.stream()
+ .map(this::getArtifactValidationResult)
+ .collect(Collectors.toList());
+ }
+
+ private ArtifactValidationResult getArtifactValidationResult(Artifact artifact) {
+ List<JsonNode> stndDefinedEvents = getStndDefinedEvents(artifact.getContent());
+ List<String> publicUrls = getPublicUrls();
+
+ Set<String> invalidSchemaReferences = stndDefinedEvents.stream()
+ .map(event -> getInvalidReferences(event, publicUrls))
+ .flatMap(Collection::stream)
+ .collect(Collectors.toSet());
+
+ return getValidationResult(artifact.getDescription(), invalidSchemaReferences);
+ }
+
+ private ArtifactValidationResult getValidationResult(IArtifactInfo artifact, Set<String> invalidReferences) {
+ boolean isValid = invalidReferences.isEmpty();
+ String message = getMessage(invalidReferences);
+ return new ArtifactValidationResult(artifact, isValid, message, this);
+ }
+
+ private String getMessage(Set<String> invalidSchemaReferences) {
+ final String emptyMessage = "";
+ return invalidSchemaReferences.isEmpty() ? emptyMessage : generateMessage(invalidSchemaReferences);
+ }
+
+ private String generateMessage(Set<String> invalidSchemaReferences) {
+ return SCHEMA_REFERENCE_ERROR_MESSAGE + ":" + NEW_LINE + String.join(NEW_LINE, invalidSchemaReferences);
+ }
+
+ private List<JsonNode> getStndDefinedEvents(byte[] artifactData) {
+ List<ObjectNode> events = vesEventsArtifactDeserializer.deserializeMultiDocumentYaml(artifactData);
+ return events.stream()
+ .filter(this::isStndDefinedEvent)
+ .collect(Collectors.toList());
+ }
+
+ private boolean isStndDefinedEvent(ObjectNode event) {
+ String actualDomain = event.at(validatorProperties.getEventDomainPath()).asText();
+ return actualDomain.equals(STND_DEFINED_DOMAIN);
+ }
+
+ private List<String> getPublicUrls() {
+ String schemaMapPath = validatorProperties.getSchemaMapPath();
+ List<SchemaMap.Mapping> mappings = schemaMapDeserializer.getSchemaMapFromFile(schemaMapPath).getMappings();
+ return mappings.stream()
+ .map(SchemaMap.Mapping::getPublicURL)
+ .collect(Collectors.toList());
+ }
+
+ private List<String> getInvalidReferences(JsonNode event, List<String> publicUrls) {
+ String schemaReferencePath = validatorProperties.getEventSchemaReferencePath();
+ JsonNode schemaReference = event.at(schemaReferencePath);
+ Stream<JsonNode> schemaReferenceStream = Stream.empty();
+
+ if (schemaReference.isArray()) {
+ schemaReferenceStream = StreamSupport.stream(schemaReference.spliterator(), false);
+ } else if (schemaReference.isValueNode()) {
+ schemaReferenceStream = Stream.of(schemaReference);
+ }
+
+ return getInvalidSchemaReferences(schemaReferenceStream, publicUrls);
+ }
+
+ private List<String> getInvalidSchemaReferences(Stream<JsonNode> schemaReferencesStream, List<String> publicUrls) {
+ return schemaReferencesStream
+ .map(this::fetchUrlFromSchemaReference)
+ .filter(reference -> !publicUrls.contains(reference))
+ .collect(Collectors.toList());
+ }
+
+ private String fetchUrlFromSchemaReference(JsonNode schemaReference) {
+ final int urlPartIndex = 0;
+ return schemaReference.asText().split(HASH_KEY)[urlPartIndex];
+ }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 0000000..f179544
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,20 @@
+vesopenapimanager:
+ validation:
+ schemaMapPath: ${SCHEMA_MAP_PATH:./src/main/resources/schema-map.json}
+ eventDomainPath: /event/structure/commonEventHeader/structure/domain/value
+ eventSchemaReferencePath: /event/structure/stndDefinedFields/structure/schemaReference/value
+ distribution:
+ asdcAddress: ${ASDC_ADDRESS:sdc-be.onap:30204}
+ msgBusAddress: message-router.onap
+ user: dcae
+ password: Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U
+ pollingInterval: 20
+ pollingTimeout: 20
+ consumerGroup: ves-openapi-manager
+ environmentName: AUTO
+ consumerID: ves-openapi-manager
+ activateServerTLSAuth: false
+ isFilterInEmptyResources: false
+ isUseHttpsWithDmaap: false
+
+
diff --git a/src/main/resources/schema-map.json b/src/main/resources/schema-map.json
new file mode 100644
index 0000000..359014c
--- /dev/null
+++ b/src/main/resources/schema-map.json
@@ -0,0 +1,58 @@
+[
+ {
+ "publicURL": "https://forge.3gpp.org/rep/sa5/MnS/blob/SA88-Rel16/OpenAPI/faultMnS.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/5gcNrm.yaml"
+ },
+ {
+ "publicURL": "https://forge.3gpp.org/invalid.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerDataFileReportMnS.yaml"
+ },
+ {
+ "publicURL": "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerMeasJobCtlMnS.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerMeasJobCtlMnS.yaml"
+ },
+ {
+ "publicURL": "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerThresMonMnS.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerThresMonMnS.yaml"
+ },
+ {
+ "publicURL": "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerfDataStreamingMnS.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerfDataStreamingMnS.yaml"
+ },
+ {
+ "publicURL": "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/comDefs.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/comDefs.yaml"
+ },
+ {
+ "publicURL": "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/coslaNrm.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/coslaNrm.yaml"
+ },
+ {
+ "publicURL": "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/faultMnS.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/faultMnS.yaml"
+ },
+ {
+ "publicURL": "https://forge.3gpp.org/rep/sa5/MnS/blob/SA88-Rel16/OpenAPI/faultMnS.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/genericNrm.yaml"
+ },
+ {
+ "publicURL": "https://forge.3gpp.org/faultMnS_dcae.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/heartbeatNtf.yaml"
+ },
+ {
+ "publicURL": "https://forge.3gpp.org/faultMnS.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/nrNrm.yaml"
+ },
+ {
+ "publicURL": "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/provMnS.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/provMnS.yaml"
+ },
+ {
+ "publicURL": "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/sliceNrm.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/sliceNrm.yaml"
+ },
+ {
+ "publicURL": "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/streamingDataMnS.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/streamingDataMnS.yaml"
+ }
+] \ No newline at end of file
diff --git a/src/test/java/org/onap/ves/openapi/manager/config/DistributionClientConfigTest.java b/src/test/java/org/onap/ves/openapi/manager/config/DistributionClientConfigTest.java
new file mode 100644
index 0000000..9118f82
--- /dev/null
+++ b/src/test/java/org/onap/ves/openapi/manager/config/DistributionClientConfigTest.java
@@ -0,0 +1,89 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.config;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.context.properties.bind.BindResult;
+import org.springframework.boot.context.properties.bind.Binder;
+import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
+import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class DistributionClientConfigTest {
+
+ @Test
+ void shouldCreateDistributionClientConfig() {
+ //given
+ String asdcAddress = "sdc-be.onap:8443";
+ String msgBusAddress = "message-router.onap";
+ String user = "dcae";
+ String password = "Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U";
+ Integer pollingInterval = 20;
+ Integer pollingTimeout = 20;
+ String consumerGroup = "ves-openapi-manager";
+ String environmentName = "AUTO";
+ String consumerID = "ves-openapi-manager";
+ Map<String, Object> properties = new HashMap<>();
+ properties.put("vesopenapimanager.distribution.asdcAddress", asdcAddress);
+ properties.put("vesopenapimanager.distribution.msgBusAddress", msgBusAddress);
+ properties.put("vesopenapimanager.distribution.user", user);
+ properties.put("vesopenapimanager.distribution.password", password);
+ properties.put("vesopenapimanager.distribution.pollingInterval", pollingInterval);
+ properties.put("vesopenapimanager.distribution.pollingTimeout", pollingTimeout);
+ properties.put("vesopenapimanager.distribution.consumerGroup", consumerGroup);
+ properties.put("vesopenapimanager.distribution.environmentName", environmentName);
+ properties.put("vesopenapimanager.distribution.consumerID", consumerID);
+ properties.put("vesopenapimanager.distribution.activateServerTLSAuth", false);
+ properties.put("vesopenapimanager.distribution.isFilterInEmptyResources", false);
+ properties.put("vesopenapimanager.distribution.isUseHttpsWithDmaap", false);
+ ConfigurationPropertySource source = new MapConfigurationPropertySource(properties);
+ Binder binder = new Binder(source);
+
+ //when
+ BindResult<DistributionClientConfig> result = binder.bind("vesopenapimanager.distribution", DistributionClientConfig.class);
+
+ //then
+ assertThat(result.isBound()).isTrue();
+ DistributionClientConfig config = result.get();
+ assertThat(config.getAsdcAddress()).isEqualTo(asdcAddress);
+ assertThat(config.getMsgBusAddress()).isEqualTo(List.of(msgBusAddress));
+ assertThat(config.getUser()).isEqualTo(user);
+ assertThat(config.getPassword()).isEqualTo(password);
+ assertThat(config.getPollingInterval()).isEqualTo(pollingInterval);
+ assertThat(config.getPollingTimeout()).isEqualTo(pollingTimeout);
+ assertThat(config.getRelevantArtifactTypes()).isEqualTo(Collections.singletonList("VES_EVENTS"));
+ assertThat(config.getConsumerGroup()).isEqualTo(consumerGroup);
+ assertThat(config.getEnvironmentName()).isEqualTo(environmentName);
+ assertThat(config.getConsumerID()).isEqualTo(consumerID);
+ assertThat(config.getKeyStorePath()).isNull();
+ assertThat(config.getKeyStorePassword()).isNull();
+ assertThat(config.activateServerTLSAuth()).isFalse();
+ assertThat(config.isFilterInEmptyResources()).isFalse();
+ assertThat(config.activateServerTLSAuth()).isFalse();
+ assertThat(config.isUseHttpsWithDmaap()).isFalse();
+ }
+}
diff --git a/src/test/java/org/onap/ves/openapi/manager/config/ValidatorPropertiesTest.java b/src/test/java/org/onap/ves/openapi/manager/config/ValidatorPropertiesTest.java
new file mode 100644
index 0000000..57b3725
--- /dev/null
+++ b/src/test/java/org/onap/ves/openapi/manager/config/ValidatorPropertiesTest.java
@@ -0,0 +1,60 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.config;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.context.properties.bind.BindResult;
+import org.springframework.boot.context.properties.bind.Binder;
+import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
+import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ValidatorPropertiesTest {
+
+ @Test
+ void shouldCreateDistributionClientConfig() {
+ //given
+ String schemaMapPath = "schema-map.json";
+ String eventDomainPath = "/event/structure/commonEventHeader/structure/domain/value";
+ String eventSchemaReferencePath = "/event/structure/stndDefinedFields/structure/schemaReference/value";
+
+ Map<String, Object> properties = new HashMap<>();
+ properties.put("vesopenapimanager.validation.schemaMapPath", schemaMapPath);
+ properties.put("vesopenapimanager.validation.eventDomainPath", eventDomainPath);
+ properties.put("vesopenapimanager.validation.eventSchemaReferencePath", eventSchemaReferencePath);
+
+ ConfigurationPropertySource source = new MapConfigurationPropertySource(properties);
+ Binder binder = new Binder(source);
+
+ //when
+ BindResult<ValidatorProperties> result = binder.bind("vesopenapimanager.validation", ValidatorProperties.class);
+
+ //then
+ assertThat(result.isBound()).isTrue();
+ ValidatorProperties config = result.get();
+ assertThat(config.getSchemaMapPath()).isEqualTo(schemaMapPath);
+ assertThat(config.getEventDomainPath()).isEqualTo(eventDomainPath);
+ assertThat(config.getEventSchemaReferencePath()).isEqualTo(eventSchemaReferencePath);
+ }
+}
diff --git a/src/test/java/org/onap/ves/openapi/manager/model/DistributionStatusMessageTest.java b/src/test/java/org/onap/ves/openapi/manager/model/DistributionStatusMessageTest.java
new file mode 100644
index 0000000..e84b919
--- /dev/null
+++ b/src/test/java/org/onap/ves/openapi/manager/model/DistributionStatusMessageTest.java
@@ -0,0 +1,56 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.model;
+
+import org.junit.jupiter.api.Test;
+import org.onap.sdc.utils.DistributionStatusEnum;
+
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+public class DistributionStatusMessageTest {
+ @Test
+ void shouldCreateDistributionStatusMessage() {
+ //given
+ long timestamp = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli();
+ String consumerId = "ves-consumer";
+ String artifactUrl = "http://artifact-url:1234/test";
+ String distributionId = "distribution-id";
+
+ //when
+ DistributionStatusMessage distributionStatusMessage = new DistributionStatusMessage(
+ artifactUrl,
+ distributionId,
+ consumerId,
+ timestamp,
+ DistributionStatusEnum.DOWNLOAD_OK);
+
+ //then
+ assertThat(distributionStatusMessage.getArtifactURL()).isEqualTo(artifactUrl);
+ assertThat(distributionStatusMessage.getDistributionID()).isEqualTo(distributionId);
+ assertThat(distributionStatusMessage.getConsumerID()).isEqualTo(consumerId);
+ assertThat(distributionStatusMessage.getTimestamp()).isEqualTo(timestamp);
+ assertThat(distributionStatusMessage.getStatus()).isEqualTo(DistributionStatusEnum.DOWNLOAD_OK);
+ }
+}
diff --git a/src/test/java/org/onap/ves/openapi/manager/service/ServiceFunctionalTest.java b/src/test/java/org/onap/ves/openapi/manager/service/ServiceFunctionalTest.java
new file mode 100644
index 0000000..a3beb4e
--- /dev/null
+++ b/src/test/java/org/onap/ves/openapi/manager/service/ServiceFunctionalTest.java
@@ -0,0 +1,94 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Test;
+import org.onap.sdc.api.notification.INotificationData;
+import org.onap.sdc.http.SdcConnectorClient;
+import org.onap.sdc.impl.DistributionClientDownloadResultImpl;
+import org.onap.sdc.impl.DistributionClientImpl;
+import org.onap.sdc.utils.DistributionActionResultEnum;
+import org.onap.ves.openapi.manager.config.DistributionClientConfig;
+import org.onap.ves.openapi.manager.config.ValidatorProperties;
+import org.onap.ves.openapi.manager.service.notification.ArtifactsCollectorStatusSender;
+import org.onap.ves.openapi.manager.service.notification.FinalStatusSender;
+import org.onap.ves.openapi.manager.service.notification.ValidationStatusSender;
+import org.onap.ves.openapi.manager.service.serialization.SchemaMapDeserializer;
+import org.onap.ves.openapi.manager.service.serialization.VesEventsArtifactDeserializer;
+import org.onap.ves.openapi.manager.service.testModel.Service;
+import org.onap.ves.openapi.manager.service.validation.ArtifactsValidator;
+import org.onap.ves.openapi.manager.service.validation.SchemaReferenceValidator;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class ServiceFunctionalTest {
+
+ private final DistributionClientImpl distributionClient = mock(DistributionClientImpl.class);
+ private final SdcConnectorClient sdcConnectorClient = mock(SdcConnectorClient.class);
+ private final DistributionClientConfig config = mock(DistributionClientConfig.class);
+ private final ValidatorProperties validatorProperties = mock(ValidatorProperties.class);
+
+ private final ObjectMapper objectMapper = new ObjectMapper();
+ private final VesEventsArtifactDeserializer vesEventsArtifactDeserializer = new VesEventsArtifactDeserializer(objectMapper);
+ private final SchemaMapDeserializer schemaMapDeserializer = new SchemaMapDeserializer(objectMapper);
+
+ private final List<ArtifactsValidator> validators = List.of(new SchemaReferenceValidator(vesEventsArtifactDeserializer, schemaMapDeserializer, validatorProperties));
+ private final ArtifactsCollector artifactsCollector = new ArtifactsCollector(sdcConnectorClient);
+ private final ArtifactsCollectorStatusSender artifactsCollectorStatusSender = new ArtifactsCollectorStatusSender(distributionClient);
+ private final ValidationStatusSender validationStatusSender = new ValidationStatusSender(distributionClient);
+ private final FinalStatusSender finalStatusSender = new FinalStatusSender(distributionClient);
+ private final ClientCallback clientCallback = new ClientCallback(validators, artifactsCollector, artifactsCollectorStatusSender, validationStatusSender, finalStatusSender);
+
+ private final INotificationData service = new Service();
+
+
+ @Test
+ void shouldNotThrowExceptionWhenCallingCallbackAndArtifactIsValid() throws IOException {
+ //given
+ byte[] payload = Files.readAllBytes(Paths.get("src/test/resources/ves_artifact_stndDefined_events.yaml"));
+ DistributionClientDownloadResultImpl message = new DistributionClientDownloadResultImpl(
+ DistributionActionResultEnum.SUCCESS, "message", "artifact-name", payload);
+ DistributionClientDownloadResultImpl responseStatus = new DistributionClientDownloadResultImpl(DistributionActionResultEnum.SUCCESS, "OK");
+
+ when(sdcConnectorClient.downloadArtifact(any())).thenReturn(message);
+ when(distributionClient.sendDownloadStatus(any())).thenReturn(responseStatus);
+ when(distributionClient.sendDeploymentStatus(any())).thenReturn(responseStatus);
+ when(distributionClient.getConfiguration()).thenReturn(config);
+ when(distributionClient.sendFinalDistrStatus(any())).thenReturn(responseStatus);
+ when(config.getConsumerID()).thenReturn("consumer-id");
+ when(validatorProperties.getSchemaMapPath()).thenReturn("src/test/resources/test-schema-map.json");
+ when(validatorProperties.getEventDomainPath()).thenReturn("/event/structure/commonEventHeader/structure/domain/value");
+ when(validatorProperties.getEventSchemaReferencePath()).thenReturn("/event/structure/stndDefinedFields/structure/schemaReference/value");
+
+ //when
+ //then
+ assertDoesNotThrow(() -> clientCallback.activateCallback(service));
+ }
+}
diff --git a/src/test/java/org/onap/ves/openapi/manager/service/notification/ArtifactsCollectorStatusSenderTest.java b/src/test/java/org/onap/ves/openapi/manager/service/notification/ArtifactsCollectorStatusSenderTest.java
new file mode 100644
index 0000000..377cc4b
--- /dev/null
+++ b/src/test/java/org/onap/ves/openapi/manager/service/notification/ArtifactsCollectorStatusSenderTest.java
@@ -0,0 +1,118 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.notification;
+
+import org.junit.jupiter.api.Test;
+import org.onap.sdc.api.consumer.IConfiguration;
+import org.onap.sdc.api.notification.IArtifactInfo;
+import org.onap.sdc.api.results.IDistributionClientResult;
+import org.onap.sdc.impl.DistributionClientImpl;
+import org.onap.sdc.impl.DistributionClientResultImpl;
+import org.onap.sdc.utils.DistributionActionResultEnum;
+import org.onap.sdc.utils.DistributionStatusEnum;
+import org.onap.ves.openapi.manager.config.DistributionClientConfig;
+import org.onap.ves.openapi.manager.model.DistributionStatusMessage;
+import org.onap.ves.openapi.manager.service.testModel.ArtifactInfo;
+
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class ArtifactsCollectorStatusSenderTest {
+
+ private final IConfiguration configuration = mock(IConfiguration.class);
+ private final DistributionClientImpl distributionClient = mock(DistributionClientImpl.class);
+ private final ArtifactsCollectorStatusSender sender = new ArtifactsCollectorStatusSender(distributionClient);
+
+ @Test
+ void shouldSuccessfullySendStatusToEachDownloadedArtifacts() {
+ //given
+ DistributionClientResultImpl expectedResponse = new DistributionClientResultImpl(
+ DistributionActionResultEnum.SUCCESS, "sample-response-message");
+ List<DistributionClientResultImpl> expectedResponses = List.of(expectedResponse, expectedResponse);
+
+ ArtifactInfo artifact = new ArtifactInfo(DistributionClientConfig.VES_EVENTS_ARTIFACT_TYPE);
+ List<IArtifactInfo> artifacts = List.of(artifact, artifact);
+ String consumerId = "ves-consumer";
+
+ when(distributionClient.sendDownloadStatus(any())).thenReturn(expectedResponse);
+ when(distributionClient.getConfiguration()).thenReturn(configuration);
+ when(configuration.getConsumerID()).thenReturn(consumerId);
+
+ //when
+ List<IDistributionClientResult> responses = sender.sendDownloadOk("distribution-id", artifacts);
+
+ //then
+ assertThat(responses).isEqualTo(expectedResponses);
+ }
+
+ @Test
+ void shouldSendDownloadErrorStatusToEachDownloadedArtifacts() {
+ //given
+ DistributionClientResultImpl expectedResponse = new DistributionClientResultImpl(
+ DistributionActionResultEnum.GENERAL_ERROR, "sample-response-message");
+ List<DistributionClientResultImpl> expectedResponses = List.of(expectedResponse, expectedResponse);
+
+ ArtifactInfo artifact = new ArtifactInfo(DistributionClientConfig.VES_EVENTS_ARTIFACT_TYPE);
+ List<IArtifactInfo> artifacts = List.of(artifact, artifact);
+ String consumerId = "ves-consumer";
+ when(distributionClient.sendDownloadStatus(any(),any())).thenReturn(expectedResponse);
+ when(distributionClient.getConfiguration()).thenReturn(configuration);
+ when(configuration.getConsumerID()).thenReturn(consumerId);
+ long timestamp = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli();
+
+ DistributionStatusMessage dm = new DistributionStatusMessage(
+ artifact.getArtifactURL(),
+ "distribution-id",
+ distributionClient.getConfiguration().getConsumerID(),
+ timestamp,
+ DistributionStatusEnum.DOWNLOAD_OK);
+
+ //when
+ List<IDistributionClientResult> responses = sender.sendDownloadError("distribution-id", artifacts);
+
+ //then
+ assertThat(responses).isEqualTo(expectedResponses);
+ assertThat(dm.getArtifactURL()).isEqualTo(artifact.getArtifactURL());
+ assertThat(dm.getDistributionID()).isEqualTo("distribution-id");
+ assertThat(dm.getTimestamp()).isEqualTo(timestamp);
+ assertThat(dm.getStatus()).isEqualTo(DistributionStatusEnum.DOWNLOAD_OK);
+ }
+
+ @Test
+ void shouldNotSendAnyStatusWhenNoArtifactsAreDownloaded() {
+ //given
+ List<DistributionClientResultImpl> expectedResponses = List.of();
+ List<IArtifactInfo> artifacts = List.of();
+
+ //when
+ List<IDistributionClientResult> responses = sender.sendDownloadOk("distribution-id", artifacts);
+
+ //then
+ assertThat(responses).isEqualTo(expectedResponses);
+ }
+
+} \ No newline at end of file
diff --git a/src/test/java/org/onap/ves/openapi/manager/service/notification/ArtifactsCollectorTest.java b/src/test/java/org/onap/ves/openapi/manager/service/notification/ArtifactsCollectorTest.java
new file mode 100644
index 0000000..3da47f7
--- /dev/null
+++ b/src/test/java/org/onap/ves/openapi/manager/service/notification/ArtifactsCollectorTest.java
@@ -0,0 +1,106 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.notification;
+
+import org.junit.jupiter.api.Test;
+import org.onap.sdc.api.notification.IArtifactInfo;
+import org.onap.sdc.http.SdcConnectorClient;
+import org.onap.sdc.impl.DistributionClientDownloadResultImpl;
+import org.onap.sdc.utils.DistributionActionResultEnum;
+import org.onap.ves.openapi.manager.config.DistributionClientConfig;
+import org.onap.ves.openapi.manager.exceptions.ArtifactException;
+import org.onap.ves.openapi.manager.model.Artifact;
+import org.onap.ves.openapi.manager.service.ArtifactsCollector;
+import org.onap.ves.openapi.manager.service.testModel.ArtifactInfo;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class ArtifactsCollectorTest {
+
+ private static final String NOT_VES_ARTIFACT = "NOT_VES_ARTIFACT";
+ private final SdcConnectorClient sdcConnectorClient = mock(SdcConnectorClient.class);
+ private final ArtifactsCollector artifactsCollector = new ArtifactsCollector(sdcConnectorClient);
+
+ @Test
+ void shouldReturnArtifactsContentWhenVESArtifactsAreDistributed() throws IOException {
+ //given
+ IArtifactInfo vesArtifact = new ArtifactInfo(DistributionClientConfig.VES_EVENTS_ARTIFACT_TYPE);
+ List<IArtifactInfo> artifacts = List.of(vesArtifact);
+
+ byte[] payload = getVesArtifactPayload();
+ DistributionClientDownloadResultImpl artifactDownloadResult = new DistributionClientDownloadResultImpl(
+ DistributionActionResultEnum.SUCCESS, "sample-message", "artifact-name",
+ payload);
+ when(sdcConnectorClient.downloadArtifact(vesArtifact)).thenReturn(artifactDownloadResult);
+ List<Artifact> expectedArtifacts = List.of(new Artifact(vesArtifact, payload));
+
+ //when
+ List<Artifact> artifactContents = artifactsCollector.pullArtifacts(artifacts);
+
+ //then
+ assertThat(artifactContents).isEqualTo(expectedArtifacts);
+ }
+
+ @Test
+ void shouldNotReturnArtifactsContentWhenNoVESArtifactsAreDistributed() {
+ //given
+ IArtifactInfo notVesArtifact = new ArtifactInfo(NOT_VES_ARTIFACT);
+ List<IArtifactInfo> artifactsDefinitions = List.of(notVesArtifact);
+ List<Artifact> expectedArtifacts = List.of();
+
+ //when
+ List<Artifact> artifacts = artifactsCollector.pullArtifacts(artifactsDefinitions);
+
+ //then
+ assertThat(artifacts).isEqualTo(expectedArtifacts);
+ }
+
+ @Test
+ void shouldThrowExceptionWhenArtifactNameIsEmpty() {
+ //given
+ IArtifactInfo vesArtifact = new ArtifactInfo(DistributionClientConfig.VES_EVENTS_ARTIFACT_TYPE);
+ List<IArtifactInfo> artifacts = List.of(vesArtifact);
+
+ byte[] payload = new byte[0];
+ DistributionClientDownloadResultImpl artifactDownloadResult = new DistributionClientDownloadResultImpl(
+ DistributionActionResultEnum.SUCCESS, "sample-message", "",
+ payload);
+ when(sdcConnectorClient.downloadArtifact(vesArtifact)).thenReturn(artifactDownloadResult);
+
+ //when then
+ assertThrows(
+ ArtifactException.class,
+ () -> artifactsCollector.pullArtifacts(artifacts)
+ );
+ }
+
+ private byte[] getVesArtifactPayload() throws IOException {
+ return Files.readAllBytes(Paths.get("src/test/resources/ves_artifact_stndDefined_events.yaml"));
+ }
+}
diff --git a/src/test/java/org/onap/ves/openapi/manager/service/notification/ClientCallbackTest.java b/src/test/java/org/onap/ves/openapi/manager/service/notification/ClientCallbackTest.java
new file mode 100644
index 0000000..91dfda7
--- /dev/null
+++ b/src/test/java/org/onap/ves/openapi/manager/service/notification/ClientCallbackTest.java
@@ -0,0 +1,153 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.notification;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.onap.sdc.api.notification.IArtifactInfo;
+import org.onap.sdc.api.notification.INotificationData;
+import org.onap.ves.openapi.manager.model.Artifact;
+import org.onap.ves.openapi.manager.model.ArtifactValidationResult;
+import org.onap.ves.openapi.manager.service.ArtifactsCollector;
+import org.onap.ves.openapi.manager.service.ClientCallback;
+import org.onap.ves.openapi.manager.service.testModel.Service;
+import org.onap.ves.openapi.manager.service.validation.ArtifactsValidator;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class ClientCallbackTest {
+
+ private ArtifactsCollector artifactsCollector;
+ private ArtifactsCollectorStatusSender artifactsCollectorStatusSender;
+ private ValidationStatusSender validationStatusSender;
+ private FinalStatusSender finalStatusSender;
+ private ArtifactsValidator artifactsValidator;
+ private List<ArtifactsValidator> validators;
+ private ClientCallback callback;
+
+ @BeforeEach
+ void setUpMocks() {
+ artifactsCollector = mock(ArtifactsCollector.class);
+ artifactsCollectorStatusSender = mock(ArtifactsCollectorStatusSender.class);
+ validationStatusSender = mock(ValidationStatusSender.class);
+ finalStatusSender = mock(FinalStatusSender.class);
+ artifactsValidator = mock(ArtifactsValidator.class);
+ validators = new ArrayList<>();
+ validators.add(artifactsValidator);
+
+ callback = new ClientCallback(validators, artifactsCollector, artifactsCollectorStatusSender,
+ validationStatusSender, finalStatusSender);
+ }
+
+ @Test
+ void shouldNotValidateAnyArtifactsOrSendAnyStatusIfPulledArtifactsListIsEmpty() {
+ testClientCallback(0);
+ }
+
+ @Test
+ void shouldValidateArtifactUsingValidatorAndSendStatusIfPulledArtifactsListContainsOneArtifact() {
+ testClientCallback(1);
+ }
+
+ @Test
+ void shouldValidateArtifactsUsingValidatorAndSendStatusesIfPulledArtifactsListContainsMultipleArtifacts() {
+ testClientCallback(3);
+ }
+
+ @Test
+ void shouldValidateArtifactUsingMultipleValidatorsAndSendStatusIfPulledArtifactsListContainsOneArtifact() {
+ ArtifactsValidator extraArtifactsValidator = mock(ArtifactsValidator.class);
+ testClientCallback(1, extraArtifactsValidator);
+ }
+
+ @Test
+ void shouldValidateArtifactUsingMultipleValidatorsAndSendStatusIfPulledArtifactsListContainsMultipleArtifacts() {
+ ArtifactsValidator extraArtifactsValidator = mock(ArtifactsValidator.class);
+ testClientCallback(3, extraArtifactsValidator);
+ }
+
+ private void testClientCallback(int numberOfPulledArtefacts, ArtifactsValidator... extraValidators) {
+ // given
+ validators.addAll(Arrays.asList(extraValidators));
+ final INotificationData service = new Service(numberOfPulledArtefacts);
+ ExpectedTestParameters testParameters = setupCallbackTest(service);
+
+ // when
+ callback.activateCallback(service);
+
+ // then
+ verifyMockedMethodCalls(testParameters, numberOfPulledArtefacts);
+ for(ArtifactsValidator validator: extraValidators) {
+ verify(validator, times(1)).validate(eq(testParameters.getExpectedPulledArtifacts()));
+ }
+ }
+
+ private ExpectedTestParameters setupCallbackTest(INotificationData service) {
+ final List<IArtifactInfo> expectedArtifactsList = service.getResources().get(0).getArtifacts();
+
+ final List<Artifact> expectedPulledArtifacts = new ArrayList<>();
+ final List<ArtifactValidationResult> expectedValidationResults = new ArrayList<>();
+ for(IArtifactInfo artifactInfo: expectedArtifactsList) {
+ final Artifact artifact = setUpTestArtifact(artifactInfo);
+ expectedPulledArtifacts.add(artifact);
+ final ArtifactValidationResult expectedValidationResult = new ArtifactValidationResult(
+ artifactInfo, true, artifactInfo.getArtifactName() + " validated", artifactsValidator
+ );
+ expectedValidationResults.add(expectedValidationResult);
+ }
+
+ when(artifactsCollector.pullArtifacts(expectedArtifactsList)).thenReturn(expectedPulledArtifacts);
+ when(artifactsValidator.validate(expectedPulledArtifacts)).thenReturn(expectedValidationResults);
+
+ return new ExpectedTestParameters(expectedPulledArtifacts, expectedValidationResults, expectedArtifactsList);
+ }
+
+ private Artifact setUpTestArtifact(IArtifactInfo artifactInfo) {
+ final byte[] expectedArtifactContent = ("test content " + artifactInfo.getArtifactName()).getBytes();
+ return new Artifact(artifactInfo, expectedArtifactContent);
+ }
+
+ private void verifyMockedMethodCalls(ExpectedTestParameters testParameters, int numberOfPulledArtifacts) {
+ verify(artifactsCollector, times(1)).pullArtifacts(eq(testParameters.getExpectedArtifactsList()));
+ verify(artifactsCollectorStatusSender, times(numberOfPulledArtifacts)).sendDownloadOk(any(), eq(testParameters.getExpectedArtifactsList()));
+ verify(validationStatusSender, times(1)).send(any(), eq(testParameters.getExpectedValidationResults()));
+ validators.forEach(validator -> verify(validator, times(1)).validate(eq(testParameters.getExpectedPulledArtifacts())));
+ }
+
+ @Getter
+ @AllArgsConstructor
+ private static class ExpectedTestParameters {
+ final private List<Artifact> expectedPulledArtifacts;
+ final private List<ArtifactValidationResult> expectedValidationResults;
+ final private List<IArtifactInfo> expectedArtifactsList;
+ }
+}
diff --git a/src/test/java/org/onap/ves/openapi/manager/service/notification/ValidationStatusSenderTest.java b/src/test/java/org/onap/ves/openapi/manager/service/notification/ValidationStatusSenderTest.java
new file mode 100644
index 0000000..e4bb504
--- /dev/null
+++ b/src/test/java/org/onap/ves/openapi/manager/service/notification/ValidationStatusSenderTest.java
@@ -0,0 +1,84 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.notification;
+
+import org.junit.jupiter.api.Test;
+import org.onap.sdc.api.consumer.IConfiguration;
+import org.onap.sdc.api.results.IDistributionClientResult;
+import org.onap.sdc.impl.DistributionClientImpl;
+import org.onap.sdc.impl.DistributionClientResultImpl;
+import org.onap.sdc.utils.DistributionActionResultEnum;
+import org.onap.ves.openapi.manager.config.DistributionClientConfig;
+import org.onap.ves.openapi.manager.model.ArtifactValidationResult;
+import org.onap.ves.openapi.manager.service.testModel.ArtifactInfo;
+import org.onap.ves.openapi.manager.service.validation.ArtifactsValidator;
+import org.onap.ves.openapi.manager.service.validation.SchemaReferenceValidator;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class ValidationStatusSenderTest {
+
+ private final ArtifactsValidator validator = mock(SchemaReferenceValidator.class);
+ private final IConfiguration configuration = mock(IConfiguration.class);
+ private final DistributionClientImpl distributionClient = mock(DistributionClientImpl.class);
+ private final ValidationStatusSender statusSender = new ValidationStatusSender(distributionClient);
+
+ @Test
+ void shouldSendValidationStatusForEachValidationResult() {
+ //given
+ String distributionId = "distribution-id";
+ String consumerId = "ves-consumer";
+
+ DistributionClientResultImpl sendingResult =
+ new DistributionClientResultImpl(DistributionActionResultEnum.SUCCESS, "sample-message");
+ List<IDistributionClientResult> expectedSendingResults = List.of(sendingResult, sendingResult);
+
+ ArtifactInfo artifact = new ArtifactInfo(DistributionClientConfig.VES_EVENTS_ARTIFACT_TYPE);
+ List<ArtifactValidationResult> validationResults = getValidationResults(artifact);
+
+ when(distributionClient.sendDeploymentStatus(any())).thenReturn(sendingResult);
+ when(distributionClient.sendDeploymentStatus(any(), anyString())).thenReturn(sendingResult);
+ when(distributionClient.getConfiguration()).thenReturn(configuration);
+ when(configuration.getConsumerID()).thenReturn(consumerId);
+
+ //when
+ List<IDistributionClientResult> sendingResults = statusSender.send(distributionId, validationResults);
+
+ //then
+ assertThat(sendingResults).isEqualTo(expectedSendingResults);
+
+ }
+
+ private List<ArtifactValidationResult> getValidationResults(ArtifactInfo artifactInfo) {
+ ArtifactValidationResult validationResultValid = new ArtifactValidationResult(artifactInfo, true,
+ "sample-message", validator);
+ ArtifactValidationResult validationResultInvalid = new ArtifactValidationResult(artifactInfo, false,
+ "sample-message", validator);
+ return List.of(validationResultValid, validationResultInvalid);
+ }
+
+} \ No newline at end of file
diff --git a/src/test/java/org/onap/ves/openapi/manager/service/serialization/SchemaMapDeserializerTest.java b/src/test/java/org/onap/ves/openapi/manager/service/serialization/SchemaMapDeserializerTest.java
new file mode 100644
index 0000000..6b16c89
--- /dev/null
+++ b/src/test/java/org/onap/ves/openapi/manager/service/serialization/SchemaMapDeserializerTest.java
@@ -0,0 +1,84 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.serialization;
+
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Test;
+import org.onap.ves.openapi.manager.model.SchemaMap;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class SchemaMapDeserializerTest {
+
+ final ObjectMapper objectMapper = new ObjectMapper();
+ private final SchemaMapDeserializer deserializer =
+ new SchemaMapDeserializer(objectMapper);
+
+ @Test
+ void shouldReturnSchemaMapFromFileWhenFileExists() {
+ //given
+ List<String> expectedPublicURLs = getExpectedPublicURLs();
+ List<String> expectedLocalURLs = getExpectedLocalURLs();
+ String schemaMapPath = "src/test/resources/test-schema-map.json";
+
+ //when
+ SchemaMap schemaMap = deserializer.getSchemaMapFromFile(schemaMapPath);
+
+ //then
+ assertThat(schemaMap.getMappings().size()).isEqualTo(3);
+ assertThat(schemaMap.getMappings().stream().map(SchemaMap.Mapping::getPublicURL).collect(Collectors.toList()))
+ .isEqualTo(expectedPublicURLs);
+ assertThat(schemaMap.getMappings().stream().map(SchemaMap.Mapping::getLocalURL).collect(Collectors.toList()))
+ .isEqualTo(expectedLocalURLs);
+ }
+
+ @Test
+ void shouldReturnEmptySchemaMapWhenFileDoesNotExist() {
+ //given
+ String schemaMapPath = "src/test/resources/not-existing-schema-map.yaml";
+
+ //when
+ SchemaMap schemaMap = deserializer.getSchemaMapFromFile(schemaMapPath);
+
+ //then
+ assertThat(schemaMap.getMappings().size()).isZero();
+ }
+
+ private List<String> getExpectedPublicURLs() {
+ return List.of(
+ "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerMeasJobCtlMnS.yaml",
+ "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerThresMonMnS.yaml",
+ "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerfDataStreamingMnS.yaml"
+ );
+ }
+
+ private List<String> getExpectedLocalURLs() {
+ return List.of(
+ "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerMeasJobCtlMnS.yaml",
+ "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerThresMonMnS.yaml",
+ "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerfDataStreamingMnS.yaml"
+ );
+ }
+} \ No newline at end of file
diff --git a/src/test/java/org/onap/ves/openapi/manager/service/serialization/VesEventsArtifactDeserializerTest.java b/src/test/java/org/onap/ves/openapi/manager/service/serialization/VesEventsArtifactDeserializerTest.java
new file mode 100644
index 0000000..6c35b18
--- /dev/null
+++ b/src/test/java/org/onap/ves/openapi/manager/service/serialization/VesEventsArtifactDeserializerTest.java
@@ -0,0 +1,73 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.serialization;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.function.Predicate;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class VesEventsArtifactDeserializerTest {
+
+ private static final String EVENT_DOMAIN_PATH = "/event/structure/commonEventHeader/structure/domain/value";
+ private static final String STND_DEFINED_DOMAIN = "stndDefined";
+ private final ObjectMapper objectMapper = new ObjectMapper();
+ private final VesEventsArtifactDeserializer deserializer = new VesEventsArtifactDeserializer(objectMapper);
+
+
+ @Test
+ void shouldReturnObjectNodesPerEachYamlDocumentWhenByteCodeIsCorrect() throws IOException {
+ //given
+ byte[] bytecode = Files.readAllBytes(Paths.get("src/test/resources/ves_artifact_stndDefined_events.yaml"));
+ int expectedDocuments = 3;
+
+ //when
+ List<ObjectNode> objectNodes = deserializer.deserializeMultiDocumentYaml(bytecode);
+
+ //then
+ assertThat(objectNodes.size()).isEqualTo(expectedDocuments);
+ assertThat(objectNodes).anyMatch(isStndDefinedEvent());
+ }
+
+ @Test
+ void shouldReturnEmptyListWhenInvalidYamlByteCodeIsGiven() {
+ //given
+ byte[] invalidBytecode = new byte[] {'i','n','v','a','l','i', 'd'};
+ //when
+ List<ObjectNode> objectNodes = deserializer.deserializeMultiDocumentYaml(invalidBytecode);
+
+ //then
+ assertThat(objectNodes.size()).isZero();
+ }
+
+ private Predicate<ObjectNode> isStndDefinedEvent() {
+ return event -> event.at(EVENT_DOMAIN_PATH).asText()
+ .equals(STND_DEFINED_DOMAIN);
+ }
+
+} \ No newline at end of file
diff --git a/src/test/java/org/onap/ves/openapi/manager/service/testModel/ArtifactInfo.java b/src/test/java/org/onap/ves/openapi/manager/service/testModel/ArtifactInfo.java
new file mode 100644
index 0000000..5c7ea56
--- /dev/null
+++ b/src/test/java/org/onap/ves/openapi/manager/service/testModel/ArtifactInfo.java
@@ -0,0 +1,121 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.testModel;
+
+import org.onap.sdc.api.notification.IArtifactInfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class ArtifactInfo implements IArtifactInfo {
+
+ private final String artifactName;
+ private final String artifactType;
+ private final String artifactURL;
+ private String artifactChecksum;
+ private Integer artifactTimeout;
+ private String artifactDescription;
+ private String artifactVersion;
+ private String artifactUUID;
+ private IArtifactInfo generatedArtifact;
+ private List<IArtifactInfo> relatedArtifacts;
+
+ public ArtifactInfo(String artifactType) {
+ this.artifactName = "artifact-name";
+ this.artifactType = artifactType;
+ this.artifactURL = "http://artifact-url:1234/test";
+ }
+
+ private ArtifactInfo(IArtifactInfo iArtifactInfo) {
+ artifactName = iArtifactInfo.getArtifactName();
+ artifactType = iArtifactInfo.getArtifactType();
+ artifactURL = iArtifactInfo.getArtifactURL();
+ artifactChecksum = iArtifactInfo.getArtifactChecksum();
+ artifactDescription = iArtifactInfo.getArtifactDescription();
+ artifactTimeout = iArtifactInfo.getArtifactTimeout();
+ artifactVersion = iArtifactInfo.getArtifactVersion();
+ artifactUUID = iArtifactInfo.getArtifactUUID();
+ generatedArtifact = iArtifactInfo.getGeneratedArtifact();
+ relatedArtifacts = iArtifactInfo.getRelatedArtifacts();
+
+ }
+
+ @Override
+ public String getArtifactName() {
+ return artifactName;
+ }
+
+ @Override
+ public String getArtifactType() {
+ return artifactType;
+ }
+
+ @Override
+ public String getArtifactURL() {
+ return artifactURL;
+ }
+
+ @Override
+ public String getArtifactChecksum() {
+ return artifactChecksum;
+ }
+
+ @Override
+ public Integer getArtifactTimeout() {
+ return artifactTimeout;
+ }
+
+ @Override
+ public String getArtifactDescription() {
+ return artifactDescription;
+ }
+
+ @Override
+ public String getArtifactVersion() {
+ return artifactVersion;
+ }
+
+ @Override
+ public String getArtifactUUID() {
+ return artifactUUID;
+ }
+
+ @Override
+ public IArtifactInfo getGeneratedArtifact() {
+ return generatedArtifact;
+ }
+
+ @Override
+ public List<IArtifactInfo> getRelatedArtifacts() {
+ return relatedArtifacts;
+ }
+
+ public static List<ArtifactInfo> convertToArtifactInfoImpl(List<IArtifactInfo> list) {
+ List<ArtifactInfo> ret = new ArrayList<>();
+ if (list != null) {
+ for (IArtifactInfo artifactInfo : list) {
+ ret.add(new ArtifactInfo(artifactInfo));
+ }
+ }
+ return ret;
+ }
+}
diff --git a/src/test/java/org/onap/ves/openapi/manager/service/testModel/Resource.java b/src/test/java/org/onap/ves/openapi/manager/service/testModel/Resource.java
new file mode 100644
index 0000000..130de6f
--- /dev/null
+++ b/src/test/java/org/onap/ves/openapi/manager/service/testModel/Resource.java
@@ -0,0 +1,161 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.testModel;
+
+import org.onap.sdc.api.notification.IArtifactInfo;
+import org.onap.sdc.api.notification.IResourceInstance;
+import org.onap.ves.openapi.manager.config.DistributionClientConfig;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class Resource implements IResourceInstance {
+
+ private String resourceInstanceName;
+ private String resourceCustomizationUUID;
+ private String resourceName;
+ private String resourceVersion;
+ private String resourceType;
+ private String resourceUUID;
+ private String resourceInvariantUUID;
+ private String category;
+ private String subcategory;
+ private List<ArtifactInfo> artifacts;
+
+ public Resource(int numberOfArtifacts) {
+ this.artifacts = Stream.generate(() -> new ArtifactInfo(DistributionClientConfig.VES_EVENTS_ARTIFACT_TYPE))
+ .limit(numberOfArtifacts)
+ .collect(Collectors.toList());
+ }
+
+ public Resource() {
+ this.artifacts = List.of(new ArtifactInfo(DistributionClientConfig.VES_EVENTS_ARTIFACT_TYPE));
+ }
+
+ private Resource(IResourceInstance resourceInstance) {
+ resourceInstanceName = resourceInstance.getResourceInstanceName();
+ resourceCustomizationUUID = resourceInstance.getResourceCustomizationUUID();
+ resourceName = resourceInstance.getResourceName();
+ resourceVersion = resourceInstance.getResourceVersion();
+ resourceType = resourceInstance.getResourceType();
+ resourceUUID = resourceInstance.getResourceUUID();
+ resourceInvariantUUID = resourceInstance.getResourceInvariantUUID();
+ category = resourceInstance.getCategory();
+ subcategory = resourceInstance.getSubcategory();
+ artifacts = ArtifactInfo.convertToArtifactInfoImpl(resourceInstance.getArtifacts());
+ }
+
+ public static List<Resource> convertToJsonContainer(List<IResourceInstance> resources) {
+ return resources.stream().map(Resource::new).collect(Collectors.toList());
+ }
+
+ @Override
+ public String getResourceInstanceName() {
+ return resourceInstanceName;
+ }
+
+ public void setResourceInstanceName(String resourceInstanceName) {
+ this.resourceInstanceName = resourceInstanceName;
+ }
+
+ @Override
+ public String getResourceName() {
+ return resourceName;
+ }
+
+ public void setResourceName(String resourceName) {
+ this.resourceName = resourceName;
+ }
+
+ @Override
+ public String getResourceVersion() {
+ return resourceVersion;
+ }
+
+ public void setResourceVersion(String resourceVersion) {
+ this.resourceVersion = resourceVersion;
+ }
+
+ @Override
+ public String getResourceType() {
+ return resourceType;
+ }
+
+ public void setResourceType(String resourceType) {
+ this.resourceType = resourceType;
+ }
+
+ @Override
+ public String getResourceUUID() {
+ return resourceUUID;
+ }
+
+ public void setResourceUUID(String resourceUUID) {
+ this.resourceUUID = resourceUUID;
+ }
+
+ @Override
+ public List<IArtifactInfo> getArtifacts() {
+ return List.copyOf(artifacts);
+ }
+
+ public void setArtifacts(List<ArtifactInfo> artifacts) {
+ this.artifacts = artifacts;
+ }
+
+ public List<ArtifactInfo> getArtifactsImpl() {
+ return artifacts;
+ }
+
+ @Override
+ public String getResourceInvariantUUID() {
+ return resourceInvariantUUID;
+ }
+
+ public void setResourceInvariantUUID(String resourceInvariantUUID) {
+ this.resourceInvariantUUID = resourceInvariantUUID;
+ }
+
+ public String getResourceCustomizationUUID() {
+ return resourceCustomizationUUID;
+ }
+
+ public void setResourceCustomizationUUID(String resourceCustomizationUUID) {
+ this.resourceCustomizationUUID = resourceCustomizationUUID;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public String getSubcategory() {
+ return subcategory;
+ }
+
+ public void setSubcategory(String subcategory) {
+ this.subcategory = subcategory;
+ }
+}
diff --git a/src/test/java/org/onap/ves/openapi/manager/service/testModel/Service.java b/src/test/java/org/onap/ves/openapi/manager/service/testModel/Service.java
new file mode 100644
index 0000000..0dae772
--- /dev/null
+++ b/src/test/java/org/onap/ves/openapi/manager/service/testModel/Service.java
@@ -0,0 +1,136 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.testModel;
+
+import org.onap.sdc.api.notification.IArtifactInfo;
+import org.onap.sdc.api.notification.INotificationData;
+import org.onap.sdc.api.notification.IResourceInstance;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Service implements INotificationData {
+
+ private String distributionID;
+ private String serviceName;
+ private String serviceVersion;
+ private String serviceUUID;
+ private String serviceDescription;
+ private String serviceInvariantUUID;
+ private List<Resource> resources;
+ private List<ArtifactInfo> serviceArtifacts;
+ private String workloadContext;
+
+ public Service(int numberOfArtifacts) {
+ this.resources = List.of(new Resource(numberOfArtifacts));
+ this.serviceUUID = "UUID";
+ this.serviceName = "testService";
+ }
+
+ public Service() {
+ this.resources = List.of(new Resource());
+ this.serviceUUID = "UUID";
+ this.serviceName = "testService";
+ }
+
+ @Override
+ public String getDistributionID() {
+ return distributionID;
+ }
+
+ @Override
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ @Override
+ public String getServiceVersion() {
+ return serviceVersion;
+ }
+
+ @Override
+ public String getServiceUUID() {
+ return serviceUUID;
+ }
+
+ public String getServiceDescription() {
+ return serviceDescription;
+ }
+
+ @Override
+ public String getWorkloadContext() {
+ return workloadContext;
+ }
+
+ @Override
+ public void setWorkloadContext(String workloadContext) {
+ this.workloadContext = workloadContext;
+ }
+
+ @Override
+ public String toString() {
+ return "NotificationDataImpl [distributionID=" + distributionID + ", serviceName=" + serviceName
+ + ", serviceVersion=" + serviceVersion + ", serviceUUID=" + serviceUUID + ", serviceDescription="
+ + serviceDescription + ", serviceInvariantUUID=" + serviceInvariantUUID + ", resources=" + resources
+ + ", serviceArtifacts=" + serviceArtifacts + ", workloadContext=" + workloadContext + "]";
+ }
+
+ @Override
+ public List<IResourceInstance> getResources() {
+ return List.copyOf(resources);
+ }
+
+ @Override
+ public List<IArtifactInfo> getServiceArtifacts() {
+ return List.copyOf(serviceArtifacts);
+ }
+
+ @Override
+ public String getServiceInvariantUUID() {
+ return serviceInvariantUUID;
+ }
+
+ @Override
+ public IArtifactInfo getArtifactMetadataByUUID(String artifactUUID) {
+ IArtifactInfo ret = findArtifactInfoByUUID(artifactUUID, serviceArtifacts);
+ if (ret == null && resources != null) {
+ for (Resource currResourceInstance : resources) {
+ ret = findArtifactInfoByUUID(artifactUUID, currResourceInstance.getArtifactsImpl());
+ if (ret != null) {
+ break;
+ }
+ }
+ }
+ return ret;
+ }
+
+ private IArtifactInfo findArtifactInfoByUUID(String artifactUUID, List<ArtifactInfo> listToCheck) {
+ IArtifactInfo ret = null;
+ if (listToCheck != null) {
+ for (IArtifactInfo curr : listToCheck) {
+ if (curr.getArtifactUUID().equals(artifactUUID)) {
+ ret = curr;
+ break;
+ }
+ }
+ }
+ return ret;
+ }
+}
diff --git a/src/test/java/org/onap/ves/openapi/manager/service/validation/SchemaReferenceValidatorTest.java b/src/test/java/org/onap/ves/openapi/manager/service/validation/SchemaReferenceValidatorTest.java
new file mode 100644
index 0000000..fc17564
--- /dev/null
+++ b/src/test/java/org/onap/ves/openapi/manager/service/validation/SchemaReferenceValidatorTest.java
@@ -0,0 +1,120 @@
+/*
+ * ============LICENSE_START=======================================================
+ * VES-OPENAPI-MANAGER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. 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.ves.openapi.manager.service.validation;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.logging.log4j.util.Strings;
+import org.junit.jupiter.api.Test;
+import org.onap.sdc.api.notification.IArtifactInfo;
+import org.onap.ves.openapi.manager.config.DistributionClientConfig;
+import org.onap.ves.openapi.manager.config.ValidatorProperties;
+import org.onap.ves.openapi.manager.model.Artifact;
+import org.onap.ves.openapi.manager.model.ArtifactValidationResult;
+import org.onap.ves.openapi.manager.service.serialization.SchemaMapDeserializer;
+import org.onap.ves.openapi.manager.service.serialization.VesEventsArtifactDeserializer;
+import org.onap.ves.openapi.manager.service.testModel.ArtifactInfo;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class SchemaReferenceValidatorTest {
+
+ private final ObjectMapper objectMapper = new ObjectMapper();
+ private final VesEventsArtifactDeserializer vesEventsArtifactDeserializer =
+ new VesEventsArtifactDeserializer(objectMapper);
+ private final SchemaMapDeserializer schemaMapDeserializer = new SchemaMapDeserializer(objectMapper);
+ private final String schemaMapPath = "src/test/resources/test-schema-map.json";
+ private final String eventDomain = "/event/structure/commonEventHeader/structure/domain/value";
+ private final String schemaReference = "/event/structure/stndDefinedFields/structure/schemaReference/value";
+ private final ValidatorProperties validatorProperties = mock(ValidatorProperties.class);
+
+ private final SchemaReferenceValidator validator = new SchemaReferenceValidator(vesEventsArtifactDeserializer,
+ schemaMapDeserializer, validatorProperties);
+
+ @Test
+ void shouldReturnSuccessValidationResultWhenValidVesArtifactIsGiven() throws IOException {
+ //given
+ ArtifactInfo artifactInfo = new ArtifactInfo(DistributionClientConfig.VES_EVENTS_ARTIFACT_TYPE);
+ List<Artifact> artifacts = getArtifacts(artifactInfo,
+ "src/test/resources/ves_artifact_stndDefined_events.yaml");
+ List<ArtifactValidationResult> expectedValidationResults =
+ getExpectedResults(artifactInfo, true, Strings.EMPTY);
+
+ when(validatorProperties.getSchemaMapPath()).thenReturn(schemaMapPath);
+ when(validatorProperties.getEventDomainPath()).thenReturn(eventDomain);
+ when(validatorProperties.getEventSchemaReferencePath()).thenReturn(schemaReference);
+
+ //when
+ List<ArtifactValidationResult> validationResults = validator.validate(artifacts);
+
+ //then
+ assertThat(validationResults).isEqualTo(expectedValidationResults);
+ }
+
+ @Test
+ void shouldReturnFailedValidationResultWhenInvalidVesArtifactIsGiven() throws IOException {
+ //given
+ ArtifactInfo artifactInfo = new ArtifactInfo(DistributionClientConfig.VES_EVENTS_ARTIFACT_TYPE);
+ List<Artifact> artifacts = getArtifacts(artifactInfo,
+ "src/test/resources/ves_artifact_invalid_stndDefined_events.yaml");
+ List<ArtifactValidationResult> expectedValidationResults = getExpectedResults(artifactInfo, false,
+ SchemaReferenceValidator.SCHEMA_REFERENCE_ERROR_MESSAGE);
+
+ when(validatorProperties.getSchemaMapPath()).thenReturn(schemaMapPath);
+ when(validatorProperties.getEventDomainPath()).thenReturn(eventDomain);
+ when(validatorProperties.getEventSchemaReferencePath()).thenReturn(schemaReference);
+
+ //when
+ List<ArtifactValidationResult> validationResults = validator.validate(artifacts);
+ List<String> validationResultsMessages =
+ validationResults.stream()
+ .map(result -> SchemaReferenceValidator.SCHEMA_REFERENCE_ERROR_MESSAGE)
+ .collect(Collectors.toList());
+
+ //then
+ assertThat(validationResults).usingElementComparatorIgnoringFields("message")
+ .isEqualTo(expectedValidationResults);
+ assertThat(validationResultsMessages)
+ .isNotEmpty()
+ .allMatch(message -> message.contains(SchemaReferenceValidator.SCHEMA_REFERENCE_ERROR_MESSAGE));
+ }
+
+ private List<Artifact> getArtifacts(IArtifactInfo artifactInfo, String artifactFilePath) throws IOException {
+ Path path = Paths.get(artifactFilePath);
+ byte[] artifactByteCode = Files.readAllBytes(path);
+ Artifact artifact = new Artifact(artifactInfo, artifactByteCode);
+ return List.of(artifact);
+ }
+
+ private List<ArtifactValidationResult> getExpectedResults(IArtifactInfo artifactInfo, boolean isValid, String message) {
+ ArtifactValidationResult result = new ArtifactValidationResult(artifactInfo, isValid,
+ message, validator);
+ return List.of(result);
+ }
+} \ No newline at end of file
diff --git a/src/test/resources/test-schema-map.json b/src/test/resources/test-schema-map.json
new file mode 100644
index 0000000..2317f9f
--- /dev/null
+++ b/src/test/resources/test-schema-map.json
@@ -0,0 +1,14 @@
+[
+ {
+ "publicURL": "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerMeasJobCtlMnS.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerMeasJobCtlMnS.yaml"
+ },
+ {
+ "publicURL": "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerThresMonMnS.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerThresMonMnS.yaml"
+ },
+ {
+ "publicURL": "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerfDataStreamingMnS.yaml",
+ "localURL": "3gpp/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerfDataStreamingMnS.yaml"
+ }
+] \ No newline at end of file
diff --git a/src/test/resources/ves_artifact_invalid_stndDefined_events.yaml b/src/test/resources/ves_artifact_invalid_stndDefined_events.yaml
new file mode 100644
index 0000000..08d4716
--- /dev/null
+++ b/src/test/resources/ves_artifact_invalid_stndDefined_events.yaml
@@ -0,0 +1,107 @@
+---
+event:
+ presence: required
+ action: [ any, any, null, null, null ]
+ comment: "
+ ALARM NAME: LogHasReachedFullCapacity,
+ ALARM DESCRIPTION: 'Log Has Reached Full Capacity',
+ ALARM EFFECT: 'See alarm OPI x/2223-ABC 123 4567/1 Uen',
+ MANAGED OBJECT CLASSES: Log,
+ EVENT TYPE: 'PROCESSINGERRORALARM',
+ PROBABLE CAUSE: 'FileError',
+ PROPOSED REPAIR ACTIONS: 'See alarm OPI x/3334-ABC 123 4567/1 Uen',
+ CLEARING TYPE: Automatic
+ "
+ structure:
+ commonEventHeader:
+ presence: required
+ structure:
+ version: {presence: required, value: 4.0.1}
+ vesEventListenerVersion: {presence: required, value: 7.0.1}
+ domain: {presence: required, value: fault}
+ eventName: {presence: required, value: Fault_MyPnf-Acme_LogHasReachedFullCapacity}
+ eventId: {presence: required}
+ sequence: {presence: required}
+ priority: {presence: required, value: Normal}
+ reportingEntityName: {presence: required}
+ sourceName: {presence: required}
+ nfVendorName: {presence: required, value: Acme}
+ startEpochMicrosec: {presence: required}
+ lastEpochMicrosec: {presence: required}
+ timeZoneOffset: {presence: required}
+ faultFields:
+ presence: required
+ structure:
+ faultFieldsVersion: {presence: required, value: 4.0}
+ alarmCondition: {presence: required, value: 'LogHasReachedFullCapacity'}
+ eventCategory: {presence: required, value: 'PROCESSINGERRORALARM'}
+ eventSourceType: {presence: required}
+ specificProblem: {presence: required, value: 'Log Has Reached Full Capacity'}
+ eventSeverity: {presence: required}
+ vfStatus: {presence: required, value: Active}
+ alarmAdditionalInformation: {presence: required, structure: {
+ keyValuePair: {presence: required, structure: {key: {presence: required, value: source},value: {presence: required}}},
+ keyValuePair: {presence: required, structure: {key: {presence: required, value: probableCause},value: {presence: required, value: 'FileError'}}},
+ keyValuePair: {presence: required, structure: {key: {presence: required, value: additionalText},value: {presence: optional}}},
+ keyValuePair: {presence: required, structure: {key: {presence: required, value: additionalInfo},value: {presence: optional}}}}
+ }
+...
+---
+event:
+ presence: required
+ comment: "stndDefined event to support 3GPP FaultSupervision NotifyNewAlarm notification"
+ structure:
+ commonEventHeader:
+ presence: required
+ structure:
+ domain: {presence: required, value: stndDefined}
+ eventName: {presence: required, value: stndDefined-gNB-Nokia-Notification}
+ priority: {presence: required, value: Normal}
+ eventId: {presence: required}
+ reportingEntityId: {presence: required}
+ reportingEntityName: {presence: required}
+ sequence: {presence: required, value: 0}
+ sourceId: {presence: required}
+ sourceName: {presence: required}
+ version: {presence: required, value: 4.1}
+ vesEventListenerVersion: {presence: required, value: 7.2}
+ startEpochMicrosec: {presence: required}
+ lastEpochMicrosec: {presence: required}
+ stndDefinedNamespace: {presence: required, value: "3GPP-FaultSupervision"}
+ stndDefinedFields:
+ presence: required
+ structure:
+ schemaReference: { presence: required, value: "https://forge.3gpp.org/rep/invalid" }
+ data: {presence: required}
+ stndDefinedFieldsVersion: {presence: required, value: "1.0"}
+
+...
+---
+event:
+ presence: required
+ comment: "stndDefined event to support 3GPP FaultSupervision NotifyNewAlarm notification"
+ structure:
+ commonEventHeader:
+ presence: required
+ structure:
+ domain: {presence: required, value: stndDefined}
+ eventName: {presence: required, value: stndDefined-gNB-Nokia-Notification}
+ priority: {presence: required, value: Normal}
+ eventId: {presence: required}
+ reportingEntityId: {presence: required}
+ reportingEntityName: {presence: required}
+ sequence: {presence: required, value: 0}
+ sourceId: {presence: required}
+ sourceName: {presence: required}
+ version: {presence: required, value: 4.1}
+ vesEventListenerVersion: {presence: required, value: 7.2}
+ startEpochMicrosec: {presence: required}
+ lastEpochMicrosec: {presence: required}
+ stndDefinedNamespace: {presence: required, value: "3GPP-FaultSupervision"}
+ stndDefinedFields:
+ presence: required
+ structure:
+ schemaReference: { presence: required, value: ["https://forge.3gpp.org/rep/sa5/MnS/tree/another_invalid.yaml", "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerfDataStreamingMnS.yaml"] }
+ data: {presence: required}
+ stndDefinedFieldsVersion: {presence: required, value: "1.0"}
+... \ No newline at end of file
diff --git a/src/test/resources/ves_artifact_stndDefined_events.yaml b/src/test/resources/ves_artifact_stndDefined_events.yaml
new file mode 100644
index 0000000..11f805b
--- /dev/null
+++ b/src/test/resources/ves_artifact_stndDefined_events.yaml
@@ -0,0 +1,107 @@
+---
+event:
+ presence: required
+ action: [ any, any, null, null, null ]
+ comment: "
+ ALARM NAME: LogHasReachedFullCapacity,
+ ALARM DESCRIPTION: 'Log Has Reached Full Capacity',
+ ALARM EFFECT: 'See alarm OPI x/2223-ABC 123 4567/1 Uen',
+ MANAGED OBJECT CLASSES: Log,
+ EVENT TYPE: 'PROCESSINGERRORALARM',
+ PROBABLE CAUSE: 'FileError',
+ PROPOSED REPAIR ACTIONS: 'See alarm OPI x/3334-ABC 123 4567/1 Uen',
+ CLEARING TYPE: Automatic
+ "
+ structure:
+ commonEventHeader:
+ presence: required
+ structure:
+ version: {presence: required, value: 4.0.1}
+ vesEventListenerVersion: {presence: required, value: 7.0.1}
+ domain: {presence: required, value: fault}
+ eventName: {presence: required, value: Fault_MyPnf-Acme_LogHasReachedFullCapacity}
+ eventId: {presence: required}
+ sequence: {presence: required}
+ priority: {presence: required, value: Normal}
+ reportingEntityName: {presence: required}
+ sourceName: {presence: required}
+ nfVendorName: {presence: required, value: Acme}
+ startEpochMicrosec: {presence: required}
+ lastEpochMicrosec: {presence: required}
+ timeZoneOffset: {presence: required}
+ faultFields:
+ presence: required
+ structure:
+ faultFieldsVersion: {presence: required, value: 4.0}
+ alarmCondition: {presence: required, value: 'LogHasReachedFullCapacity'}
+ eventCategory: {presence: required, value: 'PROCESSINGERRORALARM'}
+ eventSourceType: {presence: required}
+ specificProblem: {presence: required, value: 'Log Has Reached Full Capacity'}
+ eventSeverity: {presence: required}
+ vfStatus: {presence: required, value: Active}
+ alarmAdditionalInformation: {presence: required, structure: {
+ keyValuePair: {presence: required, structure: {key: {presence: required, value: source},value: {presence: required}}},
+ keyValuePair: {presence: required, structure: {key: {presence: required, value: probableCause},value: {presence: required, value: 'FileError'}}},
+ keyValuePair: {presence: required, structure: {key: {presence: required, value: additionalText},value: {presence: optional}}},
+ keyValuePair: {presence: required, structure: {key: {presence: required, value: additionalInfo},value: {presence: optional}}}}
+ }
+...
+---
+event:
+ presence: required
+ comment: "stndDefined event to support 3GPP FaultSupervision NotifyNewAlarm notification"
+ structure:
+ commonEventHeader:
+ presence: required
+ structure:
+ domain: {presence: required, value: stndDefined}
+ eventName: {presence: required, value: stndDefined-gNB-Nokia-Notification}
+ priority: {presence: required, value: Normal}
+ eventId: {presence: required}
+ reportingEntityId: {presence: required}
+ reportingEntityName: {presence: required}
+ sequence: {presence: required, value: 0}
+ sourceId: {presence: required}
+ sourceName: {presence: required}
+ version: {presence: required, value: 4.1}
+ vesEventListenerVersion: {presence: required, value: 7.2}
+ startEpochMicrosec: {presence: required}
+ lastEpochMicrosec: {presence: required}
+ stndDefinedNamespace: {presence: required, value: "3GPP-FaultSupervision"}
+ stndDefinedFields:
+ presence: required
+ structure:
+ schemaReference: { presence: required, value: "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerMeasJobCtlMnS.yaml" }
+ data: {presence: required}
+ stndDefinedFieldsVersion: {presence: required, value: "1.0"}
+
+...
+---
+event:
+ presence: required
+ comment: "stndDefined event to support 3GPP FaultSupervision NotifyNewAlarm notification"
+ structure:
+ commonEventHeader:
+ presence: required
+ structure:
+ domain: {presence: required, value: stndDefined}
+ eventName: {presence: required, value: stndDefined-gNB-Nokia-Notification}
+ priority: {presence: required, value: Normal}
+ eventId: {presence: required}
+ reportingEntityId: {presence: required}
+ reportingEntityName: {presence: required}
+ sequence: {presence: required, value: 0}
+ sourceId: {presence: required}
+ sourceName: {presence: required}
+ version: {presence: required, value: 4.1}
+ vesEventListenerVersion: {presence: required, value: 7.2}
+ startEpochMicrosec: {presence: required}
+ lastEpochMicrosec: {presence: required}
+ stndDefinedNamespace: {presence: required, value: "3GPP-FaultSupervision"}
+ stndDefinedFields:
+ presence: required
+ structure:
+ schemaReference: { presence: required, value: ["https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerThresMonMnS.yaml", "https://forge.3gpp.org/rep/sa5/MnS/tree/SA88-Rel16/OpenAPI/PerfDataStreamingMnS.yaml"] }
+ data: {presence: required}
+ stndDefinedFieldsVersion: {presence: required, value: "1.0"}
+... \ No newline at end of file
diff --git a/version.properties b/version.properties
new file mode 100644
index 0000000..32acbf9
--- /dev/null
+++ b/version.properties
@@ -0,0 +1,6 @@
+major=1
+minor=0
+patch=0
+base_version=${major}.${minor}.${patch}
+release_version=${base_version}
+snapshot_version=${base_version}-SNAPSHOT \ No newline at end of file