aboutsummaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-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
20 files changed, 1455 insertions, 0 deletions
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