ml.distribution.POLLING_TIMEOUT=20
ml.distribution.USER=<DIST_USER>
ml.distribution.ARTIFACT_TYPES=MODEL_QUERY_SPEC,TOSCA_CSAR
-
-# Model Loader Client Configuration for the A&AI REST interface
-ml.aai.BASE_URL=https://<AAI_HOST>:8443
-ml.aai.MODEL_URL=/aai/v*/service-design-and-creation/models/model/
-ml.aai.NAMED_QUERY_URL=/aai/v*/service-design-and-creation/named-queries/named-query/
-ml.aai.VNF_IMAGE_URL=/aai/v*/service-design-and-creation/vnf-images
-ml.aai.KEYSTORE_FILE=<AAI_KEYSTORE>
-ml.aai.KEYSTORE_PASSWORD=<OBF:1234>
-ml.aai.AUTH_USER=ModelLoader
-ml.aai.AUTH_PASSWORD=
-
-# Model Loader Client Configuration for the Babel Service
-ml.babel.BASE_URL=https://<BABEL_HOST>:9516
-ml.babel.GENERATE_ARTIFACTS_URL=/services/babel-service/v1/app/generateArtifacts
-ml.babel.KEYSTORE_FILE=<BABEL_KEYSTORE>
-ml.babel.KEYSTORE_PASSWORD=<OBF:1234>
-ml.babel.TRUSTSTORE_FILE=<BABEL_TRUSTSTORE>
-ml.babel.TRUSTSTORE_PASSWORD=<OBF:1234>
<parent>
<groupId>org.onap.oparent</groupId>
<artifactId>oparent</artifactId>
- <version>2.1.0</version>
+ <version>3.3.3</version>
<relativePath />
</parent>
<groupId>org.onap.aai.model-loader</groupId>
<artifactId>model-loader</artifactId>
<name>aai-model-loader</name>
- <version>1.14.0-SNAPSHOT</version>
+ <version>1.14.3-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<start-class>org.onap.aai.modelloader.service.ModelLoaderApplication</start-class>
<nexusproxy>https://nexus.onap.org</nexusproxy>
<docker.location>${basedir}/target</docker.location>
- <spring-boot.version>2.4.13</spring-boot.version>
- <spring-cloud.version>2020.0.2</spring-cloud.version>
+ <spring-boot.version>2.7.18</spring-boot.version>
+ <spring-cloud.version>2021.0.8</spring-cloud.version>
+ <spring-kafka.version>2.9.13</spring-kafka.version>
<apache.commons-text.version>1.10.0</apache.commons-text.version>
- <commons-compress.version>1.22</commons-compress.version>
+ <commons-compress.version>1.27.0</commons-compress.version>
+ <commons-io.version>2.16.1</commons-io.version>
<gson.version>2.10.1</gson.version>
- <hamcrest-all.version>1.3</hamcrest-all.version>
<babel.version>1.13.0</babel.version>
- <aai.rest.client.version>1.2.1</aai.rest.client.version>
- <sdc-distribution-client.version>2.1.1</sdc-distribution-client.version>
+ <sdc-distribution-client.version>2.0.0</sdc-distribution-client.version>
<logback.version>1.2.11</logback.version>
<!-- docker related properties -->
<docker.fabric.version>0.39.0</docker.fabric.version>
<aai.docker.version>1.0.0</aai.docker.version>
<aai.build.directory>${project.build.directory}/${project.artifactId}-${project.version}-build/</aai.build.directory>
<aai.docker.namespace>onap</aai.docker.namespace>
- <aai.base.image>alpine</aai.base.image>
- <aai.base.image.version>1.13.2</aai.base.image.version>
<!-- This will be used for the docker images as the default format of maven build has issues -->
<maven.build.timestamp.format>yyyyMMdd'T'HHmmss'Z'</maven.build.timestamp.format>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.0</version>
- <executions>
- <execution>
- <phase>pre-clean</phase>
- <goals>
- <goal>execute</goal>
- </goals>
- <configuration>
- <source>
- def userAaiBaseImage = session.userProperties['aai.base.image'];
- def userAaiCommonVersion = session.userProperties['aai.base.image.version'];
- if (userAaiCommonVersion != null) {
- project.properties['aai.base.image.version'] = userAaiCommonVersion;
- }
- if (userAaiBaseImage != null) {
- project.properties['aai.base.image'] = userAaiBaseImage;
- }
- log.info 'Base image flavour: ' + project.properties['aai.base.image'];
- log.info 'Base image version: ' + project.properties['aai.base.image.version'];
- </source>
- </configuration>
- </execution>
- </executions>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-webflux</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.apache.kafka</groupId>
- <artifactId>kafka-clients</artifactId>
- <!-- <version>3.3.1</version> -->
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-configuration-processor</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-actuator</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.micrometer</groupId>
+ <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
- <!-- <version>3.1.2</version> -->
+ <version>${spring-kafka.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka-test</artifactId>
- <!-- <version>3.1.1</version> -->
+ <version>${spring-kafka.version}</version>
<scope>test</scope>
</dependency>
<dependency>
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.glassfish.jersey.core</groupId>
- <artifactId>jersey-common</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.onap.aai</groupId>
- <artifactId>rest-client</artifactId>
- <version>${aai.rest.client.version}</version>
- </dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${sdc-distribution-client.version}</version>
</dependency>
<dependency>
- <groupId>org.json</groupId>
- <artifactId>json</artifactId>
- <version>20131018</version>
- <!--$NO-MVN-MAN-VER$ -->
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-security</artifactId>
- </dependency>
- <dependency>
- <groupId>jline</groupId>
- <artifactId>jline</artifactId>
- <version>2.12.1</version>
+ <groupId>net.logstash.logback</groupId>
+ <artifactId>logstash-logback-encoder</artifactId>
+ <version>6.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
- <version>2.11.0</version>
+ <version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
</dependency>
<!-- Test dependencies -->
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>hamcrest-all</artifactId>
- <version>${hamcrest-all.version}</version>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
- <version>3.0.0-M4</version>
+ <version>3.1.2</version>
<configuration>
<!-- Sets the VM argument line used when unit tests are run. -->
<argLine>${surefireArgLine}</argLine>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
- <version>3.0.0-M4</version>
+ <version>3.1.2</version>
<executions>
<!-- Ensures that both integration-test and verify goals of the Failsafe
Maven plugin are executed. -->
--- /dev/null
+distribution_type: container
+container_release_tag: 1.14.0
+project: model-loader
+ref: de4e6c93f2f4038167e8b5fef92426c4daac4b83
+containers:
+ - name: model-loader
+ version: 1.14-STAGING-20240425T063121Z
--- /dev/null
+distribution_type: container
+container_release_tag: 1.14.1
+project: model-loader
+ref: 9d93fb4e58c23ddcb252e6812557bb2dbdcd4ce9
+containers:
+ - name: model-loader
+ version: 1.14-STAGING-20240527T105553Z
--- /dev/null
+distribution_type: container
+container_release_tag: 1.14.2
+project: model-loader
+ref: cf07e5a766cdb148f80bbacfb3eac6de3654e33b
+containers:
+ - name: model-loader
+ version: 1.14-STAGING-20240904T151247Z
--- /dev/null
+distribution_type: container
+container_release_tag: 1.14.3
+project: model-loader
+ref: c145056b44f5b469b5f821a38f1ae1089a4dc7d6
+containers:
+ - name: model-loader
+ version: 1.14-STAGING-20250519T093713Z
PROPS="$PROPS -Dcom.att.eelf.logging.file=logback.xml"
PROPS="$PROPS -Dlogback.configurationFile=$AJSC_HOME/logback.xml"
PROPS="$PROPS -Dserver.port=9500"
-JVM_MAX_HEAP=${MAX_HEAP:-1024}
+JVM_ARGS="${JVM_ARGS} -XX:MaxRAMPercentage=${MAX_RAM_PERCENTAGE:-70}";
echo "java $java_runtime_arguments $PROPS -jar $JARFILE"
-java $java_runtime_arguments $PROPS -jar $JARFILE
+java $java_runtime_arguments ${JVM_ARGS} $PROPS -jar $JARFILE
-FROM @aai.docker.namespace@/aai-common-@aai.base.image@:@aai.base.image.version@
-
-ARG MICRO_HOME=/opt/app/model-loader
+FROM eclipse-temurin:17-jre-alpine
+USER 1000
+ENV MICRO_HOME=/opt/app/model-loader
WORKDIR $MICRO_HOME
-USER root
-
-RUN mkdir -p /opt/aaihome $MICRO_HOME /logs && \
- ln -s /logs $MICRO_HOME/logs && \
- chown -R aaiadmin:aaiadmin $MICRO_HOME && \
- chown -R aaiadmin:aaiadmin /logs
-
-COPY --chown=aaiadmin:aaiadmin /maven/model-loader/ .
-
-ENTRYPOINT ["/bin/bash", "/opt/app/model-loader/bin/start.sh"]
+COPY --chown=1000:1000 /maven/model-loader/ .
-USER aaiadmin
+ENTRYPOINT ["/bin/sh", "/opt/app/model-loader/bin/start.sh"]
*/
package org.onap.aai.modelloader;
+import org.onap.aai.modelloader.config.BabelProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
/**
* Model Loader Spring Boot Application.
*/
@SpringBootApplication
+@EnableConfigurationProperties(BabelProperties.class)
public class ModelLoaderApplication {
public static void main(String[] args) {
*/
package org.onap.aai.modelloader.babel;
+import java.util.ArrayList;
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.BabelRequest;
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;
@Service
public class BabelArtifactService {
- private static Logger logger = LoggerFactory.getInstance().getLogger(BabelArtifactService.class);
+ 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<Artifact> 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<BabelArtifact> babelArtifacts = babelServiceClient.postArtifact(babelRequest, distributionId);
+
+ List<Artifact> 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;
- private final BabelServiceClient babelServiceClient;
- private final BabelArtifactConverter babelArtifactConverter;
+ } 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());
+ }
+ }
- public BabelArtifactService(BabelServiceClient babelServiceClient, BabelArtifactConverter babelArtifactConverter) {
- this.babelServiceClient = babelServiceClient;
- this.babelArtifactConverter = babelArtifactConverter;
- }
+ 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;
+ }
+ }
- public void invokeBabelService(List<Artifact> modelArtifacts, List<Artifact> catalogArtifacts, 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<BabelArtifact> babelArtifacts =
- babelServiceClient.postArtifact(babelRequest, distributionId);
-
- // Sort Babel artifacts based on type
- Map<ArtifactType, List<BabelArtifact>> artifactMap =
- babelArtifacts.stream().collect(Collectors.groupingBy(BabelArtifact::getType));
-
- if (artifactMap.containsKey(BabelArtifact.ArtifactType.MODEL)) {
- modelArtifacts.addAll(
- babelArtifactConverter.convertToModel(artifactMap.get(BabelArtifact.ArtifactType.MODEL)));
- artifactMap.remove(BabelArtifact.ArtifactType.MODEL);
- }
-
- if (artifactMap.containsKey(BabelArtifact.ArtifactType.VNFCATALOG)) {
- catalogArtifacts.addAll(babelArtifactConverter
- .convertToCatalog(artifactMap.get(BabelArtifact.ArtifactType.VNFCATALOG)));
- artifactMap.remove(BabelArtifact.ArtifactType.VNFCATALOG);
- }
-
- // Log unexpected artifact types
- if (!artifactMap.isEmpty()) {
- logger.warn(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR,
- babelRequest.getArtifactName() + " " + babelRequest.getArtifactVersion()
- + ". Unexpected artifact types returned by the babel service: "
- + artifactMap.keySet().toString());
- }
-
- } 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());
- }
- }
-
-}
+}
\ No newline at end of file
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * Copyright © 2017-2018 European Software Marketing Ltd.
+ * Copyright © 2025 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.
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-package org.onap.aai.modelloader.restclient;
+package org.onap.aai.modelloader.config;
-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;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
-/**
- * Mocked Client for interfacing with Babel.
- *
- */
-public class MockBabelServiceClient implements BabelServiceClient {
-
- public MockBabelServiceClient(ModelLoaderConfig config) throws BabelServiceClientException {}
+import lombok.Getter;
+import lombok.Setter;
- @Override
- public List<BabelArtifact> postArtifact(BabelRequest babelRequest, String transactionId)
- throws BabelServiceClientException {
- return Collections.emptyList();
- }
+@Getter
+@Setter
+@Component
+@ConfigurationProperties(prefix = "ml.aai")
+public class AaiProperties {
+ private String baseUrl;
+ private String modelUrl;
+ private String namedQueryUrl;
+ private String vnfImageUrl;
+ private String authUser;
+ private String authPassword;
+ private boolean useGizmo;
}
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * Copyright © 2017-2018 European Software Marketing Ltd.
+ * Copyright © 2025 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.
* limitations under the License.
* ============LICENSE_END=========================================================
*/
+package org.onap.aai.modelloader.config;
-package org.onap.aai.modelloader.service;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
-import org.onap.aai.modelloader.config.ModelLoaderConfig;
-import org.onap.aai.modelloader.restclient.BabelServiceClient;
-import org.onap.aai.modelloader.restclient.BabelServiceClientException;
+import lombok.Getter;
+import lombok.Setter;
-public interface BabelServiceClientFactory {
- public BabelServiceClient create(ModelLoaderConfig config) throws BabelServiceClientException;
+@Getter
+@Setter
+@Component
+@ConfigurationProperties(prefix = "ml.babel")
+public class BabelProperties {
+ private String baseUrl;
+ private String generateArtifactsUrl;
}
import java.util.Timer;
import java.util.TimerTask;
+import javax.annotation.PreDestroy;
+
import org.onap.aai.cl.api.Logger;
import org.onap.aai.cl.eelf.LoggerFactory;
import org.onap.aai.modelloader.notification.EventCallback;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
+import lombok.RequiredArgsConstructor;
+
@Configuration
+@RequiredArgsConstructor
@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 IDistributionClient distributionClient;
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);
+ initResult = distributionClient.init(config, eventCallback);
if (initResult.getDistributionActionResult() == DistributionActionResultEnum.SUCCESS) {
// Start distribution client
logger.debug(ModelLoaderMsgs.INITIALIZING, "Starting distribution client...");
- IDistributionClientResult startResult = client.start();
+ IDistributionClientResult startResult = distributionClient.start();
if (startResult.getDistributionActionResult() == DistributionActionResultEnum.SUCCESS) {
logger.info(ModelLoaderMsgs.INITIALIZING, "Connection to SDC established");
} else {
// Kick off a timer to retry the SDC connection
Timer timer = new Timer();
- TimerTask task = new SdcConnectionJob(client, config, eventCallback, timer);
+ TimerTask task = new SdcConnectionJob(distributionClient, config, eventCallback, timer);
timer.schedule(task, new Date(), 60000);
}
} else {
// Kick off a timer to retry the SDC connection
Timer timer = new Timer();
- TimerTask task = new SdcConnectionJob(client, config, eventCallback, timer);
+ TimerTask task = new SdcConnectionJob(distributionClient, config, eventCallback, timer);
timer.schedule(task, new Date(), 60000);
}
}
+
+ @PreDestroy
+ public void destroy() {
+ logger.info(ModelLoaderMsgs.STOPPING_CLIENT);
+ if (distributionClient != null) {
+ distributionClient.stop();
+ }
+ }
}
package org.onap.aai.modelloader.config;
-import java.io.File;
import java.nio.file.Path;
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;
// Configuration file structure
public static final String PREFIX_MODEL_LOADER_CONFIG = "ml";
public static final String PREFIX_DISTRIBUTION_CLIENT = PREFIX_MODEL_LOADER_CONFIG + ".distribution.";
- public static final String PREFIX_AAI = PREFIX_MODEL_LOADER_CONFIG + ".aai.";
- public static final String PREFIX_BABEL = PREFIX_MODEL_LOADER_CONFIG + ".babel.";
public static final String PREFIX_DEBUG = PREFIX_MODEL_LOADER_CONFIG + ".debug.";
private static final String SUFFIX_KEYSTORE_FILE = "KEYSTORE_FILE";
private static final String SUFFIX_KEYSTORE_PASS = "KEYSTORE_PASSWORD";
- private static final String SUFFIX_TRUSTSTORE_FILE = "TRUSTSTORE_FILE";
- private static final String SUFFIX_TRUSTSTORE_PASS = "TRUSTSTORE_PASSWORD";
-
// Configuration file properties
protected static final String PROP_ML_DISTRIBUTION_ACTIVE_SERVER_TLS_AUTH =
PREFIX_DISTRIBUTION_CLIENT + "ACTIVE_SERVER_TLS_AUTH";
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;
- protected static final String PROP_AAI_MODEL_RESOURCE_URL = PREFIX_AAI + "MODEL_URL";
- protected static final String PROP_AAI_NAMED_QUERY_RESOURCE_URL = PREFIX_AAI + "NAMED_QUERY_URL";
- protected static final String PROP_AAI_VNF_IMAGE_RESOURCE_URL = PREFIX_AAI + "VNF_IMAGE_URL";
- protected static final String PROP_AAI_AUTHENTICATION_USER = PREFIX_AAI + "AUTH_USER";
- protected static final String PROP_AAI_AUTHENTICATION_PASSWORD = PREFIX_AAI + "AUTH_PASSWORD";
- protected static final String PROP_AAI_USE_GIZMO = PREFIX_AAI + "USE_GIZMO";
- protected static final String PROP_AAI_USE_HTTPS = PREFIX_AAI + "USE_HTTPS";
- protected static final String PROP_BABEL_BASE_URL = PREFIX_BABEL + "BASE_URL";
- protected static final String PROP_BABEL_KEYSTORE_FILE = PREFIX_BABEL + SUFFIX_KEYSTORE_FILE;
- protected static final String PROP_BABEL_KEYSTORE_PASSWORD = PREFIX_BABEL + SUFFIX_KEYSTORE_PASS;
- protected static final String PROP_BABEL_TRUSTSTORE_FILE = PREFIX_BABEL + SUFFIX_TRUSTSTORE_FILE;
- protected static final String PROP_BABEL_TRUSTSTORE_PASSWORD = PREFIX_BABEL + SUFFIX_TRUSTSTORE_PASS;
- protected static final String PROP_BABEL_GENERATE_RESOURCE_URL = PREFIX_BABEL + "GENERATE_ARTIFACTS_URL";
- protected static final String PROP_BABEL_USE_HTTPS = PREFIX_BABEL + "USE_HTTPS";
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;
private String certLocation = ".";
return getIntegerPropertyOrZero(PROP_ML_DISTRIBUTION_HTTPS_PROXY_PORT);
}
- public String getAaiKeyStorePath() {
- return certLocation + File.separator + modelLoaderProperties.getProperty(PROP_AAI_KEYSTORE_FILE);
- }
-
- public String getBabelKeyStorePath() {
- String filename = get(PROP_BABEL_KEYSTORE_FILE);
- if (filename == null) {
- return null;
- } else {
- return certLocation + File.separator + filename;
- }
- }
-
- public String getAaiKeyStorePassword() {
- return getDeobfuscatedValue(get(PROP_AAI_KEYSTORE_PASSWORD));
- }
-
- public String getBabelKeyStorePassword() {
- return getDeobfuscatedValue(get(PROP_BABEL_KEYSTORE_PASSWORD));
- }
-
- public String getBabelTrustStorePath() {
- String filename = get(PROP_BABEL_TRUSTSTORE_FILE);
- if (filename == null) {
- return null;
- } else {
- return certLocation + File.separator + filename;
- }
- }
-
- public String getBabelTrustStorePassword() {
- return getDeobfuscatedValue(get(PROP_BABEL_TRUSTSTORE_PASSWORD));
- }
-
- public String getAaiBaseUrl() {
- return get(PROP_AAI_BASE_URL);
- }
-
- public String getBabelBaseUrl() {
- return get(PROP_BABEL_BASE_URL);
- }
-
- public String getBabelGenerateArtifactsUrl() {
- return get(PROP_BABEL_GENERATE_RESOURCE_URL);
- }
-
- public String getAaiModelUrl(String version) {
- setModelVersion(version);
- return updatePropertyOXMVersion(PROP_AAI_MODEL_RESOURCE_URL, version);
- }
-
- public String getAaiNamedQueryUrl(String version) {
- return updatePropertyOXMVersion(PROP_AAI_NAMED_QUERY_RESOURCE_URL, version);
- }
-
- public String getAaiVnfImageUrl() {
- return updatePropertyOXMVersion(PROP_AAI_VNF_IMAGE_RESOURCE_URL, getModelVersion());
- }
-
- public String getAaiAuthenticationUser() {
- return get(PROP_AAI_AUTHENTICATION_USER);
- }
public String getModelVersion() {
return modelVersion;
this.modelVersion = modelVersion;
}
- public boolean useGizmo() {
- String useGizmo = get(PROP_AAI_USE_GIZMO);
- return useGizmo != null && useGizmo.equalsIgnoreCase("true");
- }
-
- public boolean useHttpsWithAAI() {
- String useHttps = get(PROP_AAI_USE_HTTPS);
- return useHttps != null && useHttps.equalsIgnoreCase("true");
- }
-
- public boolean useHttpsWithBabel() {
- String useHttps = get(PROP_BABEL_USE_HTTPS);
- return useHttps != null && useHttps.equalsIgnoreCase("true");
- }
-
- /**
- * @return password for AAI authentication that has been reverse-engineered from its obfuscated form.
- */
- public String getAaiAuthenticationPassword() {
- String password = getDeobfuscatedValue(get(PROP_AAI_AUTHENTICATION_PASSWORD));
-
- if (password != null && password.isEmpty()) {
- password = null;
- }
-
- return password;
- }
-
/**
* @return a boolean value indicating whether the simulator is enabled.
*/
return propValue != null && "enabled".equalsIgnoreCase(propValue);
}
- /**
- * Read the value of the property and replace any wildcard OXM version "v*" with the supplied default OXM version
- *
- * @param propertyName
- * the name of the property storing the OXM version (possibly containing v*)
- * @param version
- * the default OXM version
- * @return the String value of the defined property (with any wildcard OXM version defaulted)
- */
- private String updatePropertyOXMVersion(String propertyName, String version) {
- String value = get(propertyName);
- if (version != null && value != null) {
- value = value.replace("v*", version);
- }
- return value;
- }
-
/**
* @return a boolean value indicating whether model loader is connected to ASDC.
*/
}
}
- 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");
package org.onap.aai.modelloader.entity;\r
\r
import java.util.List;\r
-import org.onap.aai.modelloader.config.ModelLoaderConfig;\r
+\r
+import org.onap.aai.modelloader.config.AaiProperties;\r
import org.onap.aai.modelloader.restclient.AaiRestClient;\r
-import org.springframework.web.client.RestTemplate;\r
\r
public abstract class ArtifactHandler {\r
\r
- protected ModelLoaderConfig config;\r
+ protected final AaiProperties aaiProperties;\r
\r
- protected ArtifactHandler(ModelLoaderConfig config) {\r
- this.config = config;\r
+ protected ArtifactHandler(AaiProperties aaiProperties) {\r
+ this.aaiProperties = aaiProperties;\r
}\r
\r
public abstract boolean pushArtifacts(List<Artifact> artifacts, String distributionId,\r
import org.apache.http.client.utils.URIBuilder;\r
import org.onap.aai.cl.api.Logger;\r
import org.onap.aai.cl.eelf.LoggerFactory;\r
-import org.onap.aai.modelloader.config.ModelLoaderConfig;\r
+import org.onap.aai.modelloader.config.AaiProperties;\r
import org.onap.aai.modelloader.entity.Artifact;\r
import org.onap.aai.modelloader.entity.ArtifactHandler;\r
import org.onap.aai.modelloader.entity.vnf.VnfImages;\r
import org.springframework.http.MediaType;\r
import org.springframework.http.ResponseEntity;\r
import org.springframework.stereotype.Component;\r
-import org.springframework.web.client.RestTemplate;\r
import org.w3c.dom.Document;\r
import org.w3c.dom.Element;\r
import org.w3c.dom.Node;\r
\r
public static final String ATTR_UUID = "uuid";\r
\r
- public VnfCatalogArtifactHandler(ModelLoaderConfig config) {\r
- super(config);\r
+ public VnfCatalogArtifactHandler(AaiProperties aaiProperties) {\r
+ super(aaiProperties);\r
}\r
\r
/*\r
* (non-Javadoc)\r
- * \r
+ *\r
* @see org.openecomp.modelloader.entity.ArtifactHandler#pushArtifacts(java.util.List, java.lang.String)\r
*/\r
@Override\r
for (Artifact completedArtifact : completedArtifacts) {\r
Map<String, String> data = new Gson().fromJson(completedArtifact.getPayload(),\r
new TypeToken<Map<String, String>>() {}.getType());\r
- String url = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/" + data.get(ATTR_UUID);\r
+ String url = aaiProperties.getBaseUrl() + aaiProperties.getVnfImageUrl() + "/vnf-image/" + data.get(ATTR_UUID);\r
// Try to delete the image. If something goes wrong we can't really do anything here\r
aaiClient.getAndDeleteResource(url, distributionId);\r
}\r
\r
/**\r
* Build a VNF image from each of the supplied data items, and distribute to AAI\r
- * \r
+ *\r
* @param restClient\r
* @param distributionId\r
* @param completedArtifacts\r
private int getVnfImage(AaiRestClient restClient, String distributionId, String imageId,\r
Map<String, String> dataItem) throws VnfImageException {\r
try {\r
- URIBuilder b = new URIBuilder(config.getAaiBaseUrl() + config.getAaiVnfImageUrl());\r
+ URIBuilder b = new URIBuilder(aaiProperties.getBaseUrl() + aaiProperties.getVnfImageUrl());\r
for (Entry<String, String> entry : dataItem.entrySet()) {\r
b.addParameter(entry.getKey(), entry.getValue());\r
}\r
\r
// TODO: Get rid of the dataItem map and replace it with the VnfImage object\r
String payload = new Gson().toJson(dataItem);\r
- String putUrl = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/" + uuid;\r
+ String putUrl = aaiProperties.getBaseUrl() + aaiProperties.getVnfImageUrl() + "/vnf-image/" + uuid;\r
ResponseEntity<String> putResp =\r
restClient.putResource(putUrl, payload, distributionId, MediaType.APPLICATION_JSON, String.class);\r
return putResp != null && putResp.getStatusCode() == HttpStatus.CREATED;\r
\r
/**\r
* Parse the VNF Catalog XML and transform into Key/Value pairs.\r
- * \r
+ *\r
* @param vnfcArtifact\r
* @return VNF Image data in Map form\r
* @throws VnfImageException\r
import java.util.Set;
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.config.AaiProperties;
import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.modelloader.entity.ArtifactType;
import org.onap.aai.modelloader.restclient.AaiRestClient;
public abstract String getUniqueIdentifier();
- public abstract boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
+ public abstract boolean push(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId,
List<Artifact> completedArtifacts);
- public abstract void rollbackModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId);
+ public abstract void rollbackModel(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId);
- protected boolean pushToGizmo(AaiRestClient aaiClient, ModelLoaderConfig config, String distId) {
+ protected boolean pushToGizmo(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId) {
try {
String gizmoPayload = GizmoTranslator.translate(getPayload());
// TODO: Use correct responseType here
- ResponseEntity<String> postResponse = aaiClient.postResource(config.getAaiBaseUrl().trim(), gizmoPayload, distId,
+ ResponseEntity<String> postResponse = aaiClient.postResource(aaiProperties.getBaseUrl().trim(), gizmoPayload, distId,
MediaType.APPLICATION_JSON, String.class);
if (postResponse.getStatusCode() != HttpStatus.OK) {
IModelArtifact model = parseModel(doc.getDocumentElement(), artifactPayload);
- if (!processParsedModel(modelList, artifactName, model)) {
+ boolean success = processParsedModel(modelList, artifactName, model);
+ if (!success) {
modelList = null;
}
} catch (Exception ex) {
package org.onap.aai.modelloader.entity.model;
import java.util.List;
-import org.onap.aai.modelloader.config.ModelLoaderConfig;
+
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.cl.eelf.LoggerFactory;
+import org.onap.aai.modelloader.config.AaiProperties;
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.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 ";
* @return true if the resource PUT as XML media was successful (status OK)
*/
private boolean putXmlResource(AaiRestClient aaiClient, String distId, String resourceUrl, String payload) {
- ResponseEntity<String> putResponse =
- aaiClient.putResource(resourceUrl, payload, distId, MediaType.APPLICATION_XML, String.class);
+ ResponseEntity<String> 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
- public boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
+ public boolean push(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId,
List<Artifact> completedArtifacts) {
- if (config.useGizmo()) {
- return pushToGizmo(aaiClient, config, distId);
+ if (aaiProperties.isUseGizmo()) {
+ return pushToGizmo(aaiClient, aaiProperties, distId);
}
- return pushToResources(aaiClient, config, distId, completedArtifacts);
+ return pushToResources(aaiClient, aaiProperties, distId, completedArtifacts);
}
- private boolean pushToResources(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
+ private boolean pushToResources(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId,
List<Artifact> completedArtifacts) {
boolean success = false;
// See whether the model is already present
- String resourceUrl = getModelUrl(config);
+ String resourceUrl = getModelUrl(aaiProperties);
// ResponseEntity<Model> result;
boolean modelExists = checkIfModelExists(aaiClient, distId, resourceUrl);
if(modelExists) {
- success = updateExistingModel(aaiClient, config, distId, completedArtifacts);
+ success = updateExistingModel(aaiClient, aaiProperties, distId, completedArtifacts);
} else {
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;
}
logErrorMsg(FAILURE_MSG_PREFIX + getType() + " " + getUniqueIdentifier() + " " + message + ROLLBACK_MSG_SUFFIX);
}
- private boolean updateExistingModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
+ private boolean updateExistingModel(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId,
List<Artifact> completedArtifacts) {
boolean success;
logInfoMsg(getType() + " " + getModelInvariantId() + " already exists. Skipping ingestion.");
- success = pushModelVersion(aaiClient, config, distId, completedArtifacts);
+ success = pushModelVersion(aaiClient, aaiProperties, distId, completedArtifacts);
return success;
}
/**
* @param aaiClient
- * @param config
+ * @param aaiProperties
* @param distId
* @param completedArtifacts
* @return
*/
- private boolean pushModelVersion(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
+ private boolean pushModelVersion(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId,
List<Artifact> completedArtifacts) {
- if (xmlResourceCanBeFetched(aaiClient, distId, getModelVerUrl(config))) {
+ if (xmlResourceCanBeFetched(aaiClient, distId, getModelVerUrl(aaiProperties))) {
logInfoMsg(getType() + " " + getUniqueIdentifier() + " already exists. Skipping ingestion.");
return true;
}
// Load the model version
boolean success = true;
- success = putXmlResource(aaiClient, distId, getModelVerUrl(config), getModelVer());
+ success = putXmlResource(aaiClient, distId, getModelVerUrl(aaiProperties), getModelVer());
if (success) {
completedArtifacts.add(this);
logInfoMsg(getType() + " " + getUniqueIdentifier() + " successfully ingested.");
@Override
- public void rollbackModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId) {
+ public void rollbackModel(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId) {
// Gizmo is resilient and doesn't require a rollback. A redistribution will work fine even if
// the model is partially loaded.
- if (config.useGizmo()) {
+ if (aaiProperties.isUseGizmo()) {
return;
}
- String url = getModelVerUrl(config);
+ String url = getModelVerUrl(aaiProperties);
if (firstVersionOfModel) {
// If this was the first version of the model which was added, we want to remove the entire
// model rather than just the version.
- url = getModelUrl(config);
+ url = getModelUrl(aaiProperties);
}
// Best effort to delete. Nothing we can do in the event this fails.
aaiClient.getAndDeleteResource(url, distId);
}
- private String getModelUrl(ModelLoaderConfig config) {
- String baseURL = config.getAaiBaseUrl().trim();
- String subURL = config.getAaiModelUrl(getModelNamespaceVersion()).trim();
+ private String getModelUrl(AaiProperties aaiProperties) {
+ String baseURL = aaiProperties.getBaseUrl().trim();
+ String subURL = String.format(aaiProperties.getModelUrl(), getModelNamespaceVersion()).trim();
String instance = getModelInvariantId();
if (!baseURL.endsWith("/") && !subURL.startsWith("/")) {
return baseURL + subURL + instance;
}
- private String getModelVerUrl(ModelLoaderConfig config) {
- String baseURL = config.getAaiBaseUrl().trim();
- String subURL = config.getAaiModelUrl(getModelNamespaceVersion()).trim() + getModelInvariantId()
+ private String getModelVerUrl(AaiProperties aaiProperties) {
+ String baseURL = aaiProperties.getBaseUrl().trim();
+ String subURL = String.format(aaiProperties.getModelUrl(), getModelNamespaceVersion()).trim() + getModelInvariantId()
+ AAI_MODEL_VER_SUB_URL;
String instance = getModelVerId();
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.config.AaiProperties;
import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.modelloader.entity.ArtifactHandler;
import org.onap.aai.modelloader.restclient.AaiRestClient;
private static Logger logger = LoggerFactory.getInstance().getLogger(ModelArtifactHandler.class.getName());
- public ModelArtifactHandler(ModelLoaderConfig config) {
- super(config);
+ public ModelArtifactHandler(AaiProperties aaiProperties) {
+ super(aaiProperties);
}
@Override
// Push the ordered list of model artifacts to A&AI. If one fails, we need to roll back the changes.
for (Artifact art : sortedModelArtifacts) {
AbstractModelArtifact model = (AbstractModelArtifact) art;
- if (!model.push(aaiClient, config, distributionID, completedArtifacts)) {
+ if (!model.push(aaiClient, aaiProperties, distributionID, completedArtifacts)) {
return false;
}
}
public void rollback(List<Artifact> completedArtifacts, String distributionId, AaiRestClient aaiClient) {
for (Artifact artifactToDelete : completedArtifacts) {
AbstractModelArtifact model = (AbstractModelArtifact) artifactToDelete;
- model.rollbackModel(aaiClient, config, distributionId);
+ model.rollbackModel(aaiClient, aaiProperties, distributionId);
}
}
}
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";
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;
/**
*/
public class ModelSorter {
+ private static Logger logger = LoggerFactory.getInstance().getLogger(ModelSorter.class);
+
/**
* Wraps a Model object to form dependencies other Models using Edges.
*/
// 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);
import java.util.List;
-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.config.AaiProperties;
import org.onap.aai.modelloader.entity.Artifact;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
}
@Override
- public boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, List<Artifact> completedArtifacts) {
- if (config.useGizmo()) {
- return pushToGizmo(aaiClient, config, distId);
+ public boolean push(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId, List<Artifact> completedArtifacts) {
+ if (aaiProperties.isUseGizmo()) {
+ return pushToGizmo(aaiClient, aaiProperties, distId);
}
- return pushToResources(aaiClient, config, distId, completedArtifacts);
+ return pushToResources(aaiClient, aaiProperties, distId, completedArtifacts);
}
- private boolean pushToResources(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
+ private boolean pushToResources(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId,
List<Artifact> completedArtifacts) {
ResponseEntity<String> getResponse =
- aaiClient.getResource(getNamedQueryUrl(config), distId, MediaType.APPLICATION_XML, String.class);
+ aaiClient.getResource(getNamedQueryUrl(aaiProperties), distId, MediaType.APPLICATION_XML, String.class);
if (getResponse == null || getResponse.getStatusCode() != HttpStatus.OK) {
// Only attempt the PUT if the model doesn't already exist
- ResponseEntity<String> putResponse = aaiClient.putResource(getNamedQueryUrl(config), getPayload(), distId,
+ ResponseEntity<String> putResponse = aaiClient.putResource(getNamedQueryUrl(aaiProperties), getPayload(), distId,
MediaType.APPLICATION_XML, String.class);
if (putResponse != null && putResponse.getStatusCode() == HttpStatus.CREATED) {
completedArtifacts.add(this);
}
@Override
- public void rollbackModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId) {
- // Gizmo is resilient and doesn't require a rollback. A redistribution will work fine even if
+ public void rollbackModel(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId) {
+ // Gizmo is resilient and doesn't require a rollback. A redistribution will work fine even if
// the model is partially loaded.
- if (config.useGizmo()) {
+ if (aaiProperties.isUseGizmo()) {
return;
}
-
+
// Best effort to delete. Nothing we can do in the event this fails.
- aaiClient.getAndDeleteResource(getNamedQueryUrl(config), distId);
+ aaiClient.getAndDeleteResource(getNamedQueryUrl(aaiProperties), distId);
}
- private String getNamedQueryUrl(ModelLoaderConfig config) {
- String baseURL = config.getAaiBaseUrl().trim();
- String subURL = config.getAaiNamedQueryUrl(getModelNamespaceVersion()).trim();
+ private String getNamedQueryUrl(AaiProperties aaiProperties) {
+ String baseURL = aaiProperties.getBaseUrl().trim();
+ String subURL = String.format(aaiProperties.getNamedQueryUrl(), getModelNamespaceVersion()).trim();
String instance = this.getNamedQueryUuid();
if (!baseURL.endsWith("/") && !subURL.startsWith("/")) {
List<Artifact> vnfcFiles = new ArrayList<>();
try (SeekableInMemoryByteChannel inMemoryByteChannel = new SeekableInMemoryByteChannel(archive);
- ZipFile zipFile = new ZipFile(inMemoryByteChannel)) {
+ ZipFile zipFile = ZipFile.builder().setSeekableByteChannel(inMemoryByteChannel).get()) {
for (Enumeration<ZipArchiveEntry> enumeration = zipFile.getEntries(); enumeration.hasMoreElements();) {
ZipArchiveEntry entry = enumeration.nextElement();
if (fileShouldBeExtracted(entry)) {
return extractFile;
}
}
-
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
+import java.util.stream.Collectors;
+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.MdcOverride;
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.IModelParser;
import org.onap.aai.modelloader.entity.model.NamedQueryArtifactParser;
* @param modelArtifacts collection of artifacts for model query specs
* @param catalogArtifacts collection of artifacts that represent vnf catalog files
* @return boolean <code>true</code> if the download process was successful otherwise <code>false</code>
+ * @throws Exception
*/
- boolean downloadArtifacts(INotificationData data, List<IArtifactInfo> artifacts, List<Artifact> modelArtifacts,
- List<Artifact> catalogArtifacts) {
- boolean success = true;
+ List<Artifact> downloadArtifacts(INotificationData data, List<IArtifactInfo> artifacts) throws Exception {
+ List<Artifact> allArtifacts = new ArrayList<>();
for (IArtifactInfo artifact : artifacts) {
try {
IDistributionClientDownloadResult downloadResult = downloadIndividualArtifacts(data, artifact);
- processDownloadedArtifacts(modelArtifacts, catalogArtifacts, artifact, downloadResult, data);
+ List<Artifact> processedArtifacts = processDownloadedArtifacts(artifact, downloadResult, data);
+ allArtifacts.addAll(processedArtifacts);
} catch (DownloadFailureException e) {
notificationPublisher.publishDownloadFailure(client, data, artifact, e.getMessage());
- success = false;
- } catch (Exception e) {
+ throw e;
+ } catch (ProcessToscaArtifactsException | InvalidArchiveException | BabelArtifactParsingException e) {
notificationPublisher.publishDeployFailure(client, data, artifact);
- success = false;
- }
-
- if (!success) {
- break;
+ throw e;
}
}
-
- return success;
+ return allArtifacts;
}
private IDistributionClientDownloadResult downloadIndividualArtifacts(INotificationData data,
return downloadResult;
}
- private void processDownloadedArtifacts(List<Artifact> modelArtifacts, List<Artifact> catalogArtifacts,
+ private List<Artifact> processDownloadedArtifacts(
IArtifactInfo artifactInfo, IDistributionClientDownloadResult downloadResult, INotificationData data)
throws ProcessToscaArtifactsException, InvalidArchiveException, BabelArtifactParsingException {
+ List<Artifact> artifacts = new ArrayList<>();
+ List<Artifact> querySpecArtifacts = new ArrayList<>();
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);
+ querySpecArtifacts = processModelQuerySpecArtifact(downloadResult);
} else {
logger.info(ModelLoaderMsgs.UNSUPPORTED_ARTIFACT_TYPE, artifactInfo.getArtifactName(),
artifactInfo.getArtifactType());
throw new InvalidArchiveException("Unsupported artifact type: " + artifactInfo.getArtifactType());
}
+ return Stream
+ .concat(artifacts.stream(), querySpecArtifacts.stream())
+ .collect(Collectors.toList());
}
- public void processToscaArtifacts(List<Artifact> modelArtifacts, List<Artifact> catalogArtifacts, byte[] payload,
- IArtifactInfo artifactInfo, String distributionId, String serviceVersion)
+ public List<Artifact> processToscaArtifacts(byte[] payload, IArtifactInfo artifactInfo, String distributionId, String serviceVersion)
throws ProcessToscaArtifactsException, InvalidArchiveException {
// Get translated artifacts from Babel Service
BabelRequest babelRequest = new BabelRequest();
babelRequest.setArtifactName(artifactInfo.getArtifactName());
babelRequest.setCsar(Base64.getEncoder().encodeToString(payload));
babelRequest.setArtifactVersion(serviceVersion);
- babelArtifactService.invokeBabelService(modelArtifacts, catalogArtifacts, babelRequest, distributionId);
+ List<Artifact> artifacts = babelArtifactService.invokeBabelService(babelRequest, distributionId);
// Get VNF Catalog artifacts directly from CSAR
List<Artifact> 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);
}
+ return Stream
+ .concat(artifacts.stream(), csarCatalogArtifacts.stream())
+ .collect(Collectors.toList());
+
}
- private void processModelQuerySpecArtifact(List<Artifact> modelArtifacts,
- IDistributionClientDownloadResult downloadResult) throws BabelArtifactParsingException {
+ private boolean isDuplicateVnfCatalogData(List<Artifact> babelArtifacts, List<Artifact> csarCatalogArtifacts) {
+ boolean babelIsEmpty = babelArtifacts.stream()
+ .filter(VnfCatalogArtifact.class::isInstance)
+ .findAny().isEmpty();
+ return !csarCatalogArtifacts.isEmpty() && !babelIsEmpty;
+ }
+
+ private List<Artifact> processModelQuerySpecArtifact(IDistributionClientDownloadResult downloadResult) throws BabelArtifactParsingException {
logger.debug(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Processing named query artifact.");
IModelParser parser = new NamedQueryArtifactParser();
List<Artifact> parsedArtifacts =
parser.parse(new String(downloadResult.getArtifactPayload()), downloadResult.getArtifactFilename());
- if (parsedArtifactsExist(parsedArtifacts)) {
- modelArtifacts.addAll(parsedArtifacts);
+ if (parsedArtifacts != null && !parsedArtifacts.isEmpty()) {
+ return parsedArtifacts;
} else {
throw new BabelArtifactParsingException(
"Could not parse generated XML: " + new String(downloadResult.getArtifactPayload()));
}
}
-
- private boolean parsedArtifactsExist(List<Artifact> parsedArtifacts) {
- return parsedArtifacts != null && !parsedArtifacts.isEmpty();
- }
}
*/
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;
@Component
public class BabelArtifactConverter {
+ private final ModelArtifactParser modelArtifactParser;
+
+ public BabelArtifactConverter(ModelArtifactParser modelArtifactParser) {
+ this.modelArtifactParser = modelArtifactParser;
+ }
+
/**
* This method converts BabelArtifacts into instances of {@link ModelArtifact}.
*
* @throws BabelArtifactParsingException if an error occurs trying to parse the generated XML files that were
* converted from tosca artifacts
*/
- public List<Artifact> convertToModel(List<BabelArtifact> xmlArtifacts) throws BabelArtifactParsingException {
- Objects.requireNonNull(xmlArtifacts);
- List<Artifact> modelArtifacts = new ArrayList<>();
- ModelArtifactParser modelArtParser = new ModelArtifactParser();
-
- // Parse TOSCA payloads
- for (BabelArtifact xmlArtifact : xmlArtifacts) {
-
- List<Artifact> 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<Artifact> convertToModel(BabelArtifact babelArtifact) throws BabelArtifactParsingException {
+ Objects.requireNonNull(babelArtifact);
+ List<Artifact> 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;
}
/**
* @param xmlArtifacts xml artifacts to be parsed
* @return List<org.openecomp.modelloader.entity.Artifact> list of converted catalog artifacts
*/
- public List<Artifact> convertToCatalog(List<BabelArtifact> xmlArtifacts) {
- Objects.requireNonNull(xmlArtifacts);
- List<Artifact> 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
import org.onap.aai.cl.eelf.LoggerFactory;
import org.onap.aai.cl.mdc.MdcContext;
import org.onap.aai.modelloader.entity.Artifact;
+import org.onap.aai.modelloader.entity.ArtifactType;
import org.onap.aai.modelloader.extraction.ArtifactInfoExtractor;
import org.onap.aai.modelloader.service.ArtifactDeploymentManager;
import org.onap.aai.modelloader.service.ModelLoaderMsgs;
logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Received distribution " + data.getDistributionID());
List<IArtifactInfo> artifacts = new ArtifactInfoExtractor().extract(data);
+ boolean success = true;
+ List<Artifact> downloadedArtifacts = new ArrayList<>();
+ try {
+ downloadedArtifacts =
+ artifactDownloadManager.downloadArtifacts(data, artifacts);
+ } catch (Exception e) {
+ success = false;
+ }
+
List<Artifact> catalogArtifacts = new ArrayList<>();
List<Artifact> modelArtifacts = new ArrayList<>();
-
- boolean success =
- artifactDownloadManager.downloadArtifacts(data, artifacts, modelArtifacts, catalogArtifacts);
+ if(downloadedArtifacts != null) {
+ for(Artifact artifact : downloadedArtifacts) {
+ if(artifact.getType() == ArtifactType.VNF_CATALOG || artifact.getType() == ArtifactType.VNF_CATALOG_XML) {
+ catalogArtifacts.add(artifact);
+ } else {
+ modelArtifacts.add(artifact);
+ }
+ }
+ }
if (success) {
- success = artifactDeploymentManager.deploy(data, modelArtifacts, catalogArtifacts);
+ success = artifactDeploymentManager.deploy(data.getDistributionID(), modelArtifacts, catalogArtifacts);
}
String statusString = success ? "SUCCESS" : "FAILURE";
import java.util.Collections;
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.config.AaiProperties;
import org.onap.aai.modelloader.entity.AaiResourcesObject;
import org.onap.aai.modelloader.service.ModelLoaderMsgs;
import org.springframework.http.HttpEntity;
@Component
public class AaiRestClient {
+ private final AaiProperties aaiProperties;
+
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;
- public AaiRestClient(ModelLoaderConfig config, RestTemplate restTemplate) {
- this.config = config;
+ public AaiRestClient(AaiProperties aaiProperties, RestTemplate restTemplate) {
+ this.aaiProperties = aaiProperties;
this.restTemplate = restTemplate;
}
private boolean useBasicAuth() {
- return config.getAaiAuthenticationUser() != null && config.getAaiAuthenticationPassword() != null;
+ return aaiProperties.getAuthUser() != null && aaiProperties.getAuthPassword() != null;
}
/**
* Create the HTTP headers required for an A&AI operation (GET/POST/PUT/DELETE)
- *
+ *
* @param transId
* @return map of headers
*/
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());
+ headers.setBasicAuth(aaiProperties.getAuthUser(), aaiProperties.getAuthPassword());
}
return headers;
}
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.config.BabelProperties;
import org.onap.aai.modelloader.service.ModelLoaderMsgs;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
+import lombok.RequiredArgsConstructor;
+
/**
* HTTPS Client for interfacing with Babel.
*
*/
@Component
+@RequiredArgsConstructor
public class BabelServiceClientImpl implements BabelServiceClient {
private static final Logger logger = LoggerFactory.getInstance().getLogger(BabelServiceClientImpl.class);
- private final ModelLoaderConfig config;
+ private final BabelProperties babelProperties;
private final RestTemplate restTemplate;
- public BabelServiceClientImpl(ModelLoaderConfig config, RestTemplate restTemplate) {
- this.config = config;
- this.restTemplate = restTemplate;
- }
-
@Override
public List<BabelArtifact> postArtifact(BabelRequest babelRequest, String transactionId) throws BabelServiceClientException {
- if (logger.isInfoEnabled()) {
- logger.info(ModelLoaderMsgs.BABEL_REST_REQUEST_PAYLOAD, " Artifact Name: " + babelRequest.getArtifactName()
+ 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();
+ String resourceUrl = babelProperties.getBaseUrl() + babelProperties.getGenerateArtifactsUrl();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
import java.util.ArrayList;
import java.util.List;
+
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;
/**
/**
* 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 <code>true</code> if all deployments were successful otherwise <code>false</code>
*/
- public boolean deploy(final INotificationData data, final List<Artifact> modelArtifacts,
+ public boolean deploy(final String distributionId, final List<Artifact> modelArtifacts,
final List<Artifact> catalogArtifacts) {
- String distributionId = data.getDistributionID();
-
List<Artifact> completedArtifacts = new ArrayList<>();
boolean deploySuccess =
modelArtifactHandler.pushArtifacts(modelArtifacts, distributionId, completedArtifacts, aaiClient);
return deploySuccess;
}
-}
+}
\ No newline at end of file
import java.util.Base64;
import java.util.List;
-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.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;
*/
@RestController
@RequestMapping("/services/model-loader/v1/model-service")
-public class ModelController implements ModelLoaderInterface {
+public class ModelController {
private static final Logger logger = LoggerFactory.getInstance().getLogger(ModelController.class);
this.artifactDownloadManager = artifactDownloadManager;
}
- /**
- * (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();
+ @GetMapping(value = "/loadModel/{modelid}", produces = "application/json")
+ public ResponseEntity<String> loadModel(@PathVariable String modelid) {
+ return ResponseEntity.ok("{\"model_loaded\":\"" + modelid + "\"}");
}
- /**
- * (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();
+ @PutMapping(value = "/saveModel/{modelid}/{modelname}", produces = "application/json")
+ public ResponseEntity<String> saveModel(@PathVariable String modelid, @PathVariable String modelname) {
+ return ResponseEntity.ok("{\"model_saved\":\"" + modelid + "-" + modelname + "\"}");
}
- @Override
- public Response ingestModel(@PathVariable String modelName, @PathVariable String modelVersion,
+ @PostMapping(value = "/ingestModel/{modelName}/{modelVersion}", produces = "application/json")
+ public ResponseEntity<String> ingestModel(@PathVariable String modelName, @PathVariable String modelVersion,
@RequestBody String payload) throws IOException {
- Response response;
+ ResponseEntity<String> response;
if (config.getIngestSimulatorEnabled()) {
response = processTestArtifact(modelName, modelVersion, payload);
} else {
logger.debug("Simulation interface disabled");
- response = Response.serverError().build();
+ response = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
return response;
}
- private Response processTestArtifact(String modelName, String modelVersion, String payload) {
+ private ResponseEntity<String> processTestArtifact(String modelName, String modelVersion, String payload) {
IArtifactInfo artifactInfo = new ArtifactInfoImpl();
((ArtifactInfoImpl) artifactInfo).setArtifactName(modelName);
((ArtifactInfoImpl) artifactInfo).setArtifactVersion(modelVersion);
- Response response;
+ ResponseEntity<String> response;
try {
logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Received test artifact " + modelName + " " + modelVersion);
logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Generating XML models from test artifact");
+ List<Artifact> artifacts = artifactDownloadManager.processToscaArtifacts(csarFile, artifactInfo, "test-transaction-id", modelVersion);
List<Artifact> modelArtifacts = new ArrayList<>();
List<Artifact> catalogArtifacts = new ArrayList<>();
-
- artifactDownloadManager.processToscaArtifacts(modelArtifacts,
- catalogArtifacts, csarFile, artifactInfo, "test-transaction-id", modelVersion);
+ 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, modelArtifacts, catalogArtifacts);
+ artifactDeploymentManager.deploy(notificationData.getDistributionID(), modelArtifacts, catalogArtifacts);
logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Deployment success was " + success);
- response = success ? Response.ok().build() : Response.serverError().build();
+ 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);
} else {
responseMessage += "\nSDC publishing is enabled but has been bypassed";
}
- response = Response.serverError().entity(responseMessage).type(MediaType.APPLICATION_XML).build();
+ response = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(responseMessage);
}
return response;
}
+++ /dev/null
-/**
- * ============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;
-}
# Spring Boot logging
logging.config=${logback.configurationFile}
+
+management.endpoints.web.exposure.include=*
+
+ml.babel.base-url=https://<BABEL_HOST>:9516
+ml.babel.generate-artifacts-url=/services/babel-service/v1/app/generateArtifacts
+
+# Model Loader Client Configuration for the A&AI REST interface
+ml.aai.base-url=https://<AAI_HOST>:8443
+ml.aai.model-url=/aai/%s/service-design-and-creation/models/model/
+ml.aai.named-query-url=/aai/%s/service-design-and-creation/named-queries/named-query/
+ml.aai.vnf-image-url=/aai/v*/service-design-and-creation/vnf-images # v* is supported by the resources api and translates to 'latest'
+ml.aai.auth-user=ModelLoader
+ml.aai.auth-password=
+ml.aai.use-gizmo=false
}
private void setOverrides(Properties configProperties) {
- configProperties.setProperty("ml.babel.BASE_URL", "http://localhost:" + wiremockPort);
+ configProperties.setProperty("ml.babel.base-url", "http://localhost:" + wiremockPort);
}
}
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Properties;
+import org.apache.kafka.clients.producer.ProducerConfig;
+import org.apache.kafka.common.serialization.StringSerializer;
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;
+import org.springframework.kafka.core.DefaultKafkaProducerFactory;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.kafka.core.ProducerFactory;
@TestConfiguration
public class DistributionClientTestConfiguration {
@Value("${wiremock.server.port}")
private int wiremockPort;
+ @Value("${spring.embedded.kafka.brokers}")
+ private String kafkaBootstrapAddress;
+
@Primary
@Bean(name = "testProperties")
- public Properties configProperties() throws IOException {
+ Properties configProperties() throws IOException {
// Load model loader system configuration
InputStream configInputStream = Files.newInputStream(Paths.get(configDir, "model-loader.properties"));
Properties configProperties = new Properties();
return configProperties;
}
+ @Bean
+ ProducerFactory<String, String> distributionClientProducerFactory() {
+ Map<String, Object> configProps = new HashMap<>();
+ configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaBootstrapAddress);
+ configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
+ configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
+
+ return new DefaultKafkaProducerFactory<>(configProps);
+ }
+
+ @Bean
+ KafkaTemplate<String, String> distributionClientKafkaTemplate() {
+ return new KafkaTemplate<>(distributionClientProducerFactory());
+ }
+
private void setOverrides(Properties configProperties) {
configProperties.setProperty("ml.distribution.ASDC_ADDRESS", "localhost:" + wiremockPort);
configProperties.setProperty("ml.babel.BASE_URL", "http://localhost:" + wiremockPort);
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")));
+ .willReturn(aResponse()
+ .withHeader("Content-Type", "application/json")
+ .withTransformers("response-template")
+ .withTransformerParameter("kafkaBootstrapAddress", kafkaBootstrapAddress)
+ .withBodyFile("kafkaBootstrap.json")));
}
-}
\ No newline at end of file
+}
--- /dev/null
+/**
+ * ============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.actuator;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+@AutoConfigureWebTestClient
+@TestPropertySource(properties = {
+ "management.endpoints.web.exposure.include=prometheus,metrics,info,health"
+})
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+public class ActuatorTest {
+
+ @Autowired
+ private WebTestClient webTestClient;
+
+ @Test
+ public void thatLivenessEndpointReturnsOk() {
+ webTestClient.get().uri("/actuator/health")
+ .exchange()
+ .expectStatus().isOk()
+ .expectBody()
+ .jsonPath("$.status")
+ .isEqualTo("UP");
+ }
+
+ // @Test
+ // public void testPrometheusEndpoint() {
+ // webTestClient.get().uri("/actuator/prometheus")
+ // .exchange()
+ // .expectStatus().isOk()
+ // .expectHeader().contentType("text/plain; charset=utf-8")
+ // .expectBody(String.class)
+ // .consumeWith(response -> {
+ // String responseBody = response.getResponseBody();
+ // assert responseBody != null;
+ // assert responseBody.contains("# HELP");
+ // assert responseBody.contains("# TYPE");
+ // });
+ // }
+}
--- /dev/null
+/**
+ * ============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 static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.onap.aai.modelloader.notification.EventCallback;
+import org.onap.sdc.api.IDistributionClient;
+import org.onap.sdc.api.results.IDistributionClientResult;
+import org.onap.sdc.utils.DistributionActionResultEnum;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+public class DistributionClientStartupConfigTest {
+
+ @Mock IDistributionClient distributionClient;
+ @Mock ModelLoaderConfig config;
+ @Mock EventCallback eventCallback;
+ @InjectMocks DistributionClientStartupConfig startupConfig;
+
+ @Test
+ public void thatClientIsInitialized() {
+ IDistributionClientResult initResult = mock(IDistributionClientResult.class);
+ when(distributionClient.init(any(), any())).thenReturn(initResult);
+ when(distributionClient.start()).thenReturn(initResult);
+ when(initResult.getDistributionActionResult()).thenReturn(DistributionActionResultEnum.SUCCESS);
+ startupConfig.initSdcClient();
+ verify(distributionClient, times(1)).init(any(), any());
+ verify(distributionClient, times(1)).start();
+ }
+
+ @Test
+ public void thatClientIsStoppedOnPreDestroy() {
+ startupConfig.destroy();
+ verify(distributionClient, times(1)).stop();
+ }
+
+}
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * Copyright © 2017-2018 European Software Marketing Ltd.
+ * Copyright © 2025 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.
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-package org.onap.aai.modelloader.service;
+package org.onap.aai.modelloader.config;
-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.MockBabelServiceClient;
-import org.springframework.stereotype.Service;
+import static org.junit.jupiter.api.Assertions.assertEquals;
-@Service
-public class MockBabelServiceClientFactory implements BabelServiceClientFactory {
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
- @Override
- public BabelServiceClient create(ModelLoaderConfig config) throws BabelServiceClientException {
- return new MockBabelServiceClient(config);
- }
+@SpringBootTest(properties = {
+ "ml.babel.generate-artifacts-url=/foo"
+})
+public class PropertiesTest {
+
+ @Autowired
+ BabelProperties babelProperties;
+
+ @Test
+ void thatBabelPropertiesBindingWorks() {
+ assertEquals("/foo", babelProperties.getGenerateArtifactsUrl());
+ }
}
import static org.junit.jupiter.api.Assertions.assertEquals;
-import java.io.File;
import java.util.List;
import java.util.Properties;
import org.eclipse.jetty.util.security.Password;
ModelLoaderConfig config =
createObfuscatedTestConfig(ModelLoaderConfig.PROP_ML_DISTRIBUTION_PASSWORD, password);
assertEquals(password, config.getPassword());
-
+
config = createUnobfuscatedTestConfig(ModelLoaderConfig.PROP_ML_DISTRIBUTION_PASSWORD, password);
assertEquals(password, config.getPassword());
}
ModelLoaderConfig config =
createObfuscatedTestConfig(ModelLoaderConfig.PROP_ML_DISTRIBUTION_KEYSTORE_PASSWORD, password);
assertEquals(password, config.getKeyStorePassword());
-
+
config = createUnobfuscatedTestConfig(ModelLoaderConfig.PROP_ML_DISTRIBUTION_KEYSTORE_PASSWORD, password);
assertEquals(password, config.getKeyStorePassword());
}
- @Test
- public void testDecryptAaiAuthenticationPassword() {
- String password = "myvoiceismypassword";
- ModelLoaderConfig config =
- createObfuscatedTestConfig(ModelLoaderConfig.PROP_AAI_AUTHENTICATION_PASSWORD, password);
- assertEquals(password, config.getAaiAuthenticationPassword());
-
- config = createUnobfuscatedTestConfig(ModelLoaderConfig.PROP_AAI_AUTHENTICATION_PASSWORD, password);
- assertEquals(password, config.getAaiAuthenticationPassword());
- }
-
- @Test
- public void testDecryptAaiKeystorePassword() {
- String password = "myvoiceismypassword";
- ModelLoaderConfig config = createObfuscatedTestConfig(ModelLoaderConfig.PROP_AAI_KEYSTORE_PASSWORD, password);
- assertEquals(password, config.getAaiKeyStorePassword());
-
- config = createUnobfuscatedTestConfig(ModelLoaderConfig.PROP_AAI_KEYSTORE_PASSWORD, password);
- assertEquals(password, config.getAaiKeyStorePassword());
- }
-
- @Test
- public void testAaiBaseUrl() {
- String url = "http://localhost:1234/";
- Properties props = new Properties();
- props.put(ModelLoaderConfig.PROP_AAI_BASE_URL, url);
- ModelLoaderConfig config = new ModelLoaderConfig(props, null);
- assertEquals(url, config.getAaiBaseUrl());
- }
-
- @Test
- public void testDecryptBabelKeystorePassword() {
- String password = "babelpassword";
- ModelLoaderConfig config = createObfuscatedTestConfig(ModelLoaderConfig.PROP_BABEL_KEYSTORE_PASSWORD, password);
- assertEquals(password, config.getBabelKeyStorePassword());
-
- config = createUnobfuscatedTestConfig(ModelLoaderConfig.PROP_BABEL_KEYSTORE_PASSWORD, password);
- assertEquals(password, config.getBabelKeyStorePassword());
- }
-
- @Test
- public void testBabelKeystorePath() {
- String root = "path_to_keystore";
- String path = "relative_keystore_path";
- Properties props = new Properties();
- props.put(ModelLoaderConfig.PROP_BABEL_KEYSTORE_FILE, path);
- ModelLoaderConfig config = new ModelLoaderConfig(props, root);
- assertEquals(root + File.separator + path, config.getBabelKeyStorePath());
- }
-
- @Test
- public void testBabelBaseUrl() {
- String url = "http://localhost/";
- Properties props = new Properties();
- props.put(ModelLoaderConfig.PROP_BABEL_BASE_URL, url);
- ModelLoaderConfig config = new ModelLoaderConfig(props, null);
- assertEquals(url, config.getBabelBaseUrl());
- }
-
- @Test
- public void testBabelGenerateArtifactsUrl() {
- String url = "/path/to/the/resource";
- Properties props = new Properties();
- props.put(ModelLoaderConfig.PROP_BABEL_GENERATE_RESOURCE_URL, url);
- ModelLoaderConfig config = new ModelLoaderConfig(props, null);
- assertEquals(url, config.getBabelGenerateArtifactsUrl());
- }
-
- @Test
- public void testGetUrls() {
- Properties props = new Properties();
- props.put(ModelLoaderConfig.PROP_AAI_MODEL_RESOURCE_URL, "/aai/v*/service-design-and-creation/models/model/");
- props.put(ModelLoaderConfig.PROP_AAI_NAMED_QUERY_RESOURCE_URL,
- "/aai/v*/service-design-and-creation/named-queries/named-query/");
- ModelLoaderConfig config = new ModelLoaderConfig(props, null);
-
- assertEquals("/aai/v9/service-design-and-creation/models/model/", config.getAaiModelUrl("v9"));
- assertEquals("/aai/v10/service-design-and-creation/named-queries/named-query/",
- config.getAaiNamedQueryUrl("v10"));
- }
-
/**
* Create a Model Loader Configuration object from the supplied Property.
- *
+ *
* @param propertyName property key
* @param propertyValue value of the property
* @return a new ModelLoaderConfig object containing a single obfuscated property value
props.put(propertyName, Password.obfuscate(propertyValue));
return new ModelLoaderConfig(props, null);
}
-
+
private ModelLoaderConfig createUnobfuscatedTestConfig(String propertyName, String propertyValue) {
Properties props = new Properties();
props.put(propertyName, propertyValue);
import static org.hamcrest.CoreMatchers.is;
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;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
-import java.util.Properties;
+import org.junit.jupiter.api.BeforeAll;
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.config.AaiProperties;
import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.modelloader.entity.ArtifactType;
import org.onap.aai.modelloader.restclient.AaiRestClient;
public class TestVnfCatalogArtifactHandler {
- protected static String CONFIG_FILE = "model-loader.properties";
+ protected static AaiProperties aaiProperties = new AaiProperties();
private AaiRestClient mockRestClient = mock(AaiRestClient.class);
+ @BeforeAll
+ public static void setup() {
+ aaiProperties.setBaseUrl("http://aai.onap:80");
+ aaiProperties.setModelUrl("/aai/%s/service-design-and-creation/models/model/");
+ aaiProperties.setNamedQueryUrl("/aai/%s/service-design-and-creation/named-queries/named-query/");
+ aaiProperties.setVnfImageUrl("/aai/v*/service-design-and-creation/vnf-images");
+ }
+
/**
* Update A&AI with 4 images, 2 of which already exist.
- *
+ *
* @throws Exception
*/
@Test
mockPutOperations();
// Example VNF Catalog XML
- VnfCatalogArtifactHandler handler = new VnfCatalogArtifactHandler(createConfig());
+ VnfCatalogArtifactHandler handler = new VnfCatalogArtifactHandler(aaiProperties);
assertTrue(handler.pushArtifacts(createVnfCatalogArtifact(), "test", new ArrayList<Artifact>(), mockRestClient));
assertPutOperationsSucceeded();
mockPutOperations();
// Example VNF Catalog XML
- VnfCatalogArtifactHandler handler = new VnfCatalogArtifactHandler(createConfig());
+ VnfCatalogArtifactHandler handler = new VnfCatalogArtifactHandler(aaiProperties);
assertThat(
handler.pushArtifacts(createVnfCatalogXmlArtifact(), "test", new ArrayList<Artifact>(), mockRestClient),
is(true));
assertThat(argument.getAllValues().get(1), containsString("VM00"));
}
- private ModelLoaderConfig createConfig() {
- Properties configProperties = new Properties();
- try {
- configProperties.load(this.getClass().getClassLoader().getResourceAsStream(CONFIG_FILE));
- } catch (IOException e) {
- fail();
- }
- ModelLoaderConfig config = new ModelLoaderConfig(configProperties, null);
- return config;
- }
-
/**
* Example VNF Catalog based on JSON data (returned by Babel)
- *
+ *
* @return test Artifacts
* @throws IOException
* @throws UnsupportedEncodingException
/**
* Example VNF Catalog based on VNF_CATALOG XML
- *
+ *
* @return test Artifacts
* @throws IOException
* @throws UnsupportedEncodingException
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.hasSize;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import java.util.Collections;
import java.util.List;
+import org.junit.jupiter.api.BeforeAll;
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.AaiProperties;
import org.onap.aai.modelloader.config.ModelLoaderConfig;
import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.modelloader.restclient.AaiRestClient;
@Mock
private AaiRestClient aaiClient;
+ private static AaiProperties aaiProperties = new AaiProperties();
+
+ @BeforeAll
+ public static void setup() {
+ aaiProperties.setBaseUrl("http://aai.onap:80");
+ aaiProperties.setModelUrl("/aai/%s/service-design-and-creation/models/model/");
+ aaiProperties.setNamedQueryUrl("/aai/%s/service-design-and-creation/named-queries/named-query/");
+ aaiProperties.setVnfImageUrl("/aai/%s/service-design-and-creation/vnf-images");
+ }
+
@BeforeEach
public void setupMocks() {
MockitoAnnotations.openMocks(this);
@Test
public void testEmptyLists() {
- ModelArtifactHandler handler = new ModelArtifactHandler(config);
+ ModelArtifactHandler handler = new ModelArtifactHandler(aaiProperties);
handler.pushArtifacts(Collections.emptyList(), "", Collections.emptyList(), aaiClient);
handler.rollback(Collections.emptyList(), "", aaiClient);
assertTrue(true);
@Test
public void testPushExistingModelsWithRollback() {
- when(config.getAaiBaseUrl()).thenReturn("");
- when(config.getAaiModelUrl(any())).thenReturn("");
-
ResponseEntity operationResult = mock(ResponseEntity.class);
when(aaiClient.getResource(any(), any(), any(), any())).thenReturn(operationResult);
when(operationResult.getStatusCode()).thenReturn(HttpStatus.OK);
Artifact artifact = new ModelArtifact();
artifacts.add(artifact);
- ModelArtifactHandler handler = new ModelArtifactHandler(config);
+ ModelArtifactHandler handler = new ModelArtifactHandler(aaiProperties);
boolean pushed = handler.pushArtifacts(artifacts, "", Collections.emptyList(), aaiClient);
assertTrue(pushed);
handler.rollback(artifacts, "", aaiClient);
@Test
public void testPushNewModelsWithRollback() {
- when(config.getAaiBaseUrl()).thenReturn("");
- when(config.getAaiModelUrl(any())).thenReturn("");
- when(config.getAaiNamedQueryUrl(any())).thenReturn("");
-
ResponseEntity getResult = mock(ResponseEntity.class);
when(aaiClient.getResource(any(), any(), any(), any())).thenReturn(getResult);
when(getResult.getStatusCode()).thenReturn(HttpStatus.NOT_FOUND);
artifacts.add(namedQueryArtifact);
List<Artifact> completedArtifacts = new ArrayList<>();
- ModelArtifactHandler handler = new ModelArtifactHandler(config);
+ ModelArtifactHandler handler = new ModelArtifactHandler(aaiProperties);
boolean pushed = handler.pushArtifacts(artifacts, "", completedArtifacts, aaiClient);
assertThat(pushed, is(true));
handler.rollback(artifacts, "", aaiClient);
@Test
public void testPushNewModelsBadRequest() {
- when(config.getAaiBaseUrl()).thenReturn("");
- when(config.getAaiModelUrl(any())).thenReturn("");
- when(config.getAaiNamedQueryUrl(any())).thenReturn("");
-
ResponseEntity getResult = mock(ResponseEntity.class);
when(aaiClient.getResource(any(), any(), any(), any())).thenReturn(getResult);
when(getResult.getStatusCode()).thenReturn(HttpStatus.NOT_FOUND);
@Test
public void testBadRequestResourceModelResult() {
- when(config.getAaiBaseUrl()).thenReturn("");
- when(config.getAaiModelUrl(any())).thenReturn("");
-
ResponseEntity operationResult = mock(ResponseEntity.class);
when(aaiClient.getResource(any(), any(), any(), any())).thenReturn(operationResult);
when(operationResult.getStatusCode()).thenReturn(HttpStatus.BAD_REQUEST);
}
private void checkRollback(List<Artifact> artifacts) {
- ModelArtifactHandler handler = new ModelArtifactHandler(config);
+ ModelArtifactHandler handler = new ModelArtifactHandler(aaiProperties);
boolean pushed = handler.pushArtifacts(artifacts, "", Collections.emptyList(), aaiClient);
assertThat(pushed, is(false));
handler.rollback(artifacts, "", aaiClient);
}
}
-
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 java.util.Set;
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.entity.model.ModelArtifact;
import org.onap.aai.modelloader.service.ArtifactInfoImpl;
import org.onap.sdc.api.notification.IArtifactInfo;
import org.springframework.beans.factory.annotation.Autowired;
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}"})
@Autowired ArtifactDownloadManager artifactDownloadManager;
@Test
- public void downloadArtifacts() throws JsonProcessingException {
+ public void downloadArtifacts() throws Exception {
NotificationDataImpl notificationData = new NotificationDataImpl();
notificationData.setDistributionID("distributionID");
notificationData.setServiceVersion("2.0");
artifactInfo.setArtifactUUID("f6f907f1-3f45-4fb4-8cbe-15a4c6ee16db");
List<IArtifactInfo> artifacts = new ArrayList<>();
artifacts.add(artifactInfo);
- List<Artifact> modelArtifacts = new ArrayList<>(); // processed artifacts will be written to this list
- List<Artifact> catalogArtifacts = new ArrayList<>(); // processed artifacts will be written to this list
- boolean result = artifactDownloadManager.downloadArtifacts(notificationData, artifacts, modelArtifacts, catalogArtifacts);
+ List<Artifact> result = artifactDownloadManager.downloadArtifacts(notificationData, artifacts);
- assertEquals(1, modelArtifacts.size());
- assertEquals(ArtifactType.MODEL, modelArtifacts.get(0).getType());
- assertTrue(result);
+ assertEquals(1, result.size());
+ ModelArtifact modelArtifact = (ModelArtifact) result.get(0);
+ assertEquals(ArtifactType.MODEL, modelArtifact.getType());
+ assertEquals("3c8bc8e7-e387-46ed-8616-70e99e2206dc", modelArtifact.getModelInvariantId());
+ assertEquals("http://org.onap.aai.inventory/v28", modelArtifact.getModelNamespace());
+ assertEquals("v28", modelArtifact.getModelNamespaceVersion());
+ assertEquals("71f47717-b100-4eac-940b-7d4e86a4cbb7", modelArtifact.getModelVerId());
+ assertEquals(Set.of("82194af1-3c2c-485a-8f44-420e22a9eaa4|46b92144-923a-4d20-b85a-3cbd847668a9"), modelArtifact.getDependentModelIds());
}
}
*/
package org.onap.aai.modelloader.notification;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
+import java.util.stream.Collectors;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
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.util.ArtifactTestUtils;
import org.onap.sdc.api.IDistributionClient;
import org.onap.sdc.api.notification.IArtifactInfo;
@Mock private IDistributionClient mockDistributionClient;
@Mock private NotificationPublisher mockNotificationPublisher;
@Mock private BabelArtifactConverter mockBabelArtifactConverter;
- @Mock private BabelServiceClientFactory mockClientFactory;
@Mock private VnfCatalogExtractor mockVnfCatalogExtractor;
@InjectMocks private BabelArtifactService babelArtifactService;
@BeforeEach
public void setup() throws Exception {
MockitoAnnotations.openMocks(this);
- when(mockClientFactory.create(Mockito.any())).thenReturn(mockBabelClient);
Properties configProperties = new Properties();
configProperties.load(this.getClass().getClassLoader().getResourceAsStream("model-loader.properties"));
@Test
public void downloadArtifacts_validToscaVnfcCsarFile()
- throws IOException, BabelServiceClientException, BabelArtifactParsingException, InvalidArchiveException {
+ throws Exception {
INotificationData data = getNotificationDataWithToscaCsarFile();
IArtifactInfo artifactInfo = data.getServiceArtifacts().get(0);
when(mockBabelClient.postArtifact(any(), any())).thenReturn(createBabelArtifacts());
when(mockVnfCatalogExtractor.extract(any(), any())).thenReturn(new ArrayList<>());
- List<Artifact> modelArtifacts = new ArrayList<>();
- List<Artifact> catalogFiles = new ArrayList<>();
- assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelArtifacts, catalogFiles),
- is(true));
-
- assertEquals(2, catalogFiles.size(), "There should have been some catalog files");
+ List<Artifact> artifacts = downloadManager.downloadArtifacts(data, data.getServiceArtifacts());
+ List<Artifact> catalogArtifacts = artifacts.stream()
+ .filter(VnfCatalogArtifact.class::isInstance)
+ .collect(Collectors.toList());
+ List<Artifact> modelArtifacts = artifacts.stream()
+ .filter(ModelArtifact.class::isInstance)
+ .collect(Collectors.toList());
+ assertEquals(1, catalogArtifacts.size(), "There should be a catalog artifact");
+ assertEquals(1, modelArtifacts.size(), "There should be a model artifact");
}
@Test
public void downloadArtifacts_validXmlVnfcCsarFile()
- throws IOException, BabelServiceClientException, BabelArtifactParsingException, InvalidArchiveException {
+ throws Exception {
INotificationData data = getNotificationDataWithToscaCsarFile();
IArtifactInfo artifactInfo = data.getServiceArtifacts().get(0);
when(mockBabelClient.postArtifact(any(), any())).thenReturn(createBabelArtifactsNoVnfc());
when(mockVnfCatalogExtractor.extract(any(), any())).thenReturn(createXmlVnfcArtifacts());
- List<Artifact> modelArtifacts = new ArrayList<>();
- List<Artifact> catalogFiles = new ArrayList<>();
- assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelArtifacts, catalogFiles),
- is(true));
+ List<Artifact> artifacts = downloadManager.downloadArtifacts(data, data.getServiceArtifacts());
- assertEquals(3, catalogFiles.size(), "There should have been some catalog files");
+ List<Artifact> catalogArtifacts = artifacts.stream()
+ .filter(VnfCatalogArtifact.class::isInstance)
+ .collect(Collectors.toList());
+ List<Artifact> modelArtifacts = artifacts.stream()
+ .filter(ModelArtifact.class::isInstance)
+ .collect(Collectors.toList());
+ assertEquals(3, catalogArtifacts.size(), "There should be three catalog artifacts");
+ assertEquals(1, modelArtifacts.size(), "There should be a model artifact");
}
@Test
public void downloadArtifacts_validNoVnfcCsarFile()
- throws IOException, BabelServiceClientException, BabelArtifactParsingException, InvalidArchiveException {
+ throws Exception {
INotificationData data = getNotificationDataWithToscaCsarFile();
IArtifactInfo artifactInfo = data.getServiceArtifacts().get(0);
when(mockBabelClient.postArtifact(any(), any())).thenReturn(createBabelArtifactsNoVnfc());
when(mockVnfCatalogExtractor.extract(any(), any())).thenReturn(new ArrayList<>());
- List<Artifact> modelArtifacts = new ArrayList<>();
- List<Artifact> catalogFiles = new ArrayList<>();
- assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelArtifacts, catalogFiles),
- is(true));
+ List<Artifact> artifacts = downloadManager.downloadArtifacts(data, data.getServiceArtifacts());
+ List<Artifact> catalogArtifacts = artifacts.stream()
+ .filter(VnfCatalogArtifact.class::isInstance)
+ .collect(Collectors.toList());
- assertEquals(0, catalogFiles.size(), "There should not have been any catalog files");
+ assertEquals(0, catalogArtifacts.size(), "There should not have been any catalog files");
}
@Test
public void downloadArtifacts_invalidXmlAndToscaVnfcCsarFile()
- throws IOException, BabelServiceClientException, BabelArtifactParsingException, InvalidArchiveException {
+ throws Exception {
INotificationData data = getNotificationDataWithToscaCsarFile();
IArtifactInfo artifactInfo = data.getServiceArtifacts().get(0);
when(mockVnfCatalogExtractor.extract(any(), any())).thenReturn(createXmlVnfcArtifacts());
doNothing().when(mockNotificationPublisher).publishDeployFailure(mockDistributionClient, data, artifactInfo);
- List<Artifact> modelArtifacts = new ArrayList<>();
- List<Artifact> catalogFiles = new ArrayList<>();
- assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelArtifacts, catalogFiles),
- is(false));
+ InvalidArchiveException invalidArchiveException = assertThrows(InvalidArchiveException.class,
+ () -> downloadManager.downloadArtifacts(data, data.getServiceArtifacts()));
Mockito.verify(mockNotificationPublisher).publishDeployFailure(mockDistributionClient, data, artifactInfo);
}
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<BabelArtifact> createBabelArtifacts() {
private List<Artifact> createModelArtifacts() {
List<Artifact> modelArtifacts = new ArrayList<>();
modelArtifacts.add(new ModelArtifact());
- modelArtifacts.add(new ModelArtifact());
return modelArtifacts;
}
- private List<Artifact> createToscaVnfcArtifacts() {
- List<Artifact> vnfcArtifacts = new ArrayList<>();
- vnfcArtifacts.add(new VnfCatalogArtifact("Some VNFC payload"));
- vnfcArtifacts.add(new VnfCatalogArtifact("Some VNFC payload"));
- return vnfcArtifacts;
- }
-
private List<Artifact> createXmlVnfcArtifacts() {
List<Artifact> vnfcArtifacts = new ArrayList<>();
vnfcArtifacts.add(new VnfCatalogArtifact(ArtifactType.VNF_CATALOG_XML, "Some VNFC payload"));
--- /dev/null
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+ package org.onap.aai.modelloader.notification;
+
+ import org.junit.jupiter.api.Test;
+ import org.onap.sdc.api.IDistributionClient;
+ import org.onap.sdc.api.consumer.IComponentDoneStatusMessage;
+ import org.onap.sdc.api.consumer.IConfiguration;
+ import org.onap.sdc.api.notification.INotificationData;
+ import org.onap.sdc.utils.DistributionStatusEnum;
+ import org.springframework.boot.test.context.SpringBootTest;
+ import org.springframework.test.context.TestPropertySource;
+ import static org.mockito.Mockito.*;
+ import static org.junit.jupiter.api.Assertions.*;
+
+ @SpringBootTest
+ @TestPropertySource(properties = {"CONFIG_HOME=src/test/resources"})
+ public class CompDoneStatusMessageBuilderTest {
+
+ @Test
+ public void testBuild() {
+ IDistributionClient mockClient = mock(IDistributionClient.class);
+ INotificationData mockData = mock(INotificationData.class);
+
+ IConfiguration mockConfig = mock(IConfiguration.class);
+ when(mockClient.getConfiguration()).thenReturn(mockConfig);
+ when(mockConfig.getConsumerID()).thenReturn("consumer123");
+
+ when(mockData.getDistributionID()).thenReturn("distID456");
+
+ DistributionStatusEnum status = DistributionStatusEnum.DEPLOY_OK;
+ IComponentDoneStatusMessage result = CompDoneStatusMessageBuilder.build(mockClient, mockData, status);
+
+ assertNotNull(result);
+ assertTrue(result instanceof CompDoneStatusMsg);
+ CompDoneStatusMsg statusMsg = (CompDoneStatusMsg) result;
+
+ assertEquals("distID456", statusMsg.getDistributionID());
+ assertEquals("consumer123", statusMsg.getConsumerID());
+ assertEquals(DistributionStatusEnum.DEPLOY_OK, statusMsg.getStatus());
+ }
+
+ @Test
+ public void testBuildWithFailureStatus() {
+ IDistributionClient mockClient = mock(IDistributionClient.class);
+ INotificationData mockData = mock(INotificationData.class);
+
+ IConfiguration mockConfig = mock(IConfiguration.class);
+ when(mockClient.getConfiguration()).thenReturn(mockConfig);
+ when(mockConfig.getConsumerID()).thenReturn("consumer123");
+
+ when(mockData.getDistributionID()).thenReturn("distID456");
+
+ DistributionStatusEnum status = DistributionStatusEnum.DEPLOY_ERROR;
+ IComponentDoneStatusMessage result = CompDoneStatusMessageBuilder.build(mockClient, mockData, status);
+
+ assertNotNull(result);
+ assertTrue(result instanceof CompDoneStatusMsg);
+ CompDoneStatusMsg statusMsg = (CompDoneStatusMsg) result;
+
+ assertEquals("distID456", statusMsg.getDistributionID());
+ assertEquals("consumer123", statusMsg.getConsumerID());
+ assertEquals(DistributionStatusEnum.DEPLOY_ERROR, statusMsg.getStatus());
+ }
+
+ @Test
+ public void testBuildHandlesNullValues() {
+ IDistributionClient mockClient = mock(IDistributionClient.class);
+ INotificationData mockData = mock(INotificationData.class);
+
+ IConfiguration mockConfig = mock(IConfiguration.class);
+ when(mockClient.getConfiguration()).thenReturn(mockConfig);
+ when(mockConfig.getConsumerID()).thenReturn(null);
+ when(mockData.getDistributionID()).thenReturn(null);
+
+ DistributionStatusEnum status = DistributionStatusEnum.DEPLOY_OK;
+ IComponentDoneStatusMessage result = CompDoneStatusMessageBuilder.build(mockClient, mockData, status);
+
+ assertNotNull(result);
+ assertTrue(result instanceof CompDoneStatusMsg);
+ CompDoneStatusMsg statusMsg = (CompDoneStatusMsg) result;
+
+ assertNull(statusMsg.getDistributionID());
+ assertNull(statusMsg.getConsumerID());
+ assertEquals(DistributionStatusEnum.DEPLOY_OK, statusMsg.getStatus());
+ }
+}
\ No newline at end of file
--- /dev/null
+/**
+ * ============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.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.verify;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.onap.aai.modelloader.DistributionClientTestConfiguration;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock;
+import org.springframework.context.annotation.Import;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.kafka.test.context.EmbeddedKafka;
+import org.springframework.test.annotation.DirtiesContext;
+
+import lombok.SneakyThrows;
+
+@DirtiesContext
+@AutoConfigureWireMock(port = 0)
+@Import(DistributionClientTestConfiguration.class)
+@SpringBootTest(properties = { "ml.distribution.connection.enabled=true" })
+@EmbeddedKafka(partitions = 1, ports = 9092, topics = {"${topics.distribution.notification}"})
+public class DistributionClientIntegrationTest {
+
+ @Value("${topics.distribution.notification}")
+ String topic;
+
+ @Autowired
+ KafkaTemplate<String,String> kafkaTemplate;
+
+ @MockBean
+ EventCallback eventCallback;
+
+ private CountDownLatch latch;
+
+ @BeforeEach
+ public void setup() {
+ latch = new CountDownLatch(1);
+
+ doAnswer(invocation -> {
+ latch.countDown();
+ return null;
+ }).when(eventCallback).activateCallback(any());
+ }
+
+ @Test
+ @SneakyThrows
+ void thatCallbackIsCalled() {
+ Thread.sleep(10000);
+ String distributionJson = "src/test/resources/messages/distribution.json";
+ String message = Files.readString(Paths.get(distributionJson));
+
+ kafkaTemplate.send(topic, message);
+
+ latch.await(10, TimeUnit.SECONDS);
+ verify(eventCallback).activateCallback(any());
+ }
+
+}
--- /dev/null
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.modelloader.notification;
+
+import org.junit.jupiter.api.Test;
+import org.onap.sdc.api.IDistributionClient;
+import org.onap.sdc.api.consumer.IConfiguration;
+import org.onap.sdc.api.consumer.IDistributionStatusMessage;
+import org.onap.sdc.api.notification.IArtifactInfo;
+import org.onap.sdc.api.notification.INotificationData;
+import static org.mockito.Mockito.*;
+import org.onap.sdc.utils.DistributionStatusEnum;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.TestPropertySource;
+import static org.junit.jupiter.api.Assertions.*;
+import org.springframework.test.context.TestPropertySource;
+
+@SpringBootTest
+@TestPropertySource(properties = {"CONFIG_HOME=src/test/resources"})
+public class DistributionStatusMessageBuilderTest {
+
+ @Test
+ public void testBuild() {
+ IDistributionClient mockClient = mock(IDistributionClient.class);
+ IConfiguration mockConfig = mock(IConfiguration.class);
+ when(mockClient.getConfiguration()).thenReturn(mockConfig);
+ when(mockConfig.getConsumerID()).thenReturn("testConsumerID");
+
+ INotificationData mockData = mock(INotificationData.class);
+ when(mockData.getDistributionID()).thenReturn("testDistributionID");
+
+ IArtifactInfo mockArtifact = mock(IArtifactInfo.class);
+ when(mockArtifact.getArtifactURL()).thenReturn("http://example.com/artifact");
+
+ DistributionStatusEnum status = DistributionStatusEnum.DEPLOY_OK;
+ IDistributionStatusMessage result = DistributionStatusMessageBuilder.build(mockClient, mockData, mockArtifact, status);
+
+ assertNotNull(result);
+ assertEquals("testDistributionID", result.getDistributionID());
+ assertEquals("testConsumerID", result.getConsumerID());
+ assertEquals("http://example.com/artifact", result.getArtifactURL());
+ assertEquals(DistributionStatusEnum.DEPLOY_OK, result.getStatus());
+ }
+
+ @Test
+ public void testBuildWithoutArtifactInfo() {
+ IDistributionClient mockClient = mock(IDistributionClient.class);
+ IConfiguration mockConfig = mock(IConfiguration.class);
+ when(mockClient.getConfiguration()).thenReturn(mockConfig);
+ when(mockConfig.getConsumerID()).thenReturn("testConsumerID");
+
+ INotificationData mockData = mock(INotificationData.class);
+ when(mockData.getDistributionID()).thenReturn("testDistributionID");
+
+ DistributionStatusEnum status = DistributionStatusEnum.DEPLOY_OK;
+ IDistributionStatusMessage result = DistributionStatusMessageBuilder.build(mockClient, mockData, status);
+
+ assertNotNull(result);
+ assertEquals("testDistributionID", result.getDistributionID());
+ assertEquals("testConsumerID", result.getConsumerID());
+ assertEquals("", result.getArtifactURL());
+ assertEquals(DistributionStatusEnum.DEPLOY_OK, result.getStatus());
+ }
+}
+
+
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
+import org.onap.aai.modelloader.config.AaiProperties;
import org.onap.aai.modelloader.config.ModelLoaderConfig;
import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.modelloader.entity.model.ModelArtifact;
final ObjectMapper objectMapper = new ObjectMapper();
@Mock
- ModelLoaderConfig config;
+ AaiProperties aaiProperties;
@InjectMocks
ModelArtifactHandler modelArtifactHandler;
@BeforeEach
public void setUp() {
- when(config.getAaiBaseUrl()).thenReturn("http://localhost:" + wiremockPort);
- when(config.getAaiModelUrl(any())).thenReturn("/aai/v28/service-design-and-creation/models/model/");
+ when(aaiProperties.getBaseUrl()).thenReturn("http://localhost:" + wiremockPort);
+ when(aaiProperties.getModelUrl()).thenReturn("/aai/%s/service-design-and-creation/models/model/");
}
@Test
ModelArtifact modelArtifact = new ModelArtifact();
modelArtifact.setModelInvariantId("modelInvariantId");
+ modelArtifact.setModelNamespace("v28");
modelArtifact.setPayload("");
List<Artifact> artifacts = List.of(modelArtifact);
List<Artifact> completedArtifacts = new ArrayList<>();
ModelArtifact modelArtifact = new ModelArtifact();
modelArtifact.setModelInvariantId("modelInvariantId");
modelArtifact.setModelVerId("modelVersionId");
+ modelArtifact.setModelNamespace("v28");
modelArtifact.setPayload("");
modelArtifact.setModelVer("2.0");
List<Artifact> artifacts = List.of(modelArtifact);
@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("Accept", equalTo(MediaType.APPLICATION_XML_VALUE))
.withHeader("X-FromAppId", equalTo("ModelLoader"))
.withHeader("X-TransactionId", equalTo("distributionId"))
.willReturn(aResponse()
ModelArtifact modelArtifact = new ModelArtifact();
modelArtifact.setModelInvariantId("3a40ab73-6694-4e75-bb6d-9a4a86ce35b3");
modelArtifact.setModelVerId("modelVersionId");
- // modelArtifact.setModelVer("2.0");
-
+ modelArtifact.setModelNamespace("v28");
+
List<Artifact> completedArtifacts = new ArrayList<>();
completedArtifacts.add(modelArtifact);
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<>());
+ modelArtifact.push(aaiClient, aaiProperties, null, new ArrayList<>());
}
@Test
ModelArtifact modelArtifact = new ModelArtifact();
modelArtifact.setModelInvariantId("modelInvariantId");
modelArtifact.setModelVerId("modelVersionId");
-
+ modelArtifact.setModelNamespace("v28");
+
List<Artifact> completedArtifacts = new ArrayList<>();
completedArtifacts.add(modelArtifact);
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
+}
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import java.util.Properties;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
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.config.AaiProperties;
import org.onap.aai.modelloader.entity.Artifact;
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;
*/
public class TestArtifactDeploymentManager {
- private static final String CONFIG_FILE = "model-loader.properties";
private static final String SHOULD_HAVE_RETURNED_FALSE = "This should have returned false";
- private Properties configProperties;
private ArtifactDeploymentManager manager;
@Mock private ModelArtifactHandler modelArtifactHandlerMock;
@BeforeEach
public void setup() throws IOException {
MockitoAnnotations.openMocks(this);
- configProperties = new Properties();
- configProperties.load(this.getClass().getClassLoader().getResourceAsStream(CONFIG_FILE));
+ AaiProperties aaiProperties = new AaiProperties();
+ aaiProperties.setBaseUrl("http://aai.onap:80");
+ aaiProperties.setModelUrl("/aai/%s/service-design-and-creation/models/model/");
+ aaiProperties.setNamedQueryUrl("/aai/%s/service-design-and-creation/named-queries/named-query/");
+ aaiProperties.setVnfImageUrl("/aai/%s/service-design-and-creation/vnf-images");
- ModelLoaderConfig modelLoaderConfig = new ModelLoaderConfig(configProperties, null);
- AaiRestClient aaiRestClient = new AaiRestClient(modelLoaderConfig, new RestTemplate());
+ AaiRestClient aaiRestClient = new AaiRestClient(aaiProperties, new RestTemplate());
manager = new ArtifactDeploymentManager(modelArtifactHandlerMock, vnfCatalogArtifactHandlerMock, aaiRestClient);
}
@AfterEach
public void tearDown() {
- configProperties = null;
modelArtifactHandlerMock = null;
vnfCatalogArtifactHandlerMock = null;
manager = null;
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<BabelArtifact> toscaArtifacts = setupTest(xml, data);
- List<Artifact> modelArtifacts = new BabelArtifactConverter().convertToModel(toscaArtifacts);
+ BabelArtifact toscaArtifact = setupTest(xml, data);
+ List<Artifact> modelArtifacts = new BabelArtifactConverter(new ModelArtifactParser()).convertToModel(toscaArtifact);
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(modelArtifactHandlerMock).pushArtifacts(eq(modelArtifacts), eq(data.getDistributionID()), any(),
any());
eq(data.getDistributionID()), any());
}
- private List<BabelArtifact> setupTest(byte[] xml, INotificationData data) throws IOException {
- List<BabelArtifact> 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
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(modelArtifactHandlerMock).pushArtifacts(eq(new ArrayList<Artifact>()),
eq(data.getDistributionID()), any(), any());
throws IOException, BabelArtifactParsingException, InvalidArchiveException {
INotificationData data = getNotificationDataWithOneOfEach();
byte[] xml = new ArtifactTestUtils().loadResource("convertedYmls/AAI-SCP-Test-VSP-resource-1.0.xml");
- List<BabelArtifact> toscaArtifacts = setupTest(xml, data);
- List<Artifact> modelArtifacts = new BabelArtifactConverter().convertToModel(toscaArtifacts);
+ BabelArtifact toscaArtifact = setupTest(xml, data);
+ List<Artifact> modelArtifacts = new BabelArtifactConverter(new ModelArtifactParser()).convertToModel(toscaArtifact);
List<org.onap.aai.modelloader.entity.Artifact> catalogFiles = new ArrayList<>();
catalogFiles.add(new VnfCatalogArtifact("Some catalog content"));
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(modelArtifactHandlerMock).pushArtifacts(eq(modelArtifacts), eq(data.getDistributionID()), any(),
/**
* Deploy both models and VNF images.
- *
+ *
* @throws IOException
* @throws BabelArtifactParsingException
* @throws InvalidArchiveException
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<BabelArtifact> toscaArtifacts = setupTest(xml, data);
- List<Artifact> modelArtifacts = new BabelArtifactConverter().convertToModel(toscaArtifacts);
+ BabelArtifact toscaArtifact = setupTest(xml, data);
+ List<Artifact> modelArtifacts = new BabelArtifactConverter(new ModelArtifactParser()).convertToModel(toscaArtifact);
List<org.onap.aai.modelloader.entity.Artifact> catalogFiles = new ArrayList<>();
catalogFiles.add(new VnfCatalogArtifact("Some catalog content"));
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(vnfCatalogArtifactHandlerMock).pushArtifacts(eq(catalogFiles), eq(data.getDistributionID()),
any(), any());
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.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
import static org.onap.aai.modelloader.fixture.NotificationDataFixtureBuilder.getNotificationDataWithInvalidType;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
+import java.util.stream.Collectors;
-import org.hamcrest.collection.IsEmptyCollection;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.onap.aai.babel.service.data.BabelArtifact;
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.entity.model.NamedQueryArtifact;
+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.util.ArtifactTestUtils;
import org.onap.sdc.api.IDistributionClient;
import org.onap.sdc.api.notification.IArtifactInfo;
@Mock private IDistributionClient mockDistributionClient;
@Mock private NotificationPublisher mockNotificationPublisher;
@Mock private BabelArtifactConverter mockBabelArtifactConverter;
- @Mock private BabelServiceClientFactory mockClientFactory;
@InjectMocks BabelArtifactService babelArtifactService;
private VnfCatalogExtractor vnfCatalogExtractor;
public void setup() throws Exception {
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"));
/**
* Test downloading zero artifacts from SDC.
+ * @throws Exception
*/
@Test
- public void testDownloadWithZeroArtifacts() {
- List<Artifact> modelFiles = new ArrayList<>();
- List<Artifact> catalogFiles = new ArrayList<>();
- assertThat(downloadManager.downloadArtifacts(getNotificationDataWithOneService(), new ArrayList<>(), modelFiles,
- catalogFiles), is(true));
- assertThat(modelFiles, is(empty()));
- assertThat(catalogFiles, is(empty()));
+ public void testDownloadWithZeroArtifacts() throws Exception {
+ List<Artifact> artifacts = downloadManager.downloadArtifacts(getNotificationDataWithOneService(), new ArrayList<>());
+ assertThat(artifacts, is(empty()));
Mockito.verifyNoInteractions(mockBabelClient, mockDistributionClient, mockNotificationPublisher,
mockBabelArtifactConverter);
}
doNothing().when(mockNotificationPublisher).publishDownloadFailure(mockDistributionClient, data, artifact,
errorMessage);
- assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), null, null), is(false));
+ assertThrows(DownloadFailureException.class,
+ () -> downloadManager.downloadArtifacts(data, data.getServiceArtifacts()));
Mockito.verify(mockDistributionClient).download(artifact);
Mockito.verify(mockNotificationPublisher).publishDownloadFailure(mockDistributionClient, data, artifact,
Mockito.verifyNoInteractions(mockBabelClient, mockBabelArtifactConverter);
}
- @Test
- public void testErrorCreatingBabelClient() throws Exception {
- when(mockClientFactory.create(any())).thenThrow(new BabelServiceClientException(new Exception()));
-
- INotificationData data = getNotificationDataWithToscaCsarFile();
- IArtifactInfo artifactInfo = data.getServiceArtifacts().get(0);
- setupValidDownloadCsarMocks(data, artifactInfo, new ArtifactTestUtils());
- doNothing().when(mockNotificationPublisher).publishDeployFailure(mockDistributionClient, data, artifactInfo);
-
- assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), null, null), is(false));
-
- Mockito.verify(mockDistributionClient).download(artifactInfo);
- Mockito.verify(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, artifactInfo);
- Mockito.verify(mockNotificationPublisher).publishDeployFailure(mockDistributionClient, data, artifactInfo);
- }
-
@Test
public void downloadArtifacts_invalidToscaCsarFile() throws IOException, BabelServiceClientException {
INotificationData data = getNotificationDataWithToscaCsarFile();
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));
+ assertThrows(ProcessToscaArtifactsException.class,
+ () -> downloadManager.downloadArtifacts(data, data.getServiceArtifacts()));
Mockito.verify(mockDistributionClient).download(artifact);
Mockito.verify(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, artifact);
DistributionActionResultEnum.SUCCESS, null, "This is not a valid Model Query Spec".getBytes()));
doNothing().when(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, artifact);
- assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelArtifacts, null),
- is(false));
+ assertThrows(BabelArtifactParsingException.class,
+ () -> downloadManager.downloadArtifacts(data, data.getServiceArtifacts()));
Mockito.verify(mockDistributionClient).download(artifact);
Mockito.verify(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, artifact);
@Test
public void downloadArtifacts_validToscaCsarFile()
- throws IOException, BabelServiceClientException, BabelArtifactParsingException {
+ throws Exception {
INotificationData data = getNotificationDataWithToscaCsarFile();
IArtifactInfo artifactInfo = data.getServiceArtifacts().get(0);
setupValidDownloadCsarMocks(data, artifactInfo, new ArtifactTestUtils());
- List<org.onap.aai.modelloader.entity.Artifact> modelArtifacts = new ArrayList<>();
- List<org.onap.aai.modelloader.entity.Artifact> catalogFiles = new ArrayList<>();
- assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelArtifacts, catalogFiles),
- is(true));
- assertThat(catalogFiles.size(), is(0));
+ List<Artifact> artifacts = downloadManager.downloadArtifacts(data, data.getServiceArtifacts());
+ List<Artifact> modelArtifacts = artifacts.stream().filter(ModelArtifact.class::isInstance)
+ .collect(Collectors.toList());
+ List<Artifact> catalogArtifacts = artifacts.stream().filter(VnfCatalogArtifact.class::isInstance)
+ .collect(Collectors.toList());
+ assertThat(modelArtifacts.size(), is(1));
+ assertThat(catalogArtifacts.size(), is(1));
Mockito.verify(mockDistributionClient).download(artifactInfo);
Mockito.verify(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, artifactInfo);
}
private void setupValidDownloadCsarMocks(INotificationData data, IArtifactInfo artifactInfo,
- ArtifactTestUtils artifactTestUtils) throws IOException, BabelServiceClientException {
+ ArtifactTestUtils artifactTestUtils) throws IOException, BabelServiceClientException, BabelArtifactParsingException {
when(mockDistributionClient.download(artifactInfo))
.thenReturn(createDistributionClientDownloadResult(DistributionActionResultEnum.SUCCESS, null,
artifactTestUtils.loadResource("compressedArtifacts/service-VscpaasTest-csar.csar")));
when(mockBabelClient.postArtifact(any(), any())).thenReturn(createBabelArtifacts());
+
+ when(mockBabelArtifactConverter.convertToModel(any(BabelArtifact.class))).thenReturn(List.of(new ModelArtifact()));
+ when(mockBabelArtifactConverter.convertToCatalog(any(BabelArtifact.class))).thenReturn(new VnfCatalogArtifact(""));
}
private List<BabelArtifact> createBabelArtifacts() {
@Test
public void downloadArtifactsWithValidModelQuerySpec()
- throws IOException, BabelServiceClientException, BabelArtifactParsingException {
+ throws Exception {
INotificationData data = getNotificationDataWithModelQuerySpec();
IArtifactInfo artifact = data.getServiceArtifacts().get(0);
setupValidModelQuerySpecMocks(new ArtifactTestUtils(), data, artifact);
- List<org.onap.aai.modelloader.entity.Artifact> modelFiles = new ArrayList<>();
- List<org.onap.aai.modelloader.entity.Artifact> catalogFiles = new ArrayList<>();
- assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelFiles, catalogFiles),
- is(true));
+ List<Artifact> artifacts = downloadManager.downloadArtifacts(data, data.getServiceArtifacts());
+ List<Artifact> namedQueryArtifacts = artifacts.stream().filter(NamedQueryArtifact.class::isInstance)
+ .collect(Collectors.toList());
+ List<Artifact> catalogArtifacts = artifacts.stream().filter(VnfCatalogArtifact.class::isInstance)
+ .collect(Collectors.toList());
- assertThat(modelFiles, is(not(IsEmptyCollection.empty())));
- assertThat(catalogFiles, is(empty()));
+ assertThat(namedQueryArtifacts.size(), is(1));
+ assertThat(catalogArtifacts, is(empty()));
Mockito.verify(mockDistributionClient).download(artifact);
Mockito.verify(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, artifact);
@Test
public void downloadArtifacts_validCsarAndModelFiles()
- throws IOException, BabelServiceClientException, BabelArtifactParsingException {
+ throws Exception {
ArtifactTestUtils artifactTestUtils = new ArtifactTestUtils();
INotificationData data = getNotificationDataWithOneOfEach();
- List<IArtifactInfo> artifacts = new ArrayList<>();
+ List<IArtifactInfo> artifactInfos = new ArrayList<>();
IArtifactInfo serviceArtifact = data.getServiceArtifacts().get(0);
IArtifactInfo modelSpecArtifact = data.getResources().get(1).getArtifacts().get(0);
- artifacts.add(serviceArtifact);
- artifacts.add(modelSpecArtifact);
+ artifactInfos.add(serviceArtifact);
+ artifactInfos.add(modelSpecArtifact);
setupValidDownloadCsarMocks(data, serviceArtifact, artifactTestUtils);
setupValidModelQuerySpecMocks(artifactTestUtils, data, modelSpecArtifact);
- List<org.onap.aai.modelloader.entity.Artifact> modelFiles = new ArrayList<>();
- List<org.onap.aai.modelloader.entity.Artifact> catalogFiles = new ArrayList<>();
- assertThat(downloadManager.downloadArtifacts(data, artifacts, modelFiles, catalogFiles), is(true));
+ List<Artifact> artifacts = downloadManager.downloadArtifacts(data, artifactInfos);
+ List<Artifact> modelArtifacts = artifacts.stream().filter(artifact -> !(artifact instanceof VnfCatalogArtifact))
+ .collect(Collectors.toList());
+ List<Artifact> catalogArtifacts = artifacts.stream().filter(VnfCatalogArtifact.class::isInstance)
+ .collect(Collectors.toList());
+ assertThat(modelArtifacts.size(), is(2));
+ assertThat(catalogArtifacts.size(), is(1));
Mockito.verify(mockDistributionClient).download(serviceArtifact);
Mockito.verify(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, serviceArtifact);
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())).thenReturn(createBabelArtifacts());
List<Artifact> modelArtifacts = new ArrayList<>();
List<Artifact> catalogFiles = new ArrayList<>();
- assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), modelArtifacts, catalogFiles),
- is(false));
+ assertThrows(ProcessToscaArtifactsException.class,
+ () -> downloadManager.downloadArtifacts(data, data.getServiceArtifacts()));
+
assertThat(modelArtifacts, is(empty()));
assertThat(catalogFiles, is(empty()));
DistributionActionResultEnum.SUCCESS, null, "This content does not matter.".getBytes()));
doNothing().when(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, artifact);
- assertThat(downloadManager.downloadArtifacts(data, data.getServiceArtifacts(), null, new ArrayList<>()),
- is(false));
+ assertThrows(InvalidArchiveException.class,
+ () -> downloadManager.downloadArtifacts(data, data.getServiceArtifacts()));
+
Mockito.verify(mockDistributionClient).download(artifact);
Mockito.verify(mockNotificationPublisher).publishDownloadSuccess(mockDistributionClient, data, artifact);
Mockito.verify(mockNotificationPublisher).publishDeployFailure(mockDistributionClient, data, artifact);
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
-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 org.junit.jupiter.api.Test;
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;
@Test
public void convert_nullToscaFiles() throws BabelArtifactParsingException {
assertThrows(NullPointerException.class, () -> {
- new BabelArtifactConverter().convertToModel(null);
+ new BabelArtifactConverter(new ModelArtifactParser()).convertToModel(null);
fail("An instance of ArtifactGenerationException should have been thrown");
});
}
- @Test
- public void testEmptyToscaFiles() throws BabelArtifactParsingException {
- assertTrue(new BabelArtifactConverter().convertToModel(new ArrayList<>()).isEmpty(),
- "Nothing should have been returned");
- }
-
@Test
public void testInvalidXml() throws IOException, BabelArtifactParsingException {
assertThrows(BabelArtifactParsingException.class, () -> {
INotificationData data = NotificationDataFixtureBuilder.getNotificationDataWithToscaCsarFile();
- List<BabelArtifact> toscaArtifacts = setupTest(problemXml, data);
+ BabelArtifact toscaArtifact = setupTest(problemXml, data);
- new BabelArtifactConverter().convertToModel(toscaArtifacts);
+ new BabelArtifactConverter(new ModelArtifactParser()).convertToModel(toscaArtifact);
fail("An instance of ModelArtifactParsingException should have been thrown");
});
}
- private List<BabelArtifact> setupTest(byte[] xml, INotificationData data) throws IOException {
- List<BabelArtifact> 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
INotificationData data = NotificationDataFixtureBuilder.getNotificationDataWithToscaCsarFile();
byte[] xml = new ArtifactTestUtils().loadResource("convertedYmls/AAI-SCP-Test-VSP-resource-1.0.xml");
- List<BabelArtifact> toscaArtifacts = setupTest(xml, data);
+ BabelArtifact toscaArtifact = setupTest(xml, data);
- List<Artifact> modelArtifacts = new BabelArtifactConverter().convertToModel(toscaArtifacts);
+ List<Artifact> modelArtifacts = new BabelArtifactConverter(new ModelArtifactParser()).convertToModel(toscaArtifact);
assertEquals(1, modelArtifacts.size(), "There should have been 1 artifact");
assertEquals(new String(xml), modelArtifacts.get(0).getPayload());
*/
package org.onap.aai.modelloader.notification;
-import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Properties;
-
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.modelloader.entity.model.BabelArtifactParsingException;
+import org.onap.aai.modelloader.entity.Artifact;
+import org.onap.aai.modelloader.entity.ArtifactType;
import org.onap.aai.modelloader.fixture.NotificationDataFixtureBuilder;
import org.onap.aai.modelloader.service.ArtifactDeploymentManager;
import org.onap.sdc.api.IDistributionClient;
@Test
@SuppressWarnings("unchecked")
- public void activateCallback_downloadFails() {
+ public void activateCallback_downloadFails() throws Exception {
INotificationData data = NotificationDataFixtureBuilder.getNotificationDataWithToscaCsarFile();
- when(mockArtifactDownloadManager.downloadArtifacts(any(INotificationData.class), any(List.class),
- any(List.class), any(List.class))).thenReturn(false);
+ when(mockArtifactDownloadManager.downloadArtifacts(any(INotificationData.class), any(List.class)
+ )).thenThrow(DownloadFailureException.class);
eventCallback.activateCallback(data);
- verify(mockArtifactDownloadManager).downloadArtifacts(any(INotificationData.class), any(List.class),
- any(List.class), any(List.class));
+ verify(mockArtifactDownloadManager).downloadArtifacts(any(INotificationData.class), any(List.class));
Mockito.verifyNoInteractions(mockArtifactDeploymentManager);
}
@SuppressWarnings("unchecked")
@Test
- public void activateCallback() throws BabelArtifactParsingException {
+ public void activateCallback() throws Exception {
INotificationData data = NotificationDataFixtureBuilder.getNotificationDataWithToscaCsarFile();
- when(mockArtifactDownloadManager.downloadArtifacts(any(INotificationData.class), any(List.class),
- any(List.class), any(List.class))).thenReturn(true);
+ when(mockArtifactDownloadManager.downloadArtifacts(any(INotificationData.class), any(List.class)))
+ .thenReturn(Collections.emptyList());
- 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(mockArtifactDownloadManager).downloadArtifacts(any(INotificationData.class), any(List.class));
+ verify(mockArtifactDeploymentManager).deploy(any(String.class), any(List.class), any(List.class));
+ }
+ @Test
+ public void testActivateCallback_withVnfCatalogArtifacts() throws Exception {
+ INotificationData data = NotificationDataFixtureBuilder.getNotificationDataWithCatalogFile();
+
+ List<Artifact> downloadedArtifacts = new ArrayList<>();
+ downloadedArtifacts.add(new Artifact(ArtifactType.MODEL));
+ downloadedArtifacts.add(new Artifact(ArtifactType.VNF_CATALOG));
+
+ when(mockArtifactDownloadManager.downloadArtifacts(any(INotificationData.class), any(List.class)))
+ .thenReturn(downloadedArtifacts);
+
+ eventCallback.activateCallback(data);
+
+ verify(mockArtifactDeploymentManager).deploy(eq("ID"),
+ argThat(list -> list.stream().anyMatch(a -> a.getType() == ArtifactType.MODEL)),
+ anyList());
}
}
--- /dev/null
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.modelloader.restclient;
+
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.Test;
+
+public class BabelServiceClientExceptionTest {
+
+ @Test
+ public void testConstructorWithMessage() {
+ String expectedMessage = "This is a test error message";
+ BabelServiceClientException exception = new BabelServiceClientException(expectedMessage);
+ assertNotNull(exception);
+ assertEquals(expectedMessage, exception.getMessage(), "The exception message should match.");
+ }
+
+ @Test
+ public void testConstructorWithException() {
+ Exception underlyingException = new Exception("Underlying exception");
+ BabelServiceClientException exception = new BabelServiceClientException(underlyingException);
+
+ // Assert
+ assertNotNull(exception);
+ assertEquals(underlyingException, exception.getCause(), "The cause should match the passed exception.");
+ }
+}
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
-import java.util.Properties;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import javax.xml.parsers.DocumentBuilderFactory;
-import org.onap.aai.modelloader.config.ModelLoaderConfig;
+import org.onap.aai.modelloader.config.AaiProperties;
import org.onap.aai.modelloader.entity.ArtifactType;
import org.onap.aai.modelloader.entity.model.ModelArtifact;
import org.onap.aai.modelloader.entity.model.ModelArtifactParser;
// This test requires a running A&AI system. To test locally, annotate with org.junit.Test
public void testRestClient() throws Exception {
- Properties props = new Properties();
- props.setProperty("ml.distribution.ARTIFACT_TYPES", "MODEL_INVENTORY_PROFILE,MODEL_QUERY_SPEC,VNF_CATALOG");
- props.setProperty("ml.aai.BASE_URL", "https://localhost:8443");
- props.setProperty("ml.aai.MODEL_URL", "/aai/v9/service-design-and-creation/models/model/");
-
- ModelLoaderConfig config = new ModelLoaderConfig(props, ".");
+ AaiProperties aaiProperties = new AaiProperties();
+ aaiProperties.setBaseUrl("http://aai.onap:80");
+ aaiProperties.setModelUrl("/aai/%s/service-design-and-creation/models/model/");
+ aaiProperties.setNamedQueryUrl("/aai/%s/service-design-and-creation/named-queries/named-query/");
+ aaiProperties.setVnfImageUrl("/aai/%s/service-design-and-creation/vnf-images");
File xmlFile = new File(MODEL_FILE);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
model.setPayload(readFile(MODEL_FILE));
model.setModelNamespace("http://org.openecomp.aai.inventory/v9");
- AaiRestClient aaiClient = new AaiRestClient(config, new RestTemplate());
+ AaiRestClient aaiClient = new AaiRestClient(aaiProperties, new RestTemplate());
// GET model
ResponseEntity opResult =
- aaiClient.getResource(getUrl(model, config), "example-trans-id-0", MediaType.APPLICATION_XML, String.class);
+ aaiClient.getResource(getUrl(model, aaiProperties), "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",
+ opResult = aaiClient.putResource(getUrl(model, aaiProperties), model.getPayload(), "example-trans-id-1",
MediaType.APPLICATION_XML, String.class);
assertEquals(opResult.getStatusCode(), HttpStatus.CREATED);
// DELETE the model
- opResult = aaiClient.getAndDeleteResource(getUrl(model, config), "example-trans-id-3");
+ opResult = aaiClient.getAndDeleteResource(getUrl(model, aaiProperties), "example-trans-id-3");
assertEquals(opResult.getStatusCode(), HttpStatus.NO_CONTENT);
} catch (Exception e) {
e.printStackTrace();
return new String(encoded);
}
- private String getUrl(ModelArtifact model, ModelLoaderConfig config) {
+ private String getUrl(ModelArtifact model, AaiProperties aaiProperties) {
String subUrl;
if (model.getType().equals(ArtifactType.MODEL)) {
- subUrl = config.getAaiModelUrl(model.getModelNamespaceVersion()).trim();
+ subUrl = String.format(aaiProperties.getModelUrl(), model.getModelNamespaceVersion()).trim();
} else {
- subUrl = config.getAaiNamedQueryUrl(model.getModelNamespaceVersion()).trim();
+ subUrl = String.format(aaiProperties.getNamedQueryUrl(), model.getModelNamespaceVersion()).trim();
}
- String baseUrl = config.getAaiBaseUrl().trim();
+ String baseUrl = aaiProperties.getBaseUrl().trim();
if (!baseUrl.endsWith("/") && !subUrl.startsWith("/")) {
baseUrl = baseUrl + "/";
}
--- /dev/null
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.modelloader.service;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.test.web.servlet.MockMvc;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+
+@WebMvcTest(EchoService.class)
+public class EchoServiceTest {
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @Test
+ public void testEcho() throws Exception {
+ String input = "hello";
+ mockMvc.perform(get("/services/model-loader/v1/echo-service/echo/{input}", input))
+ .andExpect(status().isOk())
+ .andExpect(content().string(input));
+ }
+
+ @Test
+ public void testEchoSpecialCharacters() throws Exception {
+ String input = "!@#$%^&*()";
+ mockMvc.perform(get("/services/model-loader/v1/echo-service/echo/{input}", input))
+ .andExpect(status().isOk())
+ .andExpect(content().string(input));
+ }
+}
import java.util.Base64;
import java.util.Collections;
-import javax.ws.rs.core.Response;
-
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
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;
/**
@Autowired NotificationPublisher notificationPublisher;
@Autowired VnfCatalogExtractor vnfCatalogExtractor;
- @Mock BabelServiceClientFactory clientFactory;
@Mock BabelServiceClient babelServiceClient;
@InjectMocks BabelArtifactService babelArtifactService;
@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() {
- Response response = modelController.loadModel("");
- assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
+ ResponseEntity<String> response = modelController.loadModel("");
+ assertThat(response.getStatusCode(), is(HttpStatus.OK));
}
@Test
public void testSaveModel() {
- Response response = modelController.saveModel("", "");
- assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
+ ResponseEntity<String> 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");
- Response response = modelController.ingestModel("model-name", "", Base64.getEncoder().encodeToString(csarPayload));
- assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
+ ResponseEntity<String> 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");
- Response response = modelController.ingestModel("", "", Base64.getEncoder().encodeToString(csarPayload));
- assertThat(response.getStatus(), is(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()));
+ ResponseEntity<String> response = modelController.ingestModel("", "", Base64.getEncoder().encodeToString(csarPayload));
+ assertThat(response.getStatusCode(), is(HttpStatus.INTERNAL_SERVER_ERROR));
}
}
import java.io.IOException;
import java.util.Base64;
-import javax.ws.rs.core.Response;
-
import org.junit.jupiter.api.Test;
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;
/**
@Test
public void testIngestModel() throws IOException {
byte[] csarPayload = new ArtifactTestUtils().loadResource("compressedArtifacts/service-VscpaasTest-csar.csar");
- Response response = controller.ingestModel("model-name", "", Base64.getEncoder().encodeToString(csarPayload));
- assertThat(response.getStatus(), is(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()));
+ ResponseEntity<String> response = controller.ingestModel("model-name", "", Base64.getEncoder().encodeToString(csarPayload));
+ assertThat(response.getStatusCode(), is(HttpStatus.INTERNAL_SERVER_ERROR));
}
--- /dev/null
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.modelloader.service;
+
+import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.*;
+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.notification.EventCallback;
+import org.onap.sdc.api.IDistributionClient;
+import org.onap.sdc.api.results.IDistributionClientResult;
+import org.onap.sdc.utils.DistributionActionResultEnum;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.TestPropertySource;
+
+import java.util.Timer;
+
+@SpringBootTest
+@TestPropertySource(properties = {"CONFIG_HOME=src/test/resources",})
+public class TestSdcConnectionJob {
+
+ @Mock
+ private IDistributionClient client;
+
+ @Mock
+ private ModelLoaderConfig config;
+
+ @Mock
+ private EventCallback callback;
+
+ @Mock
+ private Timer timer;
+
+ @Mock
+ private IDistributionClientResult clientResult;
+
+ @Mock
+ private Logger logger;
+
+ private SdcConnectionJob connectionJob;
+
+ @BeforeEach
+ public void setUp() {
+ MockitoAnnotations.openMocks(this);
+ LoggerFactory loggerFactorySpy = mock(LoggerFactory.class);
+ when(loggerFactorySpy.getLogger(SdcConnectionJob.class.getName())).thenReturn(logger);
+ connectionJob = new SdcConnectionJob(client, config, callback, timer);
+ }
+
+ @Test
+ public void testRunWhenASDCConnectionDisabled() {
+ when(config.getASDCConnectionDisabled()).thenReturn(true);
+ connectionJob.run();
+ verify(client, never()).init(any(), any());
+ verify(client, never()).start();
+ verify(config, times(1)).getASDCConnectionDisabled();
+ }
+
+ @Test
+ public void testRunInitializationFails() {
+ when(config.getASDCConnectionDisabled()).thenReturn(false);
+ when(client.init(config, callback)).thenReturn(clientResult);
+ when(clientResult.getDistributionActionResult()).thenReturn(DistributionActionResultEnum.FAIL);
+ connectionJob.run();
+ verify(client).init(config, callback);
+ verify(client, never()).start();
+ verify(config, times(1)).getASDCConnectionDisabled();
+ }
+
+ @Test
+ public void testRunInitializationSucceedsButStartFails() {
+ when(config.getASDCConnectionDisabled()).thenReturn(false);
+ when(client.init(config, callback)).thenReturn(clientResult);
+ when(clientResult.getDistributionActionResult()).thenReturn(DistributionActionResultEnum.SUCCESS);
+
+ IDistributionClientResult startResult = mock(IDistributionClientResult.class);
+ when(client.start()).thenReturn(startResult);
+ when(startResult.getDistributionActionResult()).thenReturn(DistributionActionResultEnum.FAIL);
+
+ connectionJob.run();
+ verify(client,times(1)).start();
+ verify(timer, never()).cancel();
+ verify(config, times(1)).getASDCConnectionDisabled();
+ }
+
+ @Test
+ public void testRunInitializationAndStartBothSucceed() {
+ when(config.getASDCConnectionDisabled()).thenReturn(false);
+ when(client.init(config, callback)).thenReturn(clientResult);
+ when(clientResult.getDistributionActionResult()).thenReturn(DistributionActionResultEnum.SUCCESS);
+
+ IDistributionClientResult startResult = mock(IDistributionClientResult.class);
+ when(client.start()).thenReturn(startResult);
+ when(startResult.getDistributionActionResult()).thenReturn(DistributionActionResultEnum.SUCCESS);
+
+ connectionJob.run();
+ verify(client).init(config, callback);
+ verify(client,times(1)).start();
+ verify(timer).cancel();
+ }
+
+}
{
- "kafkaBootStrapServer": "localhost:9092",
+ "kafkaBootStrapServer": "{{parameters.kafkaBootstrapAddress}}",
"distrNotificationTopicName": "SDC-DISTR-NOTIF-TOPIC-AUTO",
"distrStatusTopicName": "SDC-DISTR-STATUS-TOPIC-AUTO"
-}
\ No newline at end of file
+}
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
+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)
+ml.babel.generate-artifacts-url=/services/babel-service/v1/app/generateArtifacts
+ml.babel.base-url=http://localhost:${wiremock.server.port}
-spring.main.allow-bean-definition-overriding=true
\ No newline at end of file
+spring.main.allow-bean-definition-overriding=true
--- /dev/null
+{
+ "distributionID": "ac6f29fc-d6b3-428b-8ee2-b2e3ea636fe9",
+ "serviceName": "pnf_macro",
+ "serviceVersion": "1.0",
+ "serviceUUID": "1b8b0466-f7f2-4616-8198-055228f8d1eb",
+ "serviceDescription": "ONAP SDK Service",
+ "serviceInvariantUUID": "8939eac6-07f9-4395-b7ab-fe5c1a3e7cfe",
+ "resources": [
+ {
+ "resourceInstanceName": "pnf_macro 0",
+ "resourceName": "pnf_macro",
+ "resourceVersion": "1.0",
+ "resoucreType": "PNF",
+ "resourceUUID": "ef5c823c-c048-4d0c-94d3-4569ee66947c",
+ "resourceInvariantUUID": "27dd7ddf-babc-402e-b04a-bb76a0f58a4a",
+ "resourceCustomizationUUID": "33e9569f-0e58-4bb4-9825-43925ddeb213",
+ "category": "Generic",
+ "subcategory": "Network Service",
+ "artifacts": [
+ {
+ "artifactName": "vf-license-model.xml",
+ "artifactType": "VF_LICENSE",
+ "artifactURL": "/sdc/v1/catalog/services/PnfMacro/1.0/resourceInstances/pnf_macro0/artifacts/vf-license-model.xml",
+ "artifactChecksum": "ZmJlMzZkN2NkZWRjNDUyNDUwZTY2YjE0NmNkMGFiOWI=",
+ "artifactDescription": "VF license file",
+ "artifactTimeout": 0,
+ "artifactUUID": "f8c6e818-aa35-43d2-bc23-fb2c498fb675",
+ "artifactVersion": "1"
+ },
+ {
+ "artifactName": "pNF.csar",
+ "artifactType": "ETSI_PACKAGE",
+ "artifactURL": "/sdc/v1/catalog/services/PnfMacro/1.0/resourceInstances/pnf_macro0/artifacts/pNF.csar",
+ "artifactChecksum": "ZGVhZmM4YTM3NDgwYjQxNDFmZjYzYzQ5N2E4NDFkNDE=",
+ "artifactDescription": "Artifact created from csar",
+ "artifactTimeout": 0,
+ "artifactUUID": "27a07164-8d63-4d7e-a8b3-8422e938b37c",
+ "artifactVersion": "1"
+ },
+ {
+ "artifactName": "mynetconf.yang",
+ "artifactType": "YANG_MODULE",
+ "artifactURL": "/sdc/v1/catalog/services/PnfMacro/1.0/resourceInstances/pnf_macro0/artifacts/mynetconf.yang",
+ "artifactChecksum": "N2Q1MDkxNjUwYzU1MWI2OTUzNmY4YTc3YmQ2YTlkZTc=",
+ "artifactDescription": "Artifact created from csar",
+ "artifactTimeout": 0,
+ "artifactUUID": "b5ce5c4e-4501-45e6-826b-6cbfbe8dbfee",
+ "artifactVersion": "1"
+ },
+ {
+ "artifactName": "vendor-license-model.xml",
+ "artifactType": "VENDOR_LICENSE",
+ "artifactURL": "/sdc/v1/catalog/services/PnfMacro/1.0/resourceInstances/pnf_macro0/artifacts/vendor-license-model.xml",
+ "artifactChecksum": "MTZiYmJhZmJiOTBjZmVkYzNjM2UwNjFkZmZmYzNkNjc=",
+ "artifactDescription": " Vendor license file",
+ "artifactTimeout": 0,
+ "artifactUUID": "8c68e938-4988-4107-834a-eab4c4e65392",
+ "artifactVersion": "1"
+ },
+ {
+ "artifactName": "PM_Dictionary.yaml",
+ "artifactType": "PM_DICTIONARY",
+ "artifactURL": "/sdc/v1/catalog/services/PnfMacro/1.0/resourceInstances/pnf_macro0/artifacts/PM_Dictionary.yaml",
+ "artifactChecksum": "ZDJlYTVlNjA2ZGRhOTc3MDBkODVjNmEyMjA2OTA5YTE=",
+ "artifactDescription": "Artifact created from csar",
+ "artifactTimeout": 0,
+ "artifactUUID": "e014ef41-35a6-4222-9c52-907c3a42a0b3",
+ "artifactVersion": "1"
+ },
+ {
+ "artifactName": "MyPnf_Pnf_v1.yaml",
+ "artifactType": "VES_EVENTS",
+ "artifactURL": "/sdc/v1/catalog/services/PnfMacro/1.0/resourceInstances/pnf_macro0/artifacts/MyPnf_Pnf_v1.yaml",
+ "artifactChecksum": "ZTllOGUwNjdiYWEyMWJhZDc4NjNlOGNmNGJkZWVlMWY=",
+ "artifactDescription": "Artifact created from csar",
+ "artifactTimeout": 0,
+ "artifactUUID": "e01c8cab-cb60-493b-895f-b1998bbaed84",
+ "artifactVersion": "1"
+ }
+ ]
+ }
+ ],
+ "serviceArtifacts": [
+ {
+ "artifactName": "service-PnfMacro-template.yml",
+ "artifactType": "TOSCA_TEMPLATE",
+ "artifactURL": "/sdc/v1/catalog/services/PnfMacro/1.0/artifacts/service-PnfMacro-template.yml",
+ "artifactChecksum": "YmEzMTIzYTU5NDQ4MGIzNThmM2Q3N2Q5OTNiZjhlYjA=",
+ "artifactDescription": "TOSCA representation of the asset",
+ "artifactTimeout": 0,
+ "artifactUUID": "9c5c224c-7c6e-41c6-abd9-0bc5169e566c",
+ "artifactVersion": "1"
+ },
+ {
+ "artifactName": "service-PnfMacro-csar.csar",
+ "artifactType": "TOSCA_CSAR",
+ "artifactURL": "/sdc/v1/catalog/services/PnfMacro/1.0/artifacts/service-PnfMacro-csar.csar",
+ "artifactChecksum": "MTQ5YmNkMjVkOWI2NmJhYzg5NTNiNzQ3YTA2NGIzYTA=",
+ "artifactDescription": "TOSCA definition package of the asset",
+ "artifactTimeout": 0,
+ "artifactUUID": "61d45180-7c5f-4ae0-9044-6b005de76b3f",
+ "artifactVersion": "1"
+ }
+ ],
+ "workloadContext": "Production"
+}
# Disable ASDC polling & enable REST interface
ml.distribution.ASDC_CONNECTION_DISABLE=true
ml.debug.INGEST_SIMULATOR=enabled
-
-# Model Loader Client Configuration for the A&AI REST interface
-ml.aai.BASE_URL=https://localhost:8443
-ml.aai.MODEL_URL=/aai/v*/service-design-and-creation/models/model/
-ml.aai.NAMED_QUERY_URL=/aai/v*/service-design-and-creation/named-queries/named-query/
-ml.aai.VNF_IMAGE_URL=/aai/v*/service-design-and-creation/vnf-images
-ml.aai.KEYSTORE_FILE=aai-client-cert.p12
-ml.aai.KEYSTORE_PASSWORD=
-ml.aai.AUTH_USER=ModelLoader
-ml.aai.AUTH_PASSWORD=
# Disable ASDC polling & enable REST interface
ml.distribution.ASDC_CONNECTION_DISABLE=true
ml.debug.INGEST_SIMULATOR=enabled
-
-# Model Loader Client Configuration for the A&AI REST interface
-ml.aai.BASE_URL=https://localhost:8443
-ml.aai.MODEL_URL=/aai/v*/service-design-and-creation/models/model/
-ml.aai.NAMED_QUERY_URL=/aai/v*/service-design-and-creation/named-queries/named-query/
-ml.aai.VNF_IMAGE_URL=/aai/v*/service-design-and-creation/vnf-images
-ml.aai.KEYSTORE_FILE=aai-client-cert.p12
-ml.aai.KEYSTORE_PASSWORD=
ml.distribution.KEYSTORE_PASSWORD=
ml.distribution.KEYSTORE_FILE=
ml.distribution.PASSWORD=Aa123456
-ml.distribution.POLLING_INTERVAL=15
-ml.distribution.POLLING_TIMEOUT=3
+ml.distribution.POLLING_INTERVAL=2
+ml.distribution.POLLING_TIMEOUT=1
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";
# Disable ASDC polling & enable REST interface
ml.distribution.ASDC_CONNECTION_DISABLE=true
ml.debug.INGEST_SIMULATOR=enabled
-
-# Model Loader Client Configuration for the A&AI REST interface
-ml.aai.BASE_URL=https://localhost:8443
-ml.aai.MODEL_URL=/aai/v*/service-design-and-creation/models/model/
-ml.aai.NAMED_QUERY_URL=/aai/v*/service-design-and-creation/named-queries/named-query/
-ml.aai.VNF_IMAGE_URL=/aai/v*/service-design-and-creation/vnf-images
-ml.aai.KEYSTORE_FILE=aai-client-cert.p12
-ml.aai.KEYSTORE_PASSWORD=
-ml.aai.AUTH_USER=ModelLoader
-ml.aai.AUTH_PASSWORD=
-
-# Model Loader Client Configuration for the Babel Service
-ml.babel.BASE_URL=
-ml.babel.GENERATE_ARTIFACTS_URL=/services/babel-service/v1/app/generateArtifacts
-ml.babel.KEYSTORE_FILE=aai-client-cert.p12
-ml.babel.KEYSTORE_PASSWORD=
ml.distribution.POLLING_TIMEOUT=20
ml.distribution.USER=ci
ml.distribution.ARTIFACT_TYPES=MODEL_QUERY_SPEC,TOSCA_CSAR
-
-# Model Loader Client Configuration for the A&AI REST interface
-ml.aai.BASE_URL=https://localhost:8443
-ml.aai.MODEL_URL=/aai/v*/service-design-and-creation/models/model/
-ml.aai.NAMED_QUERY_URL=/aai/v*/service-design-and-creation/named-queries/named-query/
-ml.aai.VNF_IMAGE_URL=/aai/v*/service-design-and-creation/vnf-images
-ml.aai.KEYSTORE_FILE=aai-client-cert.p12
-ml.aai.KEYSTORE_PASSWORD=
-ml.aai.AUTH_USER=ModelLoader
-ml.aai.AUTH_PASSWORD=
-
-# Model Loader Client Configuration for the Babel Service
-ml.babel.BASE_URL=
-ml.babel.GENERATE_ARTIFACTS_URL=
-ml.babel.KEYSTORE_FILE=
-ml.babel.KEYSTORE_PASSWORD=
# because they are used in Jenkins, whose plug-in doesn't support
major=1
-minor=13
-patch=6
+minor=14
+patch=3
base_version=${major}.${minor}.${patch}