From: Fiete Ostkamp Date: Mon, 29 Apr 2024 14:27:03 +0000 (+0200) Subject: Refactor babel-related code to not update parameter values X-Git-Url: https://gerrit.onap.org/r/gitweb?p=aai%2Fmodel-loader.git;a=commitdiff_plain;h=HEAD;hp=50889fa7107127868a9a4391218772ff58d0ac2e Refactor babel-related code to not update parameter values - return processed Artifact's as List in BabelArtifactService and ArtifactDownloadManager Issue-ID: AAI-3840 Change-Id: Ibc78517e87ebf1bfc9c6336555c96e6d1506cf5c Signed-off-by: Fiete Ostkamp --- diff --git a/.gitignore b/.gitignore index 56f75e2..e4b4035 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ debug-logs/ .checkstyle .idea/ *.iml +.vscode \ No newline at end of file diff --git a/INFO.yaml b/INFO.yaml index fb42332..3cd8e0a 100644 --- a/INFO.yaml +++ b/INFO.yaml @@ -41,6 +41,16 @@ committers: id: 'jimmydot' company: 'ATT' timezone: 'America/Detroit' + - name: 'Fiete Ostkamp' + email: 'fiete.ostkamp@telekom.de' + id: 'fostkamp' + company: 'Deutsche Telekom' + timezone: 'Europe/Berlin' + - name: 'Nandkishor Patke' + email: 'nandkishor-laxman.patke@t-systems.com' + id: 'nandkishorpatke' + company: 'T-Systems' + timezone: 'Asia/Kolkata' tsc: approval: 'https://lists.onap.org/g/onap-tsc' changes: @@ -65,3 +75,9 @@ tsc: - type: 'removal' name: 'Harish Kajur' link: 'https://lists.onap.org/g/onap-tsc/message/8850' + - type: 'Addition' + name: 'Fiete Ostkamp' + link: 'https://lists.onap.org/g/onap-tsc/message/9499' + - type: 'Addition' + name: 'Nandkishor Patke' + link: 'https://lists.onap.org/g/onap-tsc/message/9499' diff --git a/Readme.md b/README.md similarity index 100% rename from Readme.md rename to README.md diff --git a/pom.xml b/pom.xml index abf60e2..fb4aad4 100644 --- a/pom.xml +++ b/pom.xml @@ -26,14 +26,14 @@ org.onap.oparent oparent - 2.1.0 + 3.3.3 org.onap.aai.model-loader model-loader aai-model-loader - 1.12.0-SNAPSHOT + 1.14.0-SNAPSHOT @@ -44,6 +44,13 @@ pom import + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + @@ -51,13 +58,14 @@ org.onap.aai.modelloader.service.ModelLoaderApplication https://nexus.onap.org ${basedir}/target - 2.3.12.RELEASE + 2.7.18 + 2021.0.8 1.10.0 1.22 + 2.10.1 1.3 - 1.9.5 - 1.2.1 - 2.0.0 + 1.13.0 + 2.1.1 1.2.11 0.39.0 @@ -65,7 +73,7 @@ ${project.build.directory}/${project.artifactId}-${project.version}-build/ onap alpine - 1.8.1 + 1.13.2 yyyyMMdd'T'HHmmss'Z' @@ -214,6 +222,7 @@ + org.springframework.boot @@ -229,10 +238,26 @@ + + org.springframework.boot + spring-boot-starter-aop + test + org.apache.kafka kafka-clients - 3.3.1 + + + + org.springframework.kafka + spring-kafka + + + + org.springframework.kafka + spring-kafka-test + + test org.onap.aai @@ -246,19 +271,10 @@ - - org.glassfish.jersey.core - jersey-common - test - - - org.onap.aai - rest-client - ${aai.rest.client.version} - com.google.code.gson gson + ${gson.version} @@ -266,7 +282,7 @@ com.mikesamuel json-sanitizer - 1.2.0 + 1.2.3 @@ -278,32 +294,20 @@ ch.qos.logback logback-classic - ${logback.version} + ${logback.version} + ch.qos.logback logback-core - ${logback.version} + ${logback.version} + org.onap.sdc.sdc-distribution-client sdc-distribution-client ${sdc-distribution-client.version} - - org.json - json - 20131018 - - - org.eclipse.jetty - jetty-security - - - jline - jline - 2.12.1 - org.apache.commons commons-compress @@ -319,19 +323,36 @@ commons-text ${apache.commons-text.version} - - - junit - junit - test + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-sleuth-zipkin + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + + org.hamcrest hamcrest-all ${hamcrest-all.version} test + + org.junit.jupiter + junit-jupiter + test + + + org.junit.jupiter + junit-jupiter-api + test + org.mockito mockito-core @@ -341,6 +362,17 @@ org.springframework.boot spring-boot-starter-test test + + + com.vaadin.external.google + android-json + + + + + org.springframework.cloud + spring-cloud-contract-wiremock + test @@ -565,7 +597,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M4 + 3.1.2 ${surefireArgLine} @@ -578,7 +610,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.0.0-M4 + 3.1.2 diff --git a/releases/1.13.5-container-release.yaml b/releases/1.13.5-container-release.yaml new file mode 100644 index 0000000..0177137 --- /dev/null +++ b/releases/1.13.5-container-release.yaml @@ -0,0 +1,7 @@ +distribution_type: container +container_release_tag: 1.13.5 +project: model-loader +ref: ba282826d84f17e3156de99c39e6b1d50813f8ba +containers: + - name: model-loader + version: 1.13-STAGING-20240326T082727Z diff --git a/releases/1.13.5-maven-release.yaml b/releases/1.13.5-maven-release.yaml new file mode 100644 index 0000000..71cc585 --- /dev/null +++ b/releases/1.13.5-maven-release.yaml @@ -0,0 +1,4 @@ +distribution_type: maven +log_dir: aai-model-loader-maven-stage-master/1396/ +project: model-loader +version: 1.13.5 diff --git a/releases/1.13.6-container-release.yaml b/releases/1.13.6-container-release.yaml new file mode 100644 index 0000000..873cd80 --- /dev/null +++ b/releases/1.13.6-container-release.yaml @@ -0,0 +1,7 @@ +distribution_type: container +container_release_tag: 1.13.6 +project: model-loader +ref: df2ad94ee9b641a4c2c19969816a6275f6d056e3 +containers: + - name: model-loader + version: 1.13-STAGING-20240417T124725Z diff --git a/releases/1.14.0-container-release.yaml b/releases/1.14.0-container-release.yaml new file mode 100644 index 0000000..cba0f30 --- /dev/null +++ b/releases/1.14.0-container-release.yaml @@ -0,0 +1,7 @@ +distribution_type: container +container_release_tag: 1.14.0 +project: model-loader +ref: de4e6c93f2f4038167e8b5fef92426c4daac4b83 +containers: + - name: model-loader + version: 1.14-STAGING-20240425T063121Z diff --git a/src/test/java/org/onap/aai/modelloader/TestModelLoaderApplication.java b/src/main/java/org/onap/aai/modelloader/babel/BabelArtifact.java similarity index 60% rename from src/test/java/org/onap/aai/modelloader/TestModelLoaderApplication.java rename to src/main/java/org/onap/aai/modelloader/babel/BabelArtifact.java index 0387f2d..6de318b 100644 --- a/src/test/java/org/onap/aai/modelloader/TestModelLoaderApplication.java +++ b/src/main/java/org/onap/aai/modelloader/babel/BabelArtifact.java @@ -2,8 +2,7 @@ * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017-2018 European Software Marketing Ltd. + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,27 +17,19 @@ * limitations under the License. * ============LICENSE_END========================================================= */ -package org.onap.aai.modelloader; +package org.onap.aai.modelloader.babel; -import static org.junit.Assert.assertTrue; +import org.onap.aai.modelloader.entity.ArtifactType; -import org.junit.Test; - -/** - * Tests for ModelLoaderApplication class. - * - */ -public class TestModelLoaderApplication { - - static { - System.setProperty("CONFIG_HOME", "src/test/resources"); - } - - @Test - public void testServiceStarts() { - // The SDC Distribution Client is disabled. - ModelLoaderApplication.main(new String[0]); - assertTrue(true); - } +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +@Data +@NoArgsConstructor +@AllArgsConstructor +public class BabelArtifact { + String name; + public ArtifactType type; + String payload; } diff --git a/src/main/java/org/onap/aai/modelloader/babel/BabelArtifactService.java b/src/main/java/org/onap/aai/modelloader/babel/BabelArtifactService.java new file mode 100644 index 0000000..029814a --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/babel/BabelArtifactService.java @@ -0,0 +1,102 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.babel; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.aai.babel.service.data.BabelArtifact; +import org.onap.aai.babel.service.data.BabelArtifact.ArtifactType; +import org.onap.aai.babel.service.data.BabelRequest; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.modelloader.entity.Artifact; +import org.onap.aai.modelloader.entity.model.BabelArtifactParsingException; +import org.onap.aai.modelloader.notification.BabelArtifactConverter; +import org.onap.aai.modelloader.notification.ProcessToscaArtifactsException; +import org.onap.aai.modelloader.restclient.BabelServiceClient; +import org.onap.aai.modelloader.service.ModelLoaderMsgs; +import org.springframework.stereotype.Service; + +@Service +public class BabelArtifactService { + + private static Logger logger = LoggerFactory.getInstance().getLogger(BabelArtifactService.class); + + private final BabelServiceClient babelServiceClient; + private final BabelArtifactConverter babelArtifactConverter; + + public BabelArtifactService(BabelServiceClient babelServiceClient, BabelArtifactConverter babelArtifactConverter) { + this.babelServiceClient = babelServiceClient; + this.babelArtifactConverter = babelArtifactConverter; + } + + public List invokeBabelService(BabelRequest babelRequest, String distributionId) + throws ProcessToscaArtifactsException { + try { + logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, + "Posting artifact: " + babelRequest.getArtifactName() + ", service version: " + + babelRequest.getArtifactVersion() + + ", artifact version: " + babelRequest.getArtifactVersion()); + + List babelArtifacts = babelServiceClient.postArtifact(babelRequest, distributionId); + + List convertedArtifacts = new ArrayList<>(); + for(BabelArtifact babelArtifact : babelArtifacts) { + if(!isUnknownType(babelArtifact)) { + if(babelArtifact.getType() == ArtifactType.MODEL) { + convertedArtifacts.addAll(babelArtifactConverter.convertToModel(babelArtifact)); + } else { + convertedArtifacts.add(babelArtifactConverter.convertToCatalog(babelArtifact)); + } + } + } + + return convertedArtifacts; + + } catch (BabelArtifactParsingException e) { + logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, + "Error for artifact " + babelRequest.getArtifactName() + " " + babelRequest.getArtifactVersion() + + " " + e); + throw new ProcessToscaArtifactsException( + "An error occurred while trying to parse the Babel artifacts: " + e.getLocalizedMessage()); + } catch (Exception e) { + logger.error(ModelLoaderMsgs.BABEL_REST_REQUEST_ERROR, e, "POST", + "Error posting artifact " + babelRequest.getArtifactName() + " " + babelRequest.getArtifactVersion() + + " to Babel: " + + e.getLocalizedMessage()); + throw new ProcessToscaArtifactsException( + "An error occurred while calling the Babel service: " + e.getLocalizedMessage()); + } + } + + private boolean isUnknownType(BabelArtifact babelArtifact) { + if (babelArtifact.getType() == ArtifactType.MODEL || babelArtifact.getType() == ArtifactType.VNFCATALOG) { + return false; + } else { + logger.warn(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, + babelArtifact.getName() + " " + babelArtifact.getType() + + ". Unexpected artifact types returned by the babel service: " + + babelArtifact.getPayload()); + return true; + } + } + +} \ No newline at end of file diff --git a/src/main/java/org/onap/aai/modelloader/config/BeanConfig.java b/src/main/java/org/onap/aai/modelloader/config/BeanConfig.java new file mode 100644 index 0000000..cc6702b --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/config/BeanConfig.java @@ -0,0 +1,72 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.config; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Properties; + +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.modelloader.service.ModelLoaderMsgs; +import org.onap.sdc.api.IDistributionClient; +import org.onap.sdc.impl.DistributionClientFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class BeanConfig { + + private static final Logger logger = LoggerFactory.getInstance().getLogger(BeanConfig.class); + + + @Value("${CONFIG_HOME}") + private String configDir; + + @Bean + public Properties configProperties() throws IOException { + // Load model loader system configuration + logger.info(ModelLoaderMsgs.LOADING_CONFIGURATION); + InputStream configInputStream = Files.newInputStream(Paths.get(configDir, "model-loader.properties")); + Properties configProperties = new Properties(); + configProperties.load(configInputStream); + return configProperties; + } + + @Bean + public ModelLoaderConfig modelLoaderConfig(Properties configProperties) { + ModelLoaderConfig.setConfigHome(configDir); + return new ModelLoaderConfig(configProperties); + } + + @Bean + public IDistributionClient iDistributionClient() { + return DistributionClientFactory.createDistributionClient(); + } + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } +} diff --git a/src/main/java/org/onap/aai/modelloader/config/DistributionClientStartupConfig.java b/src/main/java/org/onap/aai/modelloader/config/DistributionClientStartupConfig.java new file mode 100644 index 0000000..cd9d919 --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/config/DistributionClientStartupConfig.java @@ -0,0 +1,88 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.config; + +import java.util.Date; +import java.util.Timer; +import java.util.TimerTask; + +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.modelloader.notification.EventCallback; +import org.onap.aai.modelloader.service.ModelLoaderMsgs; +import org.onap.aai.modelloader.service.SdcConnectionJob; +import org.onap.sdc.api.IDistributionClient; +import org.onap.sdc.api.results.IDistributionClientResult; +import org.onap.sdc.utils.DistributionActionResultEnum; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.event.EventListener; + +@Configuration +@ConditionalOnProperty(value = "ml.distribution.connection.enabled", havingValue = "true", matchIfMissing = true) +public class DistributionClientStartupConfig { + + private static final Logger logger = LoggerFactory.getInstance().getLogger(DistributionClientStartupConfig.class); + + private final IDistributionClient client; + private final ModelLoaderConfig config; + private final EventCallback eventCallback; + + public DistributionClientStartupConfig(IDistributionClient client, ModelLoaderConfig config, + EventCallback eventCallback) { + this.client = client; + this.config = config; + this.eventCallback = eventCallback; + } + + @EventListener(ApplicationReadyEvent.class) + protected void initSdcClient() { + // Initialize distribution client + logger.debug(ModelLoaderMsgs.INITIALIZING, "Initializing distribution client..."); + IDistributionClientResult initResult = null; + initResult = client.init(config, eventCallback); + + if (initResult.getDistributionActionResult() == DistributionActionResultEnum.SUCCESS) { + // Start distribution client + logger.debug(ModelLoaderMsgs.INITIALIZING, "Starting distribution client..."); + IDistributionClientResult startResult = client.start(); + if (startResult.getDistributionActionResult() == DistributionActionResultEnum.SUCCESS) { + logger.info(ModelLoaderMsgs.INITIALIZING, "Connection to SDC established"); + } else { + String errorMsg = "Failed to start distribution client: " + startResult.getDistributionMessageResult(); + logger.error(ModelLoaderMsgs.ASDC_CONNECTION_ERROR, errorMsg); + + // Kick off a timer to retry the SDC connection + Timer timer = new Timer(); + TimerTask task = new SdcConnectionJob(client, config, eventCallback, timer); + timer.schedule(task, new Date(), 60000); + } + } else { + String errorMsg = "Failed to initialize distribution client: " + initResult.getDistributionMessageResult(); + logger.error(ModelLoaderMsgs.ASDC_CONNECTION_ERROR, errorMsg); + + // Kick off a timer to retry the SDC connection + Timer timer = new Timer(); + TimerTask task = new SdcConnectionJob(client, config, eventCallback, timer); + timer.schedule(task, new Date(), 60000); + } + } +} diff --git a/src/main/java/org/onap/aai/modelloader/config/ModelLoaderConfig.java b/src/main/java/org/onap/aai/modelloader/config/ModelLoaderConfig.java index 77693bc..6723e75 100644 --- a/src/main/java/org/onap/aai/modelloader/config/ModelLoaderConfig.java +++ b/src/main/java/org/onap/aai/modelloader/config/ModelLoaderConfig.java @@ -27,12 +27,12 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.Properties; + import org.apache.commons.lang3.StringUtils; import org.eclipse.jetty.util.security.Password; import org.onap.sdc.api.consumer.IConfiguration; -import org.springframework.core.env.Environment; - /** * Properties for the Model Loader * @@ -77,6 +77,9 @@ public class ModelLoaderConfig implements IConfiguration { protected static final String PROP_ML_DISTRIBUTION_HTTP_PROXY_PORT = PREFIX_DISTRIBUTION_CLIENT + "HTTP_PROXY_PORT"; protected static final String PROP_ML_DISTRIBUTION_HTTPS_PROXY_HOST = PREFIX_DISTRIBUTION_CLIENT + "HTTPS_PROXY_HOST"; protected static final String PROP_ML_DISTRIBUTION_HTTPS_PROXY_PORT = PREFIX_DISTRIBUTION_CLIENT + "HTTPS_PROXY_PORT"; + protected static final String PROP_ML_DISTRIBUTION_SASL_JAAS_CONFIG = PREFIX_DISTRIBUTION_CLIENT + "SASL_JAAS_CONFIG"; + protected static final String PROP_ML_DISTRIBUTION_SASL_MECHANISM = PREFIX_DISTRIBUTION_CLIENT + "SASL_MECHANISM"; + protected static final String PROP_ML_DISTRIBUTION_SECURITY_PROTOCOL = PREFIX_DISTRIBUTION_CLIENT + "SECURITY_PROTOCOL"; protected static final String PROP_AAI_BASE_URL = PREFIX_AAI + "BASE_URL"; protected static final String PROP_AAI_KEYSTORE_FILE = PREFIX_AAI + SUFFIX_KEYSTORE_FILE; protected static final String PROP_AAI_KEYSTORE_PASSWORD = PREFIX_AAI + SUFFIX_KEYSTORE_PASS; @@ -97,6 +100,8 @@ public class ModelLoaderConfig implements IConfiguration { protected static final String PROP_DEBUG_INGEST_SIMULATOR = PREFIX_DEBUG + "INGEST_SIMULATOR"; protected static final String FILESEP = (System.getProperty("file.separator") == null) ? "/" : System.getProperty("file.separator"); + protected static final String PROP_AAI_CLIENT_CONNECT_TIMEOUT_MS = PREFIX_AAI + "RESTCLIENT_CONNECT_TIMEOUT"; + protected static final String PROP_AAI_CLIENT_READ_TIMEOUT_MS = PREFIX_AAI + "RESTCLIENT_READ_TIMEOUT"; private static String configHome; private Properties modelLoaderProperties = null; @@ -401,4 +406,45 @@ public class ModelLoaderConfig implements IConfiguration { } } + public int getClientConnectTimeoutMs() { + String connectTimeout = Optional.ofNullable(get(PROP_AAI_CLIENT_CONNECT_TIMEOUT_MS)).orElse("120000"); + return Integer.parseInt(connectTimeout); + } + + public int getClientReadTimeoutMs() { + String connectTimeout = Optional.ofNullable(get(PROP_AAI_CLIENT_READ_TIMEOUT_MS)).orElse("120000"); + return Integer.parseInt(connectTimeout); + } + + @Override + public String getKafkaSaslJaasConfig() { + String saslJaasConfFromEnv = System.getenv("SASL_JAAS_CONFIG"); + if(saslJaasConfFromEnv != null) { + return saslJaasConfFromEnv; + } + if(get(PROP_ML_DISTRIBUTION_SASL_JAAS_CONFIG) != null) { + return get(PROP_ML_DISTRIBUTION_SASL_JAAS_CONFIG); + } + return null; + } + + @Override + public String getKafkaSaslMechanism() { + if(get(PROP_ML_DISTRIBUTION_SASL_MECHANISM) != null) { + return get(PROP_ML_DISTRIBUTION_SASL_MECHANISM); + } + return System.getenv().getOrDefault("SASL_MECHANISM", "SCRAM-SHA-512"); + } + + /** + * One of PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL + */ + @Override + public String getKafkaSecurityProtocolConfig() { + if(get(PROP_ML_DISTRIBUTION_SECURITY_PROTOCOL) != null) { + return get(PROP_ML_DISTRIBUTION_SECURITY_PROTOCOL); + } + return System.getenv().getOrDefault("SECURITY_PROTOCOL", "SASL_PLAINTEXT"); + } + } diff --git a/src/main/java/org/onap/aai/modelloader/entity/AaiResourcesObject.java b/src/main/java/org/onap/aai/modelloader/entity/AaiResourcesObject.java new file mode 100644 index 0000000..35232f3 --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/entity/AaiResourcesObject.java @@ -0,0 +1,34 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class AaiResourcesObject { + @JsonProperty("resource-version") + private String resourceVersion; +} diff --git a/src/main/java/org/onap/aai/modelloader/entity/catalog/VnfCatalogArtifactHandler.java b/src/main/java/org/onap/aai/modelloader/entity/catalog/VnfCatalogArtifactHandler.java index c54d7b2..9b05024 100644 --- a/src/main/java/org/onap/aai/modelloader/entity/catalog/VnfCatalogArtifactHandler.java +++ b/src/main/java/org/onap/aai/modelloader/entity/catalog/VnfCatalogArtifactHandler.java @@ -30,8 +30,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.UUID; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.commons.text.StringEscapeUtils; @@ -41,9 +39,13 @@ import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.modelloader.config.ModelLoaderConfig; import org.onap.aai.modelloader.entity.Artifact; import org.onap.aai.modelloader.entity.ArtifactHandler; +import org.onap.aai.modelloader.entity.vnf.VnfImages; import org.onap.aai.modelloader.restclient.AaiRestClient; import org.onap.aai.modelloader.service.ModelLoaderMsgs; -import org.onap.aai.restclient.client.OperationResult; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -53,6 +55,7 @@ import org.xml.sax.InputSource; /** * VNF Catalog specific handling */ +@Component public class VnfCatalogArtifactHandler extends ArtifactHandler { private static Logger logger = LoggerFactory.getInstance().getLogger(VnfCatalogArtifactHandler.class.getName()); @@ -145,7 +148,7 @@ public class VnfCatalogArtifactHandler extends ArtifactHandler { String imageId = imageIdBuilder.toString(); int resultCode = getVnfImage(restClient, distributionId, imageId, dataItem); - if (resultCode == Response.Status.NOT_FOUND.getStatusCode()) { + if (resultCode == HttpStatus.NOT_FOUND.value()) { // This vnf-image is missing, so add it boolean success = putVnfImage(restClient, dataItem, distributionId); if (success) { @@ -154,7 +157,7 @@ public class VnfCatalogArtifactHandler extends ArtifactHandler { } else { throw new VnfImageException(imageId); } - } else if (resultCode == Response.Status.OK.getStatusCode()) { + } else if (resultCode == HttpStatus.OK.value()) { logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, imageId + " already exists. Skipping ingestion."); } else { // if other than 404 or 200, something went wrong @@ -170,12 +173,12 @@ public class VnfCatalogArtifactHandler extends ArtifactHandler { for (Entry entry : dataItem.entrySet()) { b.addParameter(entry.getKey(), entry.getValue()); } - OperationResult tryGet = - restClient.getResource(b.build().toString(), distributionId, MediaType.APPLICATION_JSON_TYPE); + ResponseEntity tryGet = + restClient.getResource(b.build().toString(), distributionId, MediaType.APPLICATION_JSON, VnfImages.class); if (tryGet == null) { throw new VnfImageException(imageId); } - return tryGet.getResultCode(); + return tryGet.getStatusCodeValue(); } catch (URISyntaxException ex) { throw new VnfImageException(ex); } @@ -186,11 +189,12 @@ public class VnfCatalogArtifactHandler extends ArtifactHandler { String uuid = UUID.randomUUID().toString(); dataItem.put(ATTR_UUID, uuid); + // TODO: Get rid of the dataItem map and replace it with the VnfImage object String payload = new Gson().toJson(dataItem); String putUrl = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/" + uuid; - OperationResult putResp = - restClient.putResource(putUrl, payload, distributionId, MediaType.APPLICATION_JSON_TYPE); - return putResp != null && putResp.getResultCode() == Response.Status.CREATED.getStatusCode(); + ResponseEntity putResp = + restClient.putResource(putUrl, payload, distributionId, MediaType.APPLICATION_JSON, String.class); + return putResp != null && putResp.getStatusCode() == HttpStatus.CREATED; } private List> unmarshallVnfcData(Artifact vnfcArtifact) { diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/AbstractModelArtifact.java b/src/main/java/org/onap/aai/modelloader/entity/model/AbstractModelArtifact.java index 7d5cafb..eebead3 100644 --- a/src/main/java/org/onap/aai/modelloader/entity/model/AbstractModelArtifact.java +++ b/src/main/java/org/onap/aai/modelloader/entity/model/AbstractModelArtifact.java @@ -25,7 +25,6 @@ import java.io.IOException; import java.util.HashSet; import java.util.List; import java.util.Set; -import javax.ws.rs.core.MediaType; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.modelloader.config.ModelLoaderConfig; @@ -34,8 +33,9 @@ import org.onap.aai.modelloader.entity.ArtifactType; import org.onap.aai.modelloader.restclient.AaiRestClient; import org.onap.aai.modelloader.service.ModelLoaderMsgs; import org.onap.aai.modelloader.util.GizmoTranslator; -import org.onap.aai.restclient.client.OperationResult; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; public abstract class AbstractModelArtifact extends Artifact implements IModelArtifact { @@ -85,10 +85,11 @@ public abstract class AbstractModelArtifact extends Artifact implements IModelAr protected boolean pushToGizmo(AaiRestClient aaiClient, ModelLoaderConfig config, String distId) { try { String gizmoPayload = GizmoTranslator.translate(getPayload()); - OperationResult postResponse = aaiClient.postResource(config.getAaiBaseUrl().trim(), gizmoPayload, distId, - MediaType.APPLICATION_JSON_TYPE); + // TODO: Use correct responseType here + ResponseEntity postResponse = aaiClient.postResource(config.getAaiBaseUrl().trim(), gizmoPayload, distId, + MediaType.APPLICATION_JSON, String.class); - if (postResponse.getResultCode() != HttpStatus.OK.value()) { + if (postResponse.getStatusCode() != HttpStatus.OK) { return false; } } catch (IOException e) { diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/AbstractModelArtifactParser.java b/src/main/java/org/onap/aai/modelloader/entity/model/AbstractModelArtifactParser.java index 35405e6..14f46f3 100644 --- a/src/main/java/org/onap/aai/modelloader/entity/model/AbstractModelArtifactParser.java +++ b/src/main/java/org/onap/aai/modelloader/entity/model/AbstractModelArtifactParser.java @@ -82,7 +82,8 @@ public abstract class AbstractModelArtifactParser implements IModelParser { IModelArtifact model = parseModel(doc.getDocumentElement(), artifactPayload); - if (!processParsedModel(modelList, artifactName, model)) { + boolean success = processParsedModel(modelList, artifactName, model); + if (!success) { modelList = null; } } catch (Exception ex) { diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/ConstrainedElementSet.java b/src/main/java/org/onap/aai/modelloader/entity/model/ConstrainedElementSet.java new file mode 100644 index 0000000..a91cd58 --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/entity/model/ConstrainedElementSet.java @@ -0,0 +1,58 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.entity.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.util.List; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ConstrainedElementSet { + @JsonProperty("constrained-element-set-uuid") + private String constrainedElementSetUuid; + + @JsonProperty("data-owner") + private String dataOwner; + + @JsonProperty("data-source") + private String dataSource; + + @JsonProperty("data-source-version") + private String dataSourceVersion; + + @JsonProperty("constraint-type") + private String constraintType; + + @JsonProperty("check-type") + private String checkType; + + @JsonProperty("resource-version") + private String resourceVersion; + + @JsonProperty("element-choice-sets") + private List elementChoiceSets; +} diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/ElementChoiceSet.java b/src/main/java/org/onap/aai/modelloader/entity/model/ElementChoiceSet.java new file mode 100644 index 0000000..02f9314 --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/entity/model/ElementChoiceSet.java @@ -0,0 +1,58 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.entity.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.util.List; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ElementChoiceSet { + @JsonProperty("element-choice-set-uuid") + private String elementChoiceSetUuid; + + @JsonProperty("data-owner") + private String dataOwner; + + @JsonProperty("data-source") + private String dataSource; + + @JsonProperty("data-source-version") + private String dataSourceVersion; + + @JsonProperty("element-choice-set-name") + private String elementChoiceSetName; + + @JsonProperty("cardinality") + private String cardinality; + + @JsonProperty("resource-version") + private String resourceVersion; + + @JsonProperty("model-elements") + private List modelElements; +} diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/Metadatum.java b/src/main/java/org/onap/aai/modelloader/entity/model/Metadatum.java new file mode 100644 index 0000000..f44e108 --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/entity/model/Metadatum.java @@ -0,0 +1,51 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.entity.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class Metadatum { + @JsonProperty("metaname") + private String metaName; + + @JsonProperty("metaval") + private String metaVal; + + @JsonProperty("data-owner") + private String dataOwner; + + @JsonProperty("data-source") + private String dataSource; + + @JsonProperty("data-source-version") + private String dataSourceVersion; + + @JsonProperty("resource-version") + private String resourceVersion; +} diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/Model.java b/src/main/java/org/onap/aai/modelloader/entity/model/Model.java new file mode 100644 index 0000000..8dea197 --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/entity/model/Model.java @@ -0,0 +1,59 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.entity.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Describes the model returned by aai-resources + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class Model { + + @JsonProperty("model-invariant-id") + private String modelInvariantId; + + @JsonProperty("model-role") + private String modelRole; + + @JsonProperty("data-owner") + private String dataOwner; + + @JsonProperty("data-source") + private String dataSource; + + @JsonProperty("data-source-version") + private String dataSourceVersion; + + @JsonProperty("resource-version") + private String resourceVersion; + + @JsonProperty("model-vers") + List modelVersions; +} diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java b/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java index c7631e8..364fc78 100644 --- a/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java +++ b/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java @@ -20,27 +20,26 @@ */ package org.onap.aai.modelloader.entity.model; -import java.io.StringWriter; import java.util.List; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.xml.XMLConstants; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; + +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.modelloader.config.ModelLoaderConfig; import org.onap.aai.modelloader.entity.Artifact; import org.onap.aai.modelloader.entity.ArtifactType; import org.onap.aai.modelloader.restclient.AaiRestClient; -import org.onap.aai.restclient.client.OperationResult; -import org.w3c.dom.Node; +import org.onap.aai.modelloader.service.ModelLoaderMsgs; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpServerErrorException; public class ModelArtifact extends AbstractModelArtifact { + private static Logger logger = LoggerFactory.getInstance().getLogger(ModelArtifact.class); + private static final String AAI_MODEL_VER_SUB_URL = "/model-vers/model-ver"; private static final String FAILURE_MSG_PREFIX = "Ingestion failed for "; @@ -49,7 +48,7 @@ public class ModelArtifact extends AbstractModelArtifact { private String modelVerId; private String modelInvariantId; - private Node modelVer; + private String modelVer; private boolean firstVersionOfModel = false; public ModelArtifact() { @@ -72,11 +71,11 @@ public class ModelArtifact extends AbstractModelArtifact { this.modelInvariantId = modelInvariantId; } - public Node getModelVer() { + public String getModelVer() { return modelVer; } - public void setModelVer(Node modelVer) { + public void setModelVer(String modelVer) { this.modelVer = modelVer; } @@ -95,8 +94,16 @@ public class ModelArtifact extends AbstractModelArtifact { * @return true if a request to GET this resource as XML media is successful (status OK) */ private boolean xmlResourceCanBeFetched(AaiRestClient aaiClient, String distId, String xmlResourceUrl) { - OperationResult getResponse = getResourceModel(aaiClient, distId, xmlResourceUrl); - return getResponse != null && getResponse.getResultCode() == Response.Status.OK.getStatusCode(); + try { + ResponseEntity getResponse = getResourceModel(aaiClient, distId, xmlResourceUrl); + return getResponse.getStatusCode().equals(HttpStatus.OK); + } catch (HttpClientErrorException e) { + if(e.getStatusCode().equals(HttpStatus.NOT_FOUND)) { + return false; + } else { + throw e; + } + } } /** @@ -107,8 +114,8 @@ public class ModelArtifact extends AbstractModelArtifact { * @param xmlResourceUrl * @return OperationResult the result of the operation */ - private OperationResult getResourceModel(AaiRestClient aaiClient, String distId, String xmlResourceUrl) { - return aaiClient.getResource(xmlResourceUrl, distId, MediaType.APPLICATION_XML_TYPE); + private ResponseEntity getResourceModel(AaiRestClient aaiClient, String distId, String xmlResourceUrl) { + return aaiClient.getResource(xmlResourceUrl, distId, MediaType.APPLICATION_XML, Model.class); } /** @@ -121,9 +128,14 @@ public class ModelArtifact extends AbstractModelArtifact { * @return true if the resource PUT as XML media was successful (status OK) */ private boolean putXmlResource(AaiRestClient aaiClient, String distId, String resourceUrl, String payload) { - OperationResult putResponse = - aaiClient.putResource(resourceUrl, payload, distId, MediaType.APPLICATION_XML_TYPE); - return putResponse != null && putResponse.getResultCode() == Response.Status.CREATED.getStatusCode(); + ResponseEntity putResponse = null; + try { + putResponse = + aaiClient.putResource(resourceUrl, payload, distId, MediaType.APPLICATION_XML, String.class); + } catch (HttpClientErrorException | HttpServerErrorException e) { + logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "Error putting resource: " + e.toString()); + } + return putResponse != null && putResponse.getStatusCode() == HttpStatus.CREATED; } @Override @@ -142,24 +154,44 @@ public class ModelArtifact extends AbstractModelArtifact { // See whether the model is already present String resourceUrl = getModelUrl(config); - OperationResult result = getResourceModel(aaiClient, distId, resourceUrl); + // ResponseEntity result; + boolean modelExists = checkIfModelExists(aaiClient, distId, resourceUrl); - if (result != null) { - if (result.getResultCode() == Response.Status.OK.getStatusCode()) { - success = updateExistingModel(aaiClient, config, distId, completedArtifacts); - } else if (result.getResultCode() == Response.Status.NOT_FOUND.getStatusCode()) { - success = createNewModel(aaiClient, distId, completedArtifacts, resourceUrl); - } else { - logModelUpdateFailure( - "Response code " + result.getResultCode() + " invalid for getting resource model"); - } + if(modelExists) { + success = updateExistingModel(aaiClient, config, distId, completedArtifacts); } else { - logModelUpdateFailure("Null response from RestClient"); + success = createNewModel(aaiClient, distId, completedArtifacts, resourceUrl); } + // if (result != null) { + // if (result.getStatusCode() == HttpStatus.OK) { + // success = updateExistingModel(aaiClient, config, distId, completedArtifacts); + // } else if (result.getStatusCode() == HttpStatus.NOT_FOUND) { + // success = createNewModel(aaiClient, distId, completedArtifacts, resourceUrl); + // } else { + // logModelUpdateFailure( + // "Response code " + result.getStatusCodeValue() + " invalid for getting resource model"); + // } + // } else { + // logModelUpdateFailure("Null response from RestClient"); + // } + return success; } + private boolean checkIfModelExists(AaiRestClient aaiClient, String distId, String resourceUrl) throws HttpClientErrorException { + try { + ResponseEntity response = getResourceModel(aaiClient, distId, resourceUrl); + return response.getStatusCode().equals(HttpStatus.OK); + } catch (HttpClientErrorException e) { + if(e.getStatusCode().equals(HttpStatus.NOT_FOUND)) { + return false; + } else { + throw e; + } + } + } + private boolean createNewModel(AaiRestClient aaiClient, String distId, List completedArtifacts, String resourceUrl) { boolean success; @@ -206,17 +238,12 @@ public class ModelArtifact extends AbstractModelArtifact { // Load the model version boolean success = true; - try { - success = putXmlResource(aaiClient, distId, getModelVerUrl(config), nodeToString(getModelVer())); - if (success) { - completedArtifacts.add(this); - logInfoMsg(getType() + " " + getUniqueIdentifier() + " successfully ingested."); - } else { - logModelUpdateFailure("Error pushing model"); - } - } catch (TransformerException e) { - logModelUpdateFailure(e.getMessage()); - success = false; + success = putXmlResource(aaiClient, distId, getModelVerUrl(config), getModelVer()); + if (success) { + completedArtifacts.add(this); + logInfoMsg(getType() + " " + getUniqueIdentifier() + " successfully ingested."); + } else { + logModelUpdateFailure("Error pushing model"); } return success; @@ -282,16 +309,4 @@ public class ModelArtifact extends AbstractModelArtifact { return baseURL + subURL + instance; } - - private String nodeToString(Node node) throws TransformerException { - StringWriter sw = new StringWriter(); - TransformerFactory transFact = TransformerFactory.newInstance(); - transFact.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - transFact.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - transFact.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - Transformer t = transFact.newTransformer(); - t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); - t.transform(new DOMSource(node), new StreamResult(sw)); - return sw.toString(); - } } diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifactHandler.java b/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifactHandler.java index 626ca49..7aa2191 100644 --- a/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifactHandler.java +++ b/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifactHandler.java @@ -28,7 +28,9 @@ import org.onap.aai.modelloader.entity.Artifact; import org.onap.aai.modelloader.entity.ArtifactHandler; import org.onap.aai.modelloader.restclient.AaiRestClient; import org.onap.aai.modelloader.service.ModelLoaderMsgs; +import org.springframework.stereotype.Service; +@Service public class ModelArtifactHandler extends ArtifactHandler { private static Logger logger = LoggerFactory.getInstance().getLogger(ModelArtifactHandler.class.getName()); diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifactParser.java b/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifactParser.java index adab6df..367b212 100644 --- a/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifactParser.java +++ b/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifactParser.java @@ -20,19 +20,29 @@ */ package org.onap.aai.modelloader.entity.model; +import java.io.StringWriter; import java.util.List; import java.util.Objects; import java.util.stream.Collector; import java.util.stream.IntStream; import javax.xml.XMLConstants; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.modelloader.entity.Artifact; import org.onap.aai.modelloader.service.ModelLoaderMsgs; +import org.springframework.stereotype.Component; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +@Component public class ModelArtifactParser extends AbstractModelArtifactParser { public static final String MODEL_VER = "model-ver"; @@ -53,7 +63,13 @@ public class ModelArtifactParser extends AbstractModelArtifactParser { parseRelationshipNode(node, model); } else { if (node.getNodeName().equalsIgnoreCase(MODEL_VER)) { - ((ModelArtifact) model).setModelVer(node); + String modelVersion; + try { + modelVersion = nodeToString(node); + ((ModelArtifact) model).setModelVer(modelVersion); + } catch (TransformerException e) { + logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Failed to parse resource version for input: " + node.toString()); + } if (((ModelArtifact) model).getModelNamespace() != null && !((ModelArtifact) model).getModelNamespace().isEmpty()) { Element e = (Element) node; @@ -66,6 +82,18 @@ public class ModelArtifactParser extends AbstractModelArtifactParser { } } + private String nodeToString(Node node) throws TransformerException { + StringWriter sw = new StringWriter(); + TransformerFactory transFact = TransformerFactory.newInstance(); + transFact.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + transFact.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + transFact.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + Transformer t = transFact.newTransformer(); + t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + t.transform(new DOMSource(node), new StreamResult(sw)); + return sw.toString(); + } + /** * {@inheritDoc} */ diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/ModelConstraint.java b/src/main/java/org/onap/aai/modelloader/entity/model/ModelConstraint.java new file mode 100644 index 0000000..5081bda --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/entity/model/ModelConstraint.java @@ -0,0 +1,55 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.entity.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.util.List; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ModelConstraint { + @JsonProperty("model-constraint-uuid") + private String modelConstraintUuid; + + @JsonProperty("data-owner") + private String dataOwner; + + @JsonProperty("data-source") + private String dataSource; + + @JsonProperty("data-source-version") + private String dataSourceVersion; + + @JsonProperty("constrained-element-set-uuid-to-replace") + private String constrainedElementSetUuidToReplace; + + @JsonProperty("constrained-element-sets") + private List constrainedElementSets; + + @JsonProperty("resource-version") + private String resourceVersion; +} diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/ModelElement.java b/src/main/java/org/onap/aai/modelloader/entity/model/ModelElement.java new file mode 100644 index 0000000..b259586 --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/entity/model/ModelElement.java @@ -0,0 +1,64 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.entity.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.util.List; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ModelElement { + @JsonProperty("model-element-uuid") + private String modelElementUuid; + + @JsonProperty("new-data-del-flag") + private String newDataDelFlag; + + @JsonProperty("cardinality") + private String cardinality; + + @JsonProperty("linkage-points") + private String linkagePoints; + + @JsonProperty("resource-version") + private String resourceVersion; + + @JsonProperty("model-elements") + private List modelElements; + + @JsonProperty("model-constraints") + private List modelConstraints; + + @JsonProperty("data-owner") + private String dataOwner; + + @JsonProperty("data-source") + private String dataSource; + + @JsonProperty("data-source-version") + private String dataSourceVersion; +} diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/ModelSorter.java b/src/main/java/org/onap/aai/modelloader/entity/model/ModelSorter.java index 4c39975..22367c6 100644 --- a/src/main/java/org/onap/aai/modelloader/entity/model/ModelSorter.java +++ b/src/main/java/org/onap/aai/modelloader/entity/model/ModelSorter.java @@ -29,7 +29,9 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; -import jline.internal.Log; + +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.modelloader.entity.Artifact; /** @@ -39,6 +41,8 @@ import org.onap.aai.modelloader.entity.Artifact; */ public class ModelSorter { + private static Logger logger = LoggerFactory.getInstance().getLogger(ModelSorter.class); + /** * Wraps a Model object to form dependencies other Models using Edges. */ @@ -168,7 +172,7 @@ public class ModelSorter { // create node AbstractModelArtifact referencedModel = versionIdToModelMap.get(referencedModelId); if (referencedModel == null) { - Log.debug("ignoring " + referencedModelId); + logger.debug("ignoring " + referencedModelId); continue; // referenced model not supplied, no need to sort it } referencedNode = new Node(referencedModel); diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/ModelVersion.java b/src/main/java/org/onap/aai/modelloader/entity/model/ModelVersion.java new file mode 100644 index 0000000..19703bd --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/entity/model/ModelVersion.java @@ -0,0 +1,76 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.entity.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ModelVersion { + + @JsonProperty("model-version-id") + private String modelVersionId; + + @JsonProperty("model-name") + private String modelName; + + @JsonProperty("model-version") + private String modelVersion; + + @JsonProperty("distribution-status") + private String distributionStatus; + + @JsonProperty("model-description") + private String modelDescription; + + @JsonProperty("sdnc-model-name") + private String sdncModelName; + + @JsonProperty("sdnc-model-version") + private String sdncModelVersion; + + @JsonProperty("data-owner") + private String dataOwner; + + @JsonProperty("data-source") + private String dataSource; + + @JsonProperty("data-source-version") + private String dataSourceVersion; + + @JsonProperty("resource-version") + private String resourceVersion; + + @JsonProperty("model-elements") + private List modelElements; + + @JsonProperty("metadata") + private List metadata; + +} diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/NamedQueryArtifact.java b/src/main/java/org/onap/aai/modelloader/entity/model/NamedQueryArtifact.java index 04a17fa..ff3b734 100644 --- a/src/main/java/org/onap/aai/modelloader/entity/model/NamedQueryArtifact.java +++ b/src/main/java/org/onap/aai/modelloader/entity/model/NamedQueryArtifact.java @@ -21,15 +21,15 @@ package org.onap.aai.modelloader.entity.model; import java.util.List; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; import org.onap.aai.modelloader.config.ModelLoaderConfig; import org.onap.aai.modelloader.entity.ArtifactType; import org.onap.aai.modelloader.restclient.AaiRestClient; import org.onap.aai.modelloader.entity.Artifact; -import org.onap.aai.restclient.client.OperationResult; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; public class NamedQueryArtifact extends AbstractModelArtifact { @@ -64,13 +64,13 @@ public class NamedQueryArtifact extends AbstractModelArtifact { private boolean pushToResources(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, List completedArtifacts) { - OperationResult getResponse = - aaiClient.getResource(getNamedQueryUrl(config), distId, MediaType.APPLICATION_XML_TYPE); - if (getResponse == null || getResponse.getResultCode() != Response.Status.OK.getStatusCode()) { + ResponseEntity getResponse = + aaiClient.getResource(getNamedQueryUrl(config), distId, MediaType.APPLICATION_XML, String.class); + if (getResponse == null || getResponse.getStatusCode() != HttpStatus.OK) { // Only attempt the PUT if the model doesn't already exist - OperationResult putResponse = aaiClient.putResource(getNamedQueryUrl(config), getPayload(), distId, - MediaType.APPLICATION_XML_TYPE); - if (putResponse != null && putResponse.getResultCode() == Response.Status.CREATED.getStatusCode()) { + ResponseEntity putResponse = aaiClient.putResource(getNamedQueryUrl(config), getPayload(), distId, + MediaType.APPLICATION_XML, String.class); + if (putResponse != null && putResponse.getStatusCode() == HttpStatus.CREATED) { completedArtifacts.add(this); logInfoMsg(getType().toString() + " " + getUniqueIdentifier() + " successfully ingested."); } else { diff --git a/src/main/java/org/onap/aai/modelloader/entity/vnf/VnfImage.java b/src/main/java/org/onap/aai/modelloader/entity/vnf/VnfImage.java new file mode 100644 index 0000000..3eb1600 --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/entity/vnf/VnfImage.java @@ -0,0 +1,58 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.entity.vnf; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class VnfImage { + @JsonProperty("vnf-image-uuid") + private String vnfImageUuid; + + private String application; + + @JsonProperty("application-vendor") + private String applicationVendor; + + @JsonProperty("application-version") + private String applicationVersion; + + private String selfLink; + + @JsonProperty("data-owner") + private String dataOwner; + + @JsonProperty("data-source") + private String dataSource; + + @JsonProperty("data-source-version") + private String dataSourceVersion; + + @JsonProperty("resource-version") + private String resourceVersion; +} diff --git a/src/main/java/org/onap/aai/modelloader/entity/vnf/VnfImages.java b/src/main/java/org/onap/aai/modelloader/entity/vnf/VnfImages.java new file mode 100644 index 0000000..e687366 --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/entity/vnf/VnfImages.java @@ -0,0 +1,35 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.entity.vnf; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class VnfImages { + List vnfImages; +} diff --git a/src/main/java/org/onap/aai/modelloader/extraction/VnfCatalogExtractor.java b/src/main/java/org/onap/aai/modelloader/extraction/VnfCatalogExtractor.java index 0e27d57..64ecf8a 100644 --- a/src/main/java/org/onap/aai/modelloader/extraction/VnfCatalogExtractor.java +++ b/src/main/java/org/onap/aai/modelloader/extraction/VnfCatalogExtractor.java @@ -21,10 +21,12 @@ package org.onap.aai.modelloader.extraction; import java.io.IOException; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.regex.Pattern; + import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipFile; import org.apache.commons.compress.utils.SeekableInMemoryByteChannel; @@ -36,6 +38,7 @@ import org.onap.aai.modelloader.entity.Artifact; import org.onap.aai.modelloader.entity.ArtifactType; import org.onap.aai.modelloader.entity.catalog.VnfCatalogArtifact; import org.onap.aai.modelloader.service.ModelLoaderMsgs; +import org.springframework.stereotype.Component; /** @@ -45,6 +48,7 @@ import org.onap.aai.modelloader.service.ModelLoaderMsgs; * A .csar file is a compressed archive like a zip file and this class will treat the byte array as it if were a zip * file. */ +@Component public class VnfCatalogExtractor { private static final Logger logger = LoggerFactory.getInstance().getLogger(VnfCatalogExtractor.class.getName()); @@ -75,7 +79,7 @@ public class VnfCatalogExtractor { ZipArchiveEntry entry = enumeration.nextElement(); if (fileShouldBeExtracted(entry)) { vnfcFiles.add(new VnfCatalogArtifact(ArtifactType.VNF_CATALOG_XML, - IOUtils.toString(zipFile.getInputStream(entry)))); + IOUtils.toString(zipFile.getInputStream(entry), Charset.defaultCharset()))); } } } catch (IOException e) { diff --git a/src/main/java/org/onap/aai/modelloader/notification/ArtifactDownloadManager.java b/src/main/java/org/onap/aai/modelloader/notification/ArtifactDownloadManager.java index 58bb074..90e20bd 100644 --- a/src/main/java/org/onap/aai/modelloader/notification/ArtifactDownloadManager.java +++ b/src/main/java/org/onap/aai/modelloader/notification/ArtifactDownloadManager.java @@ -24,24 +24,23 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Base64; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; -import org.onap.aai.babel.service.data.BabelArtifact; -import org.onap.aai.babel.service.data.BabelArtifact.ArtifactType; +import java.util.stream.Stream; + +import org.onap.aai.babel.service.data.BabelRequest; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.cl.mdc.MdcContext; import org.onap.aai.cl.mdc.MdcOverride; -import org.onap.aai.modelloader.config.ModelLoaderConfig; +import org.onap.aai.modelloader.babel.BabelArtifactService; import org.onap.aai.modelloader.entity.Artifact; +import org.onap.aai.modelloader.entity.ArtifactType; +import org.onap.aai.modelloader.entity.catalog.VnfCatalogArtifact; import org.onap.aai.modelloader.entity.model.BabelArtifactParsingException; import org.onap.aai.modelloader.entity.model.IModelParser; import org.onap.aai.modelloader.entity.model.NamedQueryArtifactParser; import org.onap.aai.modelloader.extraction.InvalidArchiveException; import org.onap.aai.modelloader.extraction.VnfCatalogExtractor; -import org.onap.aai.modelloader.restclient.BabelServiceClient; -import org.onap.aai.modelloader.restclient.BabelServiceClientException; -import org.onap.aai.modelloader.service.BabelServiceClientFactory; import org.onap.aai.modelloader.service.ModelLoaderMsgs; import org.onap.sdc.api.IDistributionClient; import org.onap.sdc.api.notification.IArtifactInfo; @@ -49,6 +48,7 @@ import org.onap.sdc.api.notification.INotificationData; import org.onap.sdc.api.results.IDistributionClientDownloadResult; import org.onap.sdc.utils.ArtifactTypeEnum; import org.onap.sdc.utils.DistributionActionResultEnum; +import org.springframework.stereotype.Component; /** * This class is responsible for downloading the artifacts from the ASDC. @@ -60,22 +60,22 @@ import org.onap.sdc.utils.DistributionActionResultEnum; * * TOSCA_CSAR file artifacts will be converted into XML and returned as model artifacts. */ +@Component public class ArtifactDownloadManager { private static Logger logger = LoggerFactory.getInstance().getLogger(ArtifactDownloadManager.class); - private IDistributionClient client; - private NotificationPublisher notificationPublisher; - private BabelArtifactConverter babelArtifactConverter; - private ModelLoaderConfig config; - private BabelServiceClientFactory clientFactory; - private VnfCatalogExtractor vnfCatalogExtractor; + private final IDistributionClient client; + private final NotificationPublisher notificationPublisher; + private final VnfCatalogExtractor vnfCatalogExtractor; + private final BabelArtifactService babelArtifactService; - public ArtifactDownloadManager(IDistributionClient client, ModelLoaderConfig config, - BabelServiceClientFactory clientFactory) { + public ArtifactDownloadManager(IDistributionClient client, + NotificationPublisher notificationPublisher, VnfCatalogExtractor vnfCatalogExtractor, BabelArtifactService babelArtifactService) { this.client = client; - this.config = config; - this.clientFactory = clientFactory; + this.notificationPublisher = notificationPublisher; + this.vnfCatalogExtractor = vnfCatalogExtractor; + this.babelArtifactService = babelArtifactService; } /** @@ -96,10 +96,10 @@ public class ArtifactDownloadManager { IDistributionClientDownloadResult downloadResult = downloadIndividualArtifacts(data, artifact); processDownloadedArtifacts(modelArtifacts, catalogArtifacts, artifact, downloadResult, data); } catch (DownloadFailureException e) { - getNotificationPublisher().publishDownloadFailure(client, data, artifact, e.getMessage()); + notificationPublisher.publishDownloadFailure(client, data, artifact, e.getMessage()); success = false; } catch (Exception e) { - getNotificationPublisher().publishDeployFailure(client, data, artifact); + notificationPublisher.publishDeployFailure(client, data, artifact); success = false; } @@ -126,7 +126,7 @@ public class ArtifactDownloadManager { if (DistributionActionResultEnum.SUCCESS.equals(downloadResult.getDistributionActionResult())) { logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Downloaded artifact: " + artifact.getArtifactName()); - getNotificationPublisher().publishDownloadSuccess(client, data, artifact); + notificationPublisher.publishDownloadSuccess(client, data, artifact); } else { throw new DownloadFailureException(downloadResult.getDistributionMessageResult()); } @@ -137,9 +137,11 @@ public class ArtifactDownloadManager { private void processDownloadedArtifacts(List modelArtifacts, List catalogArtifacts, IArtifactInfo artifactInfo, IDistributionClientDownloadResult downloadResult, INotificationData data) throws ProcessToscaArtifactsException, InvalidArchiveException, BabelArtifactParsingException { + List artifacts = null; if ("TOSCA_CSAR".equalsIgnoreCase(artifactInfo.getArtifactType())) { - processToscaArtifacts(modelArtifacts, catalogArtifacts, downloadResult.getArtifactPayload(), artifactInfo, + artifacts = processToscaArtifacts(downloadResult.getArtifactPayload(), artifactInfo, data.getDistributionID(), data.getServiceVersion()); + } else if (ArtifactTypeEnum.MODEL_QUERY_SPEC.toString().equalsIgnoreCase(artifactInfo.getArtifactType())) { processModelQuerySpecArtifact(modelArtifacts, downloadResult); } else { @@ -147,94 +149,46 @@ public class ArtifactDownloadManager { artifactInfo.getArtifactType()); throw new InvalidArchiveException("Unsupported artifact type: " + artifactInfo.getArtifactType()); } + if(artifacts != null) { + for(Artifact artifact : artifacts) { + if(artifact.getType() == ArtifactType.VNF_CATALOG || artifact.getType() == ArtifactType.VNF_CATALOG_XML) { + catalogArtifacts.add(artifact); + } else { + modelArtifacts.add(artifact); + } + } + } } - public void processToscaArtifacts(List modelArtifacts, List catalogArtifacts, byte[] payload, - IArtifactInfo artifactInfo, String distributionId, String serviceVersion) + public List processToscaArtifacts(byte[] payload, IArtifactInfo artifactInfo, String distributionId, String serviceVersion) throws ProcessToscaArtifactsException, InvalidArchiveException { // Get translated artifacts from Babel Service - invokeBabelService(modelArtifacts, catalogArtifacts, payload, artifactInfo, distributionId, serviceVersion); + BabelRequest babelRequest = new BabelRequest(); + babelRequest.setArtifactName(artifactInfo.getArtifactName()); + babelRequest.setCsar(Base64.getEncoder().encodeToString(payload)); + babelRequest.setArtifactVersion(serviceVersion); + List artifacts = babelArtifactService.invokeBabelService(babelRequest, distributionId); // Get VNF Catalog artifacts directly from CSAR - List csarCatalogArtifacts = getVnfCatalogExtractor().extract(payload, artifactInfo.getArtifactName()); + List csarCatalogArtifacts = vnfCatalogExtractor.extract(payload, artifactInfo.getArtifactName()); // Throw an error if VNF Catalog data is present in the Babel payload and directly in the CSAR - if (!catalogArtifacts.isEmpty() && !csarCatalogArtifacts.isEmpty()) { + if (isDuplicateVnfCatalogData(artifacts, csarCatalogArtifacts)) { logger.error(ModelLoaderMsgs.DUPLICATE_VNFC_DATA_ERROR, artifactInfo.getArtifactName()); throw new InvalidArchiveException("CSAR: " + artifactInfo.getArtifactName() + " contains VNF Catalog data in the format of both TOSCA and XML files. Only one format can be used for each CSAR file."); - } else if (!csarCatalogArtifacts.isEmpty()) { - catalogArtifacts.addAll(csarCatalogArtifacts); } - } - - public void invokeBabelService(List modelArtifacts, List catalogArtifacts, byte[] payload, - IArtifactInfo artifactInfo, String distributionId, String serviceVersion) - throws ProcessToscaArtifactsException { - try { - BabelServiceClient babelClient = createBabelServiceClient(artifactInfo, serviceVersion); - - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, - "Posting artifact: " + artifactInfo.getArtifactName() + ", service version: " + serviceVersion - + ", artifact version: " + artifactInfo.getArtifactVersion()); - - List babelArtifacts = - babelClient.postArtifact(payload, artifactInfo.getArtifactName(), serviceVersion, distributionId); - - // Sort Babel artifacts based on type - Map> artifactMap = - babelArtifacts.stream().collect(Collectors.groupingBy(BabelArtifact::getType)); + return Stream + .concat(artifacts.stream(), csarCatalogArtifacts.stream()) + .collect(Collectors.toList()); - if (artifactMap.containsKey(BabelArtifact.ArtifactType.MODEL)) { - modelArtifacts.addAll( - getBabelArtifactConverter().convertToModel(artifactMap.get(BabelArtifact.ArtifactType.MODEL))); - artifactMap.remove(BabelArtifact.ArtifactType.MODEL); - } - - if (artifactMap.containsKey(BabelArtifact.ArtifactType.VNFCATALOG)) { - catalogArtifacts.addAll(getBabelArtifactConverter() - .convertToCatalog(artifactMap.get(BabelArtifact.ArtifactType.VNFCATALOG))); - artifactMap.remove(BabelArtifact.ArtifactType.VNFCATALOG); - } - - // Log unexpected artifact types - if (!artifactMap.isEmpty()) { - logger.warn(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, - artifactInfo.getArtifactName() + " " + serviceVersion - + ". Unexpected artifact types returned by the babel service: " - + artifactMap.keySet().toString()); - } - - } catch (BabelArtifactParsingException e) { - logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, - "Error for artifact " + artifactInfo.getArtifactName() + " " + serviceVersion + e); - throw new ProcessToscaArtifactsException( - "An error occurred while trying to parse the Babel artifacts: " + e.getLocalizedMessage()); - } catch (Exception e) { - logger.error(ModelLoaderMsgs.BABEL_REST_REQUEST_ERROR, e, "POST", config.getBabelBaseUrl(), - "Error posting artifact " + artifactInfo.getArtifactName() + " " + serviceVersion + " to Babel: " - + e.getLocalizedMessage()); - throw new ProcessToscaArtifactsException( - "An error occurred while calling the Babel service: " + e.getLocalizedMessage()); - } } - BabelServiceClient createBabelServiceClient(IArtifactInfo artifact, String serviceVersion) - throws ProcessToscaArtifactsException { - BabelServiceClient babelClient; - try { - logger.debug(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Creating Babel client"); - babelClient = clientFactory.create(config); - } catch (BabelServiceClientException e) { - logger.error(ModelLoaderMsgs.BABEL_REST_REQUEST_ERROR, e, "POST", config.getBabelBaseUrl(), - "Error posting artifact " + artifact.getArtifactName() + " " + serviceVersion + " to Babel: " - + e.getLocalizedMessage()); - throw new ProcessToscaArtifactsException( - "An error occurred tyring to convert the tosca artifacts to xml artifacts: " - + e.getLocalizedMessage()); - } - - return babelClient; + private boolean isDuplicateVnfCatalogData(List babelArtifacts, List csarCatalogArtifacts) { + boolean babelIsEmpty = babelArtifacts.stream() + .filter(VnfCatalogArtifact.class::isInstance) + .findAny().isEmpty(); + return !csarCatalogArtifacts.isEmpty() && !babelIsEmpty; } private void processModelQuerySpecArtifact(List modelArtifacts, @@ -257,28 +211,4 @@ public class ArtifactDownloadManager { private boolean parsedArtifactsExist(List parsedArtifacts) { return parsedArtifacts != null && !parsedArtifacts.isEmpty(); } - - private NotificationPublisher getNotificationPublisher() { - if (notificationPublisher == null) { - notificationPublisher = new NotificationPublisher(); - } - - return notificationPublisher; - } - - private BabelArtifactConverter getBabelArtifactConverter() { - if (babelArtifactConverter == null) { - babelArtifactConverter = new BabelArtifactConverter(); - } - - return babelArtifactConverter; - } - - private VnfCatalogExtractor getVnfCatalogExtractor() { - if (vnfCatalogExtractor == null) { - vnfCatalogExtractor = new VnfCatalogExtractor(); - } - - return vnfCatalogExtractor; - } } diff --git a/src/main/java/org/onap/aai/modelloader/notification/BabelArtifactConverter.java b/src/main/java/org/onap/aai/modelloader/notification/BabelArtifactConverter.java index ad4eb7d..59d3348 100644 --- a/src/main/java/org/onap/aai/modelloader/notification/BabelArtifactConverter.java +++ b/src/main/java/org/onap/aai/modelloader/notification/BabelArtifactConverter.java @@ -20,7 +20,6 @@ */ package org.onap.aai.modelloader.notification; -import java.util.ArrayList; import java.util.List; import java.util.Objects; import org.onap.aai.babel.service.data.BabelArtifact; @@ -29,12 +28,20 @@ import org.onap.aai.modelloader.entity.catalog.VnfCatalogArtifact; import org.onap.aai.modelloader.entity.model.BabelArtifactParsingException; import org.onap.aai.modelloader.entity.model.ModelArtifact; import org.onap.aai.modelloader.entity.model.ModelArtifactParser; +import org.springframework.stereotype.Component; /** * This class is responsible for converting TOSCA artifacts into instances of {@link ModelArtifact} ready for pushing * the converted artifacts . */ -class BabelArtifactConverter { +@Component +public class BabelArtifactConverter { + + private final ModelArtifactParser modelArtifactParser; + + public BabelArtifactConverter(ModelArtifactParser modelArtifactParser) { + this.modelArtifactParser = modelArtifactParser; + } /** * This method converts BabelArtifacts into instances of {@link ModelArtifact}. @@ -44,24 +51,15 @@ class BabelArtifactConverter { * @throws BabelArtifactParsingException if an error occurs trying to parse the generated XML files that were * converted from tosca artifacts */ - List convertToModel(List xmlArtifacts) throws BabelArtifactParsingException { - Objects.requireNonNull(xmlArtifacts); - List modelArtifacts = new ArrayList<>(); - ModelArtifactParser modelArtParser = new ModelArtifactParser(); - - // Parse TOSCA payloads - for (BabelArtifact xmlArtifact : xmlArtifacts) { - - List parsedArtifacts = modelArtParser.parse(xmlArtifact.getPayload(), xmlArtifact.getName()); - - if (parsedArtifacts == null || parsedArtifacts.isEmpty()) { - throw new BabelArtifactParsingException("Could not parse generated XML: " + xmlArtifact.getPayload()); - } - - modelArtifacts.addAll(parsedArtifacts); + public List convertToModel(BabelArtifact babelArtifact) throws BabelArtifactParsingException { + Objects.requireNonNull(babelArtifact); + List parsedArtifacts = modelArtifactParser.parse(babelArtifact.getPayload(), babelArtifact.getName()); + + if (parsedArtifacts == null || parsedArtifacts.isEmpty()) { + throw new BabelArtifactParsingException("Could not parse generated XML: " + babelArtifact.getPayload()); } - return modelArtifacts; + return parsedArtifacts; } /** @@ -70,14 +68,7 @@ class BabelArtifactConverter { * @param xmlArtifacts xml artifacts to be parsed * @return List list of converted catalog artifacts */ - List convertToCatalog(List xmlArtifacts) { - Objects.requireNonNull(xmlArtifacts); - List catalogArtifacts = new ArrayList<>(); - - for (BabelArtifact xmlArtifact : xmlArtifacts) { - catalogArtifacts.add(new VnfCatalogArtifact(xmlArtifact.getPayload())); - } - - return catalogArtifacts; + public Artifact convertToCatalog(BabelArtifact babelArtifact) { + return new VnfCatalogArtifact(babelArtifact.getPayload()); } -} +} \ No newline at end of file diff --git a/src/main/java/org/onap/aai/modelloader/notification/EventCallback.java b/src/main/java/org/onap/aai/modelloader/notification/EventCallback.java index d7bccba..d047bf9 100644 --- a/src/main/java/org/onap/aai/modelloader/notification/EventCallback.java +++ b/src/main/java/org/onap/aai/modelloader/notification/EventCallback.java @@ -26,33 +26,32 @@ import java.util.List; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.cl.mdc.MdcContext; -import org.onap.aai.modelloader.config.ModelLoaderConfig; import org.onap.aai.modelloader.entity.Artifact; import org.onap.aai.modelloader.extraction.ArtifactInfoExtractor; import org.onap.aai.modelloader.service.ArtifactDeploymentManager; -import org.onap.aai.modelloader.service.BabelServiceClientFactory; import org.onap.aai.modelloader.service.ModelLoaderMsgs; import org.onap.sdc.api.IDistributionClient; import org.onap.sdc.api.consumer.INotificationCallback; import org.onap.sdc.api.notification.IArtifactInfo; import org.onap.sdc.api.notification.INotificationData; import org.slf4j.MDC; +import org.springframework.stereotype.Component; +@Component public class EventCallback implements INotificationCallback { private static Logger logger = LoggerFactory.getInstance().getLogger(EventCallback.class.getName()); private static Logger auditLogger = LoggerFactory.getInstance().getAuditLogger(EventCallback.class.getName()); - private ArtifactDeploymentManager artifactDeploymentManager; - private ArtifactDownloadManager artifactDownloadManager; - private NotificationPublisher notificationPublisher; - private IDistributionClient client; - private ModelLoaderConfig config; - private BabelServiceClientFactory babelServiceClientFactory; + private final ArtifactDeploymentManager artifactDeploymentManager; + private final ArtifactDownloadManager artifactDownloadManager; + private final NotificationPublisher notificationPublisher; + private final IDistributionClient client; - public EventCallback(IDistributionClient client, ModelLoaderConfig config, BabelServiceClientFactory babelServiceClientFactory) { + public EventCallback(IDistributionClient client, ArtifactDeploymentManager artifactDeploymentManager, ArtifactDownloadManager artifactDownloadManager, NotificationPublisher notificationPublisher) { + this.artifactDeploymentManager = artifactDeploymentManager; + this.artifactDownloadManager = artifactDownloadManager; + this.notificationPublisher = notificationPublisher; this.client = client; - this.config = config; - this.babelServiceClientFactory = babelServiceClientFactory; } @Override @@ -65,10 +64,10 @@ public class EventCallback implements INotificationCallback { List modelArtifacts = new ArrayList<>(); boolean success = - getArtifactDownloadManager().downloadArtifacts(data, artifacts, modelArtifacts, catalogArtifacts); + artifactDownloadManager.downloadArtifacts(data, artifacts, modelArtifacts, catalogArtifacts); if (success) { - success = getArtifactDeploymentManager().deploy(data, modelArtifacts, catalogArtifacts); + success = artifactDeploymentManager.deploy(data.getDistributionID(), modelArtifacts, catalogArtifacts); } String statusString = success ? "SUCCESS" : "FAILURE"; @@ -85,37 +84,12 @@ public class EventCallback implements INotificationCallback { boolean deploymentSuccess) { if (deploymentSuccess) { artifacts.stream().filter(a -> filterType.equalsIgnoreCase(a.getArtifactType())) - .forEach(a -> getNotificationPublisher().publishDeploySuccess(client, data, a)); - getNotificationPublisher().publishComponentSuccess(client, data); + .forEach(a -> notificationPublisher.publishDeploySuccess(client, data, a)); + notificationPublisher.publishComponentSuccess(client, data); } else { artifacts.stream().filter(a -> filterType.equalsIgnoreCase(a.getArtifactType())) - .forEach(a -> getNotificationPublisher().publishDeployFailure(client, data, a)); - getNotificationPublisher().publishComponentFailure(client, data, "deploy failure"); + .forEach(a -> notificationPublisher.publishDeployFailure(client, data, a)); + notificationPublisher.publishComponentFailure(client, data, "deploy failure"); } } - - private ArtifactDeploymentManager getArtifactDeploymentManager() { - if (artifactDeploymentManager == null) { - artifactDeploymentManager = new ArtifactDeploymentManager(config); - } - - return artifactDeploymentManager; - } - - private ArtifactDownloadManager getArtifactDownloadManager() { - if (artifactDownloadManager == null) { - artifactDownloadManager = new ArtifactDownloadManager(client, config, babelServiceClientFactory); - } - - return artifactDownloadManager; - } - - - private NotificationPublisher getNotificationPublisher() { - if (notificationPublisher == null) { - notificationPublisher = new NotificationPublisher(); - } - - return notificationPublisher; - } } diff --git a/src/main/java/org/onap/aai/modelloader/notification/NotificationDataImpl.java b/src/main/java/org/onap/aai/modelloader/notification/NotificationDataImpl.java index 566415e..3eb07f3 100644 --- a/src/main/java/org/onap/aai/modelloader/notification/NotificationDataImpl.java +++ b/src/main/java/org/onap/aai/modelloader/notification/NotificationDataImpl.java @@ -20,98 +20,28 @@ */ package org.onap.aai.modelloader.notification; -import java.util.Collections; import java.util.List; import org.onap.sdc.api.notification.IArtifactInfo; import org.onap.sdc.api.notification.INotificationData; import org.onap.sdc.api.notification.IResourceInstance; +import lombok.Data; + +@Data public class NotificationDataImpl implements INotificationData { private String distributionID; + private String serviceName; + private String serviceVersion; + private String serviceUUID; + private String serviceDescription; + private List resources; + private List serviceArtifacts; + private String serviceInvariantUUID; + private String workloadContext; @Override - public IArtifactInfo getArtifactMetadataByUUID(String arg0) { - return null; - } - - @Override - public String getDistributionID() { - return distributionID; - } - - public void setDistributionID(String distributionID) { - this.distributionID = distributionID; - } - - @Override - public List getResources() { - return Collections.emptyList(); - } - - @Override - public List getServiceArtifacts() { - return Collections.emptyList(); - } - - @Override - public String getServiceDescription() { - return null; - } - - @Override - public String getServiceInvariantUUID() { - return null; - } - - @Override - public String getServiceName() { - return null; - } - - @Override - public String getServiceUUID() { - return null; - } - - @Override - public String getServiceVersion() { + public IArtifactInfo getArtifactMetadataByUUID(String uuid) { return null; } - - @Override - public String getWorkloadContext() { - return null; - } - - @Override - public void setWorkloadContext(String arg0) { - // Unsupported method - not expected to be called - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((distributionID == null) ? 0 : distributionID.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - NotificationDataImpl other = (NotificationDataImpl) obj; - if (distributionID == null) { - if (other.distributionID != null) - return false; - } else if (!distributionID.equals(other.distributionID)) - return false; - return true; - } - } diff --git a/src/main/java/org/onap/aai/modelloader/notification/NotificationPublisher.java b/src/main/java/org/onap/aai/modelloader/notification/NotificationPublisher.java index 6e6ff13..7d5b1cc 100644 --- a/src/main/java/org/onap/aai/modelloader/notification/NotificationPublisher.java +++ b/src/main/java/org/onap/aai/modelloader/notification/NotificationPublisher.java @@ -38,10 +38,12 @@ import org.onap.sdc.api.notification.INotificationData; import org.onap.sdc.api.results.IDistributionClientResult; import org.onap.sdc.utils.DistributionActionResultEnum; import org.onap.sdc.utils.DistributionStatusEnum; +import org.springframework.stereotype.Component; /** * This class is responsible for publishing the status of actions performed working with artifacts. */ +@Component public class NotificationPublisher { private static Logger logger = LoggerFactory.getInstance().getLogger(NotificationPublisher.class); diff --git a/src/main/java/org/onap/aai/modelloader/restclient/AaiRestClient.java b/src/main/java/org/onap/aai/modelloader/restclient/AaiRestClient.java index 29c0c70..fca517d 100644 --- a/src/main/java/org/onap/aai/modelloader/restclient/AaiRestClient.java +++ b/src/main/java/org/onap/aai/modelloader/restclient/AaiRestClient.java @@ -20,64 +20,56 @@ */ package org.onap.aai.modelloader.restclient; -import com.sun.jersey.core.util.MultivaluedMapImpl; // NOSONAR -import java.io.IOException; -import java.io.StringReader; -import java.net.URI; import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.stream.IntStream; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriBuilder; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.modelloader.config.ModelLoaderConfig; +import org.onap.aai.modelloader.entity.AaiResourcesObject; import org.onap.aai.modelloader.service.ModelLoaderMsgs; -import org.onap.aai.restclient.client.OperationResult; -import org.onap.aai.restclient.client.RestClient; -import org.onap.aai.restclient.enums.RestAuthenticationMode; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; /** * Wrapper around the standard A&AI Rest Client interface. This currently uses Jersey client 1.x * */ +@Component public class AaiRestClient { + private static Logger logger = LoggerFactory.getInstance().getLogger(AaiRestClient.class.getName()); public static final String HEADER_TRANS_ID = "X-TransactionId"; public static final String HEADER_FROM_APP_ID = "X-FromAppId"; public static final String ML_APP_NAME = "ModelLoader"; private static final String RESOURCE_VERSION_PARAM = "resource-version"; + private final ModelLoaderConfig config; + private final RestTemplate restTemplate; - private static Logger logger = LoggerFactory.getInstance().getLogger(AaiRestClient.class.getName()); - - private ModelLoaderConfig config = null; - - public AaiRestClient(ModelLoaderConfig config) { + public AaiRestClient(ModelLoaderConfig config, RestTemplate restTemplate) { this.config = config; + this.restTemplate = restTemplate; } - /** * Send a GET request to the A&AI for a resource. + * @param * * @param url * @param transId * @param mediaType * @return */ - public OperationResult getResource(String url, String transId, MediaType mediaType) { - return setupClient().get(url, buildHeaders(transId), mediaType); + public ResponseEntity getResource(String url, String transId, MediaType mediaType, Class responseType) { + HttpHeaders headers = defaultHeaders(transId); + headers.setAccept(Collections.singletonList(mediaType)); + HttpEntity entity = new HttpEntity<>(headers); + + return restTemplate.exchange(url, HttpMethod.GET, entity, responseType); } /** @@ -89,27 +81,26 @@ public class AaiRestClient { * @param mediaType - the content type (XML or JSON) * @return operation result */ - public OperationResult putResource(String url, String payload, String transId, MediaType mediaType) { - logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_PAYLOAD, payload); - return setupClient().put(url, payload, buildHeaders(transId), mediaType, mediaType); + public ResponseEntity putResource(String url, T payload, String transId, MediaType mediaType, Class responseType) { + logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_PAYLOAD, payload.toString()); + HttpHeaders headers = defaultHeaders(transId); + headers.setAccept(Collections.singletonList(mediaType)); + headers.setContentType(mediaType); + HttpEntity entity = new HttpEntity<>(payload, headers); + + return restTemplate.exchange(url, HttpMethod.PUT, entity, responseType); } + public ResponseEntity postResource(String url, T payload, String transId, MediaType mediaType, Class responseType) { + logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_PAYLOAD, payload.toString()); + HttpHeaders headers = defaultHeaders(transId); + headers.setAccept(Collections.singletonList(mediaType)); + headers.setContentType(mediaType); + HttpEntity entity = new HttpEntity<>(payload, headers); - /** - * Send a POST request to the A&AI. - * - * @param url - the url - * @param transId - transaction ID - * @param payload - the XML or JSON payload for the request - * @param mimeType - the content type (XML or JSON) - * @return ClientResponse - */ - public OperationResult postResource(String url, String payload, String transId, MediaType mediaType) { - logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_PAYLOAD, payload); - return setupClient().post(url, payload, buildHeaders(transId), mediaType, mediaType); + return restTemplate.exchange(url, HttpMethod.POST, entity, responseType); } - /** * Send a DELETE request to the A&AI. * @@ -118,9 +109,11 @@ public class AaiRestClient { * @param transId - transaction ID * @return ClientResponse */ - public OperationResult deleteResource(String url, String resourceVersion, String transId) { - URI uri = UriBuilder.fromUri(url).queryParam(RESOURCE_VERSION_PARAM, resourceVersion).build(); - return setupClient().delete(uri.toString(), buildHeaders(transId), null); + public ResponseEntity deleteResource(String url, String resourceVersion, String transId) { + HttpHeaders headers = defaultHeaders(transId); + String uri = url + "?" + RESOURCE_VERSION_PARAM + "=" + resourceVersion; + HttpEntity entity = new HttpEntity<>(headers); + return restTemplate.exchange(uri, HttpMethod.DELETE, entity, String.class); } /** @@ -130,91 +123,34 @@ public class AaiRestClient { * @param transId - transaction ID * @return ClientResponse */ - public OperationResult getAndDeleteResource(String url, String transId) { + public ResponseEntity getAndDeleteResource(String url, String transId) { + ResponseEntity response = getResource(url, transId, MediaType.APPLICATION_XML, AaiResourcesObject.class); // First, GET the model - OperationResult getResponse = getResource(url, transId, MediaType.APPLICATION_XML_TYPE); - if (getResponse == null || getResponse.getResultCode() != Response.Status.OK.getStatusCode()) { - return getResponse; + if (response == null || response.getStatusCode() != HttpStatus.OK) { + return response; } - // Delete the model using the resource version in the response - String resVersion = null; - try { - resVersion = getResourceVersion(getResponse); - } catch (Exception e) { - logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "GET", url, e.getLocalizedMessage()); - return null; - } - - return deleteResource(url, resVersion, transId); + return deleteResource(url, response.getBody().getResourceVersion(), transId); } - public boolean useBasicAuth() { + private boolean useBasicAuth() { return config.getAaiAuthenticationUser() != null && config.getAaiAuthenticationPassword() != null; } - private RestClient setupClient() { - RestClient restClient = new RestClient(); - - //Use certs only if SSL is enabled - if (config.useHttpsWithAAI()) - {// @formatter:off - restClient.validateServerHostname(false) - .validateServerCertChain(false) - .clientCertFile(config.getAaiKeyStorePath()) - .clientCertPassword(config.getAaiKeyStorePassword()) - .connectTimeoutMs(120000) - .readTimeoutMs(120000); - // @formatter:on - } - else { - restClient.validateServerHostname(false) - .validateServerCertChain(false) - .connectTimeoutMs(120000) - .readTimeoutMs(120000); - } - - if (useBasicAuth()) { - restClient.authenticationMode(RestAuthenticationMode.SSL_BASIC); - restClient.basicAuthUsername(config.getAaiAuthenticationUser()); - restClient.basicAuthPassword(config.getAaiAuthenticationPassword()); - } - - return restClient; - } - /** * Create the HTTP headers required for an A&AI operation (GET/POST/PUT/DELETE) * * @param transId * @return map of headers */ - private Map> buildHeaders(String transId) { - MultivaluedMap headers = new MultivaluedMapImpl(); - headers.put(HEADER_TRANS_ID, Collections.singletonList(transId)); - headers.put(HEADER_FROM_APP_ID, Collections.singletonList(ML_APP_NAME)); + private HttpHeaders defaultHeaders(String transId) { + HttpHeaders headers = new HttpHeaders(); + headers.set(AaiRestClient.HEADER_TRANS_ID, transId); + headers.set(AaiRestClient.HEADER_FROM_APP_ID, AaiRestClient.ML_APP_NAME); + if (useBasicAuth()) { + headers.setBasicAuth(config.getAaiAuthenticationUser(), config.getAaiAuthenticationPassword()); + } return headers; } - - private String getResourceVersion(OperationResult getResponse) - throws ParserConfigurationException, SAXException, IOException { - String respData = getResponse.getResult(); - - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - DocumentBuilder builder = factory.newDocumentBuilder(); - InputSource is = new InputSource(new StringReader(respData)); - Document doc = builder.parse(is); - - NodeList nodesList = doc.getDocumentElement().getChildNodes(); - - // @formatter:off - return IntStream.range(0, nodesList.getLength()).mapToObj(nodesList::item) - .filter(childNode -> childNode.getNodeName().equals(RESOURCE_VERSION_PARAM)) - .findFirst() - .map(Node::getTextContent) - .orElse(null); - // @formatter:on - } } diff --git a/src/main/java/org/onap/aai/modelloader/restclient/BabelServiceClient.java b/src/main/java/org/onap/aai/modelloader/restclient/BabelServiceClient.java index f69752b..8328c42 100644 --- a/src/main/java/org/onap/aai/modelloader/restclient/BabelServiceClient.java +++ b/src/main/java/org/onap/aai/modelloader/restclient/BabelServiceClient.java @@ -23,10 +23,10 @@ package org.onap.aai.modelloader.restclient; import java.util.List; import org.onap.aai.babel.service.data.BabelArtifact; +import org.onap.aai.babel.service.data.BabelRequest; public interface BabelServiceClient { - List postArtifact(byte[] artifactPayload, String artifactName, String artifactVersion, - String transactionId) throws BabelServiceClientException; + List postArtifact(BabelRequest babelRequest, String transactionId) throws BabelServiceClientException; } diff --git a/src/main/java/org/onap/aai/modelloader/restclient/BabelServiceClientImpl.java b/src/main/java/org/onap/aai/modelloader/restclient/BabelServiceClientImpl.java new file mode 100644 index 0000000..63bd7e9 --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/restclient/BabelServiceClientImpl.java @@ -0,0 +1,87 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2019 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aai.modelloader.restclient; + +import java.util.Collections; +import java.util.List; +import org.onap.aai.babel.service.data.BabelArtifact; +import org.onap.aai.babel.service.data.BabelRequest; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.modelloader.config.ModelLoaderConfig; +import org.onap.aai.modelloader.service.ModelLoaderMsgs; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +/** + * HTTPS Client for interfacing with Babel. + * + */ +@Component +public class BabelServiceClientImpl implements BabelServiceClient { + + private static final Logger logger = LoggerFactory.getInstance().getLogger(BabelServiceClientImpl.class); + private final ModelLoaderConfig config; + private final RestTemplate restTemplate; + + public BabelServiceClientImpl(ModelLoaderConfig config, RestTemplate restTemplate) { + this.config = config; + this.restTemplate = restTemplate; + } + + @Override + public List postArtifact(BabelRequest babelRequest, String transactionId) throws BabelServiceClientException { + if (logger.isDebugEnabled()) { + logger.debug(ModelLoaderMsgs.BABEL_REST_REQUEST_PAYLOAD, " Artifact Name: " + babelRequest.getArtifactName() + + " Artifact version: " + babelRequest.getArtifactVersion() + " Artifact payload: " + babelRequest.getCsar()); + } + + String resourceUrl = config.getBabelBaseUrl() + config.getBabelGenerateArtifactsUrl(); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + headers.set(AaiRestClient.HEADER_TRANS_ID, transactionId); + headers.set(AaiRestClient.HEADER_FROM_APP_ID, AaiRestClient.ML_APP_NAME); + HttpEntity entity = new HttpEntity<>(babelRequest, headers); + + ResponseEntity> artifactResponse = restTemplate.exchange(resourceUrl, HttpMethod.POST, entity, new ParameterizedTypeReference>() {}); + + if (logger.isDebugEnabled()) { + logger.debug(ModelLoaderMsgs.DISTRIBUTION_EVENT, + "Babel response " + artifactResponse.getStatusCode() + " " + artifactResponse.getBody().toString()); + } + + if (!artifactResponse.getStatusCode().equals(HttpStatus.OK)) { + throw new BabelServiceClientException(artifactResponse.getBody().toString()); + } + + return artifactResponse.getBody(); + } +} diff --git a/src/main/java/org/onap/aai/modelloader/restclient/HttpsBabelServiceClient.java b/src/main/java/org/onap/aai/modelloader/restclient/HttpsBabelServiceClient.java deleted file mode 100644 index 289015c..0000000 --- a/src/main/java/org/onap/aai/modelloader/restclient/HttpsBabelServiceClient.java +++ /dev/null @@ -1,254 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2019 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017-2019 European Software Marketing Ltd. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.aai.modelloader.restclient; - -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; -import com.google.json.JsonSanitizer; -import com.sun.jersey.api.client.Client; // NOSONAR -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.WebResource; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Base64; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; -import javax.ws.rs.core.Response; -import org.json.JSONException; -import org.json.JSONObject; -import org.onap.aai.babel.service.data.BabelArtifact; -import org.onap.aai.cl.api.LogFields; -import org.onap.aai.cl.api.LogLine; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; -import org.onap.aai.cl.mdc.MdcContext; -import org.onap.aai.cl.mdc.MdcOverride; -import org.onap.aai.modelloader.config.ModelLoaderConfig; -import org.onap.aai.modelloader.service.ModelLoaderMsgs; - -/** - * HTTPS Client for interfacing with Babel. - * - */ -public class HttpsBabelServiceClient implements BabelServiceClient { - - private static final Logger logger = LoggerFactory.getInstance().getLogger(HttpsBabelServiceClient.class); - private static final Logger metricsLogger = - LoggerFactory.getInstance().getMetricsLogger(HttpsBabelServiceClient.class); - private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); - - private static final String SSL_PROTOCOL = "TLS"; - private static final String KEYSTORE_ALGORITHM = "SunX509"; - private static final String KEYSTORE_TYPE = "PKCS12"; - - private final ModelLoaderConfig config; - private final Client client; - - /** - * @param config - * @throws NoSuchAlgorithmException - * @throws KeyStoreException - * @throws CertificateException - * @throws IOException - * @throws UnrecoverableKeyException - * @throws KeyManagementException - * @throws BabelServiceClientException - */ - public HttpsBabelServiceClient(ModelLoaderConfig config) - throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, - UnrecoverableKeyException, KeyManagementException, BabelServiceClientException { - this.config = config; - - logger.debug(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Creating Babel Service client"); - //Initialize SSL Context only if SSL is enabled - if (config.useHttpsWithBabel()) { - SSLContext ctx = SSLContext.getInstance(SSL_PROTOCOL); - KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEYSTORE_ALGORITHM); - KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE); - - String clientCertPassword = config.getBabelKeyStorePassword(); - - char[] pwd = null; - if (clientCertPassword != null) { - pwd = clientCertPassword.toCharArray(); - } - - TrustManager[] trustManagers = getTrustManagers(); - - String clientCertFileName = config.getBabelKeyStorePath(); - if (clientCertFileName == null) { - ctx.init(null, trustManagers, null); - } else { - InputStream fin = Files.newInputStream(Paths.get(clientCertFileName)); - keyStore.load(fin, pwd); - kmf.init(keyStore, pwd); - ctx.init(kmf.getKeyManagers(), trustManagers, null); - } - - logger.debug(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Initialised context"); - - HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory()); - HttpsURLConnection.setDefaultHostnameVerifier((host, session) -> true); - } - - client = Client.create(new DefaultClientConfig()); - - logger.debug(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Jersey client created"); - } - - private TrustManager[] getTrustManagers() throws NoSuchAlgorithmException, KeyStoreException, CertificateException, - IOException, BabelServiceClientException { - TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - // Using null here initializes the TMF with the default trust store. - tmf.init((KeyStore) null); - - // Create a new Trust Manager from the local trust store. - String trustStoreFile = config.getBabelTrustStorePath(); - if (trustStoreFile == null) { - throw new BabelServiceClientException("No Babel trust store defined"); - } - try (InputStream myKeys = Files.newInputStream(Paths.get(trustStoreFile))) { - KeyStore myTrustStore = KeyStore.getInstance(KeyStore.getDefaultType()); - myTrustStore.load(myKeys, config.getBabelTrustStorePassword().toCharArray()); - tmf.init(myTrustStore); - } - X509TrustManager localTm = findX509TrustManager(tmf); - - // Create a custom trust manager that wraps both our trust store and the default. - final X509TrustManager finalLocalTm = localTm; - - // Find the default trust manager. - final X509TrustManager defaultTrustManager = findX509TrustManager(tmf); - - return new TrustManager[] {new X509TrustManager() { - @Override - public X509Certificate[] getAcceptedIssuers() { - return defaultTrustManager.getAcceptedIssuers(); - } - - @Override - public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - try { - finalLocalTm.checkServerTrusted(chain, authType); - } catch (CertificateException e) { // NOSONAR - defaultTrustManager.checkServerTrusted(chain, authType); - } - } - - @Override - public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { - defaultTrustManager.checkClientTrusted(chain, authType); - } - }}; - } - - private X509TrustManager findX509TrustManager(TrustManagerFactory tmf) { - X509TrustManager trustManager = null; - for (TrustManager tm : tmf.getTrustManagers()) { - if (tm instanceof X509TrustManager) { - trustManager = (X509TrustManager) tm; - break; - } - } - return trustManager; - } - - /** - * @param artifactPayload - * @param artifactName - * @param artifactVersion - * @param transactionId - * @return - * @throws BabelServiceClientException - * @throws JSONException - */ - @Override - public List postArtifact(byte[] artifactPayload, String artifactName, String artifactVersion, - String transactionId) throws BabelServiceClientException { - Objects.requireNonNull(artifactPayload); - - String encodedPayload = Base64.getEncoder().encodeToString(artifactPayload); - - JSONObject obj = new JSONObject(); - try { - obj.put("csar", encodedPayload); - obj.put("artifactVersion", artifactVersion); - obj.put("artifactName", artifactName); - } catch (JSONException ex) { - throw new BabelServiceClientException(ex); - } - - if (logger.isInfoEnabled()) { - logger.info(ModelLoaderMsgs.BABEL_REST_REQUEST_PAYLOAD, " Artifact Name: " + artifactName - + " Artifact version: " + artifactVersion + " Artifact payload: " + encodedPayload); - } - - MdcOverride override = new MdcOverride(); - override.addAttribute(MdcContext.MDC_START_TIME, ZonedDateTime.now().format(formatter)); - - WebResource webResource = client.resource(config.getBabelBaseUrl() + config.getBabelGenerateArtifactsUrl()); - ClientResponse response = webResource.type("application/json") - .header(AaiRestClient.HEADER_TRANS_ID, Collections.singletonList(transactionId)) - .header(AaiRestClient.HEADER_FROM_APP_ID, Collections.singletonList(AaiRestClient.ML_APP_NAME)) - .post(ClientResponse.class, obj.toString()); - String sanitizedJson = JsonSanitizer.sanitize(response.getEntity(String.class)); - - if (logger.isDebugEnabled()) { - logger.debug(ModelLoaderMsgs.DISTRIBUTION_EVENT, - "Babel response " + response.getStatus() + " " + sanitizedJson); - } - - metricsLogger.info(ModelLoaderMsgs.BABEL_REST_REQUEST, new LogFields() // - .setField(LogLine.DefinedFields.TARGET_ENTITY, "Babel") - .setField(LogLine.DefinedFields.STATUS_CODE, - Response.Status.fromStatusCode(response.getStatus()).getFamily() - .equals(Response.Status.Family.SUCCESSFUL) ? "COMPLETE" : "ERROR") - .setField(LogLine.DefinedFields.RESPONSE_CODE, response.getStatus()) - .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, response.getStatusInfo().toString()), // - override, response.toString()); - - if (response.getStatus() != Response.Status.OK.getStatusCode()) { - throw new BabelServiceClientException(sanitizedJson); - } - - return new Gson().fromJson(sanitizedJson, new TypeToken>() {}.getType()); - } -} diff --git a/src/main/java/org/onap/aai/modelloader/service/ArtifactDeploymentManager.java b/src/main/java/org/onap/aai/modelloader/service/ArtifactDeploymentManager.java index af006f5..e4535be 100644 --- a/src/main/java/org/onap/aai/modelloader/service/ArtifactDeploymentManager.java +++ b/src/main/java/org/onap/aai/modelloader/service/ArtifactDeploymentManager.java @@ -22,73 +22,57 @@ package org.onap.aai.modelloader.service; import java.util.ArrayList; import java.util.List; -import org.onap.aai.modelloader.config.ModelLoaderConfig; + import org.onap.aai.modelloader.entity.Artifact; import org.onap.aai.modelloader.entity.catalog.VnfCatalogArtifactHandler; import org.onap.aai.modelloader.entity.model.ModelArtifactHandler; import org.onap.aai.modelloader.restclient.AaiRestClient; -import org.onap.sdc.api.notification.INotificationData; +import org.springframework.stereotype.Component; /** * This class is responsible for deploying model and catalog artifacts. */ +@Component public class ArtifactDeploymentManager { - private ModelLoaderConfig config; - private ModelArtifactHandler modelArtifactHandler; - private VnfCatalogArtifactHandler vnfCatalogArtifactHandler; + private final ModelArtifactHandler modelArtifactHandler; + private final VnfCatalogArtifactHandler vnfCatalogArtifactHandler; + private final AaiRestClient aaiClient; - public ArtifactDeploymentManager(ModelLoaderConfig config) { - this.config = config; + public ArtifactDeploymentManager(ModelArtifactHandler modelArtifactHandler, VnfCatalogArtifactHandler vnfCatalogArtifactHandler, AaiRestClient aaiClient) { + this.modelArtifactHandler = modelArtifactHandler; + this.vnfCatalogArtifactHandler = vnfCatalogArtifactHandler; + this.aaiClient = aaiClient; } /** * Deploys model and catalog artifacts to A&AI. * - * @param data data about the notification that is being processed + * @param distributionId data about the notification that is being processed * @param modelArtifacts collection of artifacts that represent yml files found in a TOSCA_CSAR file that have been * converted to XML and also those for model query specs * @param catalogArtifacts collection of artifacts that represent vnf catalog files * @return boolean true if all deployments were successful otherwise false */ - public boolean deploy(final INotificationData data, final List modelArtifacts, + public boolean deploy(final String distributionId, final List modelArtifacts, final List catalogArtifacts) { - AaiRestClient aaiClient = new AaiRestClient(config); - String distributionId = data.getDistributionID(); - List completedArtifacts = new ArrayList<>(); boolean deploySuccess = - getModelArtifactHandler().pushArtifacts(modelArtifacts, distributionId, completedArtifacts, aaiClient); + modelArtifactHandler.pushArtifacts(modelArtifacts, distributionId, completedArtifacts, aaiClient); if (!deploySuccess) { - getModelArtifactHandler().rollback(completedArtifacts, distributionId, aaiClient); + modelArtifactHandler.rollback(completedArtifacts, distributionId, aaiClient); } else { List completedImageData = new ArrayList<>(); - deploySuccess = getVnfCatalogArtifactHandler().pushArtifacts(catalogArtifacts, distributionId, + deploySuccess = vnfCatalogArtifactHandler.pushArtifacts(catalogArtifacts, distributionId, completedImageData, aaiClient); if (!deploySuccess) { - getModelArtifactHandler().rollback(completedArtifacts, distributionId, aaiClient); - getVnfCatalogArtifactHandler().rollback(completedImageData, distributionId, aaiClient); + modelArtifactHandler.rollback(completedArtifacts, distributionId, aaiClient); + vnfCatalogArtifactHandler.rollback(completedImageData, distributionId, aaiClient); } } return deploySuccess; } - - private ModelArtifactHandler getModelArtifactHandler() { - if (modelArtifactHandler == null) { - modelArtifactHandler = new ModelArtifactHandler(config); - } - - return modelArtifactHandler; - } - - private VnfCatalogArtifactHandler getVnfCatalogArtifactHandler() { - if (vnfCatalogArtifactHandler == null) { - this.vnfCatalogArtifactHandler = new VnfCatalogArtifactHandler(config); - } - - return vnfCatalogArtifactHandler; - } -} +} \ No newline at end of file diff --git a/src/main/java/org/onap/aai/modelloader/service/ArtifactInfoImpl.java b/src/main/java/org/onap/aai/modelloader/service/ArtifactInfoImpl.java index 9af92be..f83e44d 100644 --- a/src/main/java/org/onap/aai/modelloader/service/ArtifactInfoImpl.java +++ b/src/main/java/org/onap/aai/modelloader/service/ArtifactInfoImpl.java @@ -20,116 +20,25 @@ */ package org.onap.aai.modelloader.service; -import java.util.Collections; import java.util.List; import org.onap.sdc.api.notification.IArtifactInfo; +import lombok.Data; + /** * This class is an implementation of IArtifactInfo for test purposes. */ +@Data public class ArtifactInfoImpl implements IArtifactInfo { private String artifactName; private String artifactType; private String artifactDescription; private String artifactVersion; - - @Override - public String getArtifactName() { - return artifactName; - } - - public void setArtifactName(String artifactName) { - this.artifactName = artifactName; - } - - @Override - public String getArtifactType() { - return artifactType; - } - - public void setArtifactType(String artifactType) { - this.artifactType = artifactType; - } - - @Override - public String getArtifactURL() { - return null; - } - - @Override - public String getArtifactChecksum() { - return null; - } - - @Override - public String getArtifactDescription() { - return artifactDescription; - } - - public void setArtifactDescription(String artifactDescription) { - this.artifactDescription = artifactDescription; - } - - @Override - public Integer getArtifactTimeout() { - return null; - } - - @Override - public String getArtifactVersion() { - return artifactVersion; - } - - public void setArtifactVersion(String artifactVersion) { - this.artifactVersion = artifactVersion; - } - - @Override - public String getArtifactUUID() { - return null; - } - - @Override - public IArtifactInfo getGeneratedArtifact() { - return null; - } - - @Override - public List getRelatedArtifacts() { - return Collections.emptyList(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - ArtifactInfoImpl that = (ArtifactInfoImpl) o; - - if (artifactName != null ? !artifactName.equals(that.artifactName) : that.artifactName != null) { - return false; - } - if (artifactType != null ? !artifactType.equals(that.artifactType) : that.artifactType != null) { - return false; - } - if (artifactDescription != null ? !artifactDescription.equals(that.artifactDescription) - : that.artifactDescription != null) { - return false; - } - return artifactVersion != null ? artifactVersion.equals(that.artifactVersion) : that.artifactVersion == null; - } - - @Override - public int hashCode() { - int result = artifactName != null ? artifactName.hashCode() : 0; - result = 31 * result + (artifactType != null ? artifactType.hashCode() : 0); - result = 31 * result + (artifactDescription != null ? artifactDescription.hashCode() : 0); - result = 31 * result + (artifactVersion != null ? artifactVersion.hashCode() : 0); - return result; - } + private String artifactURL; + private String artifactChecksum; + private Integer artifactTimeout; + private String artifactUUID; + private IArtifactInfo generatedArtifact; + private List relatedArtifacts; } diff --git a/src/main/java/org/onap/aai/modelloader/service/HttpsBabelServiceClientFactory.java b/src/main/java/org/onap/aai/modelloader/service/HttpsBabelServiceClientFactory.java deleted file mode 100644 index 2414991..0000000 --- a/src/main/java/org/onap/aai/modelloader/service/HttpsBabelServiceClientFactory.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017-2018 European Software Marketing Ltd. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.modelloader.service; - -import java.io.IOException; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import org.onap.aai.modelloader.config.ModelLoaderConfig; -import org.onap.aai.modelloader.restclient.BabelServiceClient; -import org.onap.aai.modelloader.restclient.BabelServiceClientException; -import org.onap.aai.modelloader.restclient.HttpsBabelServiceClient; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Service; - -@Service -@Primary -public class HttpsBabelServiceClientFactory implements BabelServiceClientFactory { - - /* - * (non-Javadoc) - * - * @see org.onap.aai.modelloader.service.BabelServiceClientFactory#create(org.onap.aai.modelloader.config. - * ModelLoaderConfig) - */ - @Override - public BabelServiceClient create(ModelLoaderConfig config) throws BabelServiceClientException { - try { - return new HttpsBabelServiceClient(config); - } catch (UnrecoverableKeyException | KeyManagementException | NoSuchAlgorithmException | KeyStoreException - | CertificateException | IOException ex) { - throw new BabelServiceClientException(ex); - } - } - -} diff --git a/src/main/java/org/onap/aai/modelloader/service/ModelController.java b/src/main/java/org/onap/aai/modelloader/service/ModelController.java new file mode 100644 index 0000000..233f2ab --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/service/ModelController.java @@ -0,0 +1,140 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.service; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; + +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.modelloader.config.ModelLoaderConfig; +import org.onap.aai.modelloader.entity.Artifact; +import org.onap.aai.modelloader.entity.ArtifactType; +import org.onap.aai.modelloader.notification.ArtifactDownloadManager; +import org.onap.aai.modelloader.notification.NotificationDataImpl; +import org.onap.aai.modelloader.notification.NotificationPublisher; +import org.onap.sdc.api.IDistributionClient; +import org.onap.sdc.api.notification.IArtifactInfo; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * Service class in charge of managing the negotiating model loading capabilities between AAI and an ASDC. + */ +@RestController +@RequestMapping("/services/model-loader/v1/model-service") +public class ModelController { + + private static final Logger logger = LoggerFactory.getInstance().getLogger(ModelController.class); + + private final IDistributionClient client; + private final ModelLoaderConfig config; + private final ArtifactDeploymentManager artifactDeploymentManager; + private final ArtifactDownloadManager artifactDownloadManager; + + public ModelController(IDistributionClient client, ModelLoaderConfig config, ArtifactDeploymentManager artifactDeploymentManager, ArtifactDownloadManager artifactDownloadManager) { + this.client = client; + this.config = config; + this.artifactDeploymentManager = artifactDeploymentManager; + this.artifactDownloadManager = artifactDownloadManager; + } + + @GetMapping(value = "/loadModel/{modelid}", produces = "application/json") + public ResponseEntity loadModel(@PathVariable String modelid) { + return ResponseEntity.ok("{\"model_loaded\":\"" + modelid + "\"}"); + } + + @PutMapping(value = "/saveModel/{modelid}/{modelname}", produces = "application/json") + public ResponseEntity saveModel(@PathVariable String modelid, @PathVariable String modelname) { + return ResponseEntity.ok("{\"model_saved\":\"" + modelid + "-" + modelname + "\"}"); + } + + @PostMapping(value = "/ingestModel/{modelName}/{modelVersion}", produces = "application/json") + public ResponseEntity ingestModel(@PathVariable String modelName, @PathVariable String modelVersion, + @RequestBody String payload) throws IOException { + ResponseEntity response; + + if (config.getIngestSimulatorEnabled()) { + response = processTestArtifact(modelName, modelVersion, payload); + } else { + logger.debug("Simulation interface disabled"); + response = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); + } + + return response; + } + + private ResponseEntity processTestArtifact(String modelName, String modelVersion, String payload) { + IArtifactInfo artifactInfo = new ArtifactInfoImpl(); + ((ArtifactInfoImpl) artifactInfo).setArtifactName(modelName); + ((ArtifactInfoImpl) artifactInfo).setArtifactVersion(modelVersion); + + ResponseEntity response; + try { + logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Received test artifact " + modelName + " " + modelVersion); + + byte[] csarFile = Base64.getDecoder().decode(payload); + + logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Generating XML models from test artifact"); + + List artifacts = artifactDownloadManager.processToscaArtifacts(csarFile, artifactInfo, "test-transaction-id", modelVersion); + List modelArtifacts = new ArrayList<>(); + List catalogArtifacts = new ArrayList<>(); + for(Artifact artifact : artifacts) { + if(artifact.getType().equals(ArtifactType.MODEL)) { + modelArtifacts.add(artifact); + } else { + catalogArtifacts.add(artifact); + } + } + + logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Loading xml models from test artifacts: " + + modelArtifacts.size() + " model(s) and " + catalogArtifacts.size() + " catalog(s)"); + + NotificationDataImpl notificationData = new NotificationDataImpl(); + notificationData.setDistributionID("TestDistributionID"); + boolean success = + artifactDeploymentManager.deploy(notificationData.getDistributionID(), modelArtifacts, catalogArtifacts); + logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Deployment success was " + success); + response = success ? ResponseEntity.ok().build() : ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); + } catch (Exception e) { + String responseMessage = e.getMessage(); + logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Exception handled: " + responseMessage); + if (config.getASDCConnectionDisabled()) { + // Make sure the NotificationPublisher logger is invoked as per the standard processing flow. + new NotificationPublisher().publishDeployFailure(client, new NotificationDataImpl(), artifactInfo); + } else { + responseMessage += "\nSDC publishing is enabled but has been bypassed"; + } + response = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(responseMessage); + } + return response; + } +} diff --git a/src/main/java/org/onap/aai/modelloader/service/ModelLoaderInterface.java b/src/main/java/org/onap/aai/modelloader/service/ModelLoaderInterface.java deleted file mode 100644 index 4c7b182..0000000 --- a/src/main/java/org/onap/aai/modelloader/service/ModelLoaderInterface.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017-2018 European Software Marketing Ltd. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.modelloader.service; - -import java.io.IOException; -import javax.ws.rs.core.Response; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -public interface ModelLoaderInterface { - - @GetMapping(value = "/loadModel/{modelid}", produces = "application/json") - @ResponseBody - Response loadModel(String modelid); - - @PutMapping(value = "/saveModel/{modelid}/{modelname}", produces = "application/json") - @ResponseBody - Response saveModel(String modelid, String modelname); - - @PostMapping(value = "/ingestModel/{modelName}/{modelVersion}", produces = "application/json") - @ResponseBody - Response ingestModel(String modelid, String modelVersion, String payload) throws IOException; -} diff --git a/src/main/java/org/onap/aai/modelloader/service/ModelLoaderService.java b/src/main/java/org/onap/aai/modelloader/service/ModelLoaderService.java deleted file mode 100644 index dc17dfe..0000000 --- a/src/main/java/org/onap/aai/modelloader/service/ModelLoaderService.java +++ /dev/null @@ -1,221 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017-2018 European Software Marketing Ltd. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.modelloader.service; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Base64; -import java.util.Date; -import java.util.List; -import java.util.Properties; -import java.util.Timer; -import java.util.TimerTask; - -import javax.annotation.PostConstruct; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; -import org.onap.aai.modelloader.config.ModelLoaderConfig; -import org.onap.aai.modelloader.entity.Artifact; -import org.onap.aai.modelloader.notification.ArtifactDownloadManager; -import org.onap.aai.modelloader.notification.EventCallback; -import org.onap.aai.modelloader.notification.NotificationDataImpl; -import org.onap.aai.modelloader.notification.NotificationPublisher; -import org.onap.sdc.api.IDistributionClient; -import org.onap.sdc.api.notification.IArtifactInfo; -import org.onap.sdc.api.results.IDistributionClientResult; -import org.onap.sdc.impl.DistributionClientFactory; -import org.onap.sdc.utils.DistributionActionResultEnum; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * Service class in charge of managing the negotiating model loading capabilities between AAI and an ASDC. - */ -@RestController -@RequestMapping("/services/model-loader/v1/model-service") -public class ModelLoaderService implements ModelLoaderInterface { - - private static final Logger logger = LoggerFactory.getInstance().getLogger(ModelLoaderService.class.getName()); - - @Value("${CONFIG_HOME}") - private String configDir; - private IDistributionClient client; - private ModelLoaderConfig config; - @Autowired - private BabelServiceClientFactory babelClientFactory; - - /** - * Responsible for loading configuration files and calling initialization. - */ - @PostConstruct - protected void start() { - // Load model loader system configuration - logger.info(ModelLoaderMsgs.LOADING_CONFIGURATION); - ModelLoaderConfig.setConfigHome(configDir); - Properties configProperties = new Properties(); - try (InputStream configInputStream = Files.newInputStream(Paths.get(configDir, "model-loader.properties"))) { - configProperties.load(configInputStream); - config = new ModelLoaderConfig(configProperties); - if (!config.getASDCConnectionDisabled()) { - initSdcClient(); - } - } catch (IOException e) { - String errorMsg = "Failed to load configuration: " + e.getMessage(); - logger.error(ModelLoaderMsgs.ASDC_CONNECTION_ERROR, errorMsg); - } - } - - /** - * Responsible for stopping the connection to the distribution client before the resource is destroyed. - */ - public void preShutdownOperations() { - logger.info(ModelLoaderMsgs.STOPPING_CLIENT); - if (client != null) { - client.stop(); - } - } - - /** - * Responsible for loading configuration files, initializing model distribution clients, and starting them. - */ - protected void initSdcClient() { - // Initialize distribution client - logger.debug(ModelLoaderMsgs.INITIALIZING, "Initializing distribution client..."); - client = DistributionClientFactory.createDistributionClient(); - EventCallback callback = new EventCallback(client, config, babelClientFactory); - - IDistributionClientResult initResult = client.init(config, callback); - - if (initResult.getDistributionActionResult() == DistributionActionResultEnum.SUCCESS) { - // Start distribution client - logger.debug(ModelLoaderMsgs.INITIALIZING, "Starting distribution client..."); - IDistributionClientResult startResult = client.start(); - if (startResult.getDistributionActionResult() == DistributionActionResultEnum.SUCCESS) { - logger.info(ModelLoaderMsgs.INITIALIZING, "Connection to SDC established"); - } else { - String errorMsg = "Failed to start distribution client: " + startResult.getDistributionMessageResult(); - logger.error(ModelLoaderMsgs.ASDC_CONNECTION_ERROR, errorMsg); - - // Kick off a timer to retry the SDC connection - Timer timer = new Timer(); - TimerTask task = new SdcConnectionJob(client, config, callback, timer); - timer.schedule(task, new Date(), 60000); - } - } else { - String errorMsg = "Failed to initialize distribution client: " + initResult.getDistributionMessageResult(); - logger.error(ModelLoaderMsgs.ASDC_CONNECTION_ERROR, errorMsg); - - // Kick off a timer to retry the SDC connection - Timer timer = new Timer(); - TimerTask task = new SdcConnectionJob(client, config, callback, timer); - timer.schedule(task, new Date(), 60000); - } - - Runtime.getRuntime().addShutdownHook(new Thread(this::preShutdownOperations)); - } - - /** - * (non-Javadoc) - * - * @see org.onap.aai.modelloader.service.ModelLoaderInterface#loadModel(java.lang.String) - */ - @Override - public Response loadModel(@PathVariable String modelid) { - return Response.ok("{\"model_loaded\":\"" + modelid + "\"}").build(); - } - - /** - * (non-Javadoc) - * - * @see org.onap.aai.modelloader.service.ModelLoaderInterface#saveModel(java.lang.String, java.lang.String) - */ - @Override - public Response saveModel(@PathVariable String modelid, @PathVariable String modelname) { - return Response.ok("{\"model_saved\":\"" + modelid + "-" + modelname + "\"}").build(); - } - - @Override - public Response ingestModel(@PathVariable String modelName, @PathVariable String modelVersion, - @RequestBody String payload) throws IOException { - Response response; - - if (config.getIngestSimulatorEnabled()) { - response = processTestArtifact(modelName, modelVersion, payload); - } else { - logger.debug("Simulation interface disabled"); - response = Response.serverError().build(); - } - - return response; - } - - private Response processTestArtifact(String modelName, String modelVersion, String payload) { - IArtifactInfo artifactInfo = new ArtifactInfoImpl(); - ((ArtifactInfoImpl) artifactInfo).setArtifactName(modelName); - ((ArtifactInfoImpl) artifactInfo).setArtifactVersion(modelVersion); - - Response response; - try { - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Received test artifact " + modelName + " " + modelVersion); - - byte[] csarFile = Base64.getDecoder().decode(payload); - - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Generating XML models from test artifact"); - - List modelArtifacts = new ArrayList<>(); - List catalogArtifacts = new ArrayList<>(); - - new ArtifactDownloadManager(client, config, babelClientFactory).processToscaArtifacts(modelArtifacts, - catalogArtifacts, csarFile, artifactInfo, "test-transaction-id", modelVersion); - - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Loading xml models from test artifacts: " - + modelArtifacts.size() + " model(s) and " + catalogArtifacts.size() + " catalog(s)"); - - NotificationDataImpl notificationData = new NotificationDataImpl(); - notificationData.setDistributionID("TestDistributionID"); - boolean success = - new ArtifactDeploymentManager(config).deploy(notificationData, modelArtifacts, catalogArtifacts); - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Deployment success was " + success); - response = success ? Response.ok().build() : Response.serverError().build(); - } catch (Exception e) { - String responseMessage = e.getMessage(); - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Exception handled: " + responseMessage); - if (config.getASDCConnectionDisabled()) { - // Make sure the NotificationPublisher logger is invoked as per the standard processing flow. - new NotificationPublisher().publishDeployFailure(client, new NotificationDataImpl(), artifactInfo); - } else { - responseMessage += "\nSDC publishing is enabled but has been bypassed"; - } - response = Response.serverError().entity(responseMessage).type(MediaType.APPLICATION_XML).build(); - } - return response; - } -} diff --git a/src/main/java/org/onap/aai/modelloader/service/SdcConnectionJob.java b/src/main/java/org/onap/aai/modelloader/service/SdcConnectionJob.java index 9a6c6e9..79cf538 100644 --- a/src/main/java/org/onap/aai/modelloader/service/SdcConnectionJob.java +++ b/src/main/java/org/onap/aai/modelloader/service/SdcConnectionJob.java @@ -34,12 +34,11 @@ public class SdcConnectionJob extends TimerTask { private static final Logger logger = LoggerFactory.getInstance().getLogger(SdcConnectionJob.class.getName()); private final IDistributionClient client; - private ModelLoaderConfig config; - private EventCallback callback; - private Timer timer; + private final ModelLoaderConfig config; + private final EventCallback callback; + private final Timer timer; public SdcConnectionJob(IDistributionClient client, ModelLoaderConfig config, EventCallback callback, Timer timer) { - super(); this.client = client; this.timer = timer; this.callback = callback; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4ea6f0a..d3b4f45 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -12,9 +12,20 @@ server.port=9500 #server.ssl.keyStoreType= #server.ssl.keyAlias= -server.tomcat.max-threads=200 +spring.application.name=model-loader + +spring.sleuth.enabled=false +spring.zipkin.baseUrl=http://jaeger-collector.istio-system:9411 +spring.sleuth.messaging.jms.enabled=false +spring.sleuth.trace-id128=true +spring.sleuth.sampler.probability=1.0 +spring.sleuth.propagation.type=w3c,b3 +spring.sleuth.supports-join=false +spring.sleuth.web.skip-pattern=/aai/util.* + +server.tomcat.threads.max=200 # The minimum number of threads always kept alive -server.tomcat.min-spare-threads=25 +server.tomcat.threads.min-spare=25 # Spring Boot logging logging.config=${logback.configurationFile} diff --git a/src/test/java/org/onap/aai/modelloader/BabelClientTestConfiguration.java b/src/test/java/org/onap/aai/modelloader/BabelClientTestConfiguration.java new file mode 100644 index 0000000..9df74fa --- /dev/null +++ b/src/test/java/org/onap/aai/modelloader/BabelClientTestConfiguration.java @@ -0,0 +1,57 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Properties; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; + +@TestConfiguration +public class BabelClientTestConfiguration { + @Value("${CONFIG_HOME}") + private String configDir; + + @Value("${wiremock.server.port}") + private int wiremockPort; + + @Primary + @Bean(name = "testProperties") + public Properties configProperties() throws IOException { + // Load model loader system configuration + InputStream configInputStream = Files.newInputStream(Paths.get(configDir, "model-loader.properties")); + Properties configProperties = new Properties(); + configProperties.load(configInputStream); + + setOverrides(configProperties); + + return configProperties; + } + + private void setOverrides(Properties configProperties) { + configProperties.setProperty("ml.babel.BASE_URL", "http://localhost:" + wiremockPort); + } +} diff --git a/src/test/java/org/onap/aai/modelloader/DistributionClientTestConfiguration.java b/src/test/java/org/onap/aai/modelloader/DistributionClientTestConfiguration.java new file mode 100644 index 0000000..1eed62f --- /dev/null +++ b/src/test/java/org/onap/aai/modelloader/DistributionClientTestConfiguration.java @@ -0,0 +1,81 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.matching; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Properties; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.event.ApplicationStartedEvent; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; +import org.springframework.context.event.EventListener; + +@TestConfiguration +public class DistributionClientTestConfiguration { + + @Value("${CONFIG_HOME}") + private String configDir; + + @Value("${wiremock.server.port}") + private int wiremockPort; + + @Primary + @Bean(name = "testProperties") + public Properties configProperties() throws IOException { + // Load model loader system configuration + InputStream configInputStream = Files.newInputStream(Paths.get(configDir, "model-loader.properties")); + Properties configProperties = new Properties(); + configProperties.load(configInputStream); + + setOverrides(configProperties); + + return configProperties; + } + + private void setOverrides(Properties configProperties) { + configProperties.setProperty("ml.distribution.ASDC_ADDRESS", "localhost:" + wiremockPort); + configProperties.setProperty("ml.babel.BASE_URL", "http://localhost:" + wiremockPort); + } + + @EventListener(ApplicationStartedEvent.class) + public void mockSdcInit() { + stubFor(get(urlEqualTo("/sdc/v1/artifactTypes")) + .withHeader("X-ECOMP-RequestID", matching(".+")) + .withHeader("X-ECOMP-InstanceID", equalTo("aai-ml-id-test")) + .willReturn(aResponse().withHeader("Content-Type", "application/json").withBodyFile("artifactTypes.json"))); + + stubFor(get(urlEqualTo("/sdc/v1/distributionKafkaData")) + .withHeader("X-ECOMP-RequestID", matching(".+")) + .withHeader("X-ECOMP-InstanceID", equalTo("aai-ml-id-test")) + .willReturn(aResponse().withHeader("Content-Type", "application/json").withBodyFile("kafkaBootstrap.json"))); + } +} \ No newline at end of file diff --git a/src/test/java/org/onap/aai/modelloader/config/TestModelLoaderConfig.java b/src/test/java/org/onap/aai/modelloader/config/TestModelLoaderConfig.java index e19b1e2..89f343c 100644 --- a/src/test/java/org/onap/aai/modelloader/config/TestModelLoaderConfig.java +++ b/src/test/java/org/onap/aai/modelloader/config/TestModelLoaderConfig.java @@ -20,17 +20,13 @@ */ package org.onap.aai.modelloader.config; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; import java.util.List; import java.util.Properties; import org.eclipse.jetty.util.security.Password; -import org.junit.Test; -import org.onap.aai.modelloader.restclient.AaiRestClient; +import org.junit.jupiter.api.Test; import org.onap.sdc.utils.ArtifactTypeEnum; /** @@ -149,23 +145,6 @@ public class TestModelLoaderConfig { assertEquals(url, config.getBabelGenerateArtifactsUrl()); } - @Test - public void testMissingAuthenticationProperties() throws IOException { - Properties props = new Properties(); - props.load(new FileInputStream("src/test/resources/model-loader-empty-auth-password.properties")); - - ModelLoaderConfig config = new ModelLoaderConfig(props, null); - AaiRestClient aaiClient = new AaiRestClient(config); - - assertFalse("Empty AAI Password should result in no basic authentication", aaiClient.useBasicAuth()); - - props.load(new FileInputStream("src/test/resources/model-loader-no-auth-password.properties")); - config = new ModelLoaderConfig(props, null); - aaiClient = new AaiRestClient(config); - - assertFalse("No AAI Password should result in no basic authentication", aaiClient.useBasicAuth()); - } - @Test public void testGetUrls() { Properties props = new Properties(); diff --git a/src/test/java/org/onap/aai/modelloader/csar/extractor/VnfCatalogExtractorTest.java b/src/test/java/org/onap/aai/modelloader/csar/extractor/VnfCatalogExtractorTest.java index bd8c33f..b3335fc 100644 --- a/src/test/java/org/onap/aai/modelloader/csar/extractor/VnfCatalogExtractorTest.java +++ b/src/test/java/org/onap/aai/modelloader/csar/extractor/VnfCatalogExtractorTest.java @@ -21,17 +21,18 @@ package org.onap.aai.modelloader.csar.extractor; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import org.junit.Test; + +import org.junit.jupiter.api.Test; import org.onap.aai.modelloader.entity.Artifact; import org.onap.aai.modelloader.entity.ArtifactType; import org.onap.aai.modelloader.extraction.InvalidArchiveException; @@ -85,8 +86,8 @@ public class VnfCatalogExtractorTest { List vnfcArtifacts = new VnfCatalogExtractor().extract( new ArtifactTestUtils().loadResource("compressedArtifacts/noVnfcFilesArchive.csar"), "noVnfcFilesArchive.csar"); - assertTrue("No VNFC files should have been extracted, but " + vnfcArtifacts.size() + " were found.", - vnfcArtifacts.isEmpty()); + assertTrue(vnfcArtifacts.isEmpty(), + "No VNFC files should have been extracted, but " + vnfcArtifacts.size() + " were found."); } @Test diff --git a/src/test/java/org/onap/aai/modelloader/distribution/EventCallbackAspect.java b/src/test/java/org/onap/aai/modelloader/distribution/EventCallbackAspect.java new file mode 100644 index 0000000..16f311b --- /dev/null +++ b/src/test/java/org/onap/aai/modelloader/distribution/EventCallbackAspect.java @@ -0,0 +1,49 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.distribution; + +import java.util.concurrent.CountDownLatch; + +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +import lombok.Getter; +import lombok.Setter; + +@Aspect +@Getter +@Setter +@Component +/** + * Aspect to asynchronously wait for the EventCallback being called after a distribution event from sdc was published + */ +public class EventCallbackAspect { + + private CountDownLatch countDownLatch; + + @After( + "execution(* org.onap.aai.modelloader.notification.EventCallback.activateCallback(..))") + private void afterEventCallbackCalled() { + if (countDownLatch != null) { + countDownLatch.countDown(); + } + } +} \ No newline at end of file diff --git a/src/test/java/org/onap/aai/modelloader/distribution/NotificationIntegrationTest.java b/src/test/java/org/onap/aai/modelloader/distribution/NotificationIntegrationTest.java new file mode 100644 index 0000000..abdefd4 --- /dev/null +++ b/src/test/java/org/onap/aai/modelloader/distribution/NotificationIntegrationTest.java @@ -0,0 +1,68 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.distribution; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.onap.aai.modelloader.notification.NotificationDataImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.test.annotation.DirtiesContext; + +@DirtiesContext +@SpringBootTest(properties = { "model-loader.sdc.connection.enabled=true"}) +@EmbeddedKafka(partitions = 1, ports = 9092, topics = {"${topics.distribution.notification}"}) +public class NotificationIntegrationTest { + + @Autowired EventCallbackAspect eventCallbackAspect; + + @Autowired + private KafkaTemplate kafkaTemplate; + + @Value("${topics.distribution.notification}") + private String topic; + + @Test + @Disabled("This test is not yet implemented") + public void thatActivateCallbackIsCalled() + throws Exception { + NotificationDataImpl notificationData = new NotificationDataImpl(); + notificationData.setDistributionID("distributionID"); + + // TODO: send distribution event here + kafkaTemplate.send(topic, notificationData); + + // TODO: mock distribution client requests to /sdc/v1/artifactTypes + // TODO: mock distribution client requests to /sdc/v1/distributionKafkaData + + // aspect will wait for EventCallback.activateCallback to be called + eventCallbackAspect.setCountDownLatch(new CountDownLatch(1)); + boolean callbackCalled = eventCallbackAspect.getCountDownLatch().await(10, TimeUnit.SECONDS); + assertTrue(callbackCalled); + } +} diff --git a/src/test/java/org/onap/aai/modelloader/entity/catalog/TestVnfCatalogArtifactHandler.java b/src/test/java/org/onap/aai/modelloader/entity/catalog/TestVnfCatalogArtifactHandler.java index cead699..3da25b0 100644 --- a/src/test/java/org/onap/aai/modelloader/entity/catalog/TestVnfCatalogArtifactHandler.java +++ b/src/test/java/org/onap/aai/modelloader/entity/catalog/TestVnfCatalogArtifactHandler.java @@ -22,8 +22,9 @@ package org.onap.aai.modelloader.entity.catalog; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -34,16 +35,17 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.Properties; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import org.junit.Test; + +import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.onap.aai.modelloader.config.ModelLoaderConfig; import org.onap.aai.modelloader.entity.Artifact; import org.onap.aai.modelloader.entity.ArtifactType; import org.onap.aai.modelloader.restclient.AaiRestClient; -import org.onap.aai.restclient.client.OperationResult; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; public class TestVnfCatalogArtifactHandler { @@ -59,24 +61,23 @@ public class TestVnfCatalogArtifactHandler { @Test public void testUpdateVnfImages() throws Exception { // GET operation - OperationResult mockGetResp = mock(OperationResult.class); + ResponseEntity mockGetResp = mock(ResponseEntity.class); // @formatter:off - when(mockGetResp.getResultCode()) - .thenReturn(Response.Status.OK.getStatusCode()) - .thenReturn(Response.Status.NOT_FOUND.getStatusCode()) - .thenReturn(Response.Status.NOT_FOUND.getStatusCode()) - .thenReturn(Response.Status.OK.getStatusCode()); + when(mockGetResp.getStatusCodeValue()) + .thenReturn(HttpStatus.OK.value()) + .thenReturn(HttpStatus.NOT_FOUND.value()) + .thenReturn(HttpStatus.NOT_FOUND.value()) + .thenReturn(HttpStatus.OK.value()); // @formatter:on - when(mockRestClient.getResource(Mockito.anyString(), Mockito.anyString(), Mockito.any(MediaType.class))) + when(mockRestClient.getResource(Mockito.anyString(), Mockito.anyString(), Mockito.any(MediaType.class), Mockito.any())) .thenReturn(mockGetResp); mockPutOperations(); // Example VNF Catalog XML VnfCatalogArtifactHandler handler = new VnfCatalogArtifactHandler(createConfig()); - assertThat(handler.pushArtifacts(createVnfCatalogArtifact(), "test", new ArrayList(), mockRestClient), - is(true)); + assertTrue(handler.pushArtifacts(createVnfCatalogArtifact(), "test", new ArrayList(), mockRestClient)); assertPutOperationsSucceeded(); } @@ -84,17 +85,17 @@ public class TestVnfCatalogArtifactHandler { @Test public void testUpdateVnfImagesFromXml() throws Exception { // GET operation - OperationResult mockGetResp = mock(OperationResult.class); + ResponseEntity mockGetResp = mock(ResponseEntity.class); // @formatter:off - when(mockGetResp.getResultCode()) - .thenReturn(Response.Status.OK.getStatusCode()) - .thenReturn(Response.Status.NOT_FOUND.getStatusCode()) - .thenReturn(Response.Status.NOT_FOUND.getStatusCode()) - .thenReturn(Response.Status.OK.getStatusCode()); + when(mockGetResp.getStatusCodeValue()) + .thenReturn(HttpStatus.OK.value()) + .thenReturn(HttpStatus.NOT_FOUND.value()) + .thenReturn(HttpStatus.NOT_FOUND.value()) + .thenReturn(HttpStatus.OK.value()); // @formatter:on - when(mockRestClient.getResource(Mockito.anyString(), Mockito.anyString(), Mockito.any(MediaType.class))) + when(mockRestClient.getResource(Mockito.anyString(), Mockito.anyString(), Mockito.any(MediaType.class), Mockito.any())) .thenReturn(mockGetResp); mockPutOperations(); @@ -107,7 +108,7 @@ public class TestVnfCatalogArtifactHandler { // Only two of the VNF images should be pushed ArgumentCaptor argument = ArgumentCaptor.forClass(String.class); AaiRestClient client = Mockito.verify(mockRestClient, Mockito.times(2)); - client.putResource(Mockito.anyString(), argument.capture(), Mockito.anyString(), Mockito.any(MediaType.class)); + client.putResource(Mockito.anyString(), argument.capture(), Mockito.anyString(), Mockito.any(MediaType.class), Mockito.any()); assertThat(argument.getAllValues().size(), is(2)); assertThat(argument.getAllValues().get(0), containsString("5.2.5")); assertThat(argument.getAllValues().get(0), containsString("VM00")); @@ -159,10 +160,10 @@ public class TestVnfCatalogArtifactHandler { * Always return CREATED (success) for a PUT operation. */ private void mockPutOperations() { - OperationResult mockPutResp = mock(OperationResult.class); - when(mockPutResp.getResultCode()).thenReturn(Response.Status.CREATED.getStatusCode()); + ResponseEntity mockPutResp = mock(ResponseEntity.class); + when(mockPutResp.getStatusCode()).thenReturn(HttpStatus.CREATED); when(mockRestClient.putResource(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), - Mockito.any(MediaType.class))).thenReturn(mockPutResp); + Mockito.any(MediaType.class), Mockito.any())).thenReturn(mockPutResp); } private void assertPutOperationsSucceeded() { @@ -170,7 +171,7 @@ public class TestVnfCatalogArtifactHandler { ArgumentCaptor argument = ArgumentCaptor.forClass(String.class); AaiRestClient mockedClient = Mockito.verify(mockRestClient, Mockito.times(2)); mockedClient.putResource(Mockito.anyString(), argument.capture(), Mockito.anyString(), - Mockito.any(MediaType.class)); + Mockito.any(MediaType.class), Mockito.any()); assertThat(argument.getAllValues().get(0), containsString("3.16.9")); assertThat(argument.getAllValues().get(0), containsString("VM00")); assertThat(argument.getAllValues().get(1), containsString("3.16.1")); diff --git a/src/test/java/org/onap/aai/modelloader/entity/catalog/TestVnfImageException.java b/src/test/java/org/onap/aai/modelloader/entity/catalog/TestVnfImageException.java index c8b14f7..793ed9a 100644 --- a/src/test/java/org/onap/aai/modelloader/entity/catalog/TestVnfImageException.java +++ b/src/test/java/org/onap/aai/modelloader/entity/catalog/TestVnfImageException.java @@ -22,9 +22,9 @@ package org.onap.aai.modelloader.entity.catalog; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * Tests for NotificationDataImpl class. diff --git a/src/test/java/org/onap/aai/modelloader/entity/model/ModelSorterTest.java b/src/test/java/org/onap/aai/modelloader/entity/model/ModelSorterTest.java index 8f4bf8d..0c79dc5 100644 --- a/src/test/java/org/onap/aai/modelloader/entity/model/ModelSorterTest.java +++ b/src/test/java/org/onap/aai/modelloader/entity/model/ModelSorterTest.java @@ -24,14 +24,16 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.isEmptyString; -import static org.junit.Assert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import org.junit.Test; + +import org.junit.jupiter.api.Test; import org.onap.aai.modelloader.entity.Artifact; public class ModelSorterTest { @@ -128,12 +130,14 @@ public class ModelSorterTest { assertThat(new ModelSorter().sort(Arrays.asList(nq1, nq2, artifact)), is(expected)); } - @Test(expected = BabelArtifactParsingException.class) + @Test public void circularDependency() throws BabelArtifactParsingException { - List modelList = new ArrayList(); - modelList.add(buildTestModel("aaaa", "1111", "bbbb|1111")); - modelList.add(buildTestModel("bbbb", "1111", "aaaa|1111")); - new ModelSorter().sort(modelList); + assertThrows(BabelArtifactParsingException.class, () -> { + List modelList = new ArrayList(); + modelList.add(buildTestModel("aaaa", "1111", "bbbb|1111")); + modelList.add(buildTestModel("bbbb", "1111", "aaaa|1111")); + new ModelSorter().sort(modelList); + }); } private ModelArtifact buildTestModel() { diff --git a/src/test/java/org/onap/aai/modelloader/entity/model/TestModelArtifactHandler.java b/src/test/java/org/onap/aai/modelloader/entity/model/TestModelArtifactHandler.java index 5ccd1d2..7a630b5 100644 --- a/src/test/java/org/onap/aai/modelloader/entity/model/TestModelArtifactHandler.java +++ b/src/test/java/org/onap/aai/modelloader/entity/model/TestModelArtifactHandler.java @@ -21,27 +21,25 @@ package org.onap.aai.modelloader.entity.model; import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.isEmptyString; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import javax.ws.rs.core.Response; -import org.junit.Before; -import org.junit.Test; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.onap.aai.modelloader.config.ModelLoaderConfig; import org.onap.aai.modelloader.entity.Artifact; import org.onap.aai.modelloader.restclient.AaiRestClient; -import org.onap.aai.restclient.client.OperationResult; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; /** * Test the Model Artifact Handler using Mocks @@ -55,9 +53,9 @@ public class TestModelArtifactHandler { @Mock private AaiRestClient aaiClient; - @Before + @BeforeEach public void setupMocks() { - MockitoAnnotations.initMocks(this); + MockitoAnnotations.openMocks(this); } @Test @@ -68,26 +66,14 @@ public class TestModelArtifactHandler { assertTrue(true); } - @Test - public void testSingleItemList() { - when(config.getAaiBaseUrl()).thenReturn(""); - when(config.getAaiModelUrl(any())).thenReturn(""); - - ModelArtifactHandler handler = new ModelArtifactHandler(config); - List artifacts = Collections.singletonList(new ModelArtifact()); - handler.pushArtifacts(artifacts, "", Collections.emptyList(), aaiClient); - handler.rollback(Collections.emptyList(), "", aaiClient); - assertThat(artifacts, hasSize(1)); - } - @Test public void testPushExistingModelsWithRollback() { when(config.getAaiBaseUrl()).thenReturn(""); when(config.getAaiModelUrl(any())).thenReturn(""); - OperationResult operationResult = mock(OperationResult.class); - when(aaiClient.getResource(any(), any(), any())).thenReturn(operationResult); - when(operationResult.getResultCode()).thenReturn(Response.Status.OK.getStatusCode()); + ResponseEntity operationResult = mock(ResponseEntity.class); + when(aaiClient.getResource(any(), any(), any(), any())).thenReturn(operationResult); + when(operationResult.getStatusCode()).thenReturn(HttpStatus.OK); List artifacts = new ArrayList<>(); Artifact artifact = new ModelArtifact(); @@ -105,13 +91,13 @@ public class TestModelArtifactHandler { when(config.getAaiModelUrl(any())).thenReturn(""); when(config.getAaiNamedQueryUrl(any())).thenReturn(""); - OperationResult getResult = mock(OperationResult.class); - when(aaiClient.getResource(any(), any(), any())).thenReturn(getResult); - when(getResult.getResultCode()).thenReturn(Response.Status.NOT_FOUND.getStatusCode()); + ResponseEntity getResult = mock(ResponseEntity.class); + when(aaiClient.getResource(any(), any(), any(), any())).thenReturn(getResult); + when(getResult.getStatusCode()).thenReturn(HttpStatus.NOT_FOUND); - OperationResult putResult = mock(OperationResult.class); - when(aaiClient.putResource(any(), any(), any(), any())).thenReturn(putResult); - when(putResult.getResultCode()).thenReturn(Response.Status.CREATED.getStatusCode()); + ResponseEntity putResult = mock(ResponseEntity.class); + when(aaiClient.putResource(any(), any(), any(), any(), any())).thenReturn(putResult); + when(putResult.getStatusCode()).thenReturn(HttpStatus.CREATED); List artifacts = new ArrayList<>(); artifacts.add(new ModelArtifact()); @@ -133,13 +119,13 @@ public class TestModelArtifactHandler { when(config.getAaiModelUrl(any())).thenReturn(""); when(config.getAaiNamedQueryUrl(any())).thenReturn(""); - OperationResult getResult = mock(OperationResult.class); - when(aaiClient.getResource(any(), any(), any())).thenReturn(getResult); - when(getResult.getResultCode()).thenReturn(Response.Status.NOT_FOUND.getStatusCode()); + ResponseEntity getResult = mock(ResponseEntity.class); + when(aaiClient.getResource(any(), any(), any(), any())).thenReturn(getResult); + when(getResult.getStatusCode()).thenReturn(HttpStatus.NOT_FOUND); - OperationResult putResult = mock(OperationResult.class); - when(aaiClient.putResource(any(), any(), any(), any())).thenReturn(putResult); - when(putResult.getResultCode()).thenReturn(Response.Status.BAD_REQUEST.getStatusCode()); + ResponseEntity putResult = mock(ResponseEntity.class); + when(aaiClient.putResource(any(), any(), any(), any(), any())).thenReturn(putResult); + when(putResult.getStatusCode()).thenReturn(HttpStatus.BAD_REQUEST); checkRollback(Collections.singletonList(new ModelArtifact())); } @@ -149,18 +135,9 @@ public class TestModelArtifactHandler { when(config.getAaiBaseUrl()).thenReturn(""); when(config.getAaiModelUrl(any())).thenReturn(""); - OperationResult operationResult = mock(OperationResult.class); - when(aaiClient.getResource(any(), any(), any())).thenReturn(operationResult); - when(operationResult.getResultCode()).thenReturn(Response.Status.BAD_REQUEST.getStatusCode()); - - checkRollback(Collections.singletonList(new ModelArtifact())); - } - - @Test - public void testNullResourceModelResult() { - when(config.getAaiBaseUrl()).thenReturn(""); - when(config.getAaiModelUrl(any())).thenReturn(""); - when(aaiClient.getResource(any(), any(), any())).thenReturn(null); + ResponseEntity operationResult = mock(ResponseEntity.class); + when(aaiClient.getResource(any(), any(), any(), any())).thenReturn(operationResult); + when(operationResult.getStatusCode()).thenReturn(HttpStatus.BAD_REQUEST); checkRollback(Collections.singletonList(new ModelArtifact())); } diff --git a/src/test/java/org/onap/aai/modelloader/entity/model/TestModelArtifactParser.java b/src/test/java/org/onap/aai/modelloader/entity/model/TestModelArtifactParser.java index aef0acc..fc0556f 100644 --- a/src/test/java/org/onap/aai/modelloader/entity/model/TestModelArtifactParser.java +++ b/src/test/java/org/onap/aai/modelloader/entity/model/TestModelArtifactParser.java @@ -23,13 +23,14 @@ package org.onap.aai.modelloader.entity.model; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.text.IsEqualIgnoringCase.equalToIgnoringCase; -import static org.junit.Assert.assertThat; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; -import org.junit.Test; + +import org.junit.jupiter.api.Test; import org.onap.aai.modelloader.entity.Artifact; import org.springframework.util.CollectionUtils; diff --git a/src/test/java/org/onap/aai/modelloader/entity/model/TestNamedQueryArtifactParser.java b/src/test/java/org/onap/aai/modelloader/entity/model/TestNamedQueryArtifactParser.java index 1d2d385..9ea900f 100644 --- a/src/test/java/org/onap/aai/modelloader/entity/model/TestNamedQueryArtifactParser.java +++ b/src/test/java/org/onap/aai/modelloader/entity/model/TestNamedQueryArtifactParser.java @@ -21,16 +21,17 @@ package org.onap.aai.modelloader.entity.model; import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.isEmptyString; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; -import org.junit.Test; + +import org.junit.jupiter.api.Test; import org.onap.aai.modelloader.entity.Artifact; public class TestNamedQueryArtifactParser { diff --git a/src/test/java/org/onap/aai/modelloader/extraction/TestArtifactInfoExtractor.java b/src/test/java/org/onap/aai/modelloader/extraction/TestArtifactInfoExtractor.java index 3bfb2a5..142b3c0 100644 --- a/src/test/java/org/onap/aai/modelloader/extraction/TestArtifactInfoExtractor.java +++ b/src/test/java/org/onap/aai/modelloader/extraction/TestArtifactInfoExtractor.java @@ -20,8 +20,8 @@ */ package org.onap.aai.modelloader.extraction; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.onap.aai.modelloader.fixture.NotificationDataFixtureBuilder.getEmptyNotificationData; import static org.onap.aai.modelloader.fixture.NotificationDataFixtureBuilder.getNotificationDataWithOneResource; import static org.onap.aai.modelloader.fixture.NotificationDataFixtureBuilder.getNotificationDataWithOneService; @@ -29,9 +29,9 @@ import static org.onap.aai.modelloader.fixture.NotificationDataFixtureBuilder.ge import java.util.ArrayList; import java.util.List; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.onap.aai.modelloader.fixture.ArtifactInfoBuilder; import org.onap.aai.modelloader.fixture.MockNotificationDataImpl; import org.onap.sdc.api.notification.IArtifactInfo; @@ -44,12 +44,12 @@ public class TestArtifactInfoExtractor { private ArtifactInfoExtractor extractor; - @Before + @BeforeEach public void setup() { extractor = new ArtifactInfoExtractor(); } - @After + @AfterEach public void tearDown() { extractor = null; } @@ -60,7 +60,7 @@ public class TestArtifactInfoExtractor { } private void doEmptyArtifactsTest(INotificationData notificationData) { - assertTrue("The list returned should have been empty", extractor.extract(notificationData).isEmpty()); + assertTrue(extractor.extract(notificationData).isEmpty(), "The list returned should have been empty"); } @Test @@ -79,8 +79,8 @@ public class TestArtifactInfoExtractor { List artifacts = extractor.extract(getNotificationDataWithOneService()); - assertEquals("One artifact should have been returned", 1, artifacts.size()); - assertEquals("The actual artifact did not match the expected one", expected, artifacts.get(0)); + assertEquals(1, artifacts.size(), "One artifact should have been returned"); + assertEquals(expected, artifacts.get(0), "The actual artifact did not match the expected one"); } @Test @@ -90,8 +90,8 @@ public class TestArtifactInfoExtractor { List artifacts = extractor.extract(getNotificationDataWithOneResource()); - assertEquals("One artifact should have been returned", 1, artifacts.size()); - assertEquals("The actual artifact did not match the expected one", expectedArtifacts, artifacts); + assertEquals(1, artifacts.size(), "One artifact should have been returned"); + assertEquals(expectedArtifacts, artifacts, "The actual artifact did not match the expected one"); } @Test @@ -102,7 +102,7 @@ public class TestArtifactInfoExtractor { List artifacts = extractor.extract(getNotificationDataWithOneServiceAndResources()); - assertEquals("Two artifact should have been returned", 2, artifacts.size()); - assertEquals("The actual artifact did not match the expected one", expectedArtifacts, artifacts); + assertEquals(2, artifacts.size(), "Two artifact should have been returned"); + assertEquals(expectedArtifacts, artifacts, "The actual artifact did not match the expected one"); } } diff --git a/src/test/java/org/onap/aai/modelloader/notification/ArtifactDownloadManagerTest.java b/src/test/java/org/onap/aai/modelloader/notification/ArtifactDownloadManagerTest.java new file mode 100644 index 0000000..eb31688 --- /dev/null +++ b/src/test/java/org/onap/aai/modelloader/notification/ArtifactDownloadManagerTest.java @@ -0,0 +1,106 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.notification; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.matching; +import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.onap.aai.modelloader.DistributionClientTestConfiguration; +import org.onap.aai.modelloader.entity.Artifact; +import org.onap.aai.modelloader.entity.ArtifactType; +import org.onap.aai.modelloader.service.ArtifactInfoImpl; +import org.onap.sdc.api.notification.IArtifactInfo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock; +import org.springframework.context.annotation.Import; +import org.springframework.http.MediaType; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.test.annotation.DirtiesContext; + +import com.fasterxml.jackson.core.JsonProcessingException; + +@DirtiesContext +@AutoConfigureWireMock(port = 0) +@EmbeddedKafka(partitions = 1, ports = 9092, topics = {"${topics.distribution.notification}"}) +@SpringBootTest(properties = { "ml.distribution.connection.enabled=true" }) +@Import(DistributionClientTestConfiguration.class) +public class ArtifactDownloadManagerTest { + + @Autowired ArtifactDownloadManager artifactDownloadManager; + + @Test + public void downloadArtifacts() throws JsonProcessingException { + NotificationDataImpl notificationData = new NotificationDataImpl(); + notificationData.setDistributionID("distributionID"); + notificationData.setServiceVersion("2.0"); + + stubFor(get(urlEqualTo("/sdc/v1/catalog/services/DemovlbCds/1.0/artifacts/service-TestSvc-csar.csar")) + .withHeader("Accept", equalTo(MediaType.APPLICATION_OCTET_STREAM_VALUE)) + .withHeader("X-ECOMP-RequestID", matching(".+")) + .withHeader("X-ECOMP-InstanceID", equalTo("aai-ml-id-test")) + .willReturn(aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_OCTET_STREAM_VALUE) + .withBodyFile("service-TestSvc-csar.csar"))); + + stubFor( + post(urlEqualTo("/services/babel-service/v1/app/generateArtifacts")) + .withHeader("X-TransactionId", equalTo("distributionID")) + .withHeader("X-FromAppId", equalTo("ModelLoader")) + .withHeader("Content-Type", equalTo(MediaType.APPLICATION_JSON_VALUE)) + .withRequestBody(matchingJsonPath("$.artifactName", equalTo("service-TestSvc-csar.csar"))) + .withRequestBody(matchingJsonPath("$.artifactVersion", equalTo("2.0"))) + .withRequestBody(matchingJsonPath("$.csar", matching(".*"))) + .willReturn( + aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withBodyFile("service-TestSvc-csar-babel-response.json"))); + + ArtifactInfoImpl artifactInfo = new ArtifactInfoImpl(); + artifactInfo.setArtifactName("service-TestSvc-csar.csar"); + artifactInfo.setArtifactVersion("1.0"); + artifactInfo.setArtifactURL("/sdc/v1/catalog/services/DemovlbCds/1.0/artifacts/service-TestSvc-csar.csar"); + artifactInfo.setArtifactType("TOSCA_CSAR"); + artifactInfo.setArtifactChecksum("ZmI5NzQ1MWViZGFkMjRjZWEwNTQzY2U0OWQwYjlmYjQ="); + artifactInfo.setArtifactUUID("f6f907f1-3f45-4fb4-8cbe-15a4c6ee16db"); + List artifacts = new ArrayList<>(); + artifacts.add(artifactInfo); + List modelArtifacts = new ArrayList<>(); // processed artifacts will be written to this list + List catalogArtifacts = new ArrayList<>(); // processed artifacts will be written to this list + boolean result = artifactDownloadManager.downloadArtifacts(notificationData, artifacts, modelArtifacts, catalogArtifacts); + + assertEquals(1, modelArtifacts.size()); + assertEquals(ArtifactType.MODEL, modelArtifacts.get(0).getType()); + assertTrue(result); + } + +} diff --git a/src/test/java/org/onap/aai/modelloader/notification/ArtifactDownloadManagerVnfcTest.java b/src/test/java/org/onap/aai/modelloader/notification/ArtifactDownloadManagerVnfcTest.java index c0de0ee..0e8a733 100644 --- a/src/test/java/org/onap/aai/modelloader/notification/ArtifactDownloadManagerVnfcTest.java +++ b/src/test/java/org/onap/aai/modelloader/notification/ArtifactDownloadManagerVnfcTest.java @@ -21,11 +21,11 @@ package org.onap.aai.modelloader.notification; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.onap.aai.modelloader.fixture.NotificationDataFixtureBuilder.getNotificationDataWithToscaCsarFile; @@ -33,11 +33,15 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Properties; -import org.junit.Before; -import org.junit.Test; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; import org.onap.aai.babel.service.data.BabelArtifact; -import org.onap.aai.modelloader.config.ModelLoaderConfig; +import org.onap.aai.modelloader.babel.BabelArtifactService; import org.onap.aai.modelloader.entity.Artifact; import org.onap.aai.modelloader.entity.ArtifactType; import org.onap.aai.modelloader.entity.catalog.VnfCatalogArtifact; @@ -55,40 +59,30 @@ import org.onap.sdc.api.notification.INotificationData; import org.onap.sdc.api.results.IDistributionClientDownloadResult; import org.onap.sdc.impl.DistributionClientDownloadResultImpl; import org.onap.sdc.utils.DistributionActionResultEnum; -import org.springframework.test.util.ReflectionTestUtils; /** * Tests {@link ArtifactDownloadManager} with VNF Catalog Artifacts. */ public class ArtifactDownloadManagerVnfcTest { - private ArtifactDownloadManager downloadManager; - private BabelServiceClient mockBabelClient; - private IDistributionClient mockDistributionClient; - private NotificationPublisher mockNotificationPublisher; - private BabelArtifactConverter mockBabelArtifactConverter; - private BabelServiceClientFactory mockClientFactory; - private VnfCatalogExtractor mockVnfCatalogExtractor; + @Mock private ArtifactDownloadManager downloadManager; + @Mock private BabelServiceClient mockBabelClient; + @Mock private IDistributionClient mockDistributionClient; + @Mock private NotificationPublisher mockNotificationPublisher; + @Mock private BabelArtifactConverter mockBabelArtifactConverter; + @Mock private BabelServiceClientFactory mockClientFactory; + @Mock private VnfCatalogExtractor mockVnfCatalogExtractor; + @InjectMocks private BabelArtifactService babelArtifactService; - @Before + @BeforeEach public void setup() throws Exception { - mockBabelClient = mock(BabelServiceClient.class); - mockDistributionClient = mock(IDistributionClient.class); - mockNotificationPublisher = mock(NotificationPublisher.class); - mockBabelArtifactConverter = mock(BabelArtifactConverter.class); - mockClientFactory = mock(BabelServiceClientFactory.class); + MockitoAnnotations.openMocks(this); when(mockClientFactory.create(Mockito.any())).thenReturn(mockBabelClient); - mockVnfCatalogExtractor = mock(VnfCatalogExtractor.class); Properties configProperties = new Properties(); configProperties.load(this.getClass().getClassLoader().getResourceAsStream("model-loader.properties")); downloadManager = new ArtifactDownloadManager(mockDistributionClient, - new ModelLoaderConfig(configProperties, "."), mockClientFactory); - - - ReflectionTestUtils.setField(downloadManager, "notificationPublisher", mockNotificationPublisher); - ReflectionTestUtils.setField(downloadManager, "babelArtifactConverter", mockBabelArtifactConverter); - ReflectionTestUtils.setField(downloadManager, "vnfCatalogExtractor", mockVnfCatalogExtractor); + mockNotificationPublisher, mockVnfCatalogExtractor, babelArtifactService); } @Test @@ -98,7 +92,7 @@ public class ArtifactDownloadManagerVnfcTest { IArtifactInfo artifactInfo = data.getServiceArtifacts().get(0); setupValidDownloadCsarMocks(data, artifactInfo); - when(mockBabelClient.postArtifact(any(), any(), any(), any())).thenReturn(createBabelArtifacts()); + when(mockBabelClient.postArtifact(any(), any())).thenReturn(createBabelArtifacts()); when(mockVnfCatalogExtractor.extract(any(), any())).thenReturn(new ArrayList<>()); List modelArtifacts = new ArrayList<>(); @@ -106,7 +100,7 @@ public class ArtifactDownloadManagerVnfcTest { assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelArtifacts, catalogFiles), is(true)); - assertEquals("There should have been some catalog files", 2, catalogFiles.size()); + assertEquals(1, catalogFiles.size(), "There should be a catalog file"); } @Test @@ -116,15 +110,15 @@ public class ArtifactDownloadManagerVnfcTest { IArtifactInfo artifactInfo = data.getServiceArtifacts().get(0); setupValidDownloadCsarMocks(data, artifactInfo); - when(mockBabelClient.postArtifact(any(), any(), any(), any())).thenReturn(createBabelArtifactsNoVnfc()); + when(mockBabelClient.postArtifact(any(), any())).thenReturn(createBabelArtifactsNoVnfc()); when(mockVnfCatalogExtractor.extract(any(), any())).thenReturn(createXmlVnfcArtifacts()); List modelArtifacts = new ArrayList<>(); List catalogFiles = new ArrayList<>(); - assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelArtifacts, catalogFiles), - is(true)); + assertTrue(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelArtifacts, catalogFiles)); - assertEquals("There should have been some catalog files", 3, catalogFiles.size()); + assertEquals(3, catalogFiles.size(), "There should be three catalog artifacts"); + assertEquals(1, modelArtifacts.size(), "There should be a model artifact"); } @Test @@ -134,7 +128,7 @@ public class ArtifactDownloadManagerVnfcTest { IArtifactInfo artifactInfo = data.getServiceArtifacts().get(0); setupValidDownloadCsarMocks(data, artifactInfo); - when(mockBabelClient.postArtifact(any(), any(), any(), any())).thenReturn(createBabelArtifactsNoVnfc()); + when(mockBabelClient.postArtifact(any(), any())).thenReturn(createBabelArtifactsNoVnfc()); when(mockVnfCatalogExtractor.extract(any(), any())).thenReturn(new ArrayList<>()); List modelArtifacts = new ArrayList<>(); @@ -142,7 +136,7 @@ public class ArtifactDownloadManagerVnfcTest { assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelArtifacts, catalogFiles), is(true)); - assertEquals("There should not have been any catalog files", 0, catalogFiles.size()); + assertEquals(0, catalogFiles.size(), "There should not have been any catalog files"); } @Test @@ -152,7 +146,7 @@ public class ArtifactDownloadManagerVnfcTest { IArtifactInfo artifactInfo = data.getServiceArtifacts().get(0); setupValidDownloadCsarMocks(data, artifactInfo); - when(mockBabelClient.postArtifact(any(), any(), any(), any())).thenReturn(createBabelArtifacts()); + when(mockBabelClient.postArtifact(any(), any())).thenReturn(createBabelArtifacts()); when(mockVnfCatalogExtractor.extract(any(), any())).thenReturn(createXmlVnfcArtifacts()); doNothing().when(mockNotificationPublisher).publishDeployFailure(mockDistributionClient, data, artifactInfo); @@ -178,8 +172,8 @@ public class ArtifactDownloadManagerVnfcTest { when(mockDistributionClient.download(artifactInfo)) .thenReturn(createDistributionClientDownloadResult(DistributionActionResultEnum.SUCCESS, null, new ArtifactTestUtils().loadResource("compressedArtifacts/service-VscpaasTest-csar.csar"))); - when(mockBabelArtifactConverter.convertToModel(Mockito.anyList())).thenReturn(createModelArtifacts()); - when(mockBabelArtifactConverter.convertToCatalog(Mockito.anyList())).thenReturn(createToscaVnfcArtifacts()); + when(mockBabelArtifactConverter.convertToModel(Mockito.any(BabelArtifact.class))).thenReturn(createModelArtifacts()); + when(mockBabelArtifactConverter.convertToCatalog(Mockito.any(BabelArtifact.class))).thenReturn(new VnfCatalogArtifact("Some VNFC payload")); } private List createBabelArtifacts() { @@ -198,17 +192,9 @@ public class ArtifactDownloadManagerVnfcTest { private List createModelArtifacts() { List modelArtifacts = new ArrayList<>(); modelArtifacts.add(new ModelArtifact()); - modelArtifacts.add(new ModelArtifact()); return modelArtifacts; } - private List createToscaVnfcArtifacts() { - List vnfcArtifacts = new ArrayList<>(); - vnfcArtifacts.add(new VnfCatalogArtifact("Some VNFC payload")); - vnfcArtifacts.add(new VnfCatalogArtifact("Some VNFC payload")); - return vnfcArtifacts; - } - private List createXmlVnfcArtifacts() { List vnfcArtifacts = new ArrayList<>(); vnfcArtifacts.add(new VnfCatalogArtifact(ArtifactType.VNF_CATALOG_XML, "Some VNFC payload")); diff --git a/src/test/java/org/onap/aai/modelloader/notification/ModelArtifactHandlerTest.java b/src/test/java/org/onap/aai/modelloader/notification/ModelArtifactHandlerTest.java new file mode 100644 index 0000000..d3495d4 --- /dev/null +++ b/src/test/java/org/onap/aai/modelloader/notification/ModelArtifactHandlerTest.java @@ -0,0 +1,245 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.notification; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.verify; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.deleteRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; + +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.onap.aai.modelloader.config.ModelLoaderConfig; +import org.onap.aai.modelloader.entity.Artifact; +import org.onap.aai.modelloader.entity.model.ModelArtifact; +import org.onap.aai.modelloader.entity.model.ModelArtifactHandler; +import org.onap.aai.modelloader.restclient.AaiRestClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.tomakehurst.wiremock.client.WireMock; + +import java.util.ArrayList; + +@SpringBootTest +@AutoConfigureWireMock(port = 0) +public class ModelArtifactHandlerTest { + + @Value("${wiremock.server.port}") + private int wiremockPort; + + final ObjectMapper objectMapper = new ObjectMapper(); + @Mock + ModelLoaderConfig config; + @InjectMocks + ModelArtifactHandler modelArtifactHandler; + + @Autowired + AaiRestClient restClient; + + @BeforeEach + public void setUp() { + when(config.getAaiBaseUrl()).thenReturn("http://localhost:" + wiremockPort); + when(config.getAaiModelUrl(any())).thenReturn("/aai/v28/service-design-and-creation/models/model/"); + } + + @Test + public void thatArtifactsCanBeCreated() { + WireMock.stubFor( + WireMock.get(urlEqualTo("/aai/v28/service-design-and-creation/models/model/modelInvariantId")) + .withHeader("Accept", equalTo("application/xml")) + .withHeader("X-TransactionId", equalTo("someId")) + .withHeader("X-FromAppId", equalTo("ModelLoader")) + .willReturn( + WireMock.aResponse() + .withStatus(HttpStatus.NOT_FOUND.value()))); + + WireMock.stubFor( + WireMock.put(urlEqualTo("/aai/v28/service-design-and-creation/models/model/modelInvariantId")) + .withHeader("Accept", equalTo(MediaType.APPLICATION_XML_VALUE)) + .withHeader("Content-Type", equalTo(MediaType.APPLICATION_XML_VALUE)) + .withHeader("X-TransactionId", equalTo("someId")) + .withHeader("X-FromAppId", equalTo("ModelLoader")) + .willReturn( + WireMock.aResponse() + .withStatus(HttpStatus.CREATED.value()))); + + ModelArtifact modelArtifact = new ModelArtifact(); + modelArtifact.setModelInvariantId("modelInvariantId"); + modelArtifact.setPayload(""); + List artifacts = List.of(modelArtifact); + List completedArtifacts = new ArrayList<>(); + + boolean result = modelArtifactHandler.pushArtifacts(artifacts, + "someId", completedArtifacts, restClient); + assertTrue(result); + WireMock.verify( + WireMock.putRequestedFor(urlEqualTo("/aai/v28/service-design-and-creation/models/model/modelInvariantId"))); + } + + @Test + public void thatArtifactsCanBeUpdated() { + // Checks if model exists in resources service + WireMock.stubFor( + WireMock.get(urlEqualTo("/aai/v28/service-design-and-creation/models/model/modelInvariantId")) + .withHeader("Accept", equalTo("application/xml")) + .withHeader("X-TransactionId", equalTo("distributionId")) + .withHeader("X-FromAppId", equalTo("ModelLoader")) + .willReturn( + WireMock.aResponse() + .withStatus(HttpStatus.OK.value()))); + + // Checks if specific version of model exists in aai-resources + WireMock.stubFor( + WireMock.get(urlEqualTo( + "/aai/v28/service-design-and-creation/models/model/modelInvariantId/model-vers/model-ver/modelVersionId")) + .withHeader("Accept", equalTo("application/xml")) + .withHeader("X-TransactionId", equalTo("distributionId")) + .withHeader("X-FromAppId", equalTo("ModelLoader")) + .willReturn( + WireMock.aResponse() + .withStatus(HttpStatus.NOT_FOUND.value()))); + + WireMock.stubFor( + WireMock.put(urlEqualTo( + "/aai/v28/service-design-and-creation/models/model/modelInvariantId/model-vers/model-ver/modelVersionId")) + .withHeader("Accept", equalTo(MediaType.APPLICATION_XML_VALUE)) + .withHeader("Content-Type", equalTo(MediaType.APPLICATION_XML_VALUE)) + .withHeader("X-TransactionId", equalTo("distributionId")) + .withHeader("X-FromAppId", equalTo("ModelLoader")) + .willReturn( + WireMock.aResponse() + .withStatus(HttpStatus.CREATED.value()))); + + ModelArtifact modelArtifact = new ModelArtifact(); + modelArtifact.setModelInvariantId("modelInvariantId"); + modelArtifact.setModelVerId("modelVersionId"); + modelArtifact.setPayload(""); + modelArtifact.setModelVer("2.0"); + List artifacts = List.of(modelArtifact); + List completedArtifacts = new ArrayList<>(); + + boolean result = modelArtifactHandler.pushArtifacts(artifacts, + "distributionId", completedArtifacts, restClient); + verify(WireMock.putRequestedFor(urlEqualTo( + "/aai/v28/service-design-and-creation/models/model/modelInvariantId/model-vers/model-ver/modelVersionId"))); + assertTrue(result); + } + + @Test + public void thatModelCanBeRolledBack() { + stubFor(WireMock.get(urlEqualTo("/aai/v28/service-design-and-creation/models/model/3a40ab73-6694-4e75-bb6d-9a4a86ce35b3")) + .withHeader("Accept", equalTo(MediaType.APPLICATION_XML_VALUE)) + .withHeader("X-FromAppId", equalTo("ModelLoader")) + .withHeader("X-TransactionId", equalTo("distributionId")) + .willReturn(aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_XML_VALUE) + .withBodyFile("modelResponse.xml"))); + + stubFor(WireMock.delete(urlEqualTo("/aai/v28/service-design-and-creation/models/model/3a40ab73-6694-4e75-bb6d-9a4a86ce35b3?resource-version=1710523260974")) + .withHeader("X-FromAppId", equalTo("ModelLoader")) + .withHeader("X-TransactionId", equalTo("distributionId")) + .willReturn(aResponse().withStatus(HttpStatus.OK.value()))); + + ModelArtifact modelArtifact = new ModelArtifact(); + modelArtifact.setModelInvariantId("3a40ab73-6694-4e75-bb6d-9a4a86ce35b3"); + modelArtifact.setModelVerId("modelVersionId"); + // modelArtifact.setModelVer("2.0"); + + List completedArtifacts = new ArrayList<>(); + completedArtifacts.add(modelArtifact); + + mockModelCreation(modelArtifact); + + modelArtifactHandler.rollback(completedArtifacts, "distributionId", restClient); + + verify( + deleteRequestedFor( + urlEqualTo("/aai/v28/service-design-and-creation/models/model/3a40ab73-6694-4e75-bb6d-9a4a86ce35b3?resource-version=1710523260974"))); + } + + /** + * To test the rollback of the full model, the ModelArtifact must have the + * firstVersionOfModel = true state. + * This flag is set during the model creation and thus needs to run before + * testing this particular aspect. + * + * @param modelArtifact + */ + private void mockModelCreation(ModelArtifact modelArtifact) { + ResponseEntity createdResult = Mockito.mock(ResponseEntity.class); + when(createdResult.getStatusCode()).thenReturn(HttpStatus.CREATED); + ResponseEntity notFoundResult = Mockito.mock(ResponseEntity.class); + when(notFoundResult.getStatusCode()).thenReturn(HttpStatus.NOT_FOUND); + AaiRestClient aaiClient = Mockito.mock(AaiRestClient.class); + when(aaiClient.putResource(any(), any(), any(), any(), any())).thenReturn(createdResult); + when(aaiClient.getResource(any(), any(), any(), any())).thenReturn(notFoundResult); + modelArtifact.push(aaiClient, config, null, new ArrayList<>()); + } + + @Test + public void thatModelVersionCanBeRolledBack() { + + WireMock.stubFor( + WireMock.get(urlEqualTo( + "/aai/v28/service-design-and-creation/models/model/modelInvariantId/model-vers/model-ver/modelVersionId")) + .withHeader("Accept", equalTo("application/xml")) + .withHeader("X-TransactionId", equalTo("distributionId")) + .withHeader("X-FromAppId", equalTo("ModelLoader")) + .willReturn( + WireMock.aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_XML_VALUE) + .withBodyFile("modelVersion.xml"))); + + stubFor(WireMock.delete(urlEqualTo("/aai/v28/service-design-and-creation/models/model/modelInvariantId/model-vers/model-ver/modelVersionId?resource-version=1708937324692")) + .withHeader("X-FromAppId", equalTo("ModelLoader")) + .withHeader("X-TransactionId", equalTo("distributionId")) + .willReturn(aResponse().withStatus(HttpStatus.OK.value()))); + + ModelArtifact modelArtifact = new ModelArtifact(); + modelArtifact.setModelInvariantId("modelInvariantId"); + modelArtifact.setModelVerId("modelVersionId"); + + List completedArtifacts = new ArrayList<>(); + completedArtifacts.add(modelArtifact); + + modelArtifactHandler.rollback(completedArtifacts, "distributionId", restClient); + + verify( + deleteRequestedFor( + urlEqualTo("/aai/v28/service-design-and-creation/models/model/modelInvariantId/model-vers/model-ver/modelVersionId?resource-version=1708937324692"))); + } +} \ No newline at end of file diff --git a/src/test/java/org/onap/aai/modelloader/notification/TestArtifactDeploymentManager.java b/src/test/java/org/onap/aai/modelloader/notification/TestArtifactDeploymentManager.java index b50bd0d..2ff4ed5 100644 --- a/src/test/java/org/onap/aai/modelloader/notification/TestArtifactDeploymentManager.java +++ b/src/test/java/org/onap/aai/modelloader/notification/TestArtifactDeploymentManager.java @@ -21,10 +21,9 @@ package org.onap.aai.modelloader.notification; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.onap.aai.modelloader.fixture.NotificationDataFixtureBuilder.getNotificationDataWithCatalogFile; import static org.onap.aai.modelloader.fixture.NotificationDataFixtureBuilder.getNotificationDataWithOneOfEach; @@ -33,10 +32,13 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Properties; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; import org.onap.aai.babel.service.data.BabelArtifact; import org.onap.aai.modelloader.config.ModelLoaderConfig; import org.onap.aai.modelloader.entity.Artifact; @@ -44,12 +46,14 @@ import org.onap.aai.modelloader.entity.catalog.VnfCatalogArtifact; import org.onap.aai.modelloader.entity.catalog.VnfCatalogArtifactHandler; import org.onap.aai.modelloader.entity.model.BabelArtifactParsingException; import org.onap.aai.modelloader.entity.model.ModelArtifactHandler; +import org.onap.aai.modelloader.entity.model.ModelArtifactParser; import org.onap.aai.modelloader.extraction.InvalidArchiveException; import org.onap.aai.modelloader.fixture.NotificationDataFixtureBuilder; +import org.onap.aai.modelloader.restclient.AaiRestClient; import org.onap.aai.modelloader.service.ArtifactDeploymentManager; import org.onap.aai.modelloader.util.ArtifactTestUtils; import org.onap.sdc.api.notification.INotificationData; -import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.web.client.RestTemplate; /** * Tests {@link ArtifactDeploymentManager}. @@ -62,28 +66,25 @@ public class TestArtifactDeploymentManager { private Properties configProperties; private ArtifactDeploymentManager manager; - private ModelArtifactHandler mockModelArtifactHandler; - private VnfCatalogArtifactHandler mockVnfCatalogArtifactHandler; + @Mock private ModelArtifactHandler modelArtifactHandlerMock; + @Mock private VnfCatalogArtifactHandler vnfCatalogArtifactHandlerMock; - @Before + @BeforeEach public void setup() throws IOException { + MockitoAnnotations.openMocks(this); configProperties = new Properties(); configProperties.load(this.getClass().getClassLoader().getResourceAsStream(CONFIG_FILE)); - mockModelArtifactHandler = mock(ModelArtifactHandler.class); - mockVnfCatalogArtifactHandler = mock(VnfCatalogArtifactHandler.class); - - manager = new ArtifactDeploymentManager(new ModelLoaderConfig(configProperties, null)); - - ReflectionTestUtils.setField(manager, "modelArtifactHandler", mockModelArtifactHandler); - ReflectionTestUtils.setField(manager, "vnfCatalogArtifactHandler", mockVnfCatalogArtifactHandler); + ModelLoaderConfig modelLoaderConfig = new ModelLoaderConfig(configProperties, null); + AaiRestClient aaiRestClient = new AaiRestClient(modelLoaderConfig, new RestTemplate()); + manager = new ArtifactDeploymentManager(modelArtifactHandlerMock, vnfCatalogArtifactHandlerMock, aaiRestClient); } - @After + @AfterEach public void tearDown() { configProperties = null; - mockModelArtifactHandler = null; - mockVnfCatalogArtifactHandler = null; + modelArtifactHandlerMock = null; + vnfCatalogArtifactHandlerMock = null; manager = null; } @@ -91,33 +92,31 @@ public class TestArtifactDeploymentManager { public void deploy_csarDeploymentsFailed() throws IOException, BabelArtifactParsingException { INotificationData data = NotificationDataFixtureBuilder.getNotificationDataWithToscaCsarFile(); byte[] xml = new ArtifactTestUtils().loadResource("convertedYmls/AAI-SCP-Test-VSP-resource-1.0.xml"); - List toscaArtifacts = setupTest(xml, data); - List modelArtifacts = new BabelArtifactConverter().convertToModel(toscaArtifacts); + BabelArtifact toscaArtifact = setupTest(xml, data); + List modelArtifacts = new BabelArtifactConverter(new ModelArtifactParser()).convertToModel(toscaArtifact); - when(mockModelArtifactHandler.pushArtifacts(eq(modelArtifacts), eq(data.getDistributionID()), any(), any())) + when(modelArtifactHandlerMock.pushArtifacts(eq(modelArtifacts), eq(data.getDistributionID()), any(), any())) .thenReturn(false); - assertThat(SHOULD_HAVE_RETURNED_FALSE, manager.deploy(data, modelArtifacts, new ArrayList<>()), is(false)); + assertThat(SHOULD_HAVE_RETURNED_FALSE, manager.deploy(data.getDistributionID(), modelArtifacts, new ArrayList<>()), is(false)); - Mockito.verify(mockModelArtifactHandler).pushArtifacts(eq(modelArtifacts), eq(data.getDistributionID()), any(), + Mockito.verify(modelArtifactHandlerMock).pushArtifacts(eq(modelArtifacts), eq(data.getDistributionID()), any(), any()); - Mockito.verify(mockVnfCatalogArtifactHandler, Mockito.never()).pushArtifacts(eq(modelArtifacts), + Mockito.verify(vnfCatalogArtifactHandlerMock, Mockito.never()).pushArtifacts(eq(modelArtifacts), eq(data.getDistributionID()), any(), any()); - Mockito.verify(mockModelArtifactHandler).rollback(eq(new ArrayList()), eq(data.getDistributionID()), + Mockito.verify(modelArtifactHandlerMock).rollback(eq(new ArrayList()), eq(data.getDistributionID()), any()); - Mockito.verify(mockVnfCatalogArtifactHandler, Mockito.never()).rollback(eq(new ArrayList()), + Mockito.verify(vnfCatalogArtifactHandlerMock, Mockito.never()).rollback(eq(new ArrayList()), eq(data.getDistributionID()), any()); } - private List setupTest(byte[] xml, INotificationData data) throws IOException { - List toscaArtifacts = new ArrayList<>(); + private BabelArtifact setupTest(byte[] xml, INotificationData data) throws IOException { org.onap.sdc.api.notification.IArtifactInfo artifactInfo = data.getServiceArtifacts().get(0); BabelArtifact xmlArtifact = new BabelArtifact(artifactInfo.getArtifactName(), BabelArtifact.ArtifactType.MODEL, new String(xml)); - toscaArtifacts.add(xmlArtifact); - return toscaArtifacts; + return xmlArtifact; } @Test @@ -128,19 +127,19 @@ public class TestArtifactDeploymentManager { List catalogFiles = new ArrayList<>(); catalogFiles.add(new VnfCatalogArtifact("Some catalog content")); - when(mockModelArtifactHandler.pushArtifacts(any(), any(), any(), any())).thenReturn(true); - when(mockVnfCatalogArtifactHandler.pushArtifacts(eq(catalogFiles), eq(data.getDistributionID()), any(), any())) + when(modelArtifactHandlerMock.pushArtifacts(any(), any(), any(), any())).thenReturn(true); + when(vnfCatalogArtifactHandlerMock.pushArtifacts(eq(catalogFiles), eq(data.getDistributionID()), any(), any())) .thenReturn(false); - assertThat(SHOULD_HAVE_RETURNED_FALSE, manager.deploy(data, new ArrayList<>(), catalogFiles), is(false)); + assertThat(SHOULD_HAVE_RETURNED_FALSE, manager.deploy(data.getDistributionID(), new ArrayList<>(), catalogFiles), is(false)); - Mockito.verify(mockModelArtifactHandler).pushArtifacts(eq(new ArrayList()), + Mockito.verify(modelArtifactHandlerMock).pushArtifacts(eq(new ArrayList()), eq(data.getDistributionID()), any(), any()); - Mockito.verify(mockVnfCatalogArtifactHandler).pushArtifacts(eq(catalogFiles), eq(data.getDistributionID()), + Mockito.verify(vnfCatalogArtifactHandlerMock).pushArtifacts(eq(catalogFiles), eq(data.getDistributionID()), any(), any()); - Mockito.verify(mockModelArtifactHandler).rollback(eq(new ArrayList()), eq(data.getDistributionID()), + Mockito.verify(modelArtifactHandlerMock).rollback(eq(new ArrayList()), eq(data.getDistributionID()), any()); - Mockito.verify(mockVnfCatalogArtifactHandler).rollback(eq(new ArrayList()), + Mockito.verify(vnfCatalogArtifactHandlerMock).rollback(eq(new ArrayList()), eq(data.getDistributionID()), any()); } @@ -163,40 +162,40 @@ public class TestArtifactDeploymentManager { throws IOException, BabelArtifactParsingException, InvalidArchiveException { INotificationData data = getNotificationDataWithOneOfEach(); byte[] xml = new ArtifactTestUtils().loadResource("convertedYmls/AAI-SCP-Test-VSP-resource-1.0.xml"); - List toscaArtifacts = setupTest(xml, data); - List modelArtifacts = new BabelArtifactConverter().convertToModel(toscaArtifacts); + BabelArtifact toscaArtifact = setupTest(xml, data); + List modelArtifacts = new BabelArtifactConverter(new ModelArtifactParser()).convertToModel(toscaArtifact); List catalogFiles = new ArrayList<>(); catalogFiles.add(new VnfCatalogArtifact("Some catalog content")); - when(mockVnfCatalogArtifactHandler.pushArtifacts(eq(catalogFiles), eq(data.getDistributionID()), any(), any())) + when(vnfCatalogArtifactHandlerMock.pushArtifacts(eq(catalogFiles), eq(data.getDistributionID()), any(), any())) .thenReturn(catalogsDeployed); - when(mockModelArtifactHandler.pushArtifacts(eq(modelArtifacts), eq(data.getDistributionID()), any(), any())) + when(modelArtifactHandlerMock.pushArtifacts(eq(modelArtifacts), eq(data.getDistributionID()), any(), any())) .thenReturn(modelsDeployed); - assertThat(SHOULD_HAVE_RETURNED_FALSE, manager.deploy(data, modelArtifacts, catalogFiles), is(false)); + assertThat(SHOULD_HAVE_RETURNED_FALSE, manager.deploy(data.getDistributionID(), modelArtifacts, catalogFiles), is(false)); // Catalog artifacts are only pushed if models are successful. - Mockito.verify(mockModelArtifactHandler).pushArtifacts(eq(modelArtifacts), eq(data.getDistributionID()), any(), + Mockito.verify(modelArtifactHandlerMock).pushArtifacts(eq(modelArtifacts), eq(data.getDistributionID()), any(), any()); if (modelsDeployed) { - Mockito.verify(mockVnfCatalogArtifactHandler).pushArtifacts(eq(catalogFiles), eq(data.getDistributionID()), + Mockito.verify(vnfCatalogArtifactHandlerMock).pushArtifacts(eq(catalogFiles), eq(data.getDistributionID()), any(), any()); } if (modelsDeployed && catalogsDeployed) { - Mockito.verify(mockModelArtifactHandler, Mockito.never()).rollback(any(), any(), any()); - Mockito.verify(mockVnfCatalogArtifactHandler, Mockito.never()).rollback(any(), any(), any()); + Mockito.verify(modelArtifactHandlerMock, Mockito.never()).rollback(any(), any(), any()); + Mockito.verify(vnfCatalogArtifactHandlerMock, Mockito.never()).rollback(any(), any(), any()); } else { if (modelsDeployed) { - Mockito.verify(mockModelArtifactHandler).rollback(eq(new ArrayList()), + Mockito.verify(modelArtifactHandlerMock).rollback(eq(new ArrayList()), eq(data.getDistributionID()), any()); - Mockito.verify(mockVnfCatalogArtifactHandler).rollback(eq(new ArrayList()), + Mockito.verify(vnfCatalogArtifactHandlerMock).rollback(eq(new ArrayList()), eq(data.getDistributionID()), any()); } else { - Mockito.verify(mockModelArtifactHandler).rollback(eq(new ArrayList()), + Mockito.verify(modelArtifactHandlerMock).rollback(eq(new ArrayList()), eq(data.getDistributionID()), any()); - Mockito.verify(mockVnfCatalogArtifactHandler, Mockito.never()).rollback(any(), any(), any()); + Mockito.verify(vnfCatalogArtifactHandlerMock, Mockito.never()).rollback(any(), any(), any()); } } } @@ -212,24 +211,24 @@ public class TestArtifactDeploymentManager { public void testDeploySuccess() throws IOException, BabelArtifactParsingException, InvalidArchiveException { INotificationData data = getNotificationDataWithOneOfEach(); byte[] xml = new ArtifactTestUtils().loadResource("convertedYmls/AAI-SCP-Test-VSP-resource-1.0.xml"); - List toscaArtifacts = setupTest(xml, data); - List modelArtifacts = new BabelArtifactConverter().convertToModel(toscaArtifacts); + BabelArtifact toscaArtifact = setupTest(xml, data); + List modelArtifacts = new BabelArtifactConverter(new ModelArtifactParser()).convertToModel(toscaArtifact); List catalogFiles = new ArrayList<>(); catalogFiles.add(new VnfCatalogArtifact("Some catalog content")); - when(mockVnfCatalogArtifactHandler.pushArtifacts(eq(catalogFiles), eq(data.getDistributionID()), any(), any())) + when(vnfCatalogArtifactHandlerMock.pushArtifacts(eq(catalogFiles), eq(data.getDistributionID()), any(), any())) .thenReturn(true); - when(mockModelArtifactHandler.pushArtifacts(eq(modelArtifacts), eq(data.getDistributionID()), any(), any())) + when(modelArtifactHandlerMock.pushArtifacts(eq(modelArtifacts), eq(data.getDistributionID()), any(), any())) .thenReturn(true); - assertThat(manager.deploy(data, modelArtifacts, catalogFiles), is(true)); + assertThat(manager.deploy(data.getDistributionID(), modelArtifacts, catalogFiles), is(true)); - Mockito.verify(mockVnfCatalogArtifactHandler).pushArtifacts(eq(catalogFiles), eq(data.getDistributionID()), + Mockito.verify(vnfCatalogArtifactHandlerMock).pushArtifacts(eq(catalogFiles), eq(data.getDistributionID()), any(), any()); - Mockito.verify(mockModelArtifactHandler).pushArtifacts(eq(modelArtifacts), eq(data.getDistributionID()), any(), + Mockito.verify(modelArtifactHandlerMock).pushArtifacts(eq(modelArtifacts), eq(data.getDistributionID()), any(), any()); - Mockito.verify(mockModelArtifactHandler, Mockito.never()).rollback(any(), any(), any()); - Mockito.verify(mockVnfCatalogArtifactHandler, Mockito.never()).rollback(any(), any(), any()); + Mockito.verify(modelArtifactHandlerMock, Mockito.never()).rollback(any(), any(), any()); + Mockito.verify(vnfCatalogArtifactHandlerMock, Mockito.never()).rollback(any(), any(), any()); } } diff --git a/src/test/java/org/onap/aai/modelloader/notification/TestArtifactDownloadManager.java b/src/test/java/org/onap/aai/modelloader/notification/TestArtifactDownloadManager.java index f8b3de9..0661583 100644 --- a/src/test/java/org/onap/aai/modelloader/notification/TestArtifactDownloadManager.java +++ b/src/test/java/org/onap/aai/modelloader/notification/TestArtifactDownloadManager.java @@ -22,12 +22,11 @@ package org.onap.aai.modelloader.notification; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.collection.IsEmptyCollection.empty; -import static org.junit.Assert.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.onap.aai.modelloader.fixture.NotificationDataFixtureBuilder.getNotificationDataWithInvalidType; import static org.onap.aai.modelloader.fixture.NotificationDataFixtureBuilder.getNotificationDataWithModelQuerySpec; @@ -39,19 +38,25 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Properties; + import org.hamcrest.collection.IsEmptyCollection; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; import org.onap.aai.babel.service.data.BabelArtifact; -import org.onap.aai.modelloader.config.ModelLoaderConfig; +import org.onap.aai.modelloader.babel.BabelArtifactService; import org.onap.aai.modelloader.entity.Artifact; +import org.onap.aai.modelloader.entity.catalog.VnfCatalogArtifact; import org.onap.aai.modelloader.entity.model.BabelArtifactParsingException; +import org.onap.aai.modelloader.entity.model.ModelArtifact; +import org.onap.aai.modelloader.extraction.VnfCatalogExtractor; import org.onap.aai.modelloader.restclient.BabelServiceClient; import org.onap.aai.modelloader.restclient.BabelServiceClientException; import org.onap.aai.modelloader.service.BabelServiceClientFactory; -import org.onap.aai.modelloader.service.HttpsBabelServiceClientFactory; import org.onap.aai.modelloader.util.ArtifactTestUtils; import org.onap.sdc.api.IDistributionClient; import org.onap.sdc.api.notification.IArtifactInfo; @@ -59,7 +64,6 @@ import org.onap.sdc.api.notification.INotificationData; import org.onap.sdc.api.results.IDistributionClientDownloadResult; import org.onap.sdc.impl.DistributionClientDownloadResultImpl; import org.onap.sdc.utils.DistributionActionResultEnum; -import org.springframework.test.util.ReflectionTestUtils; /** * Tests {@link ArtifactDownloadManager}. @@ -67,31 +71,27 @@ import org.springframework.test.util.ReflectionTestUtils; public class TestArtifactDownloadManager { private ArtifactDownloadManager downloadManager; - private BabelServiceClient mockBabelClient; - private IDistributionClient mockDistributionClient; - private NotificationPublisher mockNotificationPublisher; - private BabelArtifactConverter mockBabelArtifactConverter; - private BabelServiceClientFactory mockClientFactory; - - @Before + @Mock private BabelServiceClient mockBabelClient; + @Mock private IDistributionClient mockDistributionClient; + @Mock private NotificationPublisher mockNotificationPublisher; + @Mock private BabelArtifactConverter mockBabelArtifactConverter; + @Mock private BabelServiceClientFactory mockClientFactory; + @InjectMocks BabelArtifactService babelArtifactService; + private VnfCatalogExtractor vnfCatalogExtractor; + + @BeforeEach public void setup() throws Exception { - mockBabelClient = mock(BabelServiceClient.class); - mockDistributionClient = mock(IDistributionClient.class); - mockNotificationPublisher = mock(NotificationPublisher.class); - mockBabelArtifactConverter = mock(BabelArtifactConverter.class); - mockClientFactory = mock(HttpsBabelServiceClientFactory.class); + MockitoAnnotations.openMocks(this); + vnfCatalogExtractor = new VnfCatalogExtractor(); when(mockClientFactory.create(any())).thenReturn(mockBabelClient); Properties configProperties = new Properties(); configProperties.load(this.getClass().getClassLoader().getResourceAsStream("model-loader.properties")); downloadManager = new ArtifactDownloadManager(mockDistributionClient, - new ModelLoaderConfig(configProperties, "."), mockClientFactory); - - ReflectionTestUtils.setField(downloadManager, "notificationPublisher", mockNotificationPublisher); - ReflectionTestUtils.setField(downloadManager, "babelArtifactConverter", mockBabelArtifactConverter); + mockNotificationPublisher, vnfCatalogExtractor, babelArtifactService); } - @After + @AfterEach public void tearDown() { downloadManager = null; mockDistributionClient = null; @@ -109,7 +109,7 @@ public class TestArtifactDownloadManager { catalogFiles), is(true)); assertThat(modelFiles, is(empty())); assertThat(catalogFiles, is(empty())); - Mockito.verifyZeroInteractions(mockBabelClient, mockDistributionClient, mockNotificationPublisher, + Mockito.verifyNoInteractions(mockBabelClient, mockDistributionClient, mockNotificationPublisher, mockBabelArtifactConverter); } @@ -129,7 +129,7 @@ public class TestArtifactDownloadManager { Mockito.verify(mockNotificationPublisher).publishDownloadFailure(mockDistributionClient, data, artifact, errorMessage); - Mockito.verifyZeroInteractions(mockBabelClient, mockBabelArtifactConverter); + Mockito.verifyNoInteractions(mockBabelClient, mockBabelArtifactConverter); } @Test @@ -146,8 +146,6 @@ public class TestArtifactDownloadManager { Mockito.verify(mockDistributionClient).download(artifactInfo); Mockito.verify(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, artifactInfo); Mockito.verify(mockNotificationPublisher).publishDeployFailure(mockDistributionClient, data, artifactInfo); - - Mockito.verifyZeroInteractions(mockBabelArtifactConverter); } @Test @@ -157,17 +155,17 @@ public class TestArtifactDownloadManager { when(mockDistributionClient.download(artifact)).thenReturn(createDistributionClientDownloadResult( DistributionActionResultEnum.SUCCESS, null, "This is not a valid Tosca CSAR File".getBytes())); doNothing().when(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, artifact); - when(mockBabelClient.postArtifact(any(), any(), any(), any())).thenThrow(new BabelServiceClientException("")); + when(mockBabelClient.postArtifact(any(), any())).thenThrow(new BabelServiceClientException("")); doNothing().when(mockNotificationPublisher).publishDeployFailure(mockDistributionClient, data, artifact); assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), null, null), is(false)); Mockito.verify(mockDistributionClient).download(artifact); Mockito.verify(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, artifact); - Mockito.verify(mockBabelClient).postArtifact(any(), any(), any(), any()); + Mockito.verify(mockBabelClient).postArtifact(any(), any()); Mockito.verify(mockNotificationPublisher).publishDeployFailure(mockDistributionClient, data, artifact); - Mockito.verifyZeroInteractions(mockBabelArtifactConverter); + Mockito.verifyNoInteractions(mockBabelArtifactConverter); } @@ -189,7 +187,7 @@ public class TestArtifactDownloadManager { Mockito.verify(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, artifact); Mockito.verify(mockNotificationPublisher).publishDeployFailure(mockDistributionClient, data, artifact); - Mockito.verifyZeroInteractions(mockBabelClient, mockBabelArtifactConverter); + Mockito.verifyNoInteractions(mockBabelClient, mockBabelArtifactConverter); } @Test @@ -200,15 +198,18 @@ public class TestArtifactDownloadManager { setupValidDownloadCsarMocks(data, artifactInfo, new ArtifactTestUtils()); + when(mockBabelArtifactConverter.convertToModel(any(BabelArtifact.class))).thenReturn(List.of(new ModelArtifact())); + when(mockBabelArtifactConverter.convertToCatalog(any(BabelArtifact.class))).thenReturn(new VnfCatalogArtifact("")); + List modelArtifacts = new ArrayList<>(); - List catalogFiles = new ArrayList<>(); - assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelArtifacts, catalogFiles), - is(true)); - assertThat(catalogFiles.size(), is(0)); + List catalogArtifacts = new ArrayList<>(); + assertTrue(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelArtifacts, catalogArtifacts)); + assertThat(modelArtifacts.size(), is(1)); + assertThat(catalogArtifacts.size(), is(1)); Mockito.verify(mockDistributionClient).download(artifactInfo); Mockito.verify(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, artifactInfo); - Mockito.verify(mockBabelClient).postArtifact(any(), any(), any(), any()); + Mockito.verify(mockBabelClient).postArtifact(any(), any()); Mockito.verify(mockBabelArtifactConverter).convertToModel(any()); Mockito.verify(mockBabelArtifactConverter).convertToCatalog(any()); } @@ -218,7 +219,7 @@ public class TestArtifactDownloadManager { when(mockDistributionClient.download(artifactInfo)) .thenReturn(createDistributionClientDownloadResult(DistributionActionResultEnum.SUCCESS, null, artifactTestUtils.loadResource("compressedArtifacts/service-VscpaasTest-csar.csar"))); - when(mockBabelClient.postArtifact(any(), any(), any(), any())).thenReturn(createBabelArtifacts()); + when(mockBabelClient.postArtifact(any(), any())).thenReturn(createBabelArtifacts()); } private List createBabelArtifacts() { @@ -237,8 +238,7 @@ public class TestArtifactDownloadManager { List modelFiles = new ArrayList<>(); List catalogFiles = new ArrayList<>(); - assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelFiles, catalogFiles), - is(true)); + assertTrue(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelFiles, catalogFiles)); assertThat(modelFiles, is(not(IsEmptyCollection.empty()))); assertThat(catalogFiles, is(empty())); @@ -246,7 +246,7 @@ public class TestArtifactDownloadManager { Mockito.verify(mockDistributionClient).download(artifact); Mockito.verify(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, artifact); - Mockito.verifyZeroInteractions(mockBabelClient, mockBabelArtifactConverter); + Mockito.verifyNoInteractions(mockBabelClient, mockBabelArtifactConverter); } private void setupValidModelQuerySpecMocks(ArtifactTestUtils artifactTestUtils, INotificationData data, @@ -272,14 +272,19 @@ public class TestArtifactDownloadManager { setupValidDownloadCsarMocks(data, serviceArtifact, artifactTestUtils); setupValidModelQuerySpecMocks(artifactTestUtils, data, modelSpecArtifact); + when(mockBabelArtifactConverter.convertToModel(any(BabelArtifact.class))).thenReturn(List.of(new ModelArtifact())); + when(mockBabelArtifactConverter.convertToCatalog(any(BabelArtifact.class))).thenReturn(new VnfCatalogArtifact("")); - List modelFiles = new ArrayList<>(); - List catalogFiles = new ArrayList<>(); - assertThat(downloadManager.downloadArtifacts(data, artifacts, modelFiles, catalogFiles), is(true)); + + List modelArtifacts = new ArrayList<>(); + List catalogArtifacts = new ArrayList<>(); + assertTrue(downloadManager.downloadArtifacts(data, artifacts, modelArtifacts, catalogArtifacts)); + assertThat(modelArtifacts.size(), is(2)); + assertThat(catalogArtifacts.size(), is(1)); Mockito.verify(mockDistributionClient).download(serviceArtifact); Mockito.verify(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, serviceArtifact); - Mockito.verify(mockBabelClient).postArtifact(any(), any(), any(), any()); + Mockito.verify(mockBabelClient).postArtifact(any(), any()); Mockito.verify(mockBabelArtifactConverter).convertToModel(any()); Mockito.verify(mockBabelArtifactConverter).convertToCatalog(any()); @@ -299,10 +304,10 @@ public class TestArtifactDownloadManager { when(mockDistributionClient.download(artifactInfo)) .thenReturn(createDistributionClientDownloadResult(DistributionActionResultEnum.SUCCESS, null, artifactTestUtils.loadResource("compressedArtifacts/service-VscpaasTest-csar.csar"))); - when(mockBabelArtifactConverter.convertToModel(anyList())) + when(mockBabelArtifactConverter.convertToModel(any())) .thenThrow(BabelArtifactParsingException.class); doNothing().when(mockNotificationPublisher).publishDeployFailure(mockDistributionClient, data, artifactInfo); - when(mockBabelClient.postArtifact(any(), any(), any(), any())).thenReturn(createBabelArtifacts()); + when(mockBabelClient.postArtifact(any(), any())).thenReturn(createBabelArtifacts()); List modelArtifacts = new ArrayList<>(); List catalogFiles = new ArrayList<>(); @@ -313,7 +318,7 @@ public class TestArtifactDownloadManager { Mockito.verify(mockDistributionClient).download(artifactInfo); Mockito.verify(mockNotificationPublisher).publishDeployFailure(mockDistributionClient, data, artifactInfo); - Mockito.verify(mockBabelClient).postArtifact(any(), any(), any(), any()); + Mockito.verify(mockBabelClient).postArtifact(any(), any()); Mockito.verify(mockBabelArtifactConverter).convertToModel(any()); } @@ -332,7 +337,7 @@ public class TestArtifactDownloadManager { Mockito.verify(mockDistributionClient).download(artifact); Mockito.verify(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, artifact); Mockito.verify(mockNotificationPublisher).publishDeployFailure(mockDistributionClient, data, artifact); - Mockito.verifyZeroInteractions(mockBabelClient, mockBabelArtifactConverter); + Mockito.verifyNoInteractions(mockBabelClient, mockBabelArtifactConverter); } private IDistributionClientDownloadResult createDistributionClientDownloadResult( diff --git a/src/test/java/org/onap/aai/modelloader/notification/TestBabelArtifactConverter.java b/src/test/java/org/onap/aai/modelloader/notification/TestBabelArtifactConverter.java index 2a04ec5..aee3dc2 100644 --- a/src/test/java/org/onap/aai/modelloader/notification/TestBabelArtifactConverter.java +++ b/src/test/java/org/onap/aai/modelloader/notification/TestBabelArtifactConverter.java @@ -20,18 +20,19 @@ */ package org.onap.aai.modelloader.notification; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.fail; import java.io.IOException; -import java.util.ArrayList; import java.util.List; -import org.junit.Test; + +import org.junit.jupiter.api.Test; import org.onap.aai.babel.service.data.BabelArtifact; import org.onap.aai.modelloader.entity.Artifact; import org.onap.aai.modelloader.entity.ArtifactType; import org.onap.aai.modelloader.entity.model.BabelArtifactParsingException; +import org.onap.aai.modelloader.entity.model.ModelArtifactParser; import org.onap.aai.modelloader.fixture.NotificationDataFixtureBuilder; import org.onap.aai.modelloader.util.ArtifactTestUtils; import org.onap.sdc.api.notification.IArtifactInfo; @@ -42,41 +43,37 @@ import org.onap.sdc.api.notification.INotificationData; */ public class TestBabelArtifactConverter { - @Test(expected = NullPointerException.class) + @Test public void convert_nullToscaFiles() throws BabelArtifactParsingException { - new BabelArtifactConverter().convertToModel(null); - fail("An instance of ArtifactGenerationException should have been thrown"); + assertThrows(NullPointerException.class, () -> { + new BabelArtifactConverter(new ModelArtifactParser()).convertToModel(null); + fail("An instance of ArtifactGenerationException should have been thrown"); + }); } @Test - public void testEmptyToscaFiles() throws BabelArtifactParsingException { - assertTrue("Nothing should have been returned", - new BabelArtifactConverter().convertToModel(new ArrayList<>()).isEmpty()); - } - - @Test(expected = BabelArtifactParsingException.class) public void testInvalidXml() throws IOException, BabelArtifactParsingException { - byte[] problemXml = - "This is some xml that should cause the model artifact parser to throw an erorr" - .getBytes(); + assertThrows(BabelArtifactParsingException.class, () -> { + byte[] problemXml = + "This is some xml that should cause the model artifact parser to throw an erorr" + .getBytes(); - INotificationData data = NotificationDataFixtureBuilder.getNotificationDataWithToscaCsarFile(); + INotificationData data = NotificationDataFixtureBuilder.getNotificationDataWithToscaCsarFile(); - List toscaArtifacts = setupTest(problemXml, data); + BabelArtifact toscaArtifact = setupTest(problemXml, data); - new BabelArtifactConverter().convertToModel(toscaArtifacts); - fail("An instance of ModelArtifactParsingException should have been thrown"); + new BabelArtifactConverter(new ModelArtifactParser()).convertToModel(toscaArtifact); + fail("An instance of ModelArtifactParsingException should have been thrown"); + }); } - private List setupTest(byte[] xml, INotificationData data) throws IOException { - List toscaArtifacts = new ArrayList<>(); + private BabelArtifact setupTest(byte[] xml, INotificationData data) throws IOException { IArtifactInfo artifactInfo = data.getServiceArtifacts().get(0); BabelArtifact xmlArtifact = new BabelArtifact(artifactInfo.getArtifactName(), BabelArtifact.ArtifactType.MODEL, new String(xml)); - toscaArtifacts.add(xmlArtifact); - return toscaArtifacts; + return xmlArtifact; } @Test @@ -84,11 +81,11 @@ public class TestBabelArtifactConverter { INotificationData data = NotificationDataFixtureBuilder.getNotificationDataWithToscaCsarFile(); byte[] xml = new ArtifactTestUtils().loadResource("convertedYmls/AAI-SCP-Test-VSP-resource-1.0.xml"); - List toscaArtifacts = setupTest(xml, data); + BabelArtifact toscaArtifact = setupTest(xml, data); - List modelArtifacts = new BabelArtifactConverter().convertToModel(toscaArtifacts); + List modelArtifacts = new BabelArtifactConverter(new ModelArtifactParser()).convertToModel(toscaArtifact); - assertEquals("There should have been 1 artifact", 1, modelArtifacts.size()); + assertEquals(1, modelArtifacts.size(), "There should have been 1 artifact"); assertEquals(new String(xml), modelArtifacts.get(0).getPayload()); assertEquals(ArtifactType.MODEL, modelArtifacts.get(0).getType()); } diff --git a/src/test/java/org/onap/aai/modelloader/notification/TestEventCallback.java b/src/test/java/org/onap/aai/modelloader/notification/TestEventCallback.java index 8276d90..b5d7fd3 100644 --- a/src/test/java/org/onap/aai/modelloader/notification/TestEventCallback.java +++ b/src/test/java/org/onap/aai/modelloader/notification/TestEventCallback.java @@ -21,24 +21,24 @@ package org.onap.aai.modelloader.notification; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.IOException; import java.util.List; import java.util.Properties; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; import org.mockito.Mockito; -import org.onap.aai.modelloader.config.ModelLoaderConfig; +import org.mockito.MockitoAnnotations; import org.onap.aai.modelloader.entity.model.BabelArtifactParsingException; import org.onap.aai.modelloader.fixture.NotificationDataFixtureBuilder; import org.onap.aai.modelloader.service.ArtifactDeploymentManager; import org.onap.sdc.api.IDistributionClient; import org.onap.sdc.api.notification.INotificationData; -import org.springframework.test.util.ReflectionTestUtils; /** * Tests {@link EventCallback}. @@ -47,36 +47,25 @@ public class TestEventCallback { private static final String CONFIG_FILE = "model-loader.properties"; - private ModelLoaderConfig config; private Properties configProperties; private EventCallback eventCallback; - private ArtifactDeploymentManager mockArtifactDeploymentManager; - private ArtifactDownloadManager mockArtifactDownloadManager; - private IDistributionClient mockDistributionClient; - private NotificationPublisher mockNotificationPublisher; + @Mock private ArtifactDeploymentManager mockArtifactDeploymentManager; + @Mock private ArtifactDownloadManager mockArtifactDownloadManager; + @Mock private IDistributionClient mockDistributionClient; + @Mock private NotificationPublisher mockNotificationPublisher; - @Before + @BeforeEach public void setup() throws IOException { + MockitoAnnotations.openMocks(this); configProperties = new Properties(); configProperties.load(this.getClass().getClassLoader().getResourceAsStream(CONFIG_FILE)); - config = new ModelLoaderConfig(configProperties, null); - - mockArtifactDeploymentManager = mock(ArtifactDeploymentManager.class); - mockArtifactDownloadManager = mock(ArtifactDownloadManager.class); - mockDistributionClient = mock(IDistributionClient.class); - mockNotificationPublisher = mock(NotificationPublisher.class); - - eventCallback = new EventCallback(mockDistributionClient, config, null); - ReflectionTestUtils.setField(eventCallback, "artifactDeploymentManager", mockArtifactDeploymentManager); - ReflectionTestUtils.setField(eventCallback, "artifactDownloadManager", mockArtifactDownloadManager); - ReflectionTestUtils.setField(eventCallback, "notificationPublisher", mockNotificationPublisher); + eventCallback = new EventCallback(mockDistributionClient, mockArtifactDeploymentManager, mockArtifactDownloadManager, mockNotificationPublisher); } - @After + @AfterEach public void tearDown() { - config = null; configProperties = null; eventCallback = null; mockArtifactDeploymentManager = null; @@ -96,7 +85,7 @@ public class TestEventCallback { verify(mockArtifactDownloadManager).downloadArtifacts(any(INotificationData.class), any(List.class), any(List.class), any(List.class)); - Mockito.verifyZeroInteractions(mockArtifactDeploymentManager); + Mockito.verifyNoInteractions(mockArtifactDeploymentManager); } @SuppressWarnings("unchecked") @@ -107,13 +96,13 @@ public class TestEventCallback { when(mockArtifactDownloadManager.downloadArtifacts(any(INotificationData.class), any(List.class), any(List.class), any(List.class))).thenReturn(true); - when(mockArtifactDeploymentManager.deploy(any(INotificationData.class), any(List.class), any(List.class))) + when(mockArtifactDeploymentManager.deploy(any(String.class), any(List.class), any(List.class))) .thenReturn(true); eventCallback.activateCallback(data); verify(mockArtifactDownloadManager).downloadArtifacts(any(INotificationData.class), any(List.class), any(List.class), any(List.class)); - verify(mockArtifactDeploymentManager).deploy(any(INotificationData.class), any(List.class), any(List.class)); + verify(mockArtifactDeploymentManager).deploy(any(String.class), any(List.class), any(List.class)); } } diff --git a/src/test/java/org/onap/aai/modelloader/notification/TestNotificationDataImpl.java b/src/test/java/org/onap/aai/modelloader/notification/TestNotificationDataImpl.java deleted file mode 100644 index c045910..0000000 --- a/src/test/java/org/onap/aai/modelloader/notification/TestNotificationDataImpl.java +++ /dev/null @@ -1,83 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017-2018 European Software Marketing Ltd. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.modelloader.notification; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertThat; - -import org.junit.Test; - -/** - * Tests for NotificationDataImpl class - * - */ -public class TestNotificationDataImpl { - - @Test - public void testGettersAndSetters() { - NotificationDataImpl data = new NotificationDataImpl(); - String distributionId = "testid"; - - data.setDistributionID(distributionId); - assertThat(data.getDistributionID(), is(equalTo(distributionId))); - - // Getters return empty data - assertThat(data.getArtifactMetadataByUUID(null), is(equalTo(null))); - assertThat(data.getServiceDescription(), is(equalTo(null))); - assertThat(data.getServiceInvariantUUID(), is(equalTo(null))); - assertThat(data.getServiceName(), is(equalTo(null))); - assertThat(data.getServiceUUID(), is(equalTo(null))); - assertThat(data.getServiceVersion(), is(equalTo(null))); - assertThat(data.getResources().size(), is(0)); - assertThat(data.getServiceArtifacts().size(), is(0)); - - // Unsupported method! - String context = "testcontext"; - data.setWorkloadContext(context); - assertThat(data.getWorkloadContext(), is(equalTo(null))); - } - - - @Test - public void testEquality() { - NotificationDataImpl data = new NotificationDataImpl(); - assertThat(data, is(not(equalTo(null)))); - assertThat(data, is(not(equalTo("")))); // NOSONAR - assertThat(data, is(equalTo(data))); - - NotificationDataImpl other = new NotificationDataImpl(); - assertThat(data, is(equalTo(other))); - assertThat(data.hashCode(), is(equalTo(other.hashCode()))); - - other.setDistributionID(""); - assertThat(data, is(not(equalTo(other)))); - - data.setDistributionID("1234"); - assertThat(data, is(not(equalTo(other)))); - - other.setDistributionID("1234"); - assertThat(data, is(equalTo(other))); - assertThat(data.hashCode(), is(equalTo(other.hashCode()))); - } - -} diff --git a/src/test/java/org/onap/aai/modelloader/notification/TestNotificationPublisher.java b/src/test/java/org/onap/aai/modelloader/notification/TestNotificationPublisher.java index 253fc17..c4aa932 100644 --- a/src/test/java/org/onap/aai/modelloader/notification/TestNotificationPublisher.java +++ b/src/test/java/org/onap/aai/modelloader/notification/TestNotificationPublisher.java @@ -20,13 +20,13 @@ */ package org.onap.aai.modelloader.notification; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.onap.sdc.api.IDistributionClient; @@ -61,9 +61,9 @@ public class TestNotificationPublisher { System.setProperty("CONFIG_HOME", "src/test/resources"); } - @Before + @BeforeEach public void setupMocks() { - MockitoAnnotations.initMocks(this); + MockitoAnnotations.openMocks(this); when(client.getConfiguration()).thenReturn(config); when(client.sendDownloadStatus(any())).thenReturn(clientResult); when(client.sendComponentDoneStatus(any())).thenReturn(clientResult); diff --git a/src/test/java/org/onap/aai/modelloader/restclient/MockBabelServiceClient.java b/src/test/java/org/onap/aai/modelloader/restclient/MockBabelServiceClient.java index 604aca7..783ad2e 100644 --- a/src/test/java/org/onap/aai/modelloader/restclient/MockBabelServiceClient.java +++ b/src/test/java/org/onap/aai/modelloader/restclient/MockBabelServiceClient.java @@ -23,6 +23,7 @@ package org.onap.aai.modelloader.restclient; import java.util.Collections; import java.util.List; import org.onap.aai.babel.service.data.BabelArtifact; +import org.onap.aai.babel.service.data.BabelRequest; import org.onap.aai.modelloader.config.ModelLoaderConfig; /** @@ -34,8 +35,8 @@ public class MockBabelServiceClient implements BabelServiceClient { public MockBabelServiceClient(ModelLoaderConfig config) throws BabelServiceClientException {} @Override - public List postArtifact(byte[] artifactPayload, String artifactName, String artifactVersion, - String transactionId) throws BabelServiceClientException { + public List postArtifact(BabelRequest babelRequest, String transactionId) + throws BabelServiceClientException { return Collections.emptyList(); } } diff --git a/src/test/java/org/onap/aai/modelloader/restclient/TestAaiRestClient.java b/src/test/java/org/onap/aai/modelloader/restclient/TestAaiRestClient.java index 91aa182..c992d06 100644 --- a/src/test/java/org/onap/aai/modelloader/restclient/TestAaiRestClient.java +++ b/src/test/java/org/onap/aai/modelloader/restclient/TestAaiRestClient.java @@ -20,8 +20,7 @@ */ package org.onap.aai.modelloader.restclient; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.File; import java.io.IOException; @@ -30,14 +29,17 @@ import java.nio.file.Paths; import java.util.Properties; import java.util.stream.IntStream; import java.util.stream.Stream; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; + import javax.xml.parsers.DocumentBuilderFactory; + import org.onap.aai.modelloader.config.ModelLoaderConfig; import org.onap.aai.modelloader.entity.ArtifactType; import org.onap.aai.modelloader.entity.model.ModelArtifact; import org.onap.aai.modelloader.entity.model.ModelArtifactParser; -import org.onap.aai.restclient.client.OperationResult; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -88,21 +90,21 @@ public class TestAaiRestClient { model.setPayload(readFile(MODEL_FILE)); model.setModelNamespace("http://org.openecomp.aai.inventory/v9"); - AaiRestClient aaiClient = new AaiRestClient(config); + AaiRestClient aaiClient = new AaiRestClient(config, new RestTemplate()); // GET model - OperationResult opResult = - aaiClient.getResource(getUrl(model, config), "example-trans-id-0", MediaType.APPLICATION_XML_TYPE); - assertEquals(opResult.getResultCode(), Response.Status.NOT_FOUND.getStatusCode()); + ResponseEntity opResult = + aaiClient.getResource(getUrl(model, config), "example-trans-id-0", MediaType.APPLICATION_XML, String.class); + assertEquals(opResult.getStatusCode(), HttpStatus.NOT_FOUND); // PUT the model opResult = aaiClient.putResource(getUrl(model, config), model.getPayload(), "example-trans-id-1", - MediaType.APPLICATION_XML_TYPE); - assertEquals(opResult.getResultCode(), Response.Status.CREATED.getStatusCode()); + MediaType.APPLICATION_XML, String.class); + assertEquals(opResult.getStatusCode(), HttpStatus.CREATED); // DELETE the model opResult = aaiClient.getAndDeleteResource(getUrl(model, config), "example-trans-id-3"); - assertEquals(opResult.getResultCode(), Response.Status.NO_CONTENT.getStatusCode()); + assertEquals(opResult.getStatusCode(), HttpStatus.NO_CONTENT); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/test/java/org/onap/aai/modelloader/restclient/TestAaiServiceClient.java b/src/test/java/org/onap/aai/modelloader/restclient/TestAaiServiceClient.java deleted file mode 100644 index 00bee09..0000000 --- a/src/test/java/org/onap/aai/modelloader/restclient/TestAaiServiceClient.java +++ /dev/null @@ -1,109 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017-2018 European Software Marketing Ltd. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.modelloader.restclient; - -import static javax.servlet.http.HttpServletResponse.SC_OK; -import static org.apache.commons.io.IOUtils.write; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.Properties; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.core.MediaType; -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.AbstractHandler; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.onap.aai.modelloader.config.ModelLoaderConfig; - -/** - * Local testing of the A&AI Service client. - * - */ -public class TestAaiServiceClient { - - private Server server; - private AaiRestClient aaiClient; - - @Before - public void startJetty() throws Exception { - server = new Server(8080); - server.setHandler(getMockHandler()); - server.start(); - - Properties props = new Properties(); - props.put("ml.aai.KEYSTORE_PASSWORD", "2244"); - ModelLoaderConfig config = new ModelLoaderConfig(props, "."); - aaiClient = new AaiRestClient(config); - } - - @After - public void stopJetty() throws Exception { - server.stop(); - } - - @Test - public void testBuildAaiRestClient() { - Properties props = new Properties(); - ModelLoaderConfig config = new ModelLoaderConfig(props, "."); - new AaiRestClient(config); - assertTrue(true); - } - - @Test - public void testOperations() { - String url = "http://localhost:8080"; - String transId = ""; - MediaType mediaType = MediaType.APPLICATION_JSON_TYPE; - aaiClient.getResource(url, "", mediaType); - aaiClient.deleteResource("http://localhost", transId, ""); - aaiClient.getAndDeleteResource(url, transId); - aaiClient.postResource(url, "", transId, mediaType); - aaiClient.putResource(url, "", transId, mediaType); - assertTrue(true); - } - - - /** - * Creates an {@link AbstractHandler handler} returning an arbitrary String as a response. - * - * @return never null. - */ - private Handler getMockHandler() { - Handler handler = new AbstractHandler() { - @Override - public void handle(String target, Request request, HttpServletRequest servletRequest, - HttpServletResponse response) throws IOException, ServletException { - response.setStatus(SC_OK); - response.setContentType("text/json;charset=utf-8"); - write("", response.getOutputStream()); - request.setHandled(true); - } - }; - return handler; - } -} - diff --git a/src/test/java/org/onap/aai/modelloader/restclient/TestBabelServiceClient.java b/src/test/java/org/onap/aai/modelloader/restclient/TestBabelServiceClient.java index 8da5f89..d82bff0 100644 --- a/src/test/java/org/onap/aai/modelloader/restclient/TestBabelServiceClient.java +++ b/src/test/java/org/onap/aai/modelloader/restclient/TestBabelServiceClient.java @@ -20,90 +20,77 @@ */ package org.onap.aai.modelloader.restclient; -import static javax.servlet.http.HttpServletResponse.SC_OK; -import static org.apache.commons.io.IOUtils.write; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; -import com.google.gson.Gson; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Paths; -import java.util.ArrayList; +import java.util.Base64; import java.util.List; -import java.util.Properties; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.AbstractHandler; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.onap.aai.babel.service.data.BabelArtifact; -import org.onap.aai.modelloader.config.ModelLoaderConfig; -import org.onap.aai.modelloader.service.HttpsBabelServiceClientFactory; +import org.onap.aai.babel.service.data.BabelRequest; +import org.onap.aai.modelloader.BabelClientTestConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock; +import org.springframework.context.annotation.Import; +import org.springframework.test.annotation.DirtiesContext; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.tomakehurst.wiremock.client.WireMock; /** * Local testing of the Babel service client. * */ +@SpringBootTest +@DirtiesContext +@AutoConfigureWireMock(port = 0) +@Import(BabelClientTestConfiguration.class) public class TestBabelServiceClient { - private Server server; - private String responseBody; + @Value("${wiremock.server.port}") + private int wiremockPort; - @Before - public void startJetty() throws Exception { - List response = new ArrayList<>(); - response.add(new BabelArtifact("", null, "")); - response.add(new BabelArtifact("", null, "")); - response.add(new BabelArtifact("", null, "")); - responseBody = new Gson().toJson(response); + @Autowired BabelServiceClient client; - server = new Server(8080); - server.setHandler(getMockHandler()); - server.start(); - } - - @After - public void stopJetty() throws Exception { - server.stop(); + @BeforeAll + public static void setup() throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + List artifacts = List.of( + new BabelArtifact("art1", null, ""), + new BabelArtifact("art2", null, ""), + new BabelArtifact("art3", null, "")); + WireMock.stubFor( + WireMock.post(WireMock.urlEqualTo("/services/babel-service/v1/app/generateArtifacts")) + .withHeader("X-TransactionId", WireMock.equalTo("Test-Transaction-ID-BabelClient")) + .withHeader("X-FromAppId", WireMock.equalTo("ModelLoader")) + .withRequestBody(WireMock.matchingJsonPath("$.artifactName", WireMock.equalTo("service-Vscpass-Test"))) + .withRequestBody(WireMock.matchingJsonPath("$.artifactVersion", WireMock.equalTo("1.0"))) + .withRequestBody(WireMock.matchingJsonPath("$.csar", WireMock.matching(".*"))) + .willReturn( + WireMock.aResponse() + .withHeader("Content-Type", "application/json") + .withBody(objectMapper.writeValueAsString(artifacts)))); } @Test public void testRestClient() throws BabelServiceClientException, IOException, URISyntaxException { - Properties configProperties = new Properties(); - configProperties.put("ml.babel.KEYSTORE_PASSWORD", "OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0"); - configProperties.put("ml.babel.KEYSTORE_FILE", "src/test/resources/auth/aai-client-dummy.p12"); - configProperties.put("ml.babel.TRUSTSTORE_PASSWORD", "OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0"); - // In a real deployment this would be a different file (to the client keystore) - configProperties.put("ml.babel.TRUSTSTORE_FILE", "src/test/resources/auth/aai-client-dummy.p12"); - configProperties.put("ml.babel.BASE_URL", "http://localhost:8080/"); - configProperties.put("ml.babel.GENERATE_ARTIFACTS_URL", "generate"); - BabelServiceClient client = - new HttpsBabelServiceClientFactory().create(new ModelLoaderConfig(configProperties, ".")); - List result = - client.postArtifact(readBytesFromFile("compressedArtifacts/service-VscpaasTest-csar.csar"), - "service-Vscpass-Test", "1.0", "Test-Transaction-ID-BabelClient"); - assertThat(result.size(), is(equalTo(3))); - } + BabelRequest babelRequest = new BabelRequest(); + babelRequest.setArtifactName("service-Vscpass-Test"); + babelRequest.setCsar(Base64.getEncoder().encodeToString(readBytesFromFile("compressedArtifacts/service-VscpaasTest-csar.csar"))); + babelRequest.setArtifactVersion("1.0"); - @Test - public void testRestClientHttp() throws BabelServiceClientException, IOException, URISyntaxException { - Properties configProperties = new Properties(); - configProperties.put("ml.babel.USE_HTTPS", "false"); - configProperties.put("ml.babel.BASE_URL", "http://localhost:8080/"); - configProperties.put("ml.babel.GENERATE_ARTIFACTS_URL", "generate"); - BabelServiceClient client = - new HttpsBabelServiceClientFactory().create(new ModelLoaderConfig(configProperties, ".")); List result = - client.postArtifact(readBytesFromFile("compressedArtifacts/service-VscpaasTest-csar.csar"), - "service-Vscpass-Test", "1.0", "Test-Transaction-ID-BabelClient"); + client.postArtifact(babelRequest, "Test-Transaction-ID-BabelClient"); assertThat(result.size(), is(equalTo(3))); } @@ -111,23 +98,4 @@ public class TestBabelServiceClient { private byte[] readBytesFromFile(String resourceFile) throws IOException, URISyntaxException { return Files.readAllBytes(Paths.get(ClassLoader.getSystemResource(resourceFile).toURI())); } - - /** - * Creates an {@link AbstractHandler handler} returning an arbitrary String as a response. - * - * @return never null. - */ - private Handler getMockHandler() { - Handler handler = new AbstractHandler() { - @Override - public void handle(String target, Request request, HttpServletRequest servletRequest, - HttpServletResponse response) throws IOException, ServletException { - response.setStatus(SC_OK); - response.setContentType("text/xml;charset=utf-8"); - write(responseBody, response.getOutputStream()); - request.setHandled(true); - } - }; - return handler; - } } diff --git a/src/test/java/org/onap/aai/modelloader/restclient/TracingTest.java b/src/test/java/org/onap/aai/modelloader/restclient/TracingTest.java new file mode 100644 index 0000000..3bfceb5 --- /dev/null +++ b/src/test/java/org/onap/aai/modelloader/restclient/TracingTest.java @@ -0,0 +1,63 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom AG Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.restclient; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock; +import org.springframework.http.HttpStatus; +import org.springframework.web.client.RestTemplate; + +import com.github.tomakehurst.wiremock.client.WireMock; + +@SpringBootTest(properties = { + "spring.sleuth.enabled=true", + "spring.zipkin.baseUrl=http://localhost:${wiremock.server.port}" +}) +@AutoConfigureWireMock(port = 0) +public class TracingTest { + + @Value("${wiremock.server.port}") + private int wiremockPort; + + @Autowired RestTemplate restTemplate; + + @Test + public void thatArtifactsCanBePushed() { + WireMock.stubFor( + WireMock.post(WireMock.urlEqualTo("/api/v2/spans")) + .willReturn( + WireMock.aResponse() + .withStatus(HttpStatus.OK.value()))); + + WireMock.stubFor( + WireMock.get(WireMock.urlEqualTo("/")) + .withHeader("X-B3-TraceId", WireMock.matching(".*")) + .willReturn( + WireMock.aResponse() + .withStatus(HttpStatus.OK.value()))); + + + String response = restTemplate.getForObject("http://localhost:" + wiremockPort + "/", String.class); + } + +} diff --git a/src/test/java/org/onap/aai/modelloader/service/TestArtifactInfoImpl.java b/src/test/java/org/onap/aai/modelloader/service/TestArtifactInfoImpl.java deleted file mode 100644 index ec55f15..0000000 --- a/src/test/java/org/onap/aai/modelloader/service/TestArtifactInfoImpl.java +++ /dev/null @@ -1,123 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017-2018 European Software Marketing Ltd. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.modelloader.service; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.Matchers.empty; -import static org.junit.Assert.assertThat; - -import org.junit.Test; - -/** - * Tests for NotificationDataImpl class - * - */ -public class TestArtifactInfoImpl { - - @Test - public void testGettersAndSetters() { - ArtifactInfoImpl info = new ArtifactInfoImpl(); - String artifactName = "testname"; - - info.setArtifactName(artifactName); - assertThat(info.getArtifactName(), is(equalTo(artifactName))); - - String artifactType = "test-type"; - info.setArtifactType(artifactType); - assertThat(info.getArtifactType(), is(equalTo(artifactType))); - - String artifactVersion = "v1"; - info.setArtifactVersion(artifactVersion); - assertThat(info.getArtifactVersion(), is(equalTo(artifactVersion))); - - String artifactDescription = "test description"; - info.setArtifactDescription(artifactDescription); - assertThat(info.getArtifactDescription(), is(equalTo(artifactDescription))); - - assertThat(info.getArtifactChecksum(), is(nullValue())); - assertThat(info.getArtifactTimeout(), is(nullValue())); - assertThat(info.getArtifactURL(), is(nullValue())); - assertThat(info.getArtifactUUID(), is(nullValue())); - assertThat(info.getGeneratedArtifact(), is(nullValue())); - assertThat(info.getRelatedArtifacts(), is(empty())); - } - - - @Test - public void testEquality() { - ArtifactInfoImpl info = new ArtifactInfoImpl(); - assertThat(info, is(not(equalTo(null)))); - assertThat(info, is(not(equalTo("")))); // NOSONAR - assertThat(info, is(equalTo(info))); - - ArtifactInfoImpl other = new ArtifactInfoImpl(); - assertThat(info, is(equalTo(other))); - assertThat(info.hashCode(), is(equalTo(other.hashCode()))); - - // Artifact Name - other.setArtifactName(""); - assertThat(info, is(not(equalTo(other)))); - - info.setArtifactName("1234"); - assertThat(info, is(not(equalTo(other)))); - - other.setArtifactName("1234"); - assertThat(info, is(equalTo(other))); - assertThat(info.hashCode(), is(equalTo(other.hashCode()))); - - // Artifact Type - other.setArtifactType(""); - assertThat(info, is(not(equalTo(other)))); - - info.setArtifactType("type"); - assertThat(info, is(not(equalTo(other)))); - - other.setArtifactType("type"); - assertThat(info, is(equalTo(other))); - assertThat(info.hashCode(), is(equalTo(other.hashCode()))); - - // Artifact Description - other.setArtifactDescription(""); - assertThat(info, is(not(equalTo(other)))); - - info.setArtifactDescription("type"); - assertThat(info, is(not(equalTo(other)))); - - other.setArtifactDescription("type"); - assertThat(info, is(equalTo(other))); - assertThat(info.hashCode(), is(equalTo(other.hashCode()))); - - // Artifact Version - other.setArtifactVersion(""); - assertThat(info, is(not(equalTo(other)))); - - info.setArtifactVersion("v1"); - assertThat(info, is(not(equalTo(other)))); - - other.setArtifactVersion("v1"); - assertThat(info, is(equalTo(other))); - assertThat(info.hashCode(), is(equalTo(other.hashCode()))); - } - -} diff --git a/src/test/java/org/onap/aai/modelloader/service/TestModelController.java b/src/test/java/org/onap/aai/modelloader/service/TestModelController.java new file mode 100644 index 0000000..6cfeb65 --- /dev/null +++ b/src/test/java/org/onap/aai/modelloader/service/TestModelController.java @@ -0,0 +1,107 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.service; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.util.Base64; +import java.util.Collections; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.onap.aai.modelloader.babel.BabelArtifactService; +import org.onap.aai.modelloader.config.ModelLoaderConfig; +import org.onap.aai.modelloader.extraction.VnfCatalogExtractor; +import org.onap.aai.modelloader.notification.ArtifactDownloadManager; +import org.onap.aai.modelloader.notification.BabelArtifactConverter; +import org.onap.aai.modelloader.notification.NotificationPublisher; +import org.onap.aai.modelloader.restclient.BabelServiceClient; +import org.onap.aai.modelloader.restclient.BabelServiceClientException; +import org.onap.aai.modelloader.util.ArtifactTestUtils; +import org.onap.sdc.api.IDistributionClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.TestPropertySource; + +/** + * Tests for the ModelLoaderService class. + * + */ +@SpringBootTest +@TestPropertySource(properties = {"CONFIG_HOME=src/test/resources",}) +public class TestModelController { + + @Autowired IDistributionClient iDistributionClient; + @Autowired ModelLoaderConfig modelLoaderConfig; + @Autowired ArtifactDeploymentManager artifactDeploymentManager; + @Autowired BabelArtifactConverter babelArtifactConverter; + @Autowired NotificationPublisher notificationPublisher; + @Autowired VnfCatalogExtractor vnfCatalogExtractor; + + @Mock BabelServiceClientFactory clientFactory; + @Mock BabelServiceClient babelServiceClient; + @InjectMocks BabelArtifactService babelArtifactService; + + private ModelController modelController; + + @BeforeEach + public void init() throws BabelServiceClientException { + when(clientFactory.create(any())).thenReturn(babelServiceClient); + when(babelServiceClient.postArtifact(any(), any())).thenReturn(Collections.emptyList()); + ArtifactDownloadManager artifactDownloadManager = new ArtifactDownloadManager(iDistributionClient, notificationPublisher, vnfCatalogExtractor, babelArtifactService); + this.modelController = new ModelController(iDistributionClient, modelLoaderConfig, artifactDeploymentManager, artifactDownloadManager); + } + + @Test + public void testLoadModel() { + ResponseEntity response = modelController.loadModel(""); + assertThat(response.getStatusCode(), is(HttpStatus.OK)); + } + + @Test + public void testSaveModel() { + ResponseEntity response = modelController.saveModel("", ""); + assertThat(response.getStatusCode(), is(HttpStatus.OK)); + } + + @Test + public void testIngestModel() throws IOException { + byte[] csarPayload = new ArtifactTestUtils().loadResource("compressedArtifacts/service-VscpaasTest-csar.csar"); + ResponseEntity response = modelController.ingestModel("model-name", "", Base64.getEncoder().encodeToString(csarPayload)); + assertThat(response.getStatusCode(), is(HttpStatus.OK)); + } + + @Test + public void testIngestModelMissingName() throws IOException { + byte[] csarPayload = new ArtifactTestUtils().loadResource("compressedArtifacts/service-VscpaasTest-csar.csar"); + ResponseEntity response = modelController.ingestModel("", "", Base64.getEncoder().encodeToString(csarPayload)); + assertThat(response.getStatusCode(), is(HttpStatus.INTERNAL_SERVER_ERROR)); + } + +} diff --git a/src/test/java/org/onap/aai/modelloader/service/TestModelLoaderService.java b/src/test/java/org/onap/aai/modelloader/service/TestModelLoaderService.java deleted file mode 100644 index f38cf77..0000000 --- a/src/test/java/org/onap/aai/modelloader/service/TestModelLoaderService.java +++ /dev/null @@ -1,88 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017-2018 European Software Marketing Ltd. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.modelloader.service; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.Base64; -import javax.ws.rs.core.Response; -import org.junit.After; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.onap.aai.modelloader.util.ArtifactTestUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringRunner; - -/** - * Tests for the ModelLoaderService class. - * - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = {ModelLoaderService.class, MockBabelServiceClientFactory.class}) -@TestPropertySource(properties = {"CONFIG_HOME=src/test/resources",}) -public class TestModelLoaderService { - - @Autowired - private ModelLoaderService service; - - @After - public void shutdown() { - service.preShutdownOperations(); - } - - @Test - public void testMissingConfig() { - new ModelLoaderService().start(); - assertTrue(true); - } - - @Test - public void testLoadModel() { - Response response = service.loadModel(""); - assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode())); - } - - @Test - public void testSaveModel() { - Response response = service.saveModel("", ""); - assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode())); - } - - @Test - public void testIngestModel() throws IOException { - byte[] csarPayload = new ArtifactTestUtils().loadResource("compressedArtifacts/service-VscpaasTest-csar.csar"); - Response response = service.ingestModel("model-name", "", Base64.getEncoder().encodeToString(csarPayload)); - assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode())); - } - - @Test - public void testIngestModelMissingName() throws IOException { - byte[] csarPayload = new ArtifactTestUtils().loadResource("compressedArtifacts/service-VscpaasTest-csar.csar"); - Response response = service.ingestModel("", "", Base64.getEncoder().encodeToString(csarPayload)); - assertThat(response.getStatus(), is(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode())); - } - -} diff --git a/src/test/java/org/onap/aai/modelloader/service/TestModelLoaderServiceWithSdc.java b/src/test/java/org/onap/aai/modelloader/service/TestModelLoaderServiceWithSdc.java index d23b3ef..5d64dec 100644 --- a/src/test/java/org/onap/aai/modelloader/service/TestModelLoaderServiceWithSdc.java +++ b/src/test/java/org/onap/aai/modelloader/service/TestModelLoaderServiceWithSdc.java @@ -21,42 +21,36 @@ package org.onap.aai.modelloader.service; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import java.io.IOException; import java.util.Base64; -import javax.ws.rs.core.Response; -import org.junit.After; -import org.junit.Test; -import org.junit.runner.RunWith; + +import org.junit.jupiter.api.Test; +import org.onap.aai.modelloader.config.BeanConfig; import org.onap.aai.modelloader.util.ArtifactTestUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringRunner; /** * Tests for the ModelLoaderService class. * */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = {ModelLoaderService.class, HttpsBabelServiceClientFactory.class}) +@SpringBootTest @TestPropertySource(properties = {"CONFIG_HOME=src/test/resources",}) public class TestModelLoaderServiceWithSdc { @Autowired - private ModelLoaderService service; - - @After - public void shutdown() { - service.preShutdownOperations(); - } + private ModelController controller; @Test public void testIngestModel() throws IOException { byte[] csarPayload = new ArtifactTestUtils().loadResource("compressedArtifacts/service-VscpaasTest-csar.csar"); - Response response = service.ingestModel("model-name", "", Base64.getEncoder().encodeToString(csarPayload)); - assertThat(response.getStatus(), is(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode())); + ResponseEntity response = controller.ingestModel("model-name", "", Base64.getEncoder().encodeToString(csarPayload)); + assertThat(response.getStatusCode(), is(HttpStatus.INTERNAL_SERVER_ERROR)); } diff --git a/src/test/java/org/onap/aai/modelloader/util/ArtifactTestUtils.java b/src/test/java/org/onap/aai/modelloader/util/ArtifactTestUtils.java index 50074f1..e5db2a5 100644 --- a/src/test/java/org/onap/aai/modelloader/util/ArtifactTestUtils.java +++ b/src/test/java/org/onap/aai/modelloader/util/ArtifactTestUtils.java @@ -22,6 +22,8 @@ package org.onap.aai.modelloader.util; import java.io.IOException; import java.net.URL; +import java.nio.charset.Charset; + import org.apache.commons.io.IOUtils; import org.onap.aai.babel.service.data.BabelArtifact; @@ -53,7 +55,7 @@ public class ArtifactTestUtils { } public static String loadResourceAsString(String resourceName) throws IOException { - return IOUtils.toString(getResource(resourceName)); + return IOUtils.toString(getResource(resourceName), Charset.defaultCharset()); } private static URL getResource(String resourceName) { diff --git a/src/test/java/org/onap/aai/modelloader/util/TestGizmoTranslator.java b/src/test/java/org/onap/aai/modelloader/util/TestGizmoTranslator.java index 97d7a19..c1a862a 100644 --- a/src/test/java/org/onap/aai/modelloader/util/TestGizmoTranslator.java +++ b/src/test/java/org/onap/aai/modelloader/util/TestGizmoTranslator.java @@ -22,19 +22,23 @@ package org.onap.aai.modelloader.util; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; -import org.junit.Test; + +import org.junit.jupiter.api.Test; import org.onap.aai.modelloader.gizmo.GizmoBulkPayload; public class TestGizmoTranslator { - @Test(expected = IOException.class) + @Test public void translateInvalidXml() throws IOException { - GizmoTranslator.translate("not valid XML"); + assertThrows(IOException.class, () -> { + GizmoTranslator.translate("not valid XML"); + }); } @Test diff --git a/src/test/java/org/onap/aai/modelloader/util/TestJsonXmlConverter.java b/src/test/java/org/onap/aai/modelloader/util/TestJsonXmlConverter.java index 81a4833..ec66a59 100644 --- a/src/test/java/org/onap/aai/modelloader/util/TestJsonXmlConverter.java +++ b/src/test/java/org/onap/aai/modelloader/util/TestJsonXmlConverter.java @@ -21,14 +21,16 @@ package org.onap.aai.modelloader.util; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import java.io.ByteArrayInputStream; import java.nio.file.Files; import java.nio.file.Paths; + import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import org.junit.Test; + +import org.junit.jupiter.api.Test; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; diff --git a/src/test/resources/__files/artifactTypes.json b/src/test/resources/__files/artifactTypes.json new file mode 100644 index 0000000..de3cfce --- /dev/null +++ b/src/test/resources/__files/artifactTypes.json @@ -0,0 +1,63 @@ +[ + "AAI_SERVICE_MODEL", + "AAI_VF_INSTANCE_MODEL", + "AAI_VF_MODEL", + "AAI_VF_MODULE_MODEL", + "ANSIBLE_PLAYBOOK", + "APPC_CONFIG", + "BPEL", + "CHEF", + "CLOUD_TECHNOLOGY_SPECIFIC_ARTIFACT", + "CONTROLLER_BLUEPRINT_ARCHIVE", + "DCAE_DOC", + "DCAE_EVENT", + "DCAE_INVENTORY_BLUEPRINT", + "DCAE_INVENTORY_DOC", + "DCAE_INVENTORY_EVENT", + "DCAE_INVENTORY_JSON", + "DCAE_INVENTORY_POLICY", + "DCAE_INVENTORY_TOSCA", + "DCAE_JSON", + "DCAE_POLICY", + "DCAE_TOSCA", + "DG_XML", + "ETSI_PACKAGE", + "ASD_PACKAGE", + "GUIDE", + "HEAT_ARTIFACT", + "HEAT_ENV", + "HEAT", + "HEAT_NESTED", + "HEAT_NET", + "HEAT_VOL", + "HELM", + "ICON", + "LIFECYCLE_OPERATIONS", + "MODEL_INVENTORY_PROFILE", + "MODEL_QUERY_SPEC", + "MURANO_PKG", + "NETWORK_CALL_FLOW", + "ONBOARDED_PACKAGE", + "OTHER", + "PERFORMANCE_COUNTER", + "PLAN", + "PM_DICTIONARY", + "PNF_SW_INFORMATION", + "PUPPET", + "SHELL_SCRIPT", + "SHELL", + "SNMP_POLL", + "SNMP_TRAP", + "TOSCA_CSAR", + "TOSCA_TEMPLATE", + "UCPE_LAYER_2_CONFIGURATION", + "VENDOR_LICENSE", + "VES_EVENTS", + "VF_LICENSE", + "VF_MODULES_METADATA", + "VNF_CATALOG", + "WORKFLOW", + "YANG_MODULE", + "YANG_XML", + "YANG" +] \ No newline at end of file diff --git a/src/test/resources/__files/kafkaBootstrap.json b/src/test/resources/__files/kafkaBootstrap.json new file mode 100644 index 0000000..1820ade --- /dev/null +++ b/src/test/resources/__files/kafkaBootstrap.json @@ -0,0 +1,5 @@ +{ + "kafkaBootStrapServer": "localhost:9092", + "distrNotificationTopicName": "SDC-DISTR-NOTIF-TOPIC-AUTO", + "distrStatusTopicName": "SDC-DISTR-STATUS-TOPIC-AUTO" +} \ No newline at end of file diff --git a/src/test/resources/__files/modelResponse.xml b/src/test/resources/__files/modelResponse.xml new file mode 100644 index 0000000..36d07d8 --- /dev/null +++ b/src/test/resources/__files/modelResponse.xml @@ -0,0 +1,7 @@ + + + 3a40ab73-6694-4e75-bb6d-9a4a86ce35b3 + service + Network Service + 1710523260974 + \ No newline at end of file diff --git a/src/test/resources/__files/modelVersion.xml b/src/test/resources/__files/modelVersion.xml new file mode 100644 index 0000000..efee516 --- /dev/null +++ b/src/test/resources/__files/modelVersion.xml @@ -0,0 +1,8 @@ + + + fe578080-ce19-4604-8760-fc264fbb2565 + group-assignment + 1.0 + 1708937324692 + \ No newline at end of file diff --git a/src/test/resources/__files/service-TestSvc-csar-babel-response.json b/src/test/resources/__files/service-TestSvc-csar-babel-response.json new file mode 100644 index 0000000..7103156 --- /dev/null +++ b/src/test/resources/__files/service-TestSvc-csar-babel-response.json @@ -0,0 +1 @@ +[{"name":"AAI-test-svc-service-2.0.xml","type":"MODEL","payload":"\n 3c8bc8e7-e387-46ed-8616-70e99e2206dc\n service\n Network L1-3\n \n \n 71f47717-b100-4eac-940b-7d4e86a4cbb7\n test-svc\n 2.0\n test-svc\n \n \n T\n unbounded\n \n \n \n model-ver\n \n model-ver.model-version-id\n 46b92144-923a-4d20-b85a-3cbd847668a9\n \n \n model.model-invariant-id\n 82194af1-3c2c-485a-8f44-420e22a9eaa4\n \n \n \n \n \n \n \n"}] \ No newline at end of file diff --git a/src/test/resources/__files/service-TestSvc-csar.csar b/src/test/resources/__files/service-TestSvc-csar.csar new file mode 100644 index 0000000..711f068 Binary files /dev/null and b/src/test/resources/__files/service-TestSvc-csar.csar differ diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties new file mode 100644 index 0000000..69f4ff7 --- /dev/null +++ b/src/test/resources/application.properties @@ -0,0 +1,11 @@ +CONFIG_HOME=src/test/resources +spring.kafka.consumer.auto-offset-reset=earliest +spring.kafka.consumer.group-id=aai +spring.kafka.consumer.client-id=aai-model-loader +topics.distribution.notification=SDC-DISTR-NOTIF-TOPIC-AUTO + +spring.sleuth.enabled=false + +ml.distribution.connection.enabled=false # avoid having the distribution client running in the background (requires active kafka) + +spring.main.allow-bean-definition-overriding=true \ No newline at end of file diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index aef38e6..4bf73da 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -11,7 +11,7 @@ - + diff --git a/src/test/resources/model-loader.properties b/src/test/resources/model-loader.properties index 51a38c5..2db7c09 100644 --- a/src/test/resources/model-loader.properties +++ b/src/test/resources/model-loader.properties @@ -1,16 +1,20 @@ # Model Loader Distribution Client Configuration ml.distribution.ACTIVE_SERVER_TLS_AUTH=false ml.distribution.ASDC_ADDRESS=localhost:8443 +ml.distribution.ASDC_USE_HTTPS=false ml.distribution.CONSUMER_GROUP=aai-ml-group-test ml.distribution.CONSUMER_ID=aai-ml-id-test -ml.distribution.ENVIRONMENT_NAME=env +ml.distribution.ENVIRONMENT_NAME=AUTO ml.distribution.KEYSTORE_PASSWORD= ml.distribution.KEYSTORE_FILE= ml.distribution.PASSWORD=Aa123456 -ml.distribution.POLLING_INTERVAL=30 -ml.distribution.POLLING_TIMEOUT=20 +ml.distribution.POLLING_INTERVAL=15 +ml.distribution.POLLING_TIMEOUT=3 ml.distribution.USER=ci ml.distribution.ARTIFACT_TYPES=MODEL_QUERY_SPEC,TOSCA_CSAR +ml.distribution.SASL_JAAS_CONFIG=org.apache.kafka.common.security.scram.ScramLoginModule required username="aai-modelloader-ku" password="somePassword"; +ml.distribution.SECURITY_PROTOCOL=PLAINTEXT +ml.distribution.SASL_MECHANISM=PLAIN # Disable ASDC polling & enable REST interface ml.distribution.ASDC_CONNECTION_DISABLE=true diff --git a/version.properties b/version.properties index 78f179d..d035ea2 100644 --- a/version.properties +++ b/version.properties @@ -24,7 +24,7 @@ # because they are used in Jenkins, whose plug-in doesn't support major=1 -minor=12 +minor=14 patch=0 base_version=${major}.${minor}.${patch}