From 03a107d9254ca0e1fbbf63f2ab5b7f14f1af63f3 Mon Sep 17 00:00:00 2001 From: MD IRSHAD SHEIKH Date: Mon, 22 Mar 2021 18:18:37 +0530 Subject: [PATCH] Added CSIT for Macroflow with HEAT Issue-ID: SO-3533 Signed-off-by: MD IRSHAD SHEIKH Change-Id: Id23cd64850ffcdf165d4a5ea031d6778fd0011be --- .../config/apply-workarounds.sh | 2 + .../controller/GenericVnfsController.java | 64 ++++ .../providers/GenericVnfCacheServiceProvider.java | 5 + .../GenericVnfCacheServiceProviderImpl.java | 63 ++++ .../org/onap/so/aaisimulator/utils/Constants.java | 2 + .../so-simulators/multicloud-simulator/HELP.md | 9 + .../so-simulators/multicloud-simulator/mvnw | 310 +++++++++++++++++ .../so-simulators/multicloud-simulator/mvnw.cmd | 182 ++++++++++ .../so-simulators/multicloud-simulator/pom.xml | 86 +++++ .../MultiCloudSimulatorApplication.java | 35 ++ .../beans/InstanceNameOutput.java | 77 +++++ .../multicloudsimulator/beans/InstanceOutput.java | 79 +++++ .../beans/InstanceResponse.java | 81 +++++ .../beans/MulticloudCreateResponse.java | 106 ++++++ .../beans/MulticloudInstanceRequest.java | 104 ++++++ .../beans/MulticloudRequest.java | 158 +++++++++ .../so/multicloudsimulator/beans/Resource.java | 51 +++ .../so/multicloudsimulator/beans/Response.java | 40 +++ .../configuration/ApplicationConfiguration.java | 42 +++ .../configuration/WebSecurityConfigImpl.java | 43 +++ .../controller/MultiCloudController.java | 128 +++++++ .../so/multicloudsimulator/utils/Constants.java | 30 ++ .../src/main/resources/application.properties | 1 + .../src/main/resources/application.yaml | 16 + .../main/resources/data/InstanceNameOutput.json | 6 + .../src/main/resources/data/InstanceOutput.json | 8 + .../MultiCloudSimulatorApplicationTests.java | 55 ++++ .../so-simulators/package/docker/pom.xml | 28 ++ .../Dockerfile.multicloud-simulator-base-image | 34 ++ .../integration-etsi-testing/so-simulators/pom.xml | 1 + .../sdncsimulator/controller/ConfigController.java | 94 ++++++ .../controller/OperationsController.java | 33 ++ .../org/onap/so/sdncsimulator/models/Output.java | 11 +- .../ServiceOperationsCacheServiceProvider.java | 11 +- .../ServiceOperationsCacheServiceProviderimpl.java | 168 +++++++++- .../macro_zipped_sdc_csar.tar.gz | Bin 0 -> 111485 bytes plans/so/macroflow/config/env | 5 + .../api-handler-infra/onapheat/override.yaml | 133 ++++++++ .../bpmn-infra/onapheat/override.yaml | 366 +++++++++++++++++++++ .../catalog-db-adapter/onapheat/override.yaml | 103 ++++++ .../openstack-adapter/onapheat/override.yaml | 147 +++++++++ .../sdc-controller/onapheat/override.yaml | 81 +++++ .../so-monitoring/onapheat/override.yaml | 24 ++ .../so-vnfm-adapter/onapheat/override.yaml | 33 ++ .../vnfm-simulator/onapheat/override.yaml | 56 ++++ plans/so/macroflow/docker-compose.local.yml | 30 ++ plans/so/macroflow/docker-compose.yml | 328 ++++++++++++++++++ plans/so/macroflow/setup.sh | 104 ++++-- plans/so/macroflow/teardown.sh | 41 ++- tests/so/sanity-check/data/macroflow.json | 161 +++++++++ .../data/serviceBasicVfCnfnotification.json | 294 +++++++++++++++++ tests/so/sanity-check/macroflow.robot | 28 +- 52 files changed, 4050 insertions(+), 47 deletions(-) create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/HELP.md create mode 100755 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/mvnw create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/mvnw.cmd create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/pom.xml create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/MultiCloudSimulatorApplication.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/InstanceNameOutput.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/InstanceOutput.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/InstanceResponse.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/MulticloudCreateResponse.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/MulticloudInstanceRequest.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/MulticloudRequest.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/Resource.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/Response.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/configuration/ApplicationConfiguration.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/configuration/WebSecurityConfigImpl.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/controller/MultiCloudController.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/utils/Constants.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/application.properties create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/application.yaml create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/data/InstanceNameOutput.json create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/data/InstanceOutput.json create mode 100644 plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/test/java/org/onap/so/multicloudsimulator/MultiCloudSimulatorApplicationTests.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/package/docker/src/main/docker/docker-files/Dockerfile.multicloud-simulator-base-image create mode 100644 plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/ConfigController.java create mode 100755 plans/so/macroflow/config/distribution-test-zip/macro_zipped_sdc_csar.tar.gz create mode 100644 plans/so/macroflow/config/override-files/api-handler-infra/onapheat/override.yaml create mode 100644 plans/so/macroflow/config/override-files/bpmn-infra/onapheat/override.yaml create mode 100644 plans/so/macroflow/config/override-files/catalog-db-adapter/onapheat/override.yaml create mode 100644 plans/so/macroflow/config/override-files/openstack-adapter/onapheat/override.yaml create mode 100644 plans/so/macroflow/config/override-files/sdc-controller/onapheat/override.yaml create mode 100644 plans/so/macroflow/config/override-files/so-monitoring/onapheat/override.yaml create mode 100644 plans/so/macroflow/config/override-files/so-vnfm-adapter/onapheat/override.yaml create mode 100644 plans/so/macroflow/config/override-files/vnfm-simulator/onapheat/override.yaml create mode 100644 plans/so/macroflow/docker-compose.local.yml create mode 100644 tests/so/sanity-check/data/macroflow.json create mode 100644 tests/so/sanity-check/data/serviceBasicVfCnfnotification.json diff --git a/plans/so/integration-etsi-testing/config/apply-workarounds.sh b/plans/so/integration-etsi-testing/config/apply-workarounds.sh index 21a3aeb8..4ecf880f 100755 --- a/plans/so/integration-etsi-testing/config/apply-workarounds.sh +++ b/plans/so/integration-etsi-testing/config/apply-workarounds.sh @@ -109,6 +109,8 @@ mysql -h $DB_HOST -uroot -p$MYSQL_ROOT_PASSWORD $CATALOG_DB << EOF UPDATE orchestration_status_state_transition_directive SET FLOW_DIRECTIVE='CONTINUE' WHERE RESOURCE_TYPE='VNF' AND ORCHESTRATION_STATUS='CREATED' AND TARGET_ACTION='ACTIVATE' AND FLOW_DIRECTIVE='FAIL'; + insert into cloud_sites(ID, REGION_ID, IDENTITY_SERVICE_ID, CLOUD_VERSION, CLLI, ORCHESTRATOR) values("EtsiCloudRegion", "EtsiCloudRegion", "DEFAULT_KEYSTONE", "2.5", "clli2", "multicloud"); + COMMIT; EOF diff --git a/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/controller/GenericVnfsController.java b/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/controller/GenericVnfsController.java index 43fe47da..22209fc8 100644 --- a/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/controller/GenericVnfsController.java +++ b/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/controller/GenericVnfsController.java @@ -22,6 +22,7 @@ package org.onap.so.aaisimulator.controller; import static org.onap.so.aaisimulator.utils.Constants.APPLICATION_MERGE_PATCH_JSON; import static org.onap.so.aaisimulator.utils.Constants.BI_DIRECTIONAL_RELATIONSHIP_LIST_URL; import static org.onap.so.aaisimulator.utils.Constants.GENERIC_VNF; +import static org.onap.so.aaisimulator.utils.Constants.VF_MODULE; import static org.onap.so.aaisimulator.utils.Constants.GENERIC_VNFS_URL; import static org.onap.so.aaisimulator.utils.Constants.RELATIONSHIP_LIST_RELATIONSHIP_URL; import static org.onap.so.aaisimulator.utils.Constants.X_HTTP_METHOD_OVERRIDE; @@ -35,6 +36,8 @@ import javax.ws.rs.core.MediaType; import org.onap.aai.domain.yang.GenericVnf; import org.onap.aai.domain.yang.GenericVnfs; import org.onap.aai.domain.yang.Relationship; +import org.onap.aai.domain.yang.VfModule; +import org.onap.aai.domain.yang.VfModules; import org.onap.so.aaisimulator.service.providers.GenericVnfCacheServiceProvider; import org.onap.so.aaisimulator.utils.HttpServiceUtils; import org.onap.so.aaisimulator.utils.RequestErrorResponseUtils; @@ -47,6 +50,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; @@ -211,5 +215,65 @@ public class GenericVnfsController { return getRequestErrorResponseEntity(request, GENERIC_VNF); } + + + @GetMapping(value = "/generic-vnf/{vnf-id}/vf-modules/vf-module/{vf-module-id}", produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + public ResponseEntity getVfModule(@PathVariable("vnf-id") final String vnfId, @PathVariable("vf-module-id") final String vfModuleId, + @RequestParam(name = "depth", required = false) final Integer depth, + @RequestParam(name = "resultIndex", required = false) final Integer resultIndex, + @RequestParam(name = "resultSize", required = false) final Integer resultSize, + @RequestParam(name = "format", required = false) final String format, final HttpServletRequest request) { + LOGGER.info( + "Will get VfModule for 'vf-module-id': {} with depth: {}, resultIndex: {}, resultSize:{}, format: {} ...", + vnfId, vfModuleId, depth, resultIndex, resultSize, format); + + final Optional optional = cacheServiceProvider.getVfModule(vnfId, vfModuleId); + + if (optional.isPresent()) { + final VfModule vfModule = optional.get(); + LOGGER.info("found VfModule {} in cache", vfModule); + return ResponseEntity.ok(vfModule); + } + + LOGGER.error( + "Unable to find VfModule in cache for 'vf-module-id': {} with depth: {}, resultIndex: {}, resultSize:{}, format:{} ...", + vnfId, vfModuleId, depth, resultIndex, resultSize, format); + return getRequestErrorResponseEntity(request, VF_MODULE); + + } + + + @PutMapping(value = "/generic-vnf/{vnf-id}/vf-modules/vf-module/{vf-module-id}", consumes = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}, + produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + public ResponseEntity putVfModule(@RequestBody final VfModule vfModule, + @PathVariable("vnf-id") final String vnfId, @PathVariable("vf-module-id") final String vfModuleId, final HttpServletRequest request) { + LOGGER.info("Will add VfModule to cache with 'vf-module-id': {} ...", vfModuleId); + + cacheServiceProvider.putVfModule(vnfId, vfModuleId, vfModule); + return ResponseEntity.accepted().build(); + } + + @PostMapping(value = "/generic-vnf/{vnf-id}/vf-modules/vf-module/{vf-module-id}", + consumes = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, APPLICATION_MERGE_PATCH_JSON}, + produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + public ResponseEntity patchVfModule(@RequestBody final VfModule vfModule, + @PathVariable("vnf-id") final String vnfId, @PathVariable("vf-module-id") final String vfModuleId, + @RequestHeader(value = X_HTTP_METHOD_OVERRIDE, required = false) final String xHttpHeaderOverride, + final HttpServletRequest request) { + + LOGGER.info("Will post VfModule to cache with 'vf-module-id': {} and '{}': {} ...", vfModuleId, X_HTTP_METHOD_OVERRIDE, + xHttpHeaderOverride); + + if (HttpMethod.PATCH.toString().equalsIgnoreCase(xHttpHeaderOverride)) { + if (cacheServiceProvider.patchVfModule(vnfId, vfModuleId, vfModule)) { + return ResponseEntity.accepted().build(); + } + LOGGER.error("Unable to apply patch to VmModule using 'vf-module-id': {} ... ", vfModule); + return getRequestErrorResponseEntity(request, VF_MODULE); + } + LOGGER.error("{} not supported ... ", xHttpHeaderOverride); + + return getRequestErrorResponseEntity(request, VF_MODULE); + } } diff --git a/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/service/providers/GenericVnfCacheServiceProvider.java b/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/service/providers/GenericVnfCacheServiceProvider.java index 901c2594..5570381b 100644 --- a/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/service/providers/GenericVnfCacheServiceProvider.java +++ b/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/service/providers/GenericVnfCacheServiceProvider.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Optional; import org.onap.aai.domain.yang.GenericVnf; import org.onap.aai.domain.yang.Relationship; +import org.onap.aai.domain.yang.VfModule; import org.springframework.http.HttpHeaders; /** @@ -49,5 +50,9 @@ public interface GenericVnfCacheServiceProvider extends Clearable { boolean deleteGenericVnf(final String vnfId, final String resourceVersion); + void putVfModule(final String vnfId, final String vfModuleId, final VfModule vfModule); + Optional getVfModule(final String vnfId, final String vfModuleId); + + boolean patchVfModule(final String vnfId, final String vfModuleId, final VfModule vfModule); } diff --git a/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/service/providers/GenericVnfCacheServiceProviderImpl.java b/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/service/providers/GenericVnfCacheServiceProviderImpl.java index e7a42106..42b2d872 100644 --- a/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/service/providers/GenericVnfCacheServiceProviderImpl.java +++ b/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/service/providers/GenericVnfCacheServiceProviderImpl.java @@ -37,6 +37,8 @@ import org.onap.aai.domain.yang.RelatedToProperty; import org.onap.aai.domain.yang.Relationship; import org.onap.aai.domain.yang.RelationshipData; import org.onap.aai.domain.yang.RelationshipList; +import org.onap.aai.domain.yang.VfModule; +import org.onap.aai.domain.yang.VfModules; import org.onap.so.aaisimulator.utils.ShallowBeanCopy; import org.onap.so.simulator.cache.provider.AbstractCacheServiceProvider; import org.slf4j.Logger; @@ -58,6 +60,7 @@ public class GenericVnfCacheServiceProviderImpl extends AbstractCacheServiceProv private static final Logger LOGGER = LoggerFactory.getLogger(GenericVnfCacheServiceProviderImpl.class); private final HttpRestServiceProvider httpRestServiceProvider; + //final VfModules vfModules = new VfModules(); @Autowired public GenericVnfCacheServiceProviderImpl(final CacheManager cacheManager, @@ -255,4 +258,64 @@ public class GenericVnfCacheServiceProviderImpl extends AbstractCacheServiceProv clearCache(GENERIC_VNF_CACHE.getName()); } + @Override + public Optional getVfModule(final String vnfId, final String vfModuleId) { + LOGGER.info("Getting vfModule from cache for vnfId: {} and vfModuleId: {}", + vnfId, vfModuleId); + final Optional genericVnfOptional = getGenericVnf(vnfId); + final GenericVnf value = genericVnfOptional.get(); + final VfModules vfmodules = value.getVfModules(); + if (vfmodules != null) { + for (VfModule vfModule : vfmodules.getVfModule()) { + if (vfModule.getVfModuleId().equalsIgnoreCase(vfModuleId)){ + return Optional.of(vfModule); + } + } + } + return Optional.empty(); + } + + + @Override + public void putVfModule(final String vnfId, final String vfModuleId, final VfModule vfModule) { + LOGGER.info("Adding vfModule for vnfId: {} and vfModuleId: {}", + vnfId, vfModuleId); + final Optional genericVnfOptional = getGenericVnf(vnfId); + final Cache cache = getCache(GENERIC_VNF_CACHE.getName()); + if (genericVnfOptional.isPresent()) { + final GenericVnf genericVnf = genericVnfOptional.get(); + VfModules vfModules = null; + if(genericVnf.getVfModules()==null){ + vfModules = new VfModules(); + genericVnf.setVfModules(vfModules); + } else { + vfModules = genericVnf.getVfModules(); + } + + vfModules.getVfModule().add(vfModule); + cache.put(vfModuleId, vfModule); + } + } + + @Override + public boolean patchVfModule(final String vnfId, final String vfModuleId, final VfModule vfModule) { + final Optional genericVnfOptional = getGenericVnf(vnfId); + LOGGER.info("Create vfModule for vnfId: {} and vfModuleId: {}", + vnfId, vfModuleId); + if (genericVnfOptional.isPresent()) { + final GenericVnf cachedGenericVnf = genericVnfOptional.get(); + final VfModules vfmodules = cachedGenericVnf.getVfModules(); + LOGGER.info("vfModuleId is Matched"); + try { + vfmodules.getVfModule().stream().filter(tempVfModule -> + tempVfModule.getVfModuleId().equalsIgnoreCase(vfModuleId)).forEach(tempVfModule -> + tempVfModule.setOrchestrationStatus(vfModule.getOrchestrationStatus())); + return true; + } catch (final Exception exception) { + LOGGER.error("Unable to update VfModule for vfModuleId: {}", vfModule, exception); + } + } + LOGGER.error("Unable to find VfModule ..."); + return false; + } } diff --git a/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/utils/Constants.java b/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/utils/Constants.java index 4099c2a0..4cd5b25a 100644 --- a/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/utils/Constants.java +++ b/plans/so/integration-etsi-testing/so-simulators/aai-simulator/src/main/java/org/onap/so/aaisimulator/utils/Constants.java @@ -89,6 +89,8 @@ public class Constants { public static final String COMPOSED_OF = "org.onap.relationships.inventory.ComposedOf"; public static final String GENERIC_VNF = "generic-vnf"; + + public static final String VF_MODULE = "vf-module"; public static final String PLATFORM = "platform"; diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/HELP.md b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/HELP.md new file mode 100644 index 00000000..c8c1987d --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/HELP.md @@ -0,0 +1,9 @@ +# Getting Started + +### Reference Documentation +For further reference, please consider the following sections: + +* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) +* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.4.2/maven-plugin/reference/html/) +* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.4.2/maven-plugin/reference/html/#build-image) + diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/mvnw b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/mvnw new file mode 100755 index 00000000..a16b5431 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# https://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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/mvnw.cmd b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/mvnw.cmd new file mode 100644 index 00000000..c8d43372 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/pom.xml b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/pom.xml new file mode 100644 index 00000000..80e21746 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/pom.xml @@ -0,0 +1,86 @@ + + + 4.0.0 + + org.onap.so.simulators + so-simulators + 1.0-SNAPSHOT + + multicloud-simulator + ${project.artifactId} + MultiCloud Simulator + + 11 + 1.1 + 3.2.0 + 3.2.0 + 1.7.1-SNAPSHOT + 2.1.1.RELEASE + + + + ${project.parent.groupId} + common + ${project.version} + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + com.googlecode.json-simple + json-simple + ${json-simple.version} + + + org.onap.so.adapters + mso-adapters-rest-interface + ${mso-adapters.version} + + + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + ${spring-security.version} + + + + + + org.springframework.boot + spring-boot-maven-plugin + + org.onap.so.multicloudsimulator.MultiCloudSimulatorApplication + + + + + repackage + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/MultiCloudSimulatorApplication.java b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/MultiCloudSimulatorApplication.java new file mode 100644 index 00000000..479c4810 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/MultiCloudSimulatorApplication.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright 2021 Huawei Technologies Co., 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.so.multicloudsimulator; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author Md Irshad Sheikh (md.irshad.sheikh@huawei.com) + * + */ +@SpringBootApplication(scanBasePackages = { "org.onap" }) +public class MultiCloudSimulatorApplication { + + public static void main(String[] args) { + SpringApplication.run(MultiCloudSimulatorApplication.class, args); + + } + +} \ No newline at end of file diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/InstanceNameOutput.java b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/InstanceNameOutput.java new file mode 100644 index 00000000..1bf902a2 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/InstanceNameOutput.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright 2021 Huawei Technologies Co., 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.so.multicloudsimulator.beans; + +import com.fasterxml.jackson.databind.JsonNode; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Component; +import java.io.IOException; +import java.io.InputStream; + +@Component +@PropertySource(value = "data/InstanceNameOutput.json") +@ConfigurationProperties +public class InstanceNameOutput { + private String template_type; + private String workload_id; + private String workload_status; + public JsonNode workload_status_reason; + + public String getTemplate_type() { + return template_type; + } + + public void setTemplate_type(final String template_type) { + this.template_type = template_type; + } + + public String getWorkload_id() { + return workload_id; + } + + public void setWorkload_id(final String workload_id) { + this.workload_id = workload_id; + } + + public String getWorkload_status() { + return workload_status; + } + + public void setWorkload_status(final String workload_status) { + this.workload_status = workload_status; + } + + public JsonNode getWorkload_status_reason() { + return workload_status_reason; + } + + public void setWorkload_status_reason(final JsonNode workload_status_reason) { + this.workload_status_reason = workload_status_reason; + } + + public final static InputStream getFile(final String file) throws IOException { + return new ClassPathResource(file).getInputStream(); + } + + public final static InputStream getInstanceName() throws Exception, IOException { + return getFile("data/InstanceNameOutput.json"); + } +} diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/InstanceOutput.java b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/InstanceOutput.java new file mode 100644 index 00000000..2cb1fcac --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/InstanceOutput.java @@ -0,0 +1,79 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright 2021 Huawei Technologies Co., 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.so.multicloudsimulator.beans; + +import com.fasterxml.jackson.databind.JsonNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Component; +import java.io.IOException; +import java.io.InputStream; + +@Component +@PropertySource(value = "data/InstanceOutput.json") +@ConfigurationProperties +public class InstanceOutput { + private static final Logger LOGGER = LoggerFactory.getLogger(InstanceOutput.class); + private String template_type; + private String workload_id; + private String workload_status; + public JsonNode workload_status_reason; + + public JsonNode getWorkload_status_reason() { + return workload_status_reason; + } + + public void setWorkload_status_reason(final JsonNode workload_status_reason) { + this.workload_status_reason = workload_status_reason; + } + + public String getTemplate_type() { + return template_type; + } + + public void setTemplate_type(final String template_type) { + this.template_type = template_type; + } + + public String getWorkload_id() { + return workload_id; + } + + public void setWorkload_id(final String workload_id) { + this.workload_id = workload_id; + } + + public String getWorkload_status() { + return workload_status; + } + + public void setWorkload_status(final String workload_status) { + this.workload_status = workload_status; + } + + public static InputStream getFile(final String file) throws IOException { + return new ClassPathResource(file).getInputStream(); + } + + public static InputStream getInstance() throws Exception, IOException { + return getFile("data/InstanceOutput.json"); + } +} diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/InstanceResponse.java b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/InstanceResponse.java new file mode 100644 index 00000000..c8a58210 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/InstanceResponse.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright 2021 Huawei Technologies Co., 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.so.multicloudsimulator.beans; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ "id", "request", "namespace", "resources" }) +@JsonIgnoreProperties(value = "true") +public class InstanceResponse extends Response { + + @JsonProperty("id") + private String id; + @JsonProperty("request") + private MulticloudInstanceRequest request; + @JsonProperty("namespace") + private String namespace; + @JsonProperty("resources") + private List resources = null; + + public InstanceResponse(final String errorMsg) { + super(errorMsg); + } + + public InstanceResponse() { + super(""); + } + + public String getId() { + return id; + } + + public void setId(final String id) { + this.id = id; + } + + public MulticloudInstanceRequest getRequest() { + return request; + } + + public void setRequest(final MulticloudInstanceRequest request) { + this.request = request; + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(final String namespace) { + this.namespace = namespace; + } + + public List getResources() { + return resources; + } + + public void setResources(final List resources) { + this.resources = resources; + } + +} diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/MulticloudCreateResponse.java b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/MulticloudCreateResponse.java new file mode 100644 index 00000000..0182fd55 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/MulticloudCreateResponse.java @@ -0,0 +1,106 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright 2021 Huawei Technologies Co., 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.so.multicloudsimulator.beans; + +import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.databind.JsonNode; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonPropertyOrder({ "template_type", "workload_id", "template_response", "workload_status_reason", "workload_status" }) +public class MulticloudCreateResponse implements Serializable { + private static final long serialVersionUID = -5215028275577848311L; + + @JsonProperty("template_type") + private String templateType; + @JsonProperty("workload_id") + private String workloadId; + @JsonProperty("template_response") + private JsonNode templateResponse; + @JsonProperty("workload_status_reason") + private JsonNode workloadStatusReason; + @JsonProperty("workload_status") + private String workloadStatus; + + @JsonCreator + public MulticloudCreateResponse(@JsonProperty("template_type") String templateType, + @JsonProperty("workload_id") String workloadId, + @JsonProperty("template_response") JsonNode templateResponse) { + this.templateType = templateType; + this.workloadId = workloadId; + this.templateResponse = templateResponse; + } + + public MulticloudCreateResponse() { + + } + + public String getTemplateType() { + return templateType; + } + + public void setTemplateType(final String templateType) { + this.templateType = templateType; + } + + public String getWorkloadId() { + return workloadId; + } + + public void setWorkloadId(final String workloadId) { + this.workloadId = workloadId; + } + + public void setTemplateResponse(final JsonNode templateResponse) { + this.templateResponse = templateResponse; + } + + public JsonNode getTemplateResponse() { + return templateResponse; + } + + public void setWorkloadStatusReason(final JsonNode workloadStatusReason) { + this.workloadStatusReason = workloadStatusReason; + } + + public JsonNode getWorkloadStatusReason() { + return workloadStatusReason; + } + + public String getWorkloadSstatus() { + return workloadStatus; + } + + public void setWorkloadStatus(final String workloadStatus) { + this.workloadStatus = workloadStatus; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("templateType", templateType).append("workloadId", workloadId) + .append("templateResponse", templateResponse) + .append("workload_status_reason", workloadStatusReason.toString()) + .append("workload_status", workloadStatus).toString(); + } +} diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/MulticloudInstanceRequest.java b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/MulticloudInstanceRequest.java new file mode 100644 index 00000000..b645b9bf --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/MulticloudInstanceRequest.java @@ -0,0 +1,104 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright 2021 Huawei Technologies Co., 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.so.multicloudsimulator.beans; + +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(value = "true") +public class MulticloudInstanceRequest { + + @JsonProperty(value = "cloud-region") + private String cloudRegion; + + @JsonProperty(value = "rb-name") + private String rbName; + + @JsonProperty(value = "rb-version") + private String rbVersion; + + @JsonProperty(value = "profile-name") + private String profileName; + + @JsonProperty(value = "labels") + private Map labels; + + @JsonProperty(value = "override-values") + private Map overrideValues; + + @JsonProperty(value = "release-name") + private String vfModuleUuid; + + public String getCloudRegion() { + return cloudRegion; + } + + public void setCloudRegion(final String cloudRegion) { + this.cloudRegion = cloudRegion; + } + + public String getRbName() { + return rbName; + } + + public void setRbName(final String rbName) { + this.rbName = rbName; + } + + public String getRbVersion() { + return rbVersion; + } + + public void setRbVersion(final String rbVersion) { + this.rbVersion = rbVersion; + } + + public String getProfileName() { + return profileName; + } + + public void setProfileName(final String profileName) { + this.profileName = profileName; + } + + public Map getLabels() { + return labels; + } + + public void setLabels(Map labels) { + this.labels = labels; + } + + public Map getOverrideValues() { + return overrideValues; + } + + public void setOverrideValues(Map overrideValues) { + this.overrideValues = overrideValues; + } + + public String getVfModuleUuid() { + return vfModuleUuid; + } + + public void setVfModuleUuid(final String vfModuleUuid) { + this.vfModuleUuid = vfModuleUuid; + } + +} diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/MulticloudRequest.java b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/MulticloudRequest.java new file mode 100644 index 00000000..baeebded --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/MulticloudRequest.java @@ -0,0 +1,158 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright 2021 Huawei Technologies Co., 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.so.multicloudsimulator.beans; + +import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.databind.JsonNode; +import com.woorea.openstack.heat.model.CreateStackParam; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ "generic-vnf-id", "vf-module-id", "vf-module-model-invariant-id", "vf-module-model-version-id", + "vf-module-model-customization-id", "oof_directives", "sdnc_directives", "user_directives", "template_type", + "template_data" }) +public class MulticloudRequest implements Serializable { + private static final long serialVersionUID = -5215028275577848311L; + + @JsonProperty("generic-vnf-id") + private String genericVnfId; + + @JsonProperty("vf-module-id") + private String vfModuleId; + + @JsonProperty("vf-module-model-invariant-id") + private String vfModuleModelInvariantId; + + @JsonProperty("vf-module-model-version-id") + private String vfModuleModelVersionId; + + @JsonProperty("vf-module-model-customization-id") + private String vfModuleModelCustomizationId; + + @JsonProperty("oof_directives") + private JsonNode oofDirectives; + + @JsonProperty("sdnc_directives") + private JsonNode sdncDirectives; + + @JsonProperty("user_directives") + private JsonNode userDirectives; + + @JsonProperty("template_type") + private String templateType; + + @JsonProperty("template_data") + private CreateStackParam templateData; + + public String getGenericVnfId() { + return genericVnfId; + } + + public void setGenericVnfId(final String genericVnfId) { + this.genericVnfId = genericVnfId; + } + + public String getVfModuleId() { + return vfModuleId; + } + + public void setVfModuleId(final String vfModuleId) { + this.vfModuleId = vfModuleId; + } + + public String getVfModuleModelInvariantId() { + return vfModuleModelInvariantId; + } + + public void setVfModuleModelInvariantId(final String vfModuleModelInvariantId) { + this.vfModuleModelInvariantId = vfModuleModelInvariantId; + } + + public String getVfModuleModelVersionId() { + return vfModuleModelVersionId; + } + + public void setVfModuleModelVersionId(final String vfModuleModelVersionId) { + this.vfModuleModelVersionId = vfModuleModelVersionId; + } + + public String getVfModuleModelCustomizationId() { + return vfModuleModelCustomizationId; + } + + @JsonProperty("vf-module-model-customization-id") + public void setVfModuleModelCustomizationId(final String vfModuleModelCustomizationId) { + this.vfModuleModelCustomizationId = vfModuleModelCustomizationId; + } + + public JsonNode getOofDirectives() { + return oofDirectives; + } + + public void setOofDirectives(final JsonNode oofDirectives) { + this.oofDirectives = oofDirectives; + } + + public JsonNode getSdncDirectives() { + return sdncDirectives; + } + + public void setSdncDirectives(final JsonNode sdncDirectives) { + this.sdncDirectives = sdncDirectives; + } + + public JsonNode getUserDirectives() { + return userDirectives; + } + + public void setUserDirectives(final JsonNode userDirectives) { + this.userDirectives = userDirectives; + } + + public String getTemplateType() { + return templateType; + } + + public void setTemplateType(final String templateType) { + this.templateType = templateType; + } + + public CreateStackParam getTemplateData() { + return templateData; + } + + public void setTemplateData(CreateStackParam templateData) { + this.templateData = templateData; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("genericVnfId", genericVnfId).append("vfModuleId", vfModuleId) + .append("vfModuleModelInvariantId", vfModuleModelInvariantId) + .append("vfModuleModelVersionId", vfModuleModelVersionId) + .append("vfModuleModelCustomizationId", vfModuleModelCustomizationId) + .append("oofDirectives", oofDirectives).append("sdncDirectives", sdncDirectives) + .append("userDirectives", userDirectives).append("templateType", templateType) + .append("templateData", templateData).toString(); + } + +} diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/Resource.java b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/Resource.java new file mode 100644 index 00000000..666cbe03 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/Resource.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright 2021 Huawei Technologies Co., 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.so.multicloudsimulator.beans; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ "resource-type", "resource-link" }) +public class Resource { + + @JsonProperty("resource-type") + private String resourceType; + + @JsonProperty("resource-link") + private String resourceLink; + + @JsonProperty("resource-type") + public String getResourceType() { + return resourceType; + } + + public void setResourceType(final String resourceType) { + this.resourceType = resourceType; + } + + public String getResourceLink() { + return resourceLink; + } + + public void setResourceLink(final String resourceLink) { + this.resourceLink = resourceLink; + } + +} diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/Response.java b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/Response.java new file mode 100644 index 00000000..8f0713ea --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/beans/Response.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright 2021 Huawei Technologies Co., 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.so.multicloudsimulator.beans; + +public class Response { + + private String errorMsg; + + public Response(final String errorMsg) { + this.errorMsg = errorMsg; + } + + public Response() { + } + + public String getErrorMsg() { + return errorMsg; + } + + public void setErrorMsg(final String errorMsg) { + this.errorMsg = errorMsg; + } + +} diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/configuration/ApplicationConfiguration.java b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/configuration/ApplicationConfiguration.java new file mode 100644 index 00000000..365710e3 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/configuration/ApplicationConfiguration.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright 2021 Huawei Technologies Co., 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.so.multicloudsimulator.configuration; + +import static org.onap.so.multicloudsimulator.utils.Constants.MULTICLOUD_CACHE; +import java.util.Arrays; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.concurrent.ConcurrentMapCache; +import org.springframework.cache.support.SimpleCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ApplicationConfiguration { + + @Bean + public CacheManager cacheManager() { + final SimpleCacheManager manager = new SimpleCacheManager(); + manager.setCaches(Arrays.asList(getCache(MULTICLOUD_CACHE))); + return manager; + } + + private Cache getCache(final String name) { + return new ConcurrentMapCache(name); + } +} diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/configuration/WebSecurityConfigImpl.java b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/configuration/WebSecurityConfigImpl.java new file mode 100644 index 00000000..b1d0984a --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/configuration/WebSecurityConfigImpl.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright 2021 Huawei Technologies Co., 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.so.multicloudsimulator.configuration; + +import static org.onap.so.multicloudsimulator.utils.Constants.OPERATIONS_URL; +import org.onap.so.simulator.configuration.SimulatorSecurityConfigurer; +import org.onap.so.simulator.model.UserCredentials; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; + +@Configuration +@EnableWebSecurity +public class WebSecurityConfigImpl extends SimulatorSecurityConfigurer { + + @Autowired + public WebSecurityConfigImpl(final UserCredentials userCredentials) { + super(userCredentials.getUsers()); + } + + @Override + protected void configure(final HttpSecurity http) throws Exception { + http.csrf().disable().authorizeRequests().antMatchers(OPERATIONS_URL + "/**/**").authenticated().and() + .httpBasic(); + } + +} diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/controller/MultiCloudController.java b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/controller/MultiCloudController.java new file mode 100644 index 00000000..c99e246e --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/controller/MultiCloudController.java @@ -0,0 +1,128 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright 2021 Huawei Technologies Co., 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.so.multicloudsimulator.controller; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.MediaType; +import org.apache.commons.io.IOUtils; +import org.onap.so.multicloudsimulator.beans.InstanceOutput; +import org.onap.so.multicloudsimulator.beans.MulticloudCreateResponse; +import org.onap.so.multicloudsimulator.beans.MulticloudInstanceRequest; +import org.onap.so.multicloudsimulator.beans.InstanceResponse; +import org.onap.so.multicloudsimulator.beans.InstanceNameOutput; +import org.onap.so.multicloudsimulator.beans.MulticloudRequest; + +import org.springframework.http.ResponseEntity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +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.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.io.IOException; +import java.io.InputStream; + +import static org.onap.so.multicloudsimulator.utils.Constants.BASE_URL; + +@RestController +@RequestMapping(path = BASE_URL) +public class MultiCloudController { + + public static final String X_HTTP_METHOD_OVERRIDE = "X-HTTP-Method-Override"; + private static final Logger LOGGER = LoggerFactory.getLogger(MultiCloudController.class); + + @PostMapping(value = "/v1/instance") + public ResponseEntity createInstance(@RequestBody MulticloudInstanceRequest req) { + System.out.println("MultiCloud createInstance "); + final InstanceResponse InstanceResponse = new InstanceResponse(); + + LOGGER.info("Calling createInstance"); + return ResponseEntity.ok(InstanceResponse); + } + + @GetMapping(value = "/{cloud-owner}/{cloud-region-id}/infra_workload", produces = { MediaType.APPLICATION_JSON }) + public ResponseEntity getInstance(@PathVariable("cloud-owner") String cloudOwner, + @PathVariable("cloud-region-id") String cloudRegionId, + @RequestParam(value = "depth", required = false, defaultValue = "0") Integer depth, + @RequestParam(name = "format", required = false) final String name, final HttpServletRequest request) + throws Exception { + + LOGGER.info("found CloudOwner {}", cloudOwner); + LOGGER.info("found cloudRegionId {}", cloudRegionId); + LOGGER.info("found name {}", name); + final InputStream instanceOutput = InstanceOutput.getInstance(); + final String output = IOUtils.toString(instanceOutput, "utf-8"); + + return ResponseEntity.ok(output); + } + + @PostMapping(value = "/{cloud-owner}/{cloud-region-id}/infra_workload", consumes = { MediaType.APPLICATION_JSON, + MediaType.APPLICATION_XML }, produces = { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + public ResponseEntity postCreateInstance(@RequestBody final MulticloudCreateResponse inputRequest, + @PathVariable("cloud-owner") final String cloudOwner, + @PathVariable("cloud-region-id") final String cloudRegionId, + @RequestHeader(value = X_HTTP_METHOD_OVERRIDE, required = false) final String xHttpHeaderOverride, + final HttpServletRequest request) throws IOException { + + LOGGER.info("Calling postCreateInstance"); + inputRequest.setWorkloadStatusReason(null); + + inputRequest.setWorkloadId("sad_sammet"); + inputRequest.setTemplateType("heat"); + inputRequest.setWorkloadStatus("CREATE_COMPLETE"); + + return ResponseEntity.status(201).body(inputRequest); + } + + @GetMapping(value = "/{cloud-owner}/{cloud-region-id}/infra_workload/{workload-id}", produces = { + MediaType.APPLICATION_JSON }) + public ResponseEntity getInstanceName(@PathVariable("cloud-owner") final String cloudOwner, + @PathVariable("cloud-region-id") final String cloudRegionId, @PathVariable("workload-id") final String workloadId, + @RequestParam(value = "depth", required = false, defaultValue = "0") final Integer depth, + @RequestParam(name = "format", required = false) final String name, final HttpServletRequest request) + throws Exception { + + LOGGER.info("Calling getInstanceName"); + LOGGER.info("found CloudOwner {}", cloudOwner); + LOGGER.info("found cloudRegionId {}", cloudRegionId); + LOGGER.info("found name {}", name); + final InputStream instanceNameOutput = InstanceNameOutput.getInstanceName(); + final String output = IOUtils.toString(instanceNameOutput, "utf-8"); + + return ResponseEntity.ok(output); + } + + @PostMapping(value = "/{cloud-owner}/{cloud-region-id}/infra_workload/{workload-id}", consumes = { + MediaType.APPLICATION_JSON, + MediaType.APPLICATION_XML }, produces = { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + public ResponseEntity postCreateInstanceName(@RequestBody final MulticloudRequest inputRequest, + @PathVariable("cloud-owner") final String cloudOwner, @PathVariable("workload-id") String workloadId, + @PathVariable("cloud-region-id") final String cloudRegionId, + @RequestHeader(value = X_HTTP_METHOD_OVERRIDE, required = false) final String xHttpHeaderOverride, + final HttpServletRequest request) throws IOException { + + LOGGER.info("Calling postCreateInstanceName"); + + return ResponseEntity.status(405).build(); + } +} \ No newline at end of file diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/utils/Constants.java b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/utils/Constants.java new file mode 100644 index 00000000..e104d235 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/java/org/onap/so/multicloudsimulator/utils/Constants.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright 2021 Huawei Technologies Co., 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.so.multicloudsimulator.utils; + +public class Constants { + + public static final String BASE_URL = "/api/multicloud/v1"; + + public static final String OPERATIONS_URL = BASE_URL + "/operations"; + + public static final String MULTICLOUD_CACHE = "multicloud-cache"; + + private Constants() { + } +} diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/application.properties b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/application.properties new file mode 100644 index 00000000..e507a12f --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/application.properties @@ -0,0 +1 @@ +security.ignored=/** diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/application.yaml b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/application.yaml new file mode 100644 index 00000000..393d1b7b --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/application.yaml @@ -0,0 +1,16 @@ +server: + port: 9996 + tomcat: + max-threads: 4 +ssl-enable: false +spring: + security: + users: + - username: mso + password: $2a$04$f8SB6cW/VI26QvYM6z.GXu7hlEmwnFtePenD8zF18mS3Atu3QNqr2 + role: VID + - username: admin + password: $2a$04$f8SB6cW/VI26QvYM6z.GXu7hlEmwnFtePenD8zF18mS3Atu3QNqr2 + role: VID + main: + allow-bean-definition-overriding: true \ No newline at end of file diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/data/InstanceNameOutput.json b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/data/InstanceNameOutput.json new file mode 100644 index 00000000..8c0e88f4 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/data/InstanceNameOutput.json @@ -0,0 +1,6 @@ +{ + "workload_status_reason": null, + "template_type": "heat", + "workload_id": "sad_sammet", + "workload_status": "CREATE_COMPLETE" +} \ No newline at end of file diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/data/InstanceOutput.json b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/data/InstanceOutput.json new file mode 100644 index 00000000..e47ffb43 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/main/resources/data/InstanceOutput.json @@ -0,0 +1,8 @@ +{ + "workload_status_reason": { + "stacks": "NOTFOUND" + }, + "template_type": "heat", + "workload_id": "", + "workload_status": "GET_COMPLETE" +} diff --git a/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/test/java/org/onap/so/multicloudsimulator/MultiCloudSimulatorApplicationTests.java b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/test/java/org/onap/so/multicloudsimulator/MultiCloudSimulatorApplicationTests.java new file mode 100644 index 00000000..d9b10d45 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/multicloud-simulator/src/test/java/org/onap/so/multicloudsimulator/MultiCloudSimulatorApplicationTests.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright 2021 Huawei Technologies Co., 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.so.multicloudsimulator; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.so.multicloudsimulator.utils.Constants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringJUnit4ClassRunner.class) +@ActiveProfiles("test") +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@Configuration +class MultiCloudSimulatorApplicationTests { + @LocalServerPort + private int port; + + @Autowired + private TestRestTemplate restTemplate; + + @Test + public void test_createInstance() { + final String url = "http://localhost:" + port + Constants.BASE_URL + "/operations"; + + final ResponseEntity object = restTemplate.getForEntity(url, String.class); + + assertEquals(Constants.OPERATIONS_URL, object.getBody()); + + } + +} \ No newline at end of file diff --git a/plans/so/integration-etsi-testing/so-simulators/package/docker/pom.xml b/plans/so/integration-etsi-testing/so-simulators/package/docker/pom.xml index 9334a095..98c341e4 100644 --- a/plans/so/integration-etsi-testing/so-simulators/package/docker/pom.xml +++ b/plans/so/integration-etsi-testing/so-simulators/package/docker/pom.xml @@ -99,6 +99,29 @@ + + simulators/multicloud-simulator + + try + docker-files + Dockerfile.multicloud-simulator-base-image + + ${project.version} + + + + + + + org.onap.so.simulators:multicloud-simulator + + app.jar + + + + + + simulators/vnfm-simulator @@ -170,6 +193,11 @@ sdnc-simulator ${project.version} + + ${project.parent.groupId} + multicloud-simulator + ${project.version} + org.onap.so.simulators.vnfm vnfm-service diff --git a/plans/so/integration-etsi-testing/so-simulators/package/docker/src/main/docker/docker-files/Dockerfile.multicloud-simulator-base-image b/plans/so/integration-etsi-testing/so-simulators/package/docker/src/main/docker/docker-files/Dockerfile.multicloud-simulator-base-image new file mode 100644 index 00000000..abffd9fb --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/package/docker/src/main/docker/docker-files/Dockerfile.multicloud-simulator-base-image @@ -0,0 +1,34 @@ +FROM adoptopenjdk/openjdk11:jre-11.0.9.1_1-alpine + +ARG http_proxy +ARG https_proxy +ENV HTTP_PROXY=$http_proxy +ENV HTTPS_PROXY=$https_proxy +ENV http_proxy=$HTTP_PROXY +ENV https_proxy=$HTTPS_PROXY + +# Update the package list and upgrade installed packages +RUN apk update && apk upgrade + +# Install commonly needed tools +RUN apk --no-cache add curl netcat-openbsd sudo nss + +# Create 'so' user +RUN addgroup -g 1000 so && adduser -S -u 1000 -G so -s /bin/sh so + +RUN mkdir /app && mkdir /app/config && mkdir /app/logs && mkdir /app/ca-certificates + +COPY maven/app.jar /app +COPY configs/logging/logback-spring.xml /app +COPY scripts/start-app.sh /app + +RUN chown -R so:so /app && chmod 700 /app/*.sh + +# Springboot configuration (required) +VOLUME /app/config + +# CA certificates +VOLUME /app/ca-certificates + +WORKDIR /app +CMD ["/app/start-app.sh"] diff --git a/plans/so/integration-etsi-testing/so-simulators/pom.xml b/plans/so/integration-etsi-testing/so-simulators/pom.xml index 4be20c66..6de1d886 100644 --- a/plans/so/integration-etsi-testing/so-simulators/pom.xml +++ b/plans/so/integration-etsi-testing/so-simulators/pom.xml @@ -18,6 +18,7 @@ common + multicloud-simulator sdc-simulator aai-simulator sdnc-simulator diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/ConfigController.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/ConfigController.java new file mode 100644 index 00000000..7282e051 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/ConfigController.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright 2021 Huawei Technologies Co., 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.so.sdncsimulator.controller; + +import static org.onap.so.sdncsimulator.utils.Constants.BASE_URL; +import java.util.Optional; +import javax.ws.rs.core.MediaType; +import org.onap.sdnc.northbound.client.model.GenericResourceApiVnfTopology; +import org.onap.sdnc.northbound.client.model.GenericResourceApiVfModuleTopology; + +import org.onap.so.sdncsimulator.providers.ServiceOperationsCacheServiceProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * @author Md Irshad Sheikh (md.irshad.sheikh@huawei.com) + * + */ +@Controller +@RequestMapping(path = BASE_URL) +public class ConfigController { + private static final String HTTP_STATUS_OK = HttpStatus.OK.value() + ""; + + private static final Logger LOGGER = LoggerFactory.getLogger(OperationsController.class); + + private final ServiceOperationsCacheServiceProvider cacheServiceProvider; + + @Autowired + public ConfigController(final ServiceOperationsCacheServiceProvider cacheServiceProvider) { + this.cacheServiceProvider = cacheServiceProvider; + } + + @GetMapping(value = "/config/GENERIC-RESOURCE-API:services/service/{service-id}/service-data/vnfs/vnf/{vnf-id}/vnf-data/vnf-topology/") + public ResponseEntity getVNf(@PathVariable("service-id") String serviceId, + @PathVariable("vnf-id") String vnfId) { + + LOGGER.info("Get vnf-topology with serviceId {} and vnfId {}",serviceId, vnfId); + final Optional optional = + cacheServiceProvider.getGenericResourceApiVnfTopology(vnfId); + if (optional.isPresent()) { + final GenericResourceApiVnfTopology genericVnfTopology = optional.get(); + LOGGER.info("found VnfTopology {} in cache", genericVnfTopology); + return ResponseEntity.ok(genericVnfTopology); + } + + LOGGER.error( + "Unable to find VnfTopology in cache "); + + return ResponseEntity.badRequest().build(); + } + + @GetMapping(value = "/config/GENERIC-RESOURCE-API:services/service/{service-id}/service-data/vnfs/vnf/{vnf-id}/vnf-data/vf-modules/vf-module/{vf-module-id}/vf-module-data/vf-module-topology/", produces = { + MediaType.APPLICATION_JSON }) + public ResponseEntity getVFmodule(@PathVariable("service-id") String serviceId, + @PathVariable("vnf-id") String vnfId, @PathVariable("vf-module-id") String vfModuleId) { + LOGGER.info("Get vfModule-topology with serviceId {}, vnfId {} and vfModuleId {}",serviceId, vnfId,vfModuleId); + + final Optional optional = + cacheServiceProvider.getGenericResourceApiVfModuleTopology(vfModuleId); + + if (optional.isPresent()) { + final GenericResourceApiVfModuleTopology vfModuleTopology = optional.get(); + LOGGER.info("found vfModuleTopology {} in cache", vfModuleTopology); + return ResponseEntity.ok(vfModuleTopology); + } + + LOGGER.error( + "Unable to find VfModuleTopology in cache for "); + + return ResponseEntity.badRequest().build(); + } +} diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/OperationsController.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/OperationsController.java index 2f24ef69..58f90382 100644 --- a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/OperationsController.java +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/OperationsController.java @@ -31,6 +31,7 @@ import org.onap.sdnc.northbound.client.model.GenericResourceApiSdncrequestheader import org.onap.sdnc.northbound.client.model.GenericResourceApiServiceOperationInformation; import org.onap.sdnc.northbound.client.model.GenericResourceApiSvcActionEnumeration; import org.onap.sdnc.northbound.client.model.GenericResourceApiVnfOperationInformation; +import org.onap.sdnc.northbound.client.model.GenericResourceApiVfModuleOperationInformation; import org.onap.so.sdncsimulator.models.InputRequest; import org.onap.so.sdncsimulator.models.Output; import org.onap.so.sdncsimulator.models.OutputRequest; @@ -147,4 +148,36 @@ public class OperationsController { return cacheServiceProvider.putVnfOperationInformation(apiVnfOperationInformation); } + @PostMapping(value = "/GENERIC-RESOURCE-API:vf-module-topology-operation/", + consumes = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}, + produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + public ResponseEntity postVfModuleOperationInformation( + @RequestBody final InputRequest inputRequest, + final HttpServletRequest request) { + LOGGER.info("Request Received for VfModule : {} ...", inputRequest); + + final GenericResourceApiVfModuleOperationInformation apiVfModuleOperationInformation = inputRequest.getInput(); + if (apiVfModuleOperationInformation == null) { + LOGGER.error("Invalid input request: {}", inputRequest); + return ResponseEntity.badRequest().build(); + } + + final Output output = getOutput(apiVfModuleOperationInformation); + final OutputRequest outputRequest = new OutputRequest(output); + + if (output.getResponseCode().equals(HTTP_STATUS_OK)) { + LOGGER.info("Sucessfully executed request vnf sending response: {}", outputRequest); + return ResponseEntity.ok(outputRequest); + } + + LOGGER.error("Unable to execute input request: {}, will send OutputRequest: {}", inputRequest, outputRequest); + return ResponseEntity.badRequest().body(outputRequest); + + } + + private Output getOutput(final GenericResourceApiVfModuleOperationInformation apiVfModuleOperationInformation) { + + return cacheServiceProvider.putVfModuleOperationInformation(apiVfModuleOperationInformation); + } + } diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/models/Output.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/models/Output.java index d64b0b0c..7cc0bdaf 100644 --- a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/models/Output.java +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/models/Output.java @@ -48,7 +48,10 @@ public class Output implements Serializable { private GenericResourceApiInstanceReference serviceResponseInformation = null; @JsonProperty("vnf-response-information") - private GenericResourceApiInstanceReference vnfResponseInformation = null; + private GenericResourceApiInstanceReference vnfResponseInformation = null; + + @JsonProperty("vf-module-response-information") + private GenericResourceApiInstanceReference vfModuleResponseInformation = null; /** * @return the responseMessage @@ -164,6 +167,11 @@ public class Output implements Serializable { this.vnfResponseInformation = vnfResponseInformation; return this; + } + public Output vfModuleResponseInformation(final GenericResourceApiInstanceReference vfModuleResponseInformation) { + this.vfModuleResponseInformation = vfModuleResponseInformation; + return this; + } @JsonIgnore @@ -177,6 +185,7 @@ public class Output implements Serializable { sb.append(" responseCode: ").append(responseCode).append("\n"); sb.append(" serviceResponseInformation: ").append(serviceResponseInformation).append("\n"); sb.append(" vnfResponseInformation: ").append(vnfResponseInformation).append("\n"); + sb.append(" vfModuleResponseInformation: ").append(vfModuleResponseInformation).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProvider.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProvider.java index c3a80ec3..c04097bb 100644 --- a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProvider.java +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProvider.java @@ -20,9 +20,8 @@ package org.onap.so.sdncsimulator.providers; import java.util.Optional; -import org.onap.sdnc.northbound.client.model.GenericResourceApiServiceOperationInformation; -import org.onap.sdnc.northbound.client.model.GenericResourceApiServicemodelinfrastructureService; -import org.onap.sdnc.northbound.client.model.GenericResourceApiVnfOperationInformation; + +import org.onap.sdnc.northbound.client.model.*; import org.onap.so.sdncsimulator.models.Output; /** @@ -44,6 +43,12 @@ public interface ServiceOperationsCacheServiceProvider { Output deleteVnfOperationInformation(final GenericResourceApiVnfOperationInformation apiVnfOperationInformation); + Output putVfModuleOperationInformation(final GenericResourceApiVfModuleOperationInformation apiVfModuleOperationInformation); + + public Optional getGenericResourceApiVfModuleTopology(final String vfModueId); + + public Optional getGenericResourceApiVnfTopology(final String vnfId); + void clearAll(); } diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProviderimpl.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProviderimpl.java index 88db4c13..24017b6b 100644 --- a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProviderimpl.java +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProviderimpl.java @@ -60,7 +60,19 @@ import org.onap.sdnc.northbound.client.model.GenericResourceApiVnfinformationVnf import org.onap.sdnc.northbound.client.model.GenericResourceApiVnfrequestinputVnfRequestInput; import org.onap.sdnc.northbound.client.model.GenericResourceApiVnftopologyVnfTopology; import org.onap.sdnc.northbound.client.model.GenericResourceApiVnftopologyidentifierstructureVnfTopologyIdentifierStructure; + +import org.onap.sdnc.northbound.client.model.GenericResourceApiServicedataServicedataVnfsVnfVnfdataVfmodulesVfmoduleVfModuleData; +import org.onap.sdnc.northbound.client.model.GenericResourceApiVfModuleTopology; +import org.onap.sdnc.northbound.client.model.GenericResourceApiVnfTopology; +import org.onap.sdnc.northbound.client.model.GenericResourceApiVfModuleOperationInformation; +import org.onap.sdnc.northbound.client.model.GenericResourceApiVfmoduleinformationVfModuleInformation; +import org.onap.sdnc.northbound.client.model.GenericResourceApiVfmoduletopologyVfModuleTopology; +import org.onap.sdnc.northbound.client.model.GenericResourceApiVfmoduletopologyidentifierVfModuleTopologyIdentifier; +import org.onap.sdnc.northbound.client.model.GenericResourceApiParam; +import org.onap.sdnc.northbound.client.model.GenericResourceApiParamParam; + import org.onap.so.sdncsimulator.models.Output; +import org.onap.so.sdncsimulator.utils.Constants; import org.onap.so.simulator.cache.provider.AbstractCacheServiceProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -198,7 +210,7 @@ public class ServiceOperationsCacheServiceProviderimpl extends AbstractCacheServ if (ifVnfNotExists(vnfId, svcAction, vnfsList)) { vnfsList.add(getGenericResourceApiServicedataVnf(serviceInstanceId, vnfId, input)); - + setVnfsData(vnfsList); final GenericResourceApiServicestatusServiceStatus serviceStatus = service.getServiceStatus(); return new Output().ackFinalIndicator(serviceStatus.getFinalIndicator()) @@ -507,4 +519,158 @@ public class ServiceOperationsCacheServiceProviderimpl extends AbstractCacheServ } + @Override + public Output putVfModuleOperationInformation( + final GenericResourceApiVfModuleOperationInformation input) { + + final GenericResourceApiServiceinformationServiceInformation serviceInformation = input.getServiceInformation(); + final GenericResourceApiVnfinformationVnfInformation vnfInformation = input.getVnfInformation(); + final GenericResourceApiVfmoduleinformationVfModuleInformation vfModuleInformation = input.getVfModuleInformation(); + // Call getVfModule to make a vfList for get the vf-module-information while GET reqest + getVfModule(input); + + final GenericResourceApiSdncrequestheaderSdncRequestHeader requestHeader = input.getSdncRequestHeader(); + final String svcRequestId = getSvcRequestId(requestHeader); + + if (serviceInformation != null && isValid(serviceInformation.getServiceInstanceId()) && vnfInformation != null + && isValid(vnfInformation.getVnfId()) && vfModuleInformation !=null && isValid(vfModuleInformation.getVfModuleId())) { + + + final String serviceInstanceId = serviceInformation.getServiceInstanceId(); + final String vnfId = vnfInformation.getVnfId(); + final String vfModuleId = vfModuleInformation.getVfModuleId(); + + final Optional optional = + getGenericResourceApiServicemodelinfrastructureService(serviceInstanceId); + if (optional.isPresent()) { + final GenericResourceApiServicemodelinfrastructureService service = optional.get(); + final GenericResourceApiServicedataServiceData serviceData = service.getServiceData(); + if (serviceData != null) { + + final GenericResourceApiServicestatusServiceStatus serviceStatus = service.getServiceStatus(); + + return new Output().ackFinalIndicator(serviceStatus.getFinalIndicator()) + .responseCode(serviceStatus.getResponseCode()) + .responseMessage(serviceStatus.getResponseMessage()).svcRequestId(svcRequestId) + .serviceResponseInformation(new GenericResourceApiInstanceReference() + .instanceId(serviceInstanceId).objectPath(getObjectPath(serviceInstanceId))) + .vnfResponseInformation(new GenericResourceApiInstanceReference().instanceId(vnfId) + .objectPath(getObjectPath(serviceInstanceId, vnfId))) + .vfModuleResponseInformation(new GenericResourceApiInstanceReference().instanceId(vfModuleId) + .objectPath(getObjectPath(vnfId, vfModuleId))); + } + } + LOGGER.error( + "Unable to find existing GenericResourceApiServiceModelInfrastructure in cache using service instance id: {}", + serviceInstanceId); + } + LOGGER.error( + "Unable to add GenericResourceApiServiceOperationInformation in cache due to invalid input: {}... ", + input); + return new Output().ackFinalIndicator(YES).responseCode(HTTP_STATUS_BAD_REQUEST) + .responseMessage("Unable to add vfModule").svcRequestId(svcRequestId); + } + + private void getVfModule + (final GenericResourceApiVfModuleOperationInformation input) { + + final GenericResourceApiVfmoduletopologyVfModuleTopology apiVfModuletopologyVfModuleTopology = + new GenericResourceApiVfmoduletopologyVfModuleTopology(); + + final GenericResourceApiServicedataServicedataVnfsVnfVnfdataVfmodulesVfmoduleVfModuleData vfModuleData = + new GenericResourceApiServicedataServicedataVnfsVnfVnfdataVfmodulesVfmoduleVfModuleData(); + + final String vfModuleId = input.getVfModuleInformation().getVfModuleId(); + + vfModuleData.setVfModuleInformation(input.getVfModuleInformation()); + vfModuleData.setVfModuleRequestInput(input.getVfModuleRequestInput()); + + final GenericResourceApiVfmoduletopologyVfModuleTopology vfModuleTopology = + new GenericResourceApiVfmoduletopologyVfModuleTopology(); + + vfModuleTopology.setSdncGeneratedCloudResources(true); + final GenericResourceApiParam vfModuleParametersData = new GenericResourceApiParam(); + final List params = new ArrayList(); + final GenericResourceApiParamParam param = new GenericResourceApiParamParam(); + param.setName("k8s-rb-profile-name"); + param.setValue("k8s-rb-profile-value"); + + params.add(param); + vfModuleParametersData.setParam(params); + vfModuleTopology.setVfModuleParameters(vfModuleParametersData); + + vfModuleTopology.setOnapModelInformation(vfModuleData.getVfModuleInformation().getOnapModelInformation()); + vfModuleTopology.setVfModuleParameters(vfModuleData.getVfModuleRequestInput().getVfModuleInputParameters()); + vfModuleTopology.setAicClli(vfModuleData.getVfModuleRequestInput().getAicClli()); + vfModuleTopology.setAicCloudRegion(vfModuleData.getVfModuleRequestInput().getAicCloudRegion()); + vfModuleTopology.setCloudOwner(vfModuleData.getVfModuleRequestInput().getCloudOwner()); + + apiVfModuletopologyVfModuleTopology.vfModuleTopologyIdentifier(getVfModuleTopologyIdentifierStructure(input)); + + vfModuleTopology.setVfModuleTopologyIdentifier(apiVfModuletopologyVfModuleTopology.getVfModuleTopologyIdentifier()); + vfModuleTopology.setTenant(vfModuleData.getVfModuleRequestInput().getTenant()); + + final GenericResourceApiVfModuleTopology genericResourceApiVfModuleTopology = new GenericResourceApiVfModuleTopology(); + genericResourceApiVfModuleTopology.setVfModuleTopology(vfModuleTopology); + + final Cache cache = getCache(Constants.SERVICE_TOPOLOGY_OPERATION_CACHE); + cache.put(vfModuleId, genericResourceApiVfModuleTopology); + } + + @Override + public Optional getGenericResourceApiVfModuleTopology(final String vfModueId) { + LOGGER.info("getting GenericResourceApiVfModuleTopology from cache using key: {}", vfModueId); + final Cache cache = getCache(Constants.SERVICE_TOPOLOGY_OPERATION_CACHE); + final GenericResourceApiVfModuleTopology value = + cache.get(vfModueId, GenericResourceApiVfModuleTopology.class); + if (value != null) { + return Optional.of(value); + } + LOGGER.error("Unable to find GenericResourceApiVfModuleTopology ..."); + return Optional.empty(); + } + + private GenericResourceApiVfmoduletopologyidentifierVfModuleTopologyIdentifier getVfModuleTopologyIdentifierStructure( + @Valid final GenericResourceApiVfModuleOperationInformation input) { + + final GenericResourceApiVfmoduleinformationVfModuleInformation vfModuleInformation = input.getVfModuleInformation(); + return new GenericResourceApiVfmoduletopologyidentifierVfModuleTopologyIdentifier() + .vfModuleId(vfModuleInformation.getVfModuleId()).vfModuleType(vfModuleInformation.getVfModuleType()).vfModuleName(input.getVfModuleRequestInput().getVfModuleName()); + } + + + public void setVnfsData(List vnfsList) { + + final GenericResourceApiVnftopologyVnfTopology vnfTopology = new GenericResourceApiVnftopologyVnfTopology(); + LOGGER.info(String.valueOf(vnfsList)); + final String vnfId = vnfsList.get(0).getVnfId(); + vnfTopology.setOnapModelInformation(vnfsList.get(0).getVnfData().getVnfInformation().getOnapModelInformation()); + vnfTopology.setAicClli(String.valueOf(vnfsList.get(0).getVnfData().getVnfRequestInput().getAicClli())); + vnfTopology.setAicCloudRegion(String.valueOf(vnfsList.get(0).getVnfData().getVnfRequestInput().getAicCloudRegion())); + vnfTopology.setCloudOwner(String.valueOf(vnfsList.get(0).getVnfData().getVnfRequestInput().getCloudOwner())); + vnfTopology.setTenant(String.valueOf(vnfsList.get(0).getVnfData().getVnfRequestInput().getTenant())); + vnfTopology.setVnfResourceAssignments(vnfsList.get(0).getVnfData().getVnfTopology().getVnfResourceAssignments()); + vnfTopology.setVnfTopologyIdentifierStructure(vnfsList.get(0).getVnfData().getVnfTopology().getVnfTopologyIdentifierStructure()); + vnfTopology.setVnfParametersData(vnfsList.get(0).getVnfData().getVnfTopology().getVnfParametersData()); + vnfTopology.setSdncGeneratedCloudResources(vnfsList.get(0).getVnfData().getVnfTopology().getSdncGeneratedCloudResources()); + + final GenericResourceApiVnfTopology genericResourceApiVnfTopology = new GenericResourceApiVnfTopology(); + genericResourceApiVnfTopology.setVnfTopology(vnfTopology); + + final Cache cache = getCache(Constants.SERVICE_TOPOLOGY_OPERATION_CACHE); + cache.put(vnfId, genericResourceApiVnfTopology); + } + + @Override + public Optional getGenericResourceApiVnfTopology(final String vnfId) { + LOGGER.info("getting GenericResourceApiVnfTopology from cache using key: {}", vnfId); + final Cache cache = getCache(Constants.SERVICE_TOPOLOGY_OPERATION_CACHE); + final GenericResourceApiVnfTopology value = + cache.get(vnfId, GenericResourceApiVnfTopology.class); + if (value != null) { + return Optional.of(value); + } + LOGGER.error("Unable to find GenericResourceApiVnfTopology ..."); + return Optional.empty(); + } } diff --git a/plans/so/macroflow/config/distribution-test-zip/macro_zipped_sdc_csar.tar.gz b/plans/so/macroflow/config/distribution-test-zip/macro_zipped_sdc_csar.tar.gz new file mode 100755 index 0000000000000000000000000000000000000000..f826c2eb6008bf5e9136a938b6f1360aebc11dfe GIT binary patch literal 111485 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

2X}g*x`JIn_sBlQuoB~SD(T(>N|MgQ2@j^JE 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 literal 0 HcmV?d00001 diff --git a/plans/so/macroflow/config/env b/plans/so/macroflow/config/env index f0ed0d09..47798ead 100644 --- a/plans/so/macroflow/config/env +++ b/plans/so/macroflow/config/env @@ -1,2 +1,7 @@ +NEXUS_DOCKER_REPO_MSO=nexus3.onap.org:10001 +DOCKER_ENVIRONMENT=remote +TAG=1.7.11 +TIME_OUT_DEFAULT_VALUE_SEC=1200 PROJECT_NAME=macroflowintegrationtesting DEFAULT_NETWORK_NAME=macroflowintegrationtesting_default +MARIADB_VERSION=10.1.11 diff --git a/plans/so/macroflow/config/override-files/api-handler-infra/onapheat/override.yaml b/plans/so/macroflow/config/override-files/api-handler-infra/onapheat/override.yaml new file mode 100644 index 00000000..bdf5c4de --- /dev/null +++ b/plans/so/macroflow/config/override-files/api-handler-infra/onapheat/override.yaml @@ -0,0 +1,133 @@ +server: + port: 8080 + tomcat: + max-threads: 50 +ssl-enable: false + +mso: + msoKey: 07a7159d3bf51a0e53be7a8f89699be7 + logPath: logs + site-name: onapheat + adapters: + requestDb: + endpoint: http://request-db-adapter:8083 + auth: Basic YnBlbDpwYXNzd29yZDEk + catalog: + db: + spring: + endpoint: http://catalog-db-adapter:8082 + db: + auth: Basic YnBlbDpwYXNzd29yZDEk + config: + path: /src/main/resources/ + infra: + default: + alacarte: + orchestrationUri: /mso/async/services/ALaCarteOrchestrator + recipeTimeout: 180 + testApi: VNF_API + service: + macro: + default: + testApi: GR_API + camundaURL: http://bpmn-infra:8081 + camundaAuth: AE2E9BE6EF9249085AF98689C4EE087736A5500629A72F35068FFB88813A023581DD6E765071F1C04075B36EA4213A + async: + core-pool-size: 50 + max-pool-size: 50 + queue-capacity: 500 + sdc: + client: + auth: F3473596C526938329DF877495B494DC374D1C4198ED3AD305EA3ADCBBDA1862 + activate: + instanceid: test + userid: cs0008 + endpoint: http://c1.vm1.mso.simpledemo.onap.org:28090 + tenant: + isolation: + retry: + count: 3 + aai: + endpoint: https://aai-simulator:9993 + auth: 221187EFA3AD4E33600DE0488F287099934CE65C3D0697BCECC00BB58E784E07CD74A24581DC31DBC086FF63DF116378776E9BE3D1325885 + extApi: + endpoint: http://nbi.onap:8080/nbi/api/v3 + so: + operational-environment: + dmaap: + username: testuser + password: VjR5NDcxSzA= + host: http://c1.vm1.mso.simpledemo.onap.org:28090 + auth: 51EA5414022D7BE536E7516C4D1A6361416921849B72C0D6FC1C7F262FD9F2BBC2AD124190A332D9845A188AD80955567A4F975C84C221EEA8243BFD92FFE6896CDD1EA16ADD34E1E3D47D4A + publisher: + topic: com.att.ecomp.mso.operationalEnvironmentEvent + health: + auth: Basic bXNvX2FkbWlufHBhc3N3b3JkMSQ= + endpoints: + - subsystem: apih + uri: http://bpmn-infra:8081 + - subsystem: catalogdb + uri: http://catalog-db-adapter:8082 + +spring: + datasource: + hikari: + jdbcUrl: jdbc:mariadb://mariadb:3306/catalogdb + username: cataloguser + password: catalog123 + driver-class-name: org.mariadb.jdbc.Driver + pool-name: catdb-pool + registerMbeans: true + jpa: + show-sql: true + hibernate: + dialect: org.hibernate.dialect.MySQL5Dialect + ddl-auto: validate + naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy + enable-lazy-load-no-trans: true + jersey: + type: filter + + security: + usercredentials: + - + username: sitecontrol + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: SiteControl-Client + - + username: gui + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: GUI-Client + - + username: infraportal + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: InfraPortal-Client + - + username: InfraPortalClient + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: InfraPortal-Client + - + username: bpel + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPEL-Client + - + username: mso_admin + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: ACTUATOR + +request: + datasource: + hikari: + jdbcUrl: jdbc:mariadb://mariadb:3306/requestdb + username: requestuser + password: request123 + driver-class-name: org.mariadb.jdbc.Driver + pool-name: reqdb-pool + registerMbeans: true +org: + onap: + so: + cloud-owner: CloudOwner + adapters: + network: + encryptionKey: 07a7159d3bf51a0e53be7a8f89699be7 diff --git a/plans/so/macroflow/config/override-files/bpmn-infra/onapheat/override.yaml b/plans/so/macroflow/config/override-files/bpmn-infra/onapheat/override.yaml new file mode 100644 index 00000000..3ca554df --- /dev/null +++ b/plans/so/macroflow/config/override-files/bpmn-infra/onapheat/override.yaml @@ -0,0 +1,366 @@ +aai: + auth: 221187EFA3AD4E33600DE0488F287099934CE65C3D0697BCECC00BB58E784E07CD74A24581DC31DBC086FF63DF116378776E9BE3D1325885 + dme2: + timeout: '30000' + endpoint: https://aai-simulator:9993 + workflowAaiDistributionDelay: PT30S + pnfEntryNotificationTimeout: P14D +cds: + endpoint: blueprints-processor + port: 9111 + auth: Basic Y2NzZGthcHBzOmNjc2RrYXBwcw== + timeout: 60 +camunda: + bpm: + admin-user: + id: admin + password: so_Admin123 + history-level: full + job-execution: + max-pool-size: 30 + core-pool-size: 3 +entitymanager: + packagesToScan: com +pnf: + dmaap: + host: message-router + port: 3904 + protocol: http + uriPathPrefix: events + topicName: unauthenticated.PNF_READY + consumerGroup: consumerGroup + consumerId: consumerId + topicListenerDelayInSeconds: 5 +bpelURL: http://bpmn-infra:8081 +msb-ip: msb-iag +msb-port: 80 +mso: + msoKey: 07a7159d3bf51a0e53be7a8f89699be7 + config: + path: /var/csar/ + correlation: + timeout: 60 + logPath: logs + async: + core-pool-size: 50 + max-pool-size: 50 + queue-capacity: 500 + aai: + endpoint: https://aai-simulator:9993 + adapters: + completemsoprocess: + endpoint: http://bpmn-infra:8081/CompleteMsoProcess + requestDb: + endpoint: http://request-db-adapter:8083 + auth: Basic YnBlbDpwYXNzd29yZDEk + db: + auth: 33293332AEC4930F655D8E2E8BB08937 + password: wLg4sjrAFUS8rfVfdvTXeQ== + endpoint: http://c1.vm1.mso.simpledemo.onap.org:8083/services/RequestsDbAdapter + spring: + endpoint: http://c1.vm1.mso.simpledemo.onap.org:8083 + network: + endpoint: http://c1.vm1.mso.simpledemo.onap.org:8087/services/NetworkAdapter + rest: + endpoint: http://c1.vm1.mso.simpledemo.onap.org:8087/services/rest/v1/networks + openecomp: + db: + endpoint: http://c1.vm1.mso.simpledemo.onap.org:8083/services/RequestsDbAdapter + po: + auth: 33293332AEC4930F655D8E2E8BB08937 + password: B8EBDE0311F0AF355CF3F2FD505A8CAD + sdnc: + endpoint: http://c1.vm1.mso.simpledemo.onap.org:8086/adapters/SDNCAdapter + rest: + endpoint: http://c1.vm1.mso.simpledemo.onap.org:8086/adapters/rest/v1/sdnc + timeout: PT60M + tenant: + endpoint: http://c1.vm1.mso.simpledemo.onap.org:8087/services/TenantAdapter + vnf: + endpoint: http://c1.vm1.mso.simpledemo.onap.org:8087/services/VnfAdapter + rest: + endpoint: http://c1.vm1.mso.simpledemo.onap.org:8087/services/rest/v1/vnfs + volume-groups: + rest: + endpoint: http://c1.vm1.mso.simpledemo.onap.org:8087/services/rest/v1/volume-groups + vnf-async: + endpoint: http://c1.vm1.mso.simpledemo.onap.org:8087/services/VnfAdapterAsync + vfc: + rest: + endpoint: http://c1.vm1.mso.simpledemo.onap.org:8084/services/v1/vfcadapter + workflow: + message: + endpoint: http://c1.vm1.mso.simpledemo.onap.org:8081/mso/WorkflowMessage + bpmn: + process: + historyTimeToLive: '30' + callbackRetryAttempts: '5' + catalog: + db: + endpoint: http://catalog-db-adapter:8082/ecomp/mso/catalog + spring: + endpoint: http://catalog-db-adapter:8082 + db: + auth: Basic YnBlbDpwYXNzd29yZDEk + default: + adapter: + namespace: http://org.onap.mso + healthcheck: + log: + debug: 'false' + infra: + customer: + id: testCustIdInfra + po: + timeout: PT60M + request: + db: + endpoint: http://c1.vm1.mso.simpledemo.onap.org:8083/ + rollback: 'true' + sdnc: + password: 3141634BF7E070AA289CF2892C986C0B + service: + agnostic: + sniro: + endpoint: /sniro/api/v2/placement + host: http://c1.vm1.mso.simpledemo.onap.org:30253 + site-name: CamundaEngine + sniro: + auth: test:testpwd + callback: http://c1.vm1.mso.simpledemo.onap.org:8086/adapters/rest/SDNCNotify + endpoint: http://replaceme:28090/optimizationInstance/V1/create + timeout: PT30M + oof: + auth: test:testpwd + callbackEndpoint: http://bpmn-infra:8081/mso/WorkflowMessage + endpoint: http://oof.api.simpledemo.openecomp.org:8698/api/oof/v1/placement + timeout: PT30M + workflow: + CreateGenericVNFV1: + aai: + volume-group: + uri: /aai/v6/cloud-infrastructure/volume-groups/volume-group + default: + aai: + version: '14' + cloud-region: + version: '14' + generic-vnf: + version: '14' + v14: + customer: + uri: /aai/v14/business/customers/customer + generic-query: + uri: /aai/v14/search/generic-query + generic-vnf: + uri: /aai/v14/network/generic-vnfs/generic-vnf + l3-network: + uri: /aai/v14/network/l3-networks/l3-network + network-policy: + uri: /aai/v14/network/network-policies/network-policy + nodes-query: + uri: /aai/v14/search/nodes-query + route-table-reference: + uri: /aai/v14/network/route-table-references/route-table-reference + tenant: + uri: /aai/v14/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant + vce: + uri: /aai/v14/network/vces/vce + vpn-binding: + uri: /aai/v14/network/vpn-bindings/vpn-binding + sp-partner: + uri: /aai/v14/business/sp-partners/sp-partner + device: + uri: /aai/v14/network/devices/device + v11: + customer: + uri: /aai/v11/business/customers/customer + generic-query: + uri: /aai/v11/search/generic-query + generic-vnf: + uri: /aai/v11/network/generic-vnfs/generic-vnf + l3-network: + uri: /aai/v11/network/l3-networks/l3-network + network-policy: + uri: /aai/v11/network/network-policies/network-policy + nodes-query: + uri: /aai/v11/search/nodes-query + route-table-reference: + uri: /aai/v11/network/route-table-references/route-table-reference + tenant: + uri: /aai/v11/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant + vce: + uri: /aai/v11/network/vces/vce + vpn-binding: + uri: /aai/v11/network/vpn-bindings/vpn-binding + v8: + configuration: + uri: /aai/v11/network/configurations/configuration + customer: + uri: /aai/v8/business/customers/customer + generic-query: + uri: /aai/v8/search/generic-query + l3-network: + uri: /aai/v8/network/l3-networks/l3-network + network-policy: + uri: /aai/v8/network/network-policies/network-policy + nodes-query: + uri: /aai/v8/search/nodes-query + route-table-reference: + uri: /aai/v8/network/route-table-references/route-table-reference + tenant: + uri: /aai/v8/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant + vce: + uri: /aai/v8/network/vces/vce + vpn-binding: + uri: /aai/v8/network/vpn-bindings/vpn-binding + v9: + cloud-region: + uri: /aai/v9/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner + generic-vnf: + uri: /aai/v9/network/generic-vnfs/generic-vnf + retry: + attempts: '1' + deleteCinderVolumeV1: + aai: + volume-group: + uri: /aai/v6/cloud-infrastructure/volume-groups/volume-group + global: + default: + aai: + namespace: http://org.onap.aai.inventory/ + version: 14 + message: + endpoint: http://bpmn-infra:8081/mso/WorkflowMessage + notification: + name: GenericNotificationServiceATT + sdnc: + replication: + delay: PT60S + sdncadapter: + callback: http://bpmn-infra:8081/mso/SDNCAdapterCallbackService + vnfadapter: + create: + callback: http://c1.vm1.mso.simpledemo.onap.org:8087/mso/vnfAdapterNotify + delete: + callback: http://c1.vm1.mso.simpledemo.onap.org:8087/mso/vnfAdapterNotify + query: + callback: http://c1.vm1.mso.simpledemo.onap.org:8087/mso/vnfAdapterNotify + rollback: + callback: http://c1.vm1.mso.simpledemo.onap.org:8087/mso/vnfAdapterNotify + use: + qualified: + host: false + global: + dmaap: + username: testuser + password: alRyMzJ3NUNeakxl + host: http://10.42.111.36:904 + publisher: + topic: replaceme + naming: + endpoint: http://naming.demo.onap.com:8081/web/service/v1/genNetworkElementName + auth: Basic bTA0NzY4QG5vbi1wcm9kLm1zby5lY29tcC5hdHQuY29tOkF0dG0wNDc2OExpZmUhQA== +policy: + auth: Basic dGVzdHBkcDphbHBoYTEyMw== + default: + disposition: Skip + client: + auth: Basic bTAzNzQzOnBvbGljeVIwY2sk + endpoint: https://localhost:8081/pdp/api/ + environment: TEST +sdnc: + auth: Basic YWRtaW46S3A4Yko0U1hzek0wV1hsaGFrM2VIbGNzZTJnQXc4NHZhb0dHbUp2VXkyVQ== + host: http://sdnc-simulator:9994 + path: /restconf/operations/GENERIC-RESOURCE-API + si: + svc: + types: PORT-MIRROR,PPROBE + dmaap: + host: ueb1.simpledemo.onap.org:3904 + timeout: 30000 + lcm: + path: '/restconf/operations/LCM:' + actionTimeout: 300000 + dmapp: + readTopic: SDNC-LCM-WRITE + writeTopic: SDNC-LCM-READ +appc: + client: + topic: + read: + name: APPC-LCM-WRITE + timeout: 360000 + write: APPC-LCM-READ + sdnc: + read: SDNC-LCM-WRITE + write: SDNC-LCM-READ + response: + timeout: 360000 + key: VIlbtVl6YLhNUrtU + secret: 64AG2hF4pYeG2pq7CT6XwUOT + service: ueb + poolMembers: ueb1.simpledemo.onap.org:3904,ueb2.simpledemo.onap.org:3904 +sniro: + conductor: + enabled: true + host: http://sniro-emulator:80 + uri: /v1/release-orders + headers.auth: Basic dGVzdDp0ZXN0cHdk + manager: + timeout: PT30M + host: http://sniro-emulator:80 + uri.v1: /sniro/api/v2/placement + uri.v2: /sniro/api/placement/v2 + headers.auth: Basic dGVzdDp0ZXN0cHdk + headers.patchVersion: 1 + headers.minorVersion: 1 + headers.latestVersion: 2 +server: + port: 8081 + tomcat: + max-threads: 50 +spring: + datasource: + hikari: + jdbcUrl: jdbc:mariadb://mariadb:3306/camundabpmn + username: camundauser + password: camunda123 + driver-class-name: org.mariadb.jdbc.Driver + pool-name: bpmn-pool + registerMbeans: true + security: + usercredentials: + - + username: apihBpmn + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPMN-Client + - + username: sdncaBpmn + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPMN-Client + - + username: poBpmn + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPMN-Client + - + username: wmaBpmn + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPMN-Client + - + username: sniro + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: SNIRO-Client + - + username: mso_admin + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: ACTUATOR +so: + vnfm: + adapter: + url: http://so-vnfm-adapter:9092/so/vnfm-adapter/v1/ + auth: Basic dm5mbTpwYXNzd29yZDEk +org: + onap: + so: + cloud-owner: CloudOwner diff --git a/plans/so/macroflow/config/override-files/catalog-db-adapter/onapheat/override.yaml b/plans/so/macroflow/config/override-files/catalog-db-adapter/onapheat/override.yaml new file mode 100644 index 00000000..934e8fbd --- /dev/null +++ b/plans/so/macroflow/config/override-files/catalog-db-adapter/onapheat/override.yaml @@ -0,0 +1,103 @@ +server: + port: 8082 + tomcat: + max-threads: 50 +ssl-enable: false +mso: + logPath: logs + site-name: onapheat + catalog: + db: + spring: + endpoint: http://catalog-db-adapter:8082 + db: + auth: Basic YnBlbDpwYXNzd29yZDEk +spring: + datasource: + hikari: + jdbcUrl: jdbc:mariadb://mariadb:3306/catalogdb + username: cataloguser + password: catalog123 + driver-class-name: org.mariadb.jdbc.Driver + pool-name: catdb-pool + registerMbeans: true + flyway: + baseline-on-migrate: false + url: jdbc:mariadb://mariadb:3306/catalogdb + user: cataloguser + password: catalog123 + outOfOrder: true + validateOnMigrate: false + jpa: + generate-ddl: false + show-sql: false + hibernate: + ddl-auto: validate + naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy + enable-lazy-load-no-trans: true + database-platform: org.hibernate.dialect.MySQL5InnoDBDialect + security: + usercredentials: + - + username: bpel + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPEL-Client + - + username: mso_admin + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: ACTUATOR +#Actuator +management: + context-path: /manage +cloud_config: + identity_services: + RAX_KEYSTONE: + identity_url: "https://identity.api.rackspacecloud.com/v2.0" + mso_id: "RACKSPACE_ACCOUNT_ID" + mso_pass: "RACKSPACE_ACCOUNT_APIKEY" + admin_tenant: "dummy" + member_role: "admin" + tenant_metadata: true + identity_server_type: "KEYSTONE" + identity_authentication_type: "RACKSPACE_APIKEY" + project_domain_name: "PROJECT_DOMAIN_NAME" + user_domain_name: "USER_DOMAIN_NAME" + DEFAULT_KEYSTONE: + identity_url: "dummy" + mso_id: "dummy" + mso_pass: "dummy" + admin_tenant: "dummy" + member_role: "admin" + tenant_metadata: true + identity_server_type: "KEYSTONE" + identity_authentication_type: "USERNAME_PASSWORD" + project_domain_name: "dummy" + user_domain_name: "dummy" + cloud_sites: + Dallas: + region_id: "DFW" + clli: "DFW" + aic_version: "2.5" + identity_service_id: "RAX_KEYSTONE" + Northern Virginia: + region_id: "IAD" + clli: "IAD" + aic_version: "2.5" + identity_service_id: "RAX_KEYSTONE" + Chicago: + region_id: "ORD" + clli: "ORD" + aic_version: "2.5" + identity_service_id: "RAX_KEYSTONE" + RegionOne: + region_id: "RegionOne" + clli: "RegionOne" + aic_version: "2.5" + identity_service_id: "DEFAULT_KEYSTONE" + DEFAULT: + region_id: "dummyRegionId" + clli: "dummyClli" + aic_version: "2.5" + identity_service_id: "DEFAULT_KEYSTONE" + + diff --git a/plans/so/macroflow/config/override-files/openstack-adapter/onapheat/override.yaml b/plans/so/macroflow/config/override-files/openstack-adapter/onapheat/override.yaml new file mode 100644 index 00000000..7e2afa85 --- /dev/null +++ b/plans/so/macroflow/config/override-files/openstack-adapter/onapheat/override.yaml @@ -0,0 +1,147 @@ +server: + port: 8087 + +spring: + datasource: + hikari: + jdbcUrl: jdbc:mariadb://mariadb:3306/catalogdb + username: cataloguser + password: catalog123 + driver-class-name: org.mariadb.jdbc.Driver + pool-name: catdb-pool + registerMbeans: false + + security: + usercredentials: + - + username: sdnc + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: SDNC-Client + - + username: sitecontrol + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: SiteControl-Client + - + username: bpel + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPEL-Client + - + username: sniro + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: SNIRO-Client + - + username: apih + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: MSO-Client + - + username: mso_admin + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: ACTUATOR + + +org: + onap: + so: + adapters: + default_keystone_url_version: /v2.0 + default_keystone_reg_ex: "/[vV][0-9]" + vnf: + bpelauth: D1A67FA93B6A6419132D0F83CC771AF774FD3C60853C50C22C8C6FC5088CC79E9E81EDE9EA39F22B2F66A0068E + checkRequiredParameters: true + addGetFilesOnVolumeReq: false + sockettimeout: 30 + connecttimeout: 30 + retrycount: 5 + retryinterval: -15 + retrylist: 408,429,500,502,503,504,900 + valet_enabled: false + fail_requests_on_valet_failure: false + network: + bpelauth: D1A67FA93B6A6419132D0F83CC771AF774FD3C60853C50C22C8C6FC5088CC79E9E81EDE9EA39F22B2F66A0068E + sockettimeout: 5 + connecttimeout: 5 + retrycount: 5 + retryinterval: -15 + retrylist: 408,429,500,502,503,504,900 + encryptionKey: 07a7159d3bf51a0e53be7a8f89699be7 + tenant: + default_keystone_url_version: /v2.0 + default_keystone_reg_ex: "/[vV][0-9]" + default_tenant_description: Tenant + default_region_type: single + default_user_role: admin + default_success_status_string: Success + default_no_regions_status_string: no regions + default_quota_value: 10 + set_default_quota: false + +ecomp: + mso: + adapters: + po: + retryCodes: 504 + retryDelay: 5 + retryCount: 3 + pollTimeout: 7500 + pollInterval: 15 + +mso: + adapters: + requestDb: + endpoint: http://so-request-db-adapter.onap:8083 + auth: Basic YnBlbDpwYXNzd29yZDEk + auth: BEA8637716A7EB617DF472BA6552D22F68C1CB17B0D094D77DDA562F4ADAAC4457CAB848E1A4 + msoKey: 07a7159d3bf51a0e53be7a8f89699be7 + logPath: ./logs/openstack + msb-ip: multicloud-simulator + msb-port: 9996 + msb-scheme: http + workflow: + endpoint: http://bpmn-infra:8081/sobpmnengine + config: + cadi: + aafId: poBpmn + catalog: + db: + spring: + endpoint: http://catalog-db-adapter:8082 + db: + auth: Basic YnBlbDpwYXNzd29yZDEk + site-name: localDevEnv + async: + core-pool-size: 50 + max-pool-size: 50 + queue-capacity: 500 + +cloud_config: + identity_services: + RAX_KEYSTONE: + identity_url: "https://identity.api.rackspacecloud.com/v2.0" + mso_id: "RACKSPACE_ACCOUNT_ID" + mso_pass: "RACKSPACE_ACCOUNT_APIKEY" + admin_tenant: "service" + member_role: "admin" + tenant_metadata: true + identity_server_type: "KEYSTONE" + identity_authentication_type: "RACKSPACE_APIKEY" + cloud_sites: + Dallas: + region_id: "DFW" + clli: "DFW" + aic_version: "2.5" + identity_service_id: "RAX_KEYSTONE" + Northern Virginia: + region_id: "IAD" + clli: "IAD" + aic_version: "2.5" + identity_service_id: "RAX_KEYSTONE" + Chicago: + region_id: "ORD" + clli: "ORD" + aic_version: "2.5" + identity_service_id: "RAX_KEYSTONE" + DEFAULT: + region_id: "DFW" + clli: "DFW" + aic_version: "2.5" + identity_service_id: "RAX_KEYSTONE" diff --git a/plans/so/macroflow/config/override-files/sdc-controller/onapheat/override.yaml b/plans/so/macroflow/config/override-files/sdc-controller/onapheat/override.yaml new file mode 100644 index 00000000..ed8bd43f --- /dev/null +++ b/plans/so/macroflow/config/override-files/sdc-controller/onapheat/override.yaml @@ -0,0 +1,81 @@ +aai: + auth: 2A11B07DB6214A839394AA1EC5844695F5114FC407FF5422625FB00175A3DCB8A1FF745F22867EFA72D5369D599BBD88DA8BED4233CF5586 +server: + port: 8085 + +spring: + datasource: + hikari: + jdbcUrl: jdbc:mariadb://mariadb:3306/catalogdb + username: cataloguser + password: catalog123 + driver-class-name: org.mariadb.jdbc.Driver + pool-name: catdb-pool + registerMbeans: false + + security: + usercredentials: + - + username: asdc + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: Asdc-Client + - + username: mso_admin + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: ACTUATOR + +request: + datasource: + hikari: + jdbcUrl: jdbc:mariadb://mariadb:3306/requestdb + username: requestuser + password: request123 + driver-class-name: org.mariadb.jdbc.Driver + pool-name: reqdb-pool + registerMbeans: false + +mso: + msoKey: 07a7159d3bf51a0e53be7a8f89699be7 + logPath: ./logs/asdc + catalog: + db: + spring: + endpoint: http://catalog-db-adapter:8082 + db: + auth: Basic YnBlbDpwYXNzd29yZDEk + site-name: onapheat + camundaURL: http://bpmn-infra:8081/ + adapters: + requestDb: + endpoint: http://request-db-adapter:8083 + auth: Basic YnBlbDpwYXNzd29yZDEk + aai: + endpoint: https://aai.api.simpledemo.onap.org:8443 + asdc-connections: + asdc-controller1: + user: mso + consumerGroup: SO-OpenSource-Env11 + consumerId: SO-COpenSource-Env11 + environmentName: AUTO + asdcAddress: c2.vm1.sdc.simpledemo.onap.org:8443 + password: 76966BDD3C7414A03F7037264FF2E6C8EEC6C28F2B67F2840A1ED857C0260FEE731D73F47F828E5527125D29FD25D3E0DE39EE44C058906BF1657DE77BF897EECA93BDC07FA64F + pollingInterval: 60 + pollingTimeout: 60 + relevantArtifactTypes: HEAT,HEAT_ENV,HEAT_VOL + useHttpsWithDmaap: false + activateServerTLSAuth: false + keyStorePassword: + keyStorePath: + watchDogTimeout: 100 + isFitlerInEmptyResources: true + messageBusAddress: vm1.mr.simpledemo.onap.org,vm1.mr.simpledemo.onap.org + asdc: + config: + activity: + endpoint: http://sdc-wfd-be:8080 + key: 566B754875657232314F5548556D3665 + components: + count: 0, + componentNames: + scheduling: + enabled: false diff --git a/plans/so/macroflow/config/override-files/so-monitoring/onapheat/override.yaml b/plans/so/macroflow/config/override-files/so-monitoring/onapheat/override.yaml new file mode 100644 index 00000000..7e61c7d0 --- /dev/null +++ b/plans/so/macroflow/config/override-files/so-monitoring/onapheat/override.yaml @@ -0,0 +1,24 @@ +server: + port: 30224 + tomcat: + max-threads: 4 +ssl-enable: false +camunda: + rest: + api: + url: http://bpmn-infra:8081/sobpmnengine/engine/ + engine: default + auth: Basic YXBpaEJwbW46cGFzc3dvcmQxJA== +mso: + database: + rest: + api: + url: http://request-db-adapter:8083/infraActiveRequests/ + auth: Basic YnBlbDpwYXNzd29yZDEk +spring: + security: + usercredentials: + - + username: gui + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: GUI-Client diff --git a/plans/so/macroflow/config/override-files/so-vnfm-adapter/onapheat/override.yaml b/plans/so/macroflow/config/override-files/so-vnfm-adapter/onapheat/override.yaml new file mode 100644 index 00000000..b029bd7e --- /dev/null +++ b/plans/so/macroflow/config/override-files/so-vnfm-adapter/onapheat/override.yaml @@ -0,0 +1,33 @@ +server: + port: 9092 + tomcat: + max-threads: 4 +aai: + auth: 221187EFA3AD4E33600DE0488F287099934CE65C3D0697BCECC00BB58E784E07CD74A24581DC31DBC086FF63DF116378776E9BE3D1325885 + version: v15 + endpoint: https://aai-simulator:9993 +spring: + security: + usercredentials: + - username: vnfm + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPEL-Client + - username: mso_admin + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: ACTUATOR +mso: + key: 07a7159d3bf51a0e53be7a8f89699be7 + site-name: localSite + logPath: ./logs/vnfm-adapter +sdc: + username: mso + password: 76966BDD3C7414A03F7037264FF2E6C8EEC6C28F2B67F2840A1ED857C0260FEE731D73F47F828E5527125D29FD25D3E0DE39EE44C058906BF1657DE77BF897EECA93BDC07FA64F + key: 566B754875657232314F5548556D3665 + endpoint: http://sdc-simulator:9991/ + toscametapath: Artifacts/Deployment/OTHER/TOSCA.meta +vnfmadapter: + endpoint: http://so-vnfm-adapter:9092 +etsi-catalog-manager: + vnfpkgm: + endpoint: http://modeling-etsicatalog:8806/api/vnfpkgm/v1 + diff --git a/plans/so/macroflow/config/override-files/vnfm-simulator/onapheat/override.yaml b/plans/so/macroflow/config/override-files/vnfm-simulator/onapheat/override.yaml new file mode 100644 index 00000000..05cb1e56 --- /dev/null +++ b/plans/so/macroflow/config/override-files/vnfm-simulator/onapheat/override.yaml @@ -0,0 +1,56 @@ +spring: + h2: + console: + enabled: true + path: console + datasource: + url: jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE + username: admin + password: admin + http: + converters: + preferred-json-mapper: gson + security: + usercredentials: + - username: vnfm + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPEL-Client + +server: + port: 9093 + tomcat: + max-threads: 50 + ssl: + client-auth: need + key-alias: so@so.onap.org + key--store-password: '7Em3&j4.19xYiMelhD5?xbQ.' + key-store: classpath:so-vnfm-simulator.p12 + key-store-type: PKCS12 + request: + grant: + auth: twowaytls + dns: + name: so-vnfm-simulator + +vnfds: + vnfdlist: + - vnfdid: sgsn-mme_12df452s04131 + vnfclist: + - vnfcid: VNFC1 + resourceTemplateId: vnfd1_vnfc1 + vduId: vnfd1_vduForVnfc1 + type: COMPUTE + - vnfcid: VNFC2 + resourceTemplateId: vnfd1_vnfc2 + vduId: vnfd1_vduForVnfc2 + type: COMPUTE + - vnfdid: 2 + vnfclist: + - vnfcid: VNFC3 + resourceTemplateId: vnfd2_vnfc3 + vduId: vnfd2_vduForVnfc3 + type: COMPUTE + - vnfcid: VNFC4 + resourceTemplateId: vnfd2_vnfc4 + vduId: vnfd2_vduForVnfc4 + type: COMPUTE diff --git a/plans/so/macroflow/docker-compose.local.yml b/plans/so/macroflow/docker-compose.local.yml new file mode 100644 index 00000000..281a5162 --- /dev/null +++ b/plans/so/macroflow/docker-compose.local.yml @@ -0,0 +1,30 @@ +version: '3' +services: +################################################################################ + mariadb: + image: mariadb:${MARIADB_VERSION} +################################################################################ + catalog-db-adapter: + image: onap/so/catalog-db-adapter:${TAG} +################################################################################ + request-db-adapter: + image: onap/so/request-db-adapter:${TAG} +################################################################################ + sdnc-adapter: + image: onap/so/sdnc-adapter:${TAG} +################################################################################ + openstack-adapter: + image: onap/so/openstack-adapter:${TAG} +################################################################################ + sdc-controller: + image: onap/so/sdc-controller:${TAG} +################################################################################ + bpmn-infra: + image: onap/so/bpmn-infra:${TAG} +################################################################################ + api-handler-infra: + image: onap/so/api-handler-infra:${TAG} +############################################################################# + so-monitoring: + image: onap/so/so-monitoring:${TAG} +################################################################################ diff --git a/plans/so/macroflow/docker-compose.yml b/plans/so/macroflow/docker-compose.yml index 9df89d03..8cc1c7b6 100644 --- a/plans/so/macroflow/docker-compose.yml +++ b/plans/so/macroflow/docker-compose.yml @@ -1,5 +1,264 @@ version: '3' services: +################################################################################ + mariadb: + image: ${NEXUS_DOCKER_REPO_MSO}/mariadb:${MARIADB_VERSION} + ports: + - "3306:3306" + volumes: + - ${TEST_LAB_DIR}/volumes/mariadb/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d + - ${TEST_LAB_DIR}/volumes/mariadb/conf.d:/etc/mysql/conf.d + environment: + - MYSQL_ROOT_PASSWORD=password + hostname: + mariadb.so.testlab.onap.org + logging: + driver: "json-file" + options: + max-size: "30m" + max-file: "5" +################################################################################ + catalog-db-adapter: + image: ${NEXUS_DOCKER_REPO_MSO}/onap/so/catalog-db-adapter:${TAG} + ports: + - "8082:8082" + volumes: + - ${TEST_LAB_DIR}/volumes/so/ca-certificates/onapheat:/app/ca-certificates + - ${CONFIG_DIR_PATH_MACRO}/override-files/catalog-db-adapter/onapheat:/app/config + environment: + - APP=catalog-db-adapter + - JVM_ARGS=-Xms64m -Xmx512m + - DB_HOST=mariadb + - DB_PORT=3306 + - DB_USERNAME=so_user + - DB_PASSWORD=so_User123 + - DB_ADMIN_USERNAME=so_admin + - DB_ADMIN_PASSWORD=so_Admin123 + hostname: + catalog-db-adapter.so.testlab.onap.org + depends_on: + - mariadb + logging: + driver: "json-file" + options: + max-size: "30m" + max-file: "5" + user: root + entrypoint: /bin/sh -c '/app/wait-for.sh -q -t "300" mariadb:3306 -- "/app/start-app.sh"' +################################################################################ + request-db-adapter: + image: ${NEXUS_DOCKER_REPO_MSO}/onap/so/request-db-adapter:${TAG} + ports: + - "8083:8083" + volumes: + - ${TEST_LAB_DIR}/volumes/so/ca-certificates/onapheat:/app/ca-certificates + - ${TEST_LAB_DIR}/volumes/so/config/request-db-adapter/onapheat:/app/config + environment: + - APP=request-db-adapter + - JVM_ARGS=-Xms64m -Xmx512m + - DB_HOST=mariadb + - DB_PORT=3306 + - DB_USERNAME=so_user + - DB_PASSWORD=so_User123 + - DB_ADMIN_USERNAME=so_admin + - DB_ADMIN_PASSWORD=so_Admin123 + hostname: + request-db-adapter.so.testlab.onap.org + depends_on: + - mariadb + - catalog-db-adapter + logging: + driver: "json-file" + options: + max-size: "30m" + max-file: "5" + user: root + entrypoint: /bin/sh -c '/app/wait-for.sh -q -t "300" catalog-db-adapter:8082 -- "/app/start-app.sh"' +################################################################################ + sdnc-adapter: + image: ${NEXUS_DOCKER_REPO_MSO}/onap/so/sdnc-adapter:${TAG} + ports: + - "8086:8086" + volumes: + - ${TEST_LAB_DIR}/volumes/so/ca-certificates/onapheat:/app/ca-certificates + - ${TEST_LAB_DIR}/volumes/so/config/sdnc-adapter/onapheat:/app/config + environment: + - APP=sdnc-adapter + - JVM_ARGS=-Xms64m -Xmx512m + - DB_HOST=mariadb + - DB_PORT=3306 + - DB_USERNAME=so_user + - DB_PASSWORD=so_User123 + - DB_ADMIN_USERNAME=so_admin + - DB_ADMIN_PASSWORD=so_Admin123 + hostname: + sdnc-adapter.so.testlab.onap.org + depends_on: + - mariadb + - catalog-db-adapter + - request-db-adapter + logging: + driver: "json-file" + options: + max-size: "30m" + max-file: "5" + user: root + entrypoint: /bin/sh -c '/app/wait-for.sh -q -t "300" request-db-adapter:8083 -- "/app/start-app.sh"' +################################################################################ + openstack-adapter: + image: ${NEXUS_DOCKER_REPO_MSO}/onap/so/openstack-adapter:${TAG} + ports: + - "8087:8087" + volumes: + - ${TEST_LAB_DIR}/volumes/so/ca-certificates/onapheat:/app/ca-certificates + - ${CONFIG_DIR_PATH_MACRO}/override-files/openstack-adapter/onapheat:/app/config + environment: + - APP=openstack-adapter + - JVM_ARGS=-Xms64m -Xmx512m + - DB_HOST=mariadb + - DB_PORT=3306 + - DB_USERNAME=so_user + - DB_PASSWORD=so_User123 + - DB_ADMIN_USERNAME=so_admin + - DB_ADMIN_PASSWORD=so_Admin123 + hostname: + openstack-adapter.so.testlab.onap.org + depends_on: + - mariadb + - catalog-db-adapter + - request-db-adapter + logging: + driver: "json-file" + options: + max-size: "30m" + max-file: "5" + user: root + entrypoint: /bin/sh -c '/app/wait-for.sh -q -t "300" request-db-adapter:8083 -- "/app/start-app.sh"' +################################################################################ + sdc-controller: + image: ${NEXUS_DOCKER_REPO_MSO}/onap/so/sdc-controller:${TAG} + ports: + - "8085:8085" + volumes: + - ${TEST_LAB_DIR}/volumes/so/ca-certificates/onapheat:/app/ca-certificates + - ${CONFIG_DIR_PATH_MACRO}/distribution-test-zip:/distribution-test-zip + - ${CONFIG_DIR_PATH_MACRO}/override-files/sdc-controller/onapheat:/app/config + environment: + - APP=sdc-controller + - JVM_ARGS=-Xms64m -Xmx512m + - DB_HOST=mariadb + - DB_PORT=3306 + - DB_USERNAME=so_user + - DB_PASSWORD=so_User123 + - DB_ADMIN_USERNAME=so_admin + - DB_ADMIN_PASSWORD=so_Admin123 + hostname: + sdc-controller.so.testlab.onap.org + depends_on: + - mariadb + - catalog-db-adapter + - request-db-adapter + logging: + driver: "json-file" + options: + max-size: "30m" + max-file: "5" + user: root + entrypoint: /bin/sh -c 'mkdir -p /distribution-test-zip/unzipped && tar -xvzf /distribution-test-zip/macro_zipped_sdc_csar.tar.gz -C /distribution-test-zip/unzipped && chmod 777 -R /distribution-test-zip/ && /app/wait-for.sh -q -t "300" request-db-adapter:8083 -- "/app/start-app.sh"' +################################################################################ + bpmn-infra: + image: ${NEXUS_DOCKER_REPO_MSO}/onap/so/bpmn-infra:${TAG} + ports: + - "8081:8081" + volumes: + - ${CONFIG_DIR_PATH_MACRO}/override-files/bpmn-infra/onapheat:/app/config + - ${CONFIG_DIR_PATH}/certificates/bpmn-infra-certs:/app/bpmn-infra-certs + - ${CONFIG_DIR_PATH}/certificates/truststore/root-ca.crt:/app/ca-certificates/root-ca.crt + environment: + - APP=bpmn-infra + - JVM_ARGS=-Xms64m -Xmx512m + - DB_HOST=mariadb + - DB_PORT=3306 + - DB_USERNAME=so_user + - DB_PASSWORD=so_User123 + - DB_ADMIN_USERNAME=so_admin + - DB_ADMIN_PASSWORD=so_Admin123 + hostname: + bpmn-infra.so.testlab.onap.org + depends_on: + - mariadb + - catalog-db-adapter + - request-db-adapter + logging: + driver: "json-file" + options: + max-size: "30m" + max-file: "5" + user: root + entrypoint: /bin/sh -c '/app/wait-for.sh -q -t "300" request-db-adapter:8083 -- "/app/start-app.sh"' +################################################################################ + api-handler-infra: + image: ${NEXUS_DOCKER_REPO_MSO}/onap/so/api-handler-infra:${TAG} + ports: + - "8080:8080" + volumes: + - ${CONFIG_DIR_PATH_MACRO}/override-files/api-handler-infra/onapheat:/app/config + - ${CONFIG_DIR_PATH}/certificates/truststore/root-ca.crt:/app/ca-certificates/root-ca.crt + environment: + - APP=api-handler-infra + - JVM_ARGS=-Xms64m -Xmx512m + - DB_HOST=mariadb + - DB_PORT=3306 + - DB_USERNAME=so_user + - DB_PASSWORD=so_User123 + - DB_ADMIN_USERNAME=so_admin + - DB_ADMIN_PASSWORD=so_Admin123 + hostname: + api-handler-infra.so.testlab.onap.org + depends_on: + - mariadb + - catalog-db-adapter + - request-db-adapter + logging: + driver: "json-file" + options: + max-size: "30m" + max-file: "5" + user: root + entrypoint: /bin/sh -c '/app/wait-for.sh -q -t "300" request-db-adapter:8083 -- "/app/start-app.sh"' +############################################################################# + so-monitoring: + image: ${NEXUS_DOCKER_REPO_MSO}/onap/so/so-monitoring:${TAG} + ports: + - "30224:30224" + volumes: + - ${CONFIG_DIR_PATH_MACRO}/override-files/so-monitoring/onapheat:/app/config + environment: + - APP=so-monitoring + - JVM_ARGS=-Xms64m -Xmx512m + hostname: + so-monitoring.so.testlab.onap.org + depends_on: + - mariadb + - catalog-db-adapter + - request-db-adapter +################################################################################ + sdc-simulator: + image: simulators/sdc-simulator:latest + ports: + - "9991:9991" + environment: + - APP=SDC-SIMULATOR + - JVM_ARGS=-Xms64m -Xmx512m + hostname: + sdc-simulator + depends_on: + - mariadb + logging: + driver: "json-file" + options: + max-size: "30m" + max-file: "5" ################################################################################ aai-simulator: image: simulators/aai-simulator:latest @@ -10,9 +269,78 @@ services: - JVM_ARGS=-Xms64m -Xmx512m hostname: aai-simulator + depends_on: + - mariadb logging: driver: "json-file" options: max-size: "30m" max-file: "5" +################################################################################ + workaround-config: + image: jobs/workaround-job-container:latest + ports: + - "9990:9990" + volumes: + - ${CONFIG_DIR_PATH}/apply-workarounds.sh:/config/apply-workarounds.sh + environment: + - MYSQL_ROOT_PASSWORD=password + - DB_HOST=mariadb + - DB_PORT=3306 + - CATALOG_DB=catalogdb + depends_on: + - mariadb + command: + - "/config/apply-workarounds.sh" +################################################################################# + sdnc-simulator: + image: simulators/sdnc-simulator:latest + ports: + - "9994:9994" + environment: + - APP=SDNC-SIMULATOR + - JVM_ARGS=-Xms64m -Xmx512m + hostname: + sdnc-simulator + depends_on: + - mariadb + logging: + driver: "json-file" + options: + max-size: "30m" + max-file: "5" +################################################################################# + multicloud-simulator: + image: simulators/multicloud-simulator:latest + ports: + - "9996:9996" + environment: + - APP=MULTICLOUD-SIMULATOR + - JVM_ARGS=-Xms64m -Xmx512m + hostname: + multicloud-simulator + depends_on: + - mariadb + logging: + driver: "json-file" + options: + max-size: "30m" + max-file: "5" +################################################################################ + populate-aai-config: + image: jobs/workaround-job-container:latest + ports: + - "9995:9995" + volumes: + - ${CONFIG_DIR_PATH}/populate-aai-simulator.sh:/config/populate-aai-simulator.sh + - ${CONFIG_DIR_PATH}/wait-for.sh:/config/wait-for.sh + - ${CONFIG_DIR_PATH}/aai-simulator-populate-data:/config/aai-simulator-populate-data/ + environment: + - AAI_SIMULATOR_HOST=aai-simulator + - AAI_SIMULATOR_PORT=9993 + - TIMEOUT_IN_SECONDS=300 #5 mins + depends_on: + - aai-simulator + command: + - "/config/populate-aai-simulator.sh" ################################################################################ diff --git a/plans/so/macroflow/setup.sh b/plans/so/macroflow/setup.sh index 1f8c8b86..5bb94f75 100644 --- a/plans/so/macroflow/setup.sh +++ b/plans/so/macroflow/setup.sh @@ -1,38 +1,41 @@ #!/bin/bash # # ============LICENSE_START======================================================= -# Copyright (C) 2021 Nordix Foundation. -# ================================================================================ -# 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 +# Copyright 2021 Huawei Technologies Co., Ltd. # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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 # -# 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. +# 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. # # SPDX-License-Identifier: Apache-2.0 # ============LICENSE_END========================================================= -# @author Waqas Ikram (waqas.ikram@est.tech) - MAVEN_VERSION_DIR="apache-maven-3.3.9" MAVEN_TAR_FILE="$MAVEN_VERSION_DIR-bin.tar.gz" MAVEN_TAR_LOCATION="https://archive.apache.org/dist/maven/maven-3/3.3.9/binaries/$MAVEN_TAR_FILE" +# Macroflow SCRIPT_HOME="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" SCRIPT_NAME=$(basename $0) -CONFIG_DIR=$SCRIPT_HOME/config -ENV_FILE=$CONFIG_DIR/env -TEMP_DIR_PATH=$SCRIPT_HOME/temp - +CONFIG_DIR_MACRO=$SCRIPT_HOME/config +ENV_FILE=$CONFIG_DIR_MACRO/env +SQL_PATH=$SCRIPT_HOME/cloud_owner_sql DOCKER_COMPOSE_FILE_PATH=$SCRIPT_HOME/docker-compose.yml +DOCKER_COMPOSE_LOCAL_OVERRIDE_FILE=$SCRIPT_HOME/docker-compose.local.yml TEAR_DOWN_SCRIPT=$SCRIPT_HOME/teardown.sh +TEMP_DIR_PATH=$SCRIPT_HOME/temp +TEST_LAB_DIR_PATH=$TEMP_DIR_PATH/test_lab + +# INTEGRATION_ETSI INTEGRATION_ETSI_TESTING_DIR=$WORKSPACE/plans/so/integration-etsi-testing INTEGRATION_ETSI_TESTING_CONFIG_DIR=$INTEGRATION_ETSI_TESTING_DIR/config @@ -43,13 +46,15 @@ MVN_VERSION="$MVN -v" MVN_SETTINGS_XML="$INTEGRATION_ETSI_TESTING_DIR/settings.xml" MVN_CLEAN_INSTALL="$MVN clean install" SIMULATOR_MAVEN_PROJECT_POM="$INTEGRATION_ETSI_TESTING_DIR/so-simulators/pom.xml" +WAIT_FOR_WORKAROUND_SCRIPT=$INTEGRATION_ETSI_TESTING_CONFIG_DIR/"wait-for-workaround-job.sh" +WAIT_FOR_POPULATE_AAI_SCRIPT=$INTEGRATION_ETSI_TESTING_CONFIG_DIR/"wait-for-aai-config-job.sh" WAIT_FOR_CONTAINER_SCRIPT=$INTEGRATION_ETSI_TESTING_CONFIG_DIR/"wait-for-container.sh" echo "Running $SCRIPT_HOME/$SCRIPT_NAME ..." export $(egrep -v '^#' $ENV_FILE | xargs) -MANDATORY_VARIABLES_NAMES=( "PROJECT_NAME" "DEFAULT_NETWORK_NAME" ) +MANDATORY_VARIABLES_NAMES=( "NEXUS_DOCKER_REPO_MSO" "DOCKER_ENVIRONMENT" "TAG" "TIME_OUT_DEFAULT_VALUE_SEC" "PROJECT_NAME" "DEFAULT_NETWORK_NAME") for var in "${MANDATORY_VARIABLES_NAMES[@]}" do @@ -125,21 +130,70 @@ if [ $? -ne 0 ]; then exit 1 fi -docker-compose -f $DOCKER_COMPOSE_FILE_PATH -p $PROJECT_NAME up -d +echo "Will clone docker-config project ... " -echo "Sleeping for 1m" -sleep 1m -AAI_SIMULATOR_CONTAINER_NAME="aai-simulator" -echo "Will execute $WAIT_FOR_CONTAINER_SCRIPT to wait for $AAI_SIMULATOR_CONTAINER_NAME container to start up" -$WAIT_FOR_CONTAINER_SCRIPT -c "$AAI_SIMULATOR_CONTAINER_NAME" -t "300" -n "$DEFAULT_NETWORK_NAME" +if [[ -d "$TEST_LAB_DIR_PATH" ]]; then + echo "$TEST_LAB_DIR_PATH already exists" + echo "Removing $TEST_LAB_DIR_PATH directory ..." + rm -rf $TEST_LAB_DIR_PATH +fi + +git clone http://gerrit.onap.org/r/so/docker-config.git $TEST_LAB_DIR_PATH + +export TEST_LAB_DIR=$TEST_LAB_DIR_PATH +export CONFIG_DIR_PATH=$INTEGRATION_ETSI_TESTING_CONFIG_DIR +export CONFIG_DIR_PATH_MACRO=$CONFIG_DIR_MACRO + +if [ "$DOCKER_ENVIRONMENT" == "remote" ]; then + echo "Starting docker containers with remote images ..." + docker-compose -f $DOCKER_COMPOSE_FILE_PATH -p $PROJECT_NAME up -d +elif [ "$DOCKER_ENVIRONMENT" == "local" ]; then + echo "Starting docker containers with local images ..." + docker-compose -f $DOCKER_COMPOSE_FILE_PATH -f $DOCKER_COMPOSE_LOCAL_OVERRIDE_FILE -p $PROJECT_NAME up -d +else + echo "DOCKER_ENVIRONMENT not set correctly in $ENV_FILE. Allowed values: local | remote" + exit 1 +fi + +echo "Sleeping for 3m" +sleep 3m + +echo "Will execute $WAIT_FOR_WORKAROUND_SCRIPT script" +$WAIT_FOR_WORKAROUND_SCRIPT + if [ $? -ne 0 ]; then - echo "ERROR: $WAIT_FOR_CONTAINER_SCRIPT failed" + echo "ERROR: $WAIT_FOR_WORKAROUND_SCRIPT failed" echo "Will stop running docker containers . . ." $TEAR_DOWN_SCRIPT exit 1 fi +echo "Will execute $WAIT_FOR_POPULATE_AAI_SCRIPT script" +$WAIT_FOR_POPULATE_AAI_SCRIPT + +if [ $? -ne 0 ]; then + echo "ERROR: $WAIT_FOR_POPULATE_AAI_SCRIPT failed" + echo "Will stop running docker containers . . ." + $TEAR_DOWN_SCRIPT + exit 1 +fi + +PODS_NAMES=( "api-handler-infra" "bpmn-infra" "sdc-controller") + +for pod in "${PODS_NAMES[@]}" + do + echo "Will execute $WAIT_FOR_CONTAINER_SCRIPT to wait for $pod container to start up" + $WAIT_FOR_CONTAINER_SCRIPT -c "$pod" -t "300" -n "$DEFAULT_NETWORK_NAME" + + if [ $? -ne 0 ]; then + echo "ERROR: $WAIT_FOR_CONTAINER_SCRIPT for pod: $pod failed" + echo "Will stop running docker containers . . ." + $TEAR_DOWN_SCRIPT + exit 1 + fi +done + REPO_IP='127.0.0.1' ROBOT_VARIABLES="-v REPO_IP:${REPO_IP}" diff --git a/plans/so/macroflow/teardown.sh b/plans/so/macroflow/teardown.sh index 34d72544..ee7f6e41 100644 --- a/plans/so/macroflow/teardown.sh +++ b/plans/so/macroflow/teardown.sh @@ -1,13 +1,13 @@ #!/bin/bash # # ============LICENSE_START======================================================= -# Copyright (C) 2021 Nordix Foundation. -# ================================================================================ +# Copyright 2021 Huawei Technologies Co., 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 +# 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, @@ -15,21 +15,42 @@ # See the License for the specific language governing permissions and # limitations under the License. # -# SPDX-License-Identifier: Apache-2.0 +# SPDX-License-Identifier: Apache-2.0 # ============LICENSE_END========================================================= -# -# @author Waqas Ikram (waqas.ikram@est.tech) +INTEGRATION_ETSI_TESTING_DIR=$WORKSPACE/plans/so/integration-etsi-testing +INTEGRATION_ETSI_TESTING_CONFIG_DIR=$INTEGRATION_ETSI_TESTING_DIR/config +# Macroflow Path SCRIPT_HOME="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" SCRIPT_NAME=$(basename $0) -CONFIG_DIR=$SCRIPT_HOME/config -ENV_FILE=$CONFIG_DIR/env +CONFIG_DIR_MACRO=$SCRIPT_HOME/config +ENV_FILE=$CONFIG_DIR_MACRO/env DOCKER_COMPOSE_FILE_PATH=$SCRIPT_HOME/docker-compose.yml +DOCKER_COMPOSE_LOCAL_OVERRIDE_FILE=$SCRIPT_HOME/docker-compose.local.yml + +TEMP_DIR_PATH=$MACRO_HOME/temp +TEST_LAB_DIR_PATH=$TEMP_DIR_PATH/test_lab + + echo "Running $SCRIPT_HOME/$SCRIPT_NAME ..." export $(egrep -v '^#' $ENV_FILE | xargs) +export TEST_LAB_DIR=$TEST_LAB_DIR_PATH +export CONFIG_DIR_PATH=$INTEGRATION_ETSI_TESTING_CONFIG_DIR +export CONFIG_DIR_PATH_MACRO=$CONFIG_DIR_MACRO + + +if [ "$DOCKER_ENVIRONMENT" == "remote" ]; then + echo "Tearing down docker containers from remote images ..." + docker-compose -f $DOCKER_COMPOSE_FILE_PATH -p $PROJECT_NAME down +elif [ "$DOCKER_ENVIRONMENT" == "local" ]; then + echo "Tearing down docker containers from local images ..." + docker-compose -f $DOCKER_COMPOSE_FILE_PATH -f $DOCKER_COMPOSE_LOCAL_OVERRIDE_FILE -p $PROJECT_NAME down +else + echo "Couldn't find valid property for DOCKER_ENVIRONMENT in $ENV_FILE." + echo "Attempting normal teardown ..." + docker-compose -f $DOCKER_COMPOSE_FILE_PATH -p $PROJECT_NAME down +fi -echo "Tearing down docker containers ..." -docker-compose -f $DOCKER_COMPOSE_FILE_PATH -p $PROJECT_NAME down echo "Finished executing $SCRIPT_HOME/$SCRIPT_NAME" diff --git a/tests/so/sanity-check/data/macroflow.json b/tests/so/sanity-check/data/macroflow.json new file mode 100644 index 00000000..87f782a4 --- /dev/null +++ b/tests/so/sanity-check/data/macroflow.json @@ -0,0 +1,161 @@ +{ + "requestDetails": { + "requestInfo": { + "suppressRollback": false, + "productFamilyId": "1234", + "requestorId": "demo", + "instanceName": "CsitEtsiInstance", + "source": "VID" + }, + "modelInfo": { + "modelType": "service", + "modelInvariantId": "b9202a74-4c16-4245-83ad-1cd53c813214", + "modelVersionId": "6f2c7614-571c-4482-aa2c-5eac0308aa16", + "modelName": "vfw_k8s_demo_CNF", + "modelVersion": "1.0" + }, + "cloudConfiguration": { + "tenantId": "693c7729b2364a26a3ca602e6f66187d", + "cloudOwner": "CloudOwner", + "lcpCloudRegionId": "EtsiCloudRegion" + }, + "subscriberInfo": { + "globalSubscriberId": "DemoCustomer" + }, + "requestParameters": { + "subscriptionServiceType": "vCPE", + "userParams": [{ + "Homing_Solution": "none" + }, { + "service": { + "instanceParams": [], + "instanceName": "CsitEtsiInstance", + "resources": { + "vnfs": [ + { + "modelInfo": { + "modelName": "VF_vfw_k8s_demo_CNF", + "modelVersionId": "daeb6a5c-3a8a-40b0-a575-8cca71dd0b7c", + "modelInvariantUuid": "517403c8-fab8-4cfe-9bc5-d94f5e34b257", + "modelVersion": "1.0", + "modelCustomizationId": "8b8b67bd-01a4-42f7-b0fc-1d3a0f2765fd", + "modelInstanceName": "VF_vfw_k8s_demo_CNF 0" + }, + "cloudConfiguration": { + "tenantId": "693c7729b2364a26a3ca602e6f66187d", + "cloudOwner": "CloudOwner", + "lcpCloudRegionId": "EtsiCloudRegion" + }, + "platform": { + "platformName": "test" + }, + "lineOfBusiness": { + "lineOfBusinessName": "LOB-Demonstration" + }, + "productFamilyId": "1234", + "instanceName": "VF_frankfurt_vfw_k8s_demo_final", + "instanceParams": [{ + "sdnc_model_name": "vFW_CNF_CDS", + "sdnc_model_version": "1.0.45", + "sdnc_artifact_name": "vnf" + } + ], + "vfModules": [ + { + "modelInfo": { + "modelName": "VfVfwK8sDemoCnf..base_template..module-0", + "modelVersionId": "86224a10-c17e-42c9-9809-f3c31ba1b781", + "modelInvariantUuid": "2bc34946-d57d-4053-9e9f-d60587c9aa12", + "modelVersion": "1", + "modelCustomizationId": "905ffa63-7011-4cbe-943c-237f303b4e9f" + }, + "instanceName": "vf_frankfurt_vfw_k8s_demo_final0..VfFrankfurtVfwK8sDemoFinal..base_template..module-0", + "instanceParams": [{ + "k8s-rb-profile-name": "vfw-cnf-cds-base-profile", + "k8s-rb-profile-namespace": "test-vfw1", + "sdnc_model_name": "vFW_CNF_CDS", + "sdnc_model_version": "1.0.45", + "vf_module_label": "base_template" + } + ] + }, + { + "modelInfo": { + "modelName": "VfVfwK8sDemoCnf..vsn..module-1", + "modelVersionId": "3c50323b-5f8c-4b31-938f-8e996a2e0001", + "modelInvariantUuid": "11e50367-a4c9-4203-a838-518446ec816a", + "modelVersion": "1", + "modelCustomizationId": "1812807a-9f6b-42e4-b78c-814c3fea5a4c" + }, + "instanceName": "vf_frankfurt_vfw_k8s_demo_final0..VfFrankfurtVfwK8sDemoFinal..vsn..module-1", + "instanceParams": [{ + "k8s-rb-profile-name": "vfw-cnf-cds-base-profile", + "k8s-rb-profile-namespace": "vfirewall", + "sdnc_model_name": "vFW_CNF_CDS", + "sdnc_model_version": "7.0.0", + "vf_module_label": "vsn" + } + ] + }, + { + "modelInfo": { + "modelName": "VfVfwK8sDemoCnf..vpkg..module-2", + "modelVersionId": "104e8b4e-d404-4a5b-9beb-f92a217fd6ee", + "modelInvariantUuid": "1782dcdb-2a4c-4665-8d04-be6b989fea8e", + "modelVersion": "1", + "modelCustomizationId": "02fb0319-f37d-4e8b-9009-263fffdb2549" + }, + "instanceName": "vf_frankfurt_vfw_k8s_demo_final0..VfFrankfurtVfwK8sDemoFinal..vpkg..module-2", + "instanceParams": [{ + "k8s-rb-profile-name": "vfw-cnf-cds-base-profile", + "k8s-rb-profile-namespace": "vfirewall", + "sdnc_model_name": "vFW_CNF_CDS", + "sdnc_model_version": "7.0.0", + "vf_module_label": "vpkg" + } + ] + }, + { + "modelInfo": { + "modelName": "VfVfwK8sDemoCnf..vfw..module-3", + "modelVersionId": "a5f678db-2e5f-47be-8fab-1540bc7482d8", + "modelInvariantUuid": "c0869243-7667-4434-b9cc-84791f07a13a", + "modelVersion": "1", + "modelCustomizationId": "f144c7c8-da93-4e06-ba93-d26e69eba509" + }, + "instanceName": "vf_frankfurt_vfw_k8s_demo_final0..VfFrankfurtVfwK8sDemoFinal..vfw..module-3", + "instanceParams": [{ + "k8s-rb-profile-name": "vfw-cnf-cds-base-profile", + "k8s-rb-profile-namespace": "vfirewall", + "sdnc_model_name": "vFW_CNF_CDS", + "sdnc_model_version": "7.0.0", + "vf_module_label": "vfw" + } + ] + } + + ] + } + ] + }, + "modelInfo": { + "modelVersion": "1.0", + "modelVersionId": "6f2c7614-571c-4482-aa2c-5eac0308aa16", + "modelInvariantId": "b9202a74-4c16-4245-83ad-1cd53c813214", + "modelName": "vfw_k8s_demo_CNF", + "modelType": "service" + } + } + } + ], + "aLaCarte": false + }, + "project": { + "projectName": "etsiCsitProject" + }, + "owningEntity": { + "owningEntityId": "f2e1071e-3d47-4a65-94d4-e473ec03326a", + "owningEntityName": "OE-Demonstration" + } + } +} diff --git a/tests/so/sanity-check/data/serviceBasicVfCnfnotification.json b/tests/so/sanity-check/data/serviceBasicVfCnfnotification.json new file mode 100644 index 00000000..02485e18 --- /dev/null +++ b/tests/so/sanity-check/data/serviceBasicVfCnfnotification.json @@ -0,0 +1,294 @@ +{ + "distributionID": "2d6c5aa8-b644-4f30-a632-5577801ef959", + "serviceName": "vfw_k8s_demo_CNF", + "serviceVersion": "1.0", + "serviceUUID": "6f2c7614-571c-4482-aa2c-5eac0308aa16", + "serviceDescription": "service", + "serviceInvariantUUID": "b9202a74-4c16-4245-83ad-1cd53c813214", + "resources": [ + { + "resourceInstanceName": "VF_vfw_k8s_demo_CNF 0", + "resourceName": "VF_vfw_k8s_demo_CNF", + "resourceVersion": "1.0", + "resoucreType": "VF", + "resourceUUID": "daeb6a5c-3a8a-40b0-a575-8cca71dd0b7c", + "resourceInvariantUUID": "517403c8-fab8-4cfe-9bc5-d94f5e34b257", + "resourceCustomizationUUID": "8b8b67bd-01a4-42f7-b0fc-1d3a0f2765fd", + "category": "Generic", + "subcategory": "Abstract", + "artifacts": [{ + "artifactName": "vf_vfw_k8s_demo_cnf0_modules.json", + "artifactType": "VF_MODULES_METADATA", + "artifactURL": "/unzipped_sdc_csar/vf_vfw_k8s_demo_cnf0_modules.json", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "86224a10-c17e-42c9-9809-f3c31ba1b781", + "artifactVersion": "1" + }, +{ + "artifactName": "vf_vfw_k8s_demo_cnf1_modules.json", + "artifactType": "VF_MODULES_METADATA", + "artifactURL": "/unzipped_sdc_csar/vf_vfw_k8s_demo_cnf0_modules.json", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "3c50323b-5f8c-4b31-938f-8e996a2e0001", + "artifactVersion": "1" + }, + +{ + "artifactName": "base_template.env", + "artifactType": "HEAT_ENV", + "artifactURL": "/unzipped_sdc_csar/base_template.env", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "ede4c2de-133f-49e3-9daa-8c56b65b5c6b", + "artifactVersion": "1" + }, +{ + "artifactName": "base_template_cloudtech_k8s_charts.env", + "artifactType": "HEAT_ENV", + "artifactURL": "/unzipped_sdc_csar/base_template_cloudtech_k8s_charts.env", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "6833f47d-e91b-4887-8b55-f68ef25bccf3", + "artifactVersion": "1" + }, + +{ + "artifactName": "base_template.env", + "artifactType": "HEAT_ENV", + "artifactURL": "/unzipped_sdc_csar/base_template.env", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "7f1dbc99-849e-4af8-bdcb-6c214f939428", + "artifactVersion": "1" + }, +{ + "artifactName": "base_template_cloudtech_k8s_charts.env", + "artifactType": "HEAT_ENV", + "artifactURL": "/unzipped_sdc_csar/base_template_cloudtech_k8s_charts.env", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "71607418-af27-4712-8e0c-cfe992b95a38", + "artifactVersion": "1" + }, +{ + "artifactName": "vfw.env", + "artifactType": "HEAT_ENV", + "artifactURL": "/unzipped_sdc_csar/vfw.env", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "406fe9df-aa4c-42c1-8f83-c7ac11169fd4", + "artifactVersion": "1" + }, +{ + "artifactName": "vfw_cloudtech_k8s_charts.env", + "artifactType": "HEAT_ENV", + "artifactURL": "/unzipped_sdc_csar/vfw_cloudtech_k8s_charts.env", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "33f7aab2-3324-4523-b37a-625b0cf77dfe", + "artifactVersion": "1" + }, +{ + "artifactName": "vpkg_cloudtech_k8s_charts.env", + "artifactType": "HEAT_ENV", + "artifactURL": "/unzipped_sdc_csar/vpkg_cloudtech_k8s_charts.env", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "8ab17b5a-3fbd-4142-a75f-c55ffd4c5af5", + "artifactVersion": "1" + }, +{ + "artifactName": "vsn.env", + "artifactType": "HEAT_ENV", + "artifactURL": "/unzipped_sdc_csar/vsn.env", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "e17c1e60-f7da-4767-9a0e-02c8ff9c0f2e", + "artifactVersion": "1" + }, +{ + "artifactName": "vsn_cloudtech_k8s_charts.env", + "artifactType": "HEAT_ENV", + "artifactURL": "/unzipped_sdc_csar/vsn_cloudtech_k8s_charts.env", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "989dbc01-2fa5-463b-abaa-cf73996ea12b", + "artifactVersion": "1" + }, +{ + "artifactName": "base_template_cloudtech_k8s_charts.tgz", + "artifactType": "CLOUD_TECHNOLOGY_SPECIFIC_ARTIFACT", + "artifactURL": "/unzipped_sdc_csar/base_template_cloudtech_k8s_charts.env", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "406fe9df-aa4c-42c1-8f83-c7ac11169fd4", + "artifactVersion": "1" + }, +{ + "artifactName": "vfw_cloudtech_k8s_charts.tgz", + "artifactType": "CLOUD_TECHNOLOGY_SPECIFIC_ARTIFACT", + "artifactURL": "/unzipped_sdc_csar/vfw_cloudtech_k8s_charts.env", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "6833f47d-e91b-4887-8b55-f68ef25bccf3", + "artifactVersion": "1" + }, +{ + "artifactName": "vpkg_cloudtech_k8s_charts.tgz", + "artifactType": "CLOUD_TECHNOLOGY_SPECIFIC_ARTIFACT", + "artifactURL": "/unzipped_sdc_csar/vpkg_cloudtech_k8s_charts.env", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "406fe9df-aa4c-42c1-8f83-c7ac11169fd4", + "artifactVersion": "1" + }, +{ + "artifactName": "vsn_cloudtech_k8s_charts.tgz", + "artifactType": "CLOUD_TECHNOLOGY_SPECIFIC_ARTIFACT", + "artifactURL": "/unzipped_sdc_csar/vsn_cloudtech_k8s_charts.tgz", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "8ab17b5a-3fbd-4142-a75f-c55ffd4c5af5", + "artifactVersion": "1" + } + +, +{ + "artifactName": "vsn_cloudtech_k8s_charts.tgz", + "artifactType": "CLOUD_TECHNOLOGY_SPECIFIC_ARTIFACT", + "artifactURL": "/unzipped_sdc_csar/vsn_cloudtech_k8s_charts.tgz", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "aaeee885-5821-4e08-8da6-0bb3b74f24e9", + "artifactVersion": "1" + }, +{ + "artifactName": "vsn_cloudtech_k8s_charts.tgz", + "artifactType": "CLOUD_TECHNOLOGY_SPECIFIC_ARTIFACT", + "artifactURL": "/unzipped_sdc_csar/vsn_cloudtech_k8s_charts.tgz", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "b4510b34-e39c-4239-bacc-7dd2f3c2a418", + "artifactVersion": "1" + } + +, +{ + "artifactName": "base_template.yaml", + "artifactType": "HEAT", + "artifactURL": "/unzipped_sdc_csar/base_template.yaml", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "33f7aab2-3324-4523-b37a-625b0cf77dfe", + "artifactVersion": "1" + } + +, +{ + "artifactName": "vfw.yaml", + "artifactType": "HEAT", + "artifactURL": "/unzipped_sdc_csar/vfw.yaml", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "6833f47d-e91b-4887-8b55-f68ef25bccf3", + "artifactVersion": "1" + } + +, +{ + "artifactName": "vpkg.yaml", + "artifactType": "HEAT", + "artifactURL": "/unzipped_sdc_csar/vpkg.yaml", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "42b80d18-69ec-4233-8844-f0df6ebb6e3d", + "artifactVersion": "1" + } +, +{ + "artifactName": "vsn.yaml", + "artifactType": "HEAT", + "artifactURL": "/unzipped_sdc_csar/vsn.yaml", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "406fe9df-aa4c-42c1-8f83-c7ac11169fd4", + "artifactVersion": "1" + } + +, +{ + "artifactName": "vendor-license-model.xml", + "artifactType": "VENDOR_LICENSE", + "artifactURL": "/unzipped_sdc_csar/vendor-license-model.xml", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "6e1dbc99-849e-4af8-bdcb-6c214f939491", + "artifactVersion": "1" + } + +, +{ + "artifactName": "vf-license-model.xml", + "artifactType": "VF_LICENSE", + "artifactURL": "/unzipped_sdc_csar/vf-license-model.xml", + "artifactChecksum": "MDJkYjNmNjEzM2Y1ZDgzNzZiZWUxMjZkMzA3YzkwZDI\u003d", + "artifactDescription": "Auto-generated VF Modules information artifact", + "artifactTimeout": 120, + "artifactUUID": "ede4c2de-133f-49e3-9daa-8c56b65b5c6b", + "artifactVersion": "1" + } + +] + } + + + ], + "serviceArtifacts": [ + { + "artifactName": "service-VfwK8sDemoCnf-template.yml", + "artifactType": "TOSCA_TEMPLATE", + "artifactURL": "/unzipped_sdc_csar/service-VfwK8sDemoCnf-template.yml", + "artifactChecksum": "NTUzMDU5YzM3MTk4OGNiNjQ2OGRlMWY2YjU3MjE2YjM\u003d", + "artifactDescription": "TOSCA representation of the asset", + "artifactTimeout": 0, + "artifactUUID": "6f2c7614-571c-4482-aa2c-5eac0308aa16", + "artifactVersion": "1" + }, + { + "artifactName": "service-VfwK8sDemoCnf-csar.csar", + "artifactType": "TOSCA_CSAR", + "artifactURL": "/unzipped_sdc_csar/service-VfwK8sDemoCnf-csar.csar", + "artifactChecksum": "ZTRhOGI0M2UxN2ZhYjQ0ODI5ZDZhZTExZTFkMGU3N2Y\u003d", + "artifactDescription": "TOSCA definition package of the asset", + "artifactTimeout": 0, + "artifactUUID": "6f2c7614-571c-4482-aa2c-5eac0308aa16", + "artifactVersion": "1" + } + ], + "workloadContext": "Production" +} + diff --git a/tests/so/sanity-check/macroflow.robot b/tests/so/sanity-check/macroflow.robot index 149797a1..cd3a5b55 100644 --- a/tests/so/sanity-check/macroflow.robot +++ b/tests/so/sanity-check/macroflow.robot @@ -4,12 +4,26 @@ Library RequestsLibrary Library OperatingSystem Library json +*** Variables *** +${SLEEP_INTERVAL_SEC}= 60 + *** Test Cases *** -Healthcheck - [Documentation] Runs AAI SIMULATOR Health check - Create Session aai_simulator_session https://${REPO_IP}:9993 - &{headers}= Create Dictionary Accept=text/plain - ${resp}= Get Request aai_simulator_session /aai/v19/healthcheck headers=${headers} - log to console Received response from AAI SIMULATOR ${resp.text} +Distribute Service Template + Create Session sdc_controller_session http://${REPO_IP}:8085 + ${data}= Get Binary File ${CURDIR}${/}data${/}serviceBasicVfCnfnotification.json + &{headers}= Create Dictionary Authorization=Basic bXNvX2FkbWluOnBhc3N3b3JkMSQ= resource-location=/distribution-test-zip/unzipped/ Content-Type=application/json Accept=application/json + ${resp}= Post Request sdc_controller_session /test/treatNotification/v1 data=${data} headers=${headers} + Log To Console Received status code: ${resp.status_code} + Run Keyword If '${resp.status_code}' == '200' log to console \nexecuted with expected result Should Be Equal As Strings '${resp.status_code}' '200' - Should Be Equal As Strings '${resp.text}' 'healthy' + + +Macroflow + Create Session api_handler_session http://${REPO_IP}:8080 + ${data}= Get Binary File ${CURDIR}${/}data${/}macroflow.json + &{headers}= Create Dictionary Authorization=Basic SW5mcmFQb3J0YWxDbGllbnQ6cGFzc3dvcmQxJA== Content-Type=application/json Accept=application/json + ${service_instantiation_request}= Post Request api_handler_session /onap/so/infra/serviceInstantiation/v7/serviceInstances data=${data} headers=${headers} + Log To Console Received status code: ${service_instantiation_request.status_code} + Run Keyword If '${service_instantiation_request.status_code}' == '202' log to console \nexecuted with expected result + Should Be Equal As Strings '${service_instantiation_request.status_code}' '202' + SLEEP ${SLEEP_INTERVAL_SEC}s -- 2.16.6