diff options
Diffstat (limited to 'adapters')
35 files changed, 210 insertions, 2608 deletions
diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/pom.xml b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/pom.xml index 8359fd3829..6ed9afcc75 100644 --- a/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/pom.xml +++ b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/pom.xml @@ -105,5 +105,10 @@ <artifactId>junit</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.onap.so.adapters</groupId> + <artifactId>etsi-sol003-pkgm-adapter</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> </project> diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/lcm/extclients/SdcPackageProvider.java b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/lcm/extclients/EtsiPackageProvider.java index 497de2874c..c5164c1833 100644 --- a/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/lcm/extclients/SdcPackageProvider.java +++ b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/lcm/extclients/EtsiPackageProvider.java @@ -24,38 +24,25 @@ package org.onap.so.adapters.etsisol003adapter.lcm.extclients; import static com.google.common.base.Splitter.on; import static com.google.common.collect.Iterables.filter; -import static com.google.common.io.ByteStreams.toByteArray; -import static java.lang.String.format; -import static org.apache.http.HttpHeaders.ACCEPT; -import static org.apache.http.HttpHeaders.AUTHORIZATION; import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.abortOperation; import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.child; import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.childElement; import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.children; import static org.slf4j.LoggerFactory.getLogger; -import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.nio.charset.StandardCharsets; import java.util.HashSet; -import java.util.Iterator; -import java.util.List; import java.util.NoSuchElementException; +import java.util.Optional; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -import javax.net.ssl.SSLContext; -import org.apache.commons.codec.binary.Base64; -import org.apache.http.HttpEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.onap.so.utils.CryptoUtils; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.EtsiCatalogServiceProviderImpl; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.EtsiCatalogManagerRequestFailureException; import org.slf4j.Logger; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.yaml.snakeyaml.Yaml; import com.google.common.io.ByteStreams; @@ -63,21 +50,13 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; @Component -public class SdcPackageProvider { - private static final String GET_PACKAGE_URL = "%s/sdc/v1/catalog/resources/%s/toscaModel"; - @Value("${sdc.toscametapath:TOSCA-Metadata/TOSCA.meta}") - private List<String> toscaMetaPaths; +public class EtsiPackageProvider { + private static final String TOCSA_METADATA_FILE_PATH = "TOSCA-Metadata/TOSCA.meta"; private static final String TOSCA_VNFD_KEY = "Entry-Definitions"; - private static Logger logger = getLogger(SdcPackageProvider.class); + private static Logger logger = getLogger(EtsiPackageProvider.class); - @Value("${sdc.username}") - private String sdcUsername; - @Value("${sdc.password}") - private String sdcPassword; - @Value("${sdc.key}") - private String sdcKey; - @Value("${sdc.endpoint}") - private String baseUrl; + @Autowired + private EtsiCatalogServiceProviderImpl etsiCatalogServiceProviderImpl; public String getVnfdId(final String csarId) { return getVnfNodeProperty(csarId, "descriptor_id"); @@ -133,35 +112,25 @@ public class SdcPackageProvider { } private byte[] getPackage(final String csarId) { - final String SERVICE_NAME = "vnfm-adapter"; - try (CloseableHttpClient client = HttpClients.custom().setSSLContext(SSLContext.getDefault()).build()) { - final HttpGet httpget = new HttpGet(format(GET_PACKAGE_URL, baseUrl, csarId)); - httpget.setHeader(ACCEPT, APPLICATION_OCTET_STREAM_VALUE); - httpget.setHeader("X-ECOMP-InstanceID", SERVICE_NAME); - httpget.setHeader("X-FromAppId", SERVICE_NAME); - final String auth = sdcUsername + ":" + CryptoUtils.decrypt(sdcPassword, sdcKey); - final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1)); - final String authHeader = "Basic " + new String(encodedAuth); - httpget.setHeader(AUTHORIZATION, authHeader); - logger.debug("Fetching from SDC: " + httpget); - final CloseableHttpResponse response = client.execute(httpget); - final HttpEntity entity = response.getEntity(); - final InputStream is = entity.getContent(); - return toByteArray(is); - } catch (final Exception e) { - throw abortOperation("Unable to download " + csarId + " package from SDC", e); + try { + final Optional<byte[]> optional = etsiCatalogServiceProviderImpl.getVnfPackageContent(csarId); + if (optional.isPresent()) { + return optional.get(); + } + } catch (final Exception exception) { + logger.error("Unable to retrieve package from ETSI Catalog Manager using pkgId: {}", csarId); + throw new EtsiCatalogManagerRequestFailureException("Value is not present", exception); } + logger.error("Unable to retrieve package from ETSI Catalog Manager using pkgId: {}", csarId); + throw new EtsiCatalogManagerRequestFailureException("Value is not present"); } private String getVnfdLocation(final InputStream stream) throws IOException { - final Iterator<String> pathIterator = toscaMetaPaths.iterator(); - while (pathIterator.hasNext()) { - final String toscaMetadata = new String(getFileInZip(stream, pathIterator.next()).toByteArray()); - if (!toscaMetadata.isEmpty()) { - final String toscaVnfdLine = - filter(on("\n").split(toscaMetadata), line -> line.contains(TOSCA_VNFD_KEY)).iterator().next(); - return toscaVnfdLine.replace(TOSCA_VNFD_KEY + ":", "").trim(); - } + final String toscaMetadata = new String(getFileInZip(stream, TOCSA_METADATA_FILE_PATH).toByteArray()); + if (!toscaMetadata.isEmpty()) { + final String toscaVnfdLine = + filter(on("\n").split(toscaMetadata), line -> line.contains(TOSCA_VNFD_KEY)).iterator().next(); + return toscaVnfdLine.replace(TOSCA_VNFD_KEY + ":", "").trim(); } throw abortOperation("Unable to find valid Tosca Path"); } diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/lcm/extclients/vnfm/VnfmRestTemplateConfiguration.java b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/lcm/extclients/vnfm/VnfmRestTemplateConfiguration.java new file mode 100644 index 0000000000..2c7ddd1d49 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/lcm/extclients/vnfm/VnfmRestTemplateConfiguration.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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 + * + * 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========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm; + +import org.onap.logging.filter.spring.SpringClientPayloadFilter; +import org.onap.so.configuration.rest.HttpComponentsClientConfiguration; +import org.onap.so.logging.jaxrs.filter.SOSpringClientFilter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.BufferingClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Configuration +public class VnfmRestTemplateConfiguration { + + public static final String SOL003_LCM_REST_TEMPLATE = "Sol003LcmRestTemplate"; + + @Autowired + private HttpComponentsClientConfiguration httpComponentsClientConfiguration; + + @Bean + @Qualifier(SOL003_LCM_REST_TEMPLATE) + public RestTemplate sol003LcmRestTemplate() { + final HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = + httpComponentsClientConfiguration.httpComponentsClientHttpRequestFactory(); + final RestTemplate restTemplate = + new RestTemplate(new BufferingClientHttpRequestFactory(clientHttpRequestFactory)); + restTemplate.getInterceptors().add(new SOSpringClientFilter()); + restTemplate.getInterceptors().add((new SpringClientPayloadFilter())); + return restTemplate; + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/lcm/extclients/vnfm/VnfmServiceProviderConfiguration.java b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/lcm/extclients/vnfm/VnfmServiceProviderConfiguration.java index da727b395a..1ed3ec9ff2 100644 --- a/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/lcm/extclients/vnfm/VnfmServiceProviderConfiguration.java +++ b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/lcm/extclients/vnfm/VnfmServiceProviderConfiguration.java @@ -20,7 +20,6 @@ package org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm; -import static org.onap.so.client.RestTemplateConfig.CONFIGURABLE_REST_TEMPLATE; import java.io.IOException; import java.security.KeyManagementException; import java.security.KeyStore; @@ -83,7 +82,7 @@ public class VnfmServiceProviderConfiguration extends AbstractServiceProviderCon @Value("${vnfmadapter.temp.vnfm.oauth.endpoint:#{null}}") private String oauthEndpoint; - @Qualifier(CONFIGURABLE_REST_TEMPLATE) + @Qualifier(VnfmRestTemplateConfiguration.SOL003_LCM_REST_TEMPLATE) @Autowired private RestTemplate defaultRestTemplate; diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/lcm/lifecycle/LifecycleManager.java b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/lcm/lifecycle/LifecycleManager.java index 8ba56c5051..a2af1a4580 100644 --- a/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/lcm/lifecycle/LifecycleManager.java +++ b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/lcm/lifecycle/LifecycleManager.java @@ -24,7 +24,7 @@ import java.util.Map; import org.onap.aai.domain.yang.EsrVnfm; import org.onap.aai.domain.yang.GenericVnf; import org.onap.aai.domain.yang.Relationship; -import org.onap.so.adapters.etsisol003adapter.lcm.extclients.SdcPackageProvider; +import org.onap.so.adapters.etsisol003adapter.lcm.extclients.EtsiPackageProvider; import org.onap.so.adapters.etsisol003adapter.lcm.extclients.aai.AaiHelper; import org.onap.so.adapters.etsisol003adapter.lcm.extclients.aai.AaiServiceProvider; import org.onap.so.adapters.etsisol003adapter.lcm.extclients.aai.OamIpAddressSource; @@ -48,6 +48,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.google.common.base.Optional; +import static org.apache.commons.lang3.StringUtils.isNotBlank; /** * Manages lifecycle operations towards the VNFMs. @@ -60,12 +61,12 @@ public class LifecycleManager { private final AaiHelper aaiHelper; private final VnfmHelper vnfmHelper; private final JobManager jobManager; - private final SdcPackageProvider packageProvider; + private final EtsiPackageProvider packageProvider; @Autowired LifecycleManager(final AaiServiceProvider aaiServiceProvider, final AaiHelper aaiHelper, final VnfmHelper vnfmHelper, final VnfmServiceProvider vnfmServiceProvider, final JobManager jobManager, - final SdcPackageProvider packageProvider) { + final EtsiPackageProvider packageProvider) { this.aaiServiceProvider = aaiServiceProvider; this.vnfmServiceProvider = vnfmServiceProvider; this.aaiHelper = aaiHelper; @@ -152,15 +153,16 @@ public class LifecycleManager { } } - private InlineResponse201 sendCreateRequestToVnfm(final CreateVnfRequest aaiRequest, final GenericVnf genericVnf, - final String vnfIdInAai, final EsrVnfm vnfm) { - logger.debug("Sending a create request to SVNFM " + aaiRequest); + private InlineResponse201 sendCreateRequestToVnfm(final CreateVnfRequest createVnfRequest, + final GenericVnf genericVnf, final String vnfIdInAai, final EsrVnfm vnfm) { + logger.debug("Sending a create request to SVNFM {}", createVnfRequest); final org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.CreateVnfRequest vnfmRequest = new org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.CreateVnfRequest(); - final String vnfdId = packageProvider.getVnfdId(genericVnf.getModelVersionId()); + final String pkgId = getPackageId(createVnfRequest, genericVnf); + final String vnfdId = packageProvider.getVnfdId(pkgId); vnfmRequest.setVnfdId(vnfdId); - vnfmRequest.setVnfInstanceName(aaiRequest.getName().replaceAll(" ", "_")); + vnfmRequest.setVnfInstanceName(createVnfRequest.getName().replaceAll(" ", "_")); vnfmRequest.setVnfInstanceDescription(vnfIdInAai); final Optional<InlineResponse201> optionalResponse = vnfmServiceProvider.createVnf(vnfm, vnfmRequest); @@ -174,6 +176,15 @@ public class LifecycleManager { } } + private String getPackageId(final CreateVnfRequest createVnfRequest, final GenericVnf genericVnf) { + if (isNotBlank(createVnfRequest.getPkgId())) { + logger.info("Found createVnfRequest pkgId: {}", createVnfRequest.getPkgId()); + return createVnfRequest.getPkgId(); + } + logger.info("Found genericVnf modelVersionId: {}", genericVnf.getModelVersionId()); + return genericVnf.getModelVersionId(); + } + private void createNotificationSubscription(final EsrVnfm vnfm, final String vnfId) { try { final LccnSubscriptionRequest subscriptionRequest = vnfmHelper.createNotificationSubscriptionRequest(vnfId); diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/lcm/rest/EtsiSol003AdapterControllerTest.java b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/lcm/rest/EtsiSol003AdapterControllerTest.java index eaf40b546f..9aed675324 100644 --- a/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/lcm/rest/EtsiSol003AdapterControllerTest.java +++ b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/lcm/rest/EtsiSol003AdapterControllerTest.java @@ -27,7 +27,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; -import static org.onap.so.client.RestTemplateConfig.CONFIGURABLE_REST_TEMPLATE; +import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.VnfmRestTemplateConfiguration; import static org.springframework.test.web.client.match.MockRestRequestMatchers.content; import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; import static org.springframework.test.web.client.response.MockRestResponseCreators.withBadRequest; @@ -54,7 +54,8 @@ import org.onap.aai.domain.yang.RelationshipList; import org.onap.aaiclient.client.aai.AAIResourcesClient; import org.onap.aaiclient.client.aai.AAIVersion; import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri; -import org.onap.so.adapters.etsisol003adapter.lcm.extclients.SdcPackageProvider; +import org.onap.so.adapters.etsisol003adapter.lcm.extclients.EtsiPackageProvider; +import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.VnfmRestTemplateConfiguration; import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.InlineResponse200; import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.InlineResponse2001; import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.InlineResponse201; @@ -106,7 +107,7 @@ public class EtsiSol003AdapterControllerTest { @LocalServerPort private int port; @Autowired - @Qualifier(CONFIGURABLE_REST_TEMPLATE) + @Qualifier(VnfmRestTemplateConfiguration.SOL003_LCM_REST_TEMPLATE) private RestTemplate testRestTemplate; private MockRestServiceServer mockRestServer; @@ -114,7 +115,7 @@ public class EtsiSol003AdapterControllerTest { AAIResourcesClient aaiResourcesClient; @MockBean - SdcPackageProvider sdcPackageProvider; + EtsiPackageProvider etsiPackageProvider; @Autowired EtsiSol003AdapterController controller; diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/lcm/rest/Sol003LcnControllerTest.java b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/lcm/rest/Sol003LcnControllerTest.java index ab6ae83896..86eda0abfa 100644 --- a/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/lcm/rest/Sol003LcnControllerTest.java +++ b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/lcm/rest/Sol003LcnControllerTest.java @@ -26,7 +26,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; -import static org.onap.so.client.RestTemplateConfig.CONFIGURABLE_REST_TEMPLATE; +import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.VnfmRestTemplateConfiguration; import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; @@ -99,7 +99,7 @@ public class Sol003LcnControllerTest { @LocalServerPort private int port; @Autowired - @Qualifier(CONFIGURABLE_REST_TEMPLATE) + @Qualifier(VnfmRestTemplateConfiguration.SOL003_LCM_REST_TEMPLATE) private RestTemplate testRestTemplate; private MockRestServiceServer mockRestServer; diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-api/src/main/resources/etsisol003adapter.yaml b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-api/src/main/resources/etsisol003adapter.yaml index 9d0a5283af..578708ded8 100644 --- a/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-api/src/main/resources/etsisol003adapter.yaml +++ b/adapters/etsi-sol003-adapter/etsi-sol003-lcm/etsi-sol003-lcm-api/src/main/resources/etsisol003adapter.yaml @@ -168,6 +168,9 @@ definitions: description: The name to be applied to the VNF. tenant: $ref: '#/definitions/Tenant' + pkgId: + type: string + description: An identifier for the vnf package. additionalParams: type: object description: >- @@ -519,4 +522,4 @@ definitions: description: > Type of the resource in the scope of the VIM or the resource provider. - type: string
\ No newline at end of file + type: string diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/EtsiCatalogManagerRequestFailureException.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/EtsiCatalogManagerRequestFailureException.java index a07732f3fa..110826a6d3 100644 --- a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/EtsiCatalogManagerRequestFailureException.java +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/EtsiCatalogManagerRequestFailureException.java @@ -36,6 +36,10 @@ public class EtsiCatalogManagerRequestFailureException extends RuntimeException super(message); } + public EtsiCatalogManagerRequestFailureException(final String message, final Throwable cause) { + super(message, cause); + } + @Override public synchronized Throwable fillInStackTrace() { return this; diff --git a/adapters/mso-adapter-utils/pom.xml b/adapters/mso-adapter-utils/pom.xml index 6346983f96..2453c18f1a 100644 --- a/adapters/mso-adapter-utils/pom.xml +++ b/adapters/mso-adapter-utils/pom.xml @@ -103,11 +103,6 @@ <version>${project.version}</version> </dependency> <dependency> - <groupId>org.onap.so</groupId> - <artifactId>cloudify-client</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <scope>provided</scope> diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/beans/DeploymentInfo.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/beans/DeploymentInfo.java deleted file mode 100644 index 42b77baeeb..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/beans/DeploymentInfo.java +++ /dev/null @@ -1,91 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Copyright (C) 2018 Nokia. - * ================================================================================ - * 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.cloudify.beans; - -import java.util.Map; - -/* - * This Java bean class relays Heat stack status information to ActiveVOS processes. - * - * This bean is returned by all Heat-specific adapter operations (create, query, delete) - */ - -public final class DeploymentInfo { - - private final String id; - private final DeploymentStatus status; - private final Map<String, Object> outputs; - private final Map<String, Object> inputs; - private final String lastAction; - private final String actionStatus; - private final String errorMessage; - - DeploymentInfo(String id, DeploymentStatus deploymentStatus, Map<String, Object> deploymentOutputs, - Map<String, Object> deploymentInputs, String lastAction, String actionStatus, String errorMessage) { - - this.id = id; - this.status = deploymentStatus; - this.outputs = deploymentOutputs; - this.inputs = deploymentInputs; - this.lastAction = lastAction; - this.actionStatus = actionStatus; - this.errorMessage = errorMessage; - } - - public String getId() { - return id; - } - - public DeploymentStatus getStatus() { - return status; - } - - public Map<String, Object> getOutputs() { - return outputs; - } - - public Map<String, Object> getInputs() { - return inputs; - } - - public String getLastAction() { - return lastAction; - } - - public String getActionStatus() { - return actionStatus; - } - - public String getErrorMessage() { - return errorMessage; - } - - @Override - public String toString() { - return "DeploymentInfo {" + "id='" + id + '\'' + ", inputs='" + inputs + '\'' + ", outputs='" + outputs + '\'' - + ", lastAction='" + lastAction + '\'' + ", status='" + status + '\'' + ", errorMessage='" - + errorMessage + '\'' + '}'; - } - -} - diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/beans/DeploymentInfoBuilder.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/beans/DeploymentInfoBuilder.java deleted file mode 100644 index 072bf404e7..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/beans/DeploymentInfoBuilder.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * ============LICENSE_START======================================================= ONAP : SO - * ================================================================================ Copyright (C) 2018 Nokia. - * ============================================================================= 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.cloudify.beans; - -import java.util.HashMap; -import java.util.Map; -import org.onap.so.cloudify.v3.model.Execution; - -public final class DeploymentInfoBuilder { - - private String id = ""; - private DeploymentStatus deploymentStatus = DeploymentStatus.NOTFOUND; - private Map<String, Object> deploymentOutputs = new HashMap<>(); - private Map<String, Object> deploymentInputs = new HashMap<>(); - private String lastAction; - private String actionStatus; - private String errorMessage; - - public DeploymentInfoBuilder withId(String id) { - this.id = id; - return this; - } - - public DeploymentInfoBuilder withStatus(DeploymentStatus deploymentStatus) { - this.deploymentStatus = deploymentStatus; - return this; - } - - public DeploymentInfoBuilder withDeploymentOutputs(Map<String, Object> deploymentOutputs) { - if (deploymentOutputs != null) { - this.deploymentOutputs = deploymentOutputs; - } - return this; - } - - public DeploymentInfoBuilder withDeploymentInputs(Map<String, Object> deploymentInputs) { - this.deploymentInputs = deploymentInputs; - return this; - } - - public DeploymentInfoBuilder withLastAction(String lastAction) { - this.lastAction = lastAction; - return this; - } - - public DeploymentInfoBuilder withActionStatus(String actionStatus) { - this.actionStatus = actionStatus; - return this; - } - - public DeploymentInfoBuilder withErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - return this; - } - - public DeploymentInfoBuilder fromExecution(Execution execution) { - if (execution != null) { - this.lastAction = execution.getWorkflowId(); - this.actionStatus = execution.getStatus(); - this.errorMessage = execution.getError(); - - // Compute the status based on the last workflow - if (("install").equals(lastAction)) { - if (("terminated").equals(actionStatus)) { - this.deploymentStatus = DeploymentStatus.INSTALLED; - } else if (("failed").equals(actionStatus)) { - this.deploymentStatus = DeploymentStatus.FAILED; - } else if (("started").equals(actionStatus) || ("pending").equals(actionStatus)) { - this.deploymentStatus = DeploymentStatus.INSTALLING; - } else { - this.deploymentStatus = DeploymentStatus.UNKNOWN; - } - } else if (("uninstall").equals(lastAction)) { - if (("terminated").equals(actionStatus)) { - this.deploymentStatus = DeploymentStatus.CREATED; - } else if (("failed").equals(actionStatus)) { - this.deploymentStatus = DeploymentStatus.FAILED; - } else if (("started").equals(actionStatus) || ("pending").equals(actionStatus)) { - this.deploymentStatus = DeploymentStatus.UNINSTALLING; - } else { - this.deploymentStatus = DeploymentStatus.UNKNOWN; - } - } else { - // Could have more cases in the future for different actions. - this.deploymentStatus = DeploymentStatus.UNKNOWN; - } - } else { - this.deploymentStatus = DeploymentStatus.CREATED; - } - - return this; - } - - public DeploymentInfo build() { - return new DeploymentInfo(id, deploymentStatus, deploymentOutputs, deploymentInputs, lastAction, actionStatus, - errorMessage); - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/beans/DeploymentStatus.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/beans/DeploymentStatus.java deleted file mode 100644 index f7d6a9d214..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/beans/DeploymentStatus.java +++ /dev/null @@ -1,31 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.so.cloudify.beans; - - -/* - * Enum status values to capture the state of a deployment, based on last known workflow (assume only INSTALL and - * UNINSTALL at this point). - */ -public enum DeploymentStatus { - NOTFOUND, CREATED, INSTALLED, FAILED, INSTALLING, UNINSTALLING, UNKNOWN -} - diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoBlueprintAlreadyExists.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoBlueprintAlreadyExists.java deleted file mode 100644 index 95912994bc..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoBlueprintAlreadyExists.java +++ /dev/null @@ -1,34 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.so.cloudify.exceptions; - -public class MsoBlueprintAlreadyExists extends MsoCloudifyException { - - private static final long serialVersionUID = 1L; - - // Constructor to create a new MsoCloudifyException instance - public MsoBlueprintAlreadyExists(String blueprintId, String cloud) { - // Set the detailed error as the Exception 'message' - super(409, "Conflict", - "Blueprint " + blueprintId + " already exists in Cloudify Manager supporting cloud site + " + cloud); - } - -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoCloudifyException.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoCloudifyException.java deleted file mode 100644 index 441bd4dc07..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoCloudifyException.java +++ /dev/null @@ -1,88 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.so.cloudify.exceptions; - -import org.onap.so.openstack.exceptions.MsoException; -import org.onap.so.openstack.exceptions.MsoExceptionCategory; - -/** - * OpenStack exception. - */ -public class MsoCloudifyException extends MsoException { - - /** - * Serialization id. - */ - private static final long serialVersionUID = 3313636124141766495L; - - private int statusCode; - private String statusMessage; - private String errorDetail; - private boolean pendingWorkflow; - - /** - * Constructor to create a new MsoOpenstackException instance - * - * @param code the error code - * @param message the error message - * @param detail error details - */ - public MsoCloudifyException(int code, String message, String detail) { - // Set the detailed error as the Exception 'message' - super(detail); - super.category = MsoExceptionCategory.OPENSTACK; - - this.statusCode = code; - this.statusMessage = message; - this.errorDetail = detail; - this.pendingWorkflow = false; - } - - /** - * Constructor to propagate the caught exception (mostly for stack trace) - * - * @param code the error code - * @param message the error message - * @param detail error details - * @param e the cause - */ - public MsoCloudifyException(int code, String message, String detail, Exception e) { - // Set the detailed error as the Exception 'message' - super(detail, e); - super.category = MsoExceptionCategory.OPENSTACK; - - this.statusCode = code; - this.statusMessage = message; - this.errorDetail = detail; - this.pendingWorkflow = false; - } - - public void setPendingWorkflow(boolean pendingWorkflow) { - this.pendingWorkflow = pendingWorkflow; - } - - @Override - public String toString() { - String error = "" + statusCode + " " + statusMessage + ": " + errorDetail - + (pendingWorkflow ? " [workflow pending]" : ""); - return error; - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoCloudifyManagerNotFound.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoCloudifyManagerNotFound.java deleted file mode 100644 index bc6fd6204c..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoCloudifyManagerNotFound.java +++ /dev/null @@ -1,33 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.so.cloudify.exceptions; - -public class MsoCloudifyManagerNotFound extends MsoCloudifyException { - - private static final long serialVersionUID = 1L; - - // Constructor to create a new MsoCloudifyException instance - public MsoCloudifyManagerNotFound(String cloudSiteId) { - // Set the detailed error as the Exception 'message' - super(0, "Cloudify Manager Not Found", "No Cloudify Manager configured for cloud site " + cloudSiteId); - } - -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoCloudifyTimeout.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoCloudifyTimeout.java deleted file mode 100644 index 99b6ade326..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoCloudifyTimeout.java +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.so.cloudify.exceptions; - -import org.onap.so.cloudify.v3.model.Execution; -import org.onap.so.openstack.exceptions.MsoException; -import org.onap.so.openstack.exceptions.MsoExceptionCategory; - -/** - * MSO Exception when a Cloudify workflow execution times out waiting for completion. Exception includes the last known - * state of the workflow execution. - */ -public class MsoCloudifyTimeout extends MsoException { - - /** - * Serialization id. - */ - private static final long serialVersionUID = 3313636124141766495L; - - private Execution execution; - - /** - * Constructor to create a new MsoOpenstackException instance - * - * @param code the error code - * @param message the error message - * @param detail error details - */ - public MsoCloudifyTimeout(Execution execution) { - // Set the detailed error as the Exception 'message' - super("Cloudify Workflow Timeout for workflow " + execution.getWorkflowId() + " on deployment " - + execution.getDeploymentId()); - super.category = MsoExceptionCategory.OPENSTACK; - - this.execution = execution; - } - - public Execution getExecution() { - return this.execution; - } - - @Override - public String toString() { - String error = "Workflow timeout: workflow=" + execution.getWorkflowId() + ",deployment=" - + execution.getDeploymentId(); - return error; - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoCloudifyWorkflowException.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoCloudifyWorkflowException.java deleted file mode 100644 index 2251575671..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoCloudifyWorkflowException.java +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.so.cloudify.exceptions; - -/** - * Reports an error with a Cloudify Workflow execution. - * - * @author JC1348 - * - */ -public class MsoCloudifyWorkflowException extends MsoCloudifyException { - - private static final long serialVersionUID = 1L; - - private String workflowStatus; - private boolean workflowStillRunning = false; - - // Constructor to create a new MsoCloudifyException instance - public MsoCloudifyWorkflowException(String message, String deploymentId, String workflowId, String workflowStatus) { - super(0, "Workflow Exception", - "Workflow " + workflowId + " failed on deployment " + deploymentId + ": " + message); - this.workflowStatus = workflowStatus; - if (("pending").equals(workflowStatus) || ("started").equals(workflowStatus) - || ("cancelling").equals(workflowStatus) || ("force_cancelling").equals(workflowStatus)) { - workflowStillRunning = true; - } - } - - public String getWorkflowStatus() { - return workflowStatus; - } - - public boolean isWorkflowStillRunning() { - return workflowStillRunning; - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoDeploymentAlreadyExists.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoDeploymentAlreadyExists.java deleted file mode 100644 index 62112f4feb..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoDeploymentAlreadyExists.java +++ /dev/null @@ -1,34 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.so.cloudify.exceptions; - -public class MsoDeploymentAlreadyExists extends MsoCloudifyException { - - private static final long serialVersionUID = 1L; - - // Constructor to create a new MsoCloudifyException instance - public MsoDeploymentAlreadyExists(String deploymentId, String cloud) { - // Set the detailed error as the Exception 'message' - super(409, "Conflict", - "Deployment " + deploymentId + " already exists in Cloudify Manager suppporting cloud " + cloud); - } - -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/utils/MsoCloudifyUtils.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/utils/MsoCloudifyUtils.java deleted file mode 100644 index 446c725e48..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/utils/MsoCloudifyUtils.java +++ /dev/null @@ -1,1356 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Copyright (C) 2018 Nokia. - * ================================================================================ - * Modifications Copyright (c) 2019 Samsung - * ================================================================================ - * 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.cloudify.utils; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; -import org.onap.so.adapters.vdu.CloudInfo; -import org.onap.so.adapters.vdu.PluginAction; -import org.onap.so.adapters.vdu.VduArtifact; -import org.onap.so.adapters.vdu.VduArtifact.ArtifactType; -import org.onap.so.adapters.vdu.VduException; -import org.onap.so.adapters.vdu.VduInstance; -import org.onap.so.adapters.vdu.VduModelInfo; -import org.onap.so.adapters.vdu.VduPlugin; -import org.onap.so.adapters.vdu.VduStateType; -import org.onap.so.adapters.vdu.VduStatus; -import org.onap.so.cloud.CloudConfig; -import org.onap.so.cloudify.base.client.CloudifyBaseException; -import org.onap.so.cloudify.base.client.CloudifyClientTokenProvider; -import org.onap.so.cloudify.base.client.CloudifyConnectException; -import org.onap.so.cloudify.base.client.CloudifyRequest; -import org.onap.so.cloudify.base.client.CloudifyResponseException; -import org.onap.so.cloudify.beans.DeploymentInfo; -import org.onap.so.cloudify.beans.DeploymentInfoBuilder; -import org.onap.so.cloudify.beans.DeploymentStatus; -import org.onap.so.cloudify.exceptions.MsoCloudifyException; -import org.onap.so.cloudify.exceptions.MsoCloudifyManagerNotFound; -import org.onap.so.cloudify.exceptions.MsoDeploymentAlreadyExists; -import org.onap.so.cloudify.v3.client.BlueprintsResource.GetBlueprint; -import org.onap.so.cloudify.v3.client.BlueprintsResource.UploadBlueprint; -import org.onap.so.cloudify.v3.client.Cloudify; -import org.onap.so.cloudify.v3.client.DeploymentsResource.CreateDeployment; -import org.onap.so.cloudify.v3.client.DeploymentsResource.DeleteDeployment; -import org.onap.so.cloudify.v3.client.DeploymentsResource.GetDeployment; -import org.onap.so.cloudify.v3.client.DeploymentsResource.GetDeploymentOutputs; -import org.onap.so.cloudify.v3.client.ExecutionsResource.CancelExecution; -import org.onap.so.cloudify.v3.client.ExecutionsResource.GetExecution; -import org.onap.so.cloudify.v3.client.ExecutionsResource.ListExecutions; -import org.onap.so.cloudify.v3.client.ExecutionsResource.StartExecution; -import org.onap.so.cloudify.v3.model.AzureConfig; -import org.onap.so.cloudify.v3.model.Blueprint; -import org.onap.so.cloudify.v3.model.CancelExecutionParams; -import org.onap.so.cloudify.v3.model.CloudifyError; -import org.onap.so.cloudify.v3.model.CreateDeploymentParams; -import org.onap.so.cloudify.v3.model.Deployment; -import org.onap.so.cloudify.v3.model.DeploymentOutputs; -import org.onap.so.cloudify.v3.model.Execution; -import org.onap.so.cloudify.v3.model.Executions; -import org.onap.so.cloudify.v3.model.OpenstackConfig; -import org.onap.so.cloudify.v3.model.StartExecutionParams; -import org.onap.so.config.beans.PoConfig; -import org.onap.so.db.catalog.beans.CloudSite; -import org.onap.so.db.catalog.beans.CloudifyManager; -import org.onap.so.db.catalog.beans.HeatTemplateParam; -import org.onap.logging.filter.base.ErrorCode; -import org.onap.so.logger.MessageEnum; -import org.onap.so.openstack.exceptions.MsoAdapterException; -import org.onap.so.openstack.exceptions.MsoCloudSiteNotFound; -import org.onap.so.openstack.exceptions.MsoException; -import org.onap.so.openstack.exceptions.MsoExceptionCategory; -import org.onap.so.openstack.exceptions.MsoIOException; -import org.onap.so.openstack.exceptions.MsoOpenstackException; -import org.onap.so.openstack.utils.MsoCommonUtils; -import org.onap.so.utils.CryptoUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.env.Environment; -import org.springframework.stereotype.Component; - -@Component -public class MsoCloudifyUtils extends MsoCommonUtils implements VduPlugin { - - private static final String CLOUDIFY = "Cloudify"; - private static final String CREATE_DEPLOYMENT = "CreateDeployment"; - private static final String DELETE_DEPLOYMENT = "DeleteDeployment"; - private static final String TERMINATED = "terminated"; - private static final String CANCELLED = "cancelled"; - private static final String UNINSTALL = "uninstall"; - private static final String UPLOAD_BLUEPRINT = "UPLOAD_BLUEPRINT"; - - // Fetch cloud configuration each time (may be cached in CloudConfig class) - @Autowired - protected CloudConfig cloudConfig; - - @Autowired - private Environment environment; - - @Autowired - private PoConfig poConfig; - - private static final Logger logger = LoggerFactory.getLogger(MsoCloudifyUtils.class); - - // Properties names and variables (with default values) - protected String createPollIntervalProp = "org.onap.so.adapters.po.pollInterval"; - private String deletePollIntervalProp = "org.onap.so.adapters.po.pollInterval"; - - protected String createPollIntervalDefault = "15"; - private String deletePollIntervalDefault = "15"; - - private static final ObjectMapper JSON_MAPPER = new ObjectMapper(); - - /** - * Create a new Deployment from a specified blueprint, and install it in the specified cloud location and tenant. - * The blueprint identifier and parameter map are passed in as arguments, along with the cloud access credentials. - * The blueprint should have been previously uploaded to Cloudify. - * - * It is expected that parameters have been validated and contain at minimum the required parameters for the given - * template with no extra (undefined) parameters.. - * - * The deployment ID supplied by the caller must be unique in the scope of the Cloudify tenant (not the Openstack - * tenant). However, it should also be globally unique, as it will be the identifier for the resource going forward - * in Inventory. This latter is managed by the higher levels invoking this function. - * - * This function executes the "install" workflow on the newly created workflow. Cloudify will be polled for - * completion unless the client requests otherwise. - * - * An error will be thrown if the requested Deployment already exists in the specified Cloudify instance. - * - * @param cloudSiteId The cloud (may be a region) in which to create the stack. - * @param tenantId The Openstack ID of the tenant in which to create the Stack - * @param deploymentId The identifier (name) of the deployment to create - * @param blueprintId The blueprint from which to create the deployment. - * @param inputs A map of key/value inputs - * @param pollForCompletion Indicator that polling should be handled in Java vs. in the client - * @param timeoutMinutes Timeout after which the "install" will be cancelled - * @param backout Flag to delete deployment on install Failure - defaulted to True - * @return A DeploymentInfo object - * @throws MsoCloudifyException Thrown if the Cloudify API call returns an exception. - * @throws MsoIOException Thrown on Cloudify connection errors. - */ - - public DeploymentInfo createAndInstallDeployment(String cloudSiteId, String tenantId, String deploymentId, - String blueprintId, Map<String, ? extends Object> inputs, boolean pollForCompletion, int timeoutMinutes, - boolean backout) throws MsoException { - // Obtain the cloud site information where we will create the stack - Optional<CloudSite> cloudSite = cloudConfig.getCloudSite(cloudSiteId); - if (!cloudSite.isPresent()) { - throw new MsoCloudSiteNotFound(cloudSiteId); - } - - Cloudify cloudify = getCloudifyClient(cloudSite.get()); - - logger.debug("Ready to Create Deployment ({}) with input params: {}", deploymentId, inputs); - - // Build up the inputs, including: - // - from provided "environment" file - // - passed in by caller - // - special input for cloud-specific Credentials - Map<String, Object> expandedInputs = new HashMap<>(inputs); - - String platform = cloudSite.get().getPlatform(); - if (platform == null || platform.isEmpty() || ("OPENSTACK").equalsIgnoreCase(platform)) { - // Create the Cloudify OpenstackConfig with the credentials - OpenstackConfig openstackConfig = getOpenstackConfig(cloudSite.get(), tenantId); - expandedInputs.put("openstack_config", openstackConfig); - } else if (("AZURE").equalsIgnoreCase(platform)) { - // Create Cloudify AzureConfig with the credentials - AzureConfig azureConfig = getAzureConfig(cloudSite.get(), tenantId); - expandedInputs.put("azure_config", azureConfig); - } - - // Build up the parameters to create a new deployment - CreateDeploymentParams deploymentParams = new CreateDeploymentParams(); - deploymentParams.setBlueprintId(blueprintId); - deploymentParams.setInputs(expandedInputs); - - Deployment deployment = null; - try { - CreateDeployment createDeploymentRequest = cloudify.deployments().create(deploymentId, deploymentParams); - logger.debug(createDeploymentRequest.toString()); - - deployment = executeAndRecordCloudifyRequest(createDeploymentRequest); - } catch (CloudifyResponseException e) { - // Since this came on the 'Create Deployment' command, nothing was changed - // in the cloud. Return the error as an exception. - if (e.getStatus() == 409) { - // Deployment already exists. Return a specific error for this case - MsoException me = new MsoDeploymentAlreadyExists(deploymentId, cloudSiteId); - me.addContext(CREATE_DEPLOYMENT); - throw me; - } else { - // Convert the CloudifyResponseException to an MsoException - logger.debug("ERROR STATUS = {},\n{}\n{}", e.getStatus(), e.getMessage(), e.getLocalizedMessage()); - MsoException me = cloudifyExceptionToMsoException(e, CREATE_DEPLOYMENT); - me.setCategory(MsoExceptionCategory.OPENSTACK); - throw me; - } - } catch (CloudifyConnectException e) { - // Error connecting to Cloudify instance. Convert to an MsoException - throw cloudifyExceptionToMsoException(e, CREATE_DEPLOYMENT); - } catch (RuntimeException e) { - // Catch-all - throw runtimeExceptionToMsoException(e, CREATE_DEPLOYMENT); - } - - /* - * It can take some time for Cloudify to be ready to execute a workflow on the deployment. Sleep 30 seconds - * based on observation of behavior in a Cloudify VM instance (delay due to "create_deployment_environment"). - */ - sleep(30000); - - /* - * Next execute the "install" workflow. Note - this assumes there are no additional parameters required for the - * workflow. - */ - int createPollInterval = - Integer.parseInt(this.environment.getProperty(createPollIntervalProp, createPollIntervalDefault)); - int pollTimeout = (timeoutMinutes * 60) + createPollInterval; - - Execution installWorkflow = null; - - try { - installWorkflow = executeWorkflow(cloudify, deploymentId, "install", null, pollForCompletion, pollTimeout, - createPollInterval); - - if (installWorkflow.getStatus().equals(TERMINATED)) { - // Success! - // Create and return a DeploymentInfo structure. Include the Runtime outputs - return new DeploymentInfoBuilder().withId(deployment.getId()) - .withDeploymentInputs(deployment.getInputs()) - .withDeploymentOutputs(getDeploymentOutputs(cloudify, deploymentId).get()) - .fromExecution(installWorkflow).build(); - } else { - // The workflow completed with errors. Must try to back it out. - if (!backout) { - logger.warn("{} Deployment installation failed, backout deletion suppressed {} {}", - MessageEnum.RA_CREATE_STACK_ERR, ErrorCode.BusinessProcessError.getValue(), - "Exception in Deployment Installation, backout suppressed"); - } else { - // Poll on delete if we rollback - use same values for now - int deletePollInterval = createPollInterval; - int deletePollTimeout = pollTimeout; - - try { - // Run the uninstall to undo the install - Execution uninstallWorkflow = executeWorkflow(cloudify, deploymentId, UNINSTALL, null, - pollForCompletion, deletePollTimeout, deletePollInterval); - - if (uninstallWorkflow.getStatus().equals(TERMINATED)) { - // The uninstall completed. Delete the deployment itself - DeleteDeployment deleteRequest = cloudify.deployments().deleteByName(deploymentId); - executeAndRecordCloudifyRequest(deleteRequest); - } else { - // Didn't uninstall successfully. Log this error - logger.error("{} Create Deployment: Cloudify error rolling back deployment install: {} {}", - MessageEnum.RA_CREATE_STACK_ERR, installWorkflow.getError(), - ErrorCode.BusinessProcessError.getValue()); - } - } catch (Exception e) { - // Catch-all for backout errors trying to uninstall/delete - // Log this error, and return the original exception - logger.error("{} Create Stack: Nested exception rolling back deployment install: {}", - MessageEnum.RA_CREATE_STACK_ERR, ErrorCode.BusinessProcessError.getValue(), e); - } - } - - MsoCloudifyException me = - new MsoCloudifyException(0, "Workflow Execution Failed", installWorkflow.getError()); - me.addContext(CREATE_DEPLOYMENT); - - throw me; - } - } catch (MsoException me) { - // Install failed. Unless requested otherwise, back out the deployment - - if (!backout) { - logger.warn("{} Deployment installation failed, backout deletion suppressed {}", - MessageEnum.RA_CREATE_STACK_ERR, ErrorCode.BusinessProcessError.getValue()); - } else { - // Poll on delete if we rollback - use same values for now - int deletePollInterval = createPollInterval; - int deletePollTimeout = pollTimeout; - - try { - // Run the uninstall to undo the install. - // Always try to run it, as it should be idempotent - executeWorkflow(cloudify, deploymentId, UNINSTALL, null, pollForCompletion, deletePollTimeout, - deletePollInterval); - - // Delete the deployment itself - DeleteDeployment deleteRequest = cloudify.deployments().deleteByName(deploymentId); - executeAndRecordCloudifyRequest(deleteRequest); - } catch (Exception e) { - // Catch-all for backout errors trying to uninstall/delete - // Log this error, and return the original exception - logger.error("{} Create Stack: Nested exception rolling back deployment install: {} ", - MessageEnum.RA_CREATE_STACK_ERR, ErrorCode.BusinessProcessError.getValue(), e); - } - } - - // Propagate the original exception from Stack Query. - me.addContext(CREATE_DEPLOYMENT); - - throw me; - } - } - - - /* - * Get the runtime Outputs of a deployment. Return the Map of tag/value outputs. - */ - private Optional<Map<String, Object>> getDeploymentOutputs(Cloudify cloudify, String deploymentId) - throws MsoException { - // Build and send the Cloudify request - DeploymentOutputs deploymentOutputs; - try { - GetDeploymentOutputs queryDeploymentOutputs = cloudify.deployments().outputsById(deploymentId); - logger.debug(queryDeploymentOutputs.toString()); - - deploymentOutputs = executeAndRecordCloudifyRequest(queryDeploymentOutputs); - if (deploymentOutputs != null) { - return Optional.ofNullable(deploymentOutputs.getOutputs()); - } else { - return Optional.empty(); - } - } catch (CloudifyConnectException ce) { - // Couldn't connect to Cloudify - logger.error("{} QueryDeploymentOutputs: Cloudify connection failure: {} ", MessageEnum.RA_CREATE_STACK_ERR, - ErrorCode.BusinessProcessError.getValue(), ce); - throw new MsoIOException(ce.getMessage(), ce); - } catch (CloudifyResponseException re) { - if (re.getStatus() == 404) { - // No Outputs - return Optional.empty(); - } - throw new MsoCloudifyException(re.getStatus(), re.getMessage(), re.getLocalizedMessage(), re); - } catch (Exception e) { - // Catch-all - throw new MsoAdapterException(e.getMessage(), e); - } - } - - /* - * Execute a workflow on a deployment. Handle polling for completion with timeout. Return the final Execution object - * with status. Throw an exception on Errors. Question - how does the client know whether rollback needs to be done? - */ - private Execution executeWorkflow(Cloudify cloudify, String deploymentId, String workflowId, - Map<String, Object> workflowParams, boolean pollForCompletion, int timeout, int pollInterval) - throws MsoCloudifyException { - logger.debug("Executing '{}' workflow on deployment '{}'", workflowId, deploymentId); - - StartExecutionParams executeParams = new StartExecutionParams(); - executeParams.setWorkflowId(workflowId); - executeParams.setDeploymentId(deploymentId); - executeParams.setParameters(workflowParams); - - Execution execution = null; - String executionId = null; - String command = "start"; - Exception savedException = null; - - try { - StartExecution executionRequest = cloudify.executions().start(executeParams); - logger.debug(executionRequest.toString()); - execution = executeAndRecordCloudifyRequest(executionRequest); - executionId = execution.getId(); - - if (!pollForCompletion) { - // Client did not request polling, so just return the Execution object - return execution; - } - - // Enter polling loop - boolean timedOut = false; - int pollTimeout = timeout; - - String status = execution.getStatus(); - - // Create a reusable cloudify query request - GetExecution queryExecution = cloudify.executions().byId(executionId); - command = "query"; - - while (!timedOut && !(status.equals(TERMINATED) || ("failed").equals(status) || status.equals(CANCELLED))) { - // workflow is still running; check for timeout - if (pollTimeout <= 0) { - logger.debug("workflow {} timed out on deployment {}", execution.getWorkflowId(), - execution.getDeploymentId()); - timedOut = true; - continue; - } - - sleep(pollInterval * 1000L); - - pollTimeout -= pollInterval; - logger.debug("pollTimeout remaining: " + pollTimeout); - - execution = queryExecution.execute(); - if (execution != null) { - status = execution.getStatus(); - } else { - status = TERMINATED; - } - } - - // Broke the loop. Check again for a terminal state - if (status.equals(TERMINATED)) { - // Success! - logger.debug("Workflow '{}' completed successfully on deployment '{}'", workflowId, deploymentId); - return execution; - } else if (("failed").equals(status)) { - // Workflow failed. Log it and return the execution object (don't throw exception here) - logger.error("{} Cloudify workflow failure: {} {} Execute Workflow: Failed: {}", - MessageEnum.RA_CREATE_STACK_ERR, execution.getError(), - ErrorCode.BusinessProcessError.getValue(), execution.getError()); - return execution; - } else if (status.equals(CANCELLED)) { - // Workflow was cancelled, leaving the deployment in an indeterminate state. Log it and return the - // execution object (don't throw exception here) - logger.error("{} Cloudify workflow cancelled. Deployment is in an indeterminate state {} {} {}", - MessageEnum.RA_CREATE_STACK_ERR, ErrorCode.BusinessProcessError.getValue(), - "Execute Workflow cancelled: ", workflowId); - return execution; - } else { - // Can only get here after a timeout - logger.error("{} Cloudify workflow timeout {} Execute Workflow: Timed Out", - MessageEnum.RA_CREATE_STACK_ERR, ErrorCode.BusinessProcessError.getValue()); - } - } catch (CloudifyConnectException ce) { - logger.error("{} {} Execute Workflow ({} {}): Cloudify connection failure {} ", - MessageEnum.RA_CREATE_STACK_ERR, ErrorCode.BusinessProcessError.getValue(), command, ce); - savedException = ce; - } catch (CloudifyResponseException re) { - logger.error("{} {} Execute Workflow ({}): Cloudify response error {} ", MessageEnum.RA_CREATE_STACK_ERR, - ErrorCode.BusinessProcessError.getValue(), command, re.getMessage(), re); - savedException = re; - } catch (RuntimeException e) { - // Catch-all - logger.error("{} {} Execute Workflow ({}): Internal error {}", MessageEnum.RA_CREATE_STACK_ERR, - ErrorCode.BusinessProcessError.getValue(), command, e.getMessage(), e); - savedException = e; - } - - // Get to this point ONLY on an error or timeout - // The cloudify execution is still running (we've not received a terminal status), - // so try to Cancel it. - CancelExecutionParams cancelParams = new CancelExecutionParams(); - cancelParams.setAction("cancel"); - // TODO: Use force_cancel? - - Execution cancelExecution = null; - - try { - CancelExecution cancelRequest = cloudify.executions().cancel(executionId, cancelParams); - logger.debug(cancelRequest.toString()); - cancelExecution = cancelRequest.execute(); - - // Enter polling loop - boolean timedOut = false; - int cancelTimeout = timeout; // TODO: For now, just use same timeout - - String status = null; - if (cancelExecution != null) { - status = cancelExecution.getStatus(); - } - // Poll for completion. Create a reusable cloudify query request - GetExecution queryExecution = cloudify.executions().byId(executionId); - - while (!timedOut && !CANCELLED.equals(status)) { - // workflow is still running; check for timeout - if (cancelTimeout <= 0) { - logger.debug("Cancel timeout for workflow {} on deployment {}", workflowId, deploymentId); - timedOut = true; - continue; - } - - sleep(pollInterval * 1000L); - - cancelTimeout -= pollInterval; - logger.debug("pollTimeout remaining: {}", cancelTimeout); - - execution = queryExecution.execute(); - if (execution != null) { - status = execution.getStatus(); - } - } - - // Broke the loop. Check again for a terminal state - if (CANCELLED.equals(status)) { - // Finished cancelling. Return the original exception - logger.debug("Cancel workflow {} completed on deployment {}", workflowId, deploymentId); - throw new MsoCloudifyException(-1, "", "", savedException); - } else { - // Can only get here after a timeout - logger.debug("Cancel workflow {} timeout out on deployment {}", workflowId, deploymentId); - MsoCloudifyException exception = new MsoCloudifyException(-1, "", "", savedException); - exception.setPendingWorkflow(true); - throw exception; - } - } catch (Exception e) { - // Catch-all. Log the message and throw the original exception - logger.debug("Cancel workflow {} failed for deployment {} :", workflowId, deploymentId, e); - MsoCloudifyException exception = new MsoCloudifyException(-1, "", "", savedException); - exception.setPendingWorkflow(true); - throw exception; - } - } - - - - /** - * Query for a Cloudify Deployment (by Name). This call will always return a DeploymentInfo object. If the - * deployment does not exist, an "empty" DeploymentInfo will be returned - containing only the deployment ID and a - * special status of NOTFOUND. - * - * @param tenantId The Openstack ID of the tenant in which to query - * @param cloudSiteId The cloud identifier (may be a region) in which to query - * @return A StackInfo object - * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception. - */ - public DeploymentInfo queryDeployment(String cloudSiteId, String tenantId, String deploymentId) - throws MsoException { - logger.debug("Query Cloudify Deployment: {} in tenant {}", deploymentId, tenantId); - - // Obtain the cloud site information where we will create the stack - Optional<CloudSite> cloudSite = cloudConfig.getCloudSite(cloudSiteId); - if (!cloudSite.isPresent()) { - throw new MsoCloudSiteNotFound(cloudSiteId); - } - - Cloudify cloudify = getCloudifyClient(cloudSite.get()); - - // Build and send the Cloudify request - Deployment deployment = new Deployment(); - try { - GetDeployment queryDeployment = cloudify.deployments().byId(deploymentId); - logger.debug(queryDeployment.toString()); - deployment = executeAndRecordCloudifyRequest(queryDeployment); - - // Next look for the latest execution - ListExecutions listExecutions = - cloudify.executions().listFiltered("deployment_id=" + deploymentId, "-created_at"); - Executions executions = listExecutions.execute(); - - // If no executions, does this give NOT_FOUND or empty set? - if (executions == null || executions.getItems().isEmpty()) { - return new DeploymentInfoBuilder().withId(deployment.getId()) - .withDeploymentInputs(deployment.getInputs()).build(); - } else { - return new DeploymentInfoBuilder().withId(deployment.getId()) - .withDeploymentInputs(deployment.getInputs()) - .withDeploymentOutputs(getDeploymentOutputs(cloudify, deploymentId).get()) - .fromExecution(executions.getItems().get(0)).build(); - } - } catch (CloudifyConnectException ce) { - // Couldn't connect to Cloudify - logger.error("{} QueryDeployment: Cloudify connection failure: {} ", MessageEnum.RA_CREATE_STACK_ERR, - ErrorCode.BusinessProcessError.getValue(), ce); - throw new MsoIOException(ce.getMessage(), ce); - } catch (CloudifyResponseException re) { - if (re.getStatus() == 404) { - // Got a NOT FOUND error. React differently based on deployment vs. execution - if (deployment != null) { - // Got NOT_FOUND on the executions. Assume this is a valid "empty" set - return new DeploymentInfoBuilder().withId(deployment.getId()) - .withDeploymentInputs(deployment.getInputs()) - .withDeploymentOutputs(getDeploymentOutputs(cloudify, deploymentId).get()).build(); - } else { - // Deployment not found. Default status of a DeploymentInfo object is NOTFOUND - return new DeploymentInfoBuilder().withId(deploymentId).build(); - } - } - throw new MsoCloudifyException(re.getStatus(), re.getMessage(), re.getLocalizedMessage(), re); - } catch (Exception e) { - // Catch-all - throw new MsoAdapterException(e.getMessage(), e); - } - } - - - /** - * Delete a Cloudify deployment (by ID). If the deployment is not found, it will be considered a successful - * deletion. The return value is a DeploymentInfo object which contains the last deployment status. - * - * There is no rollback from a successful deletion. A deletion failure will also result in an undefined deployment - * state - the components may or may not have been all or partially deleted, so the resulting deployment must be - * considered invalid. - * - * @param tenantId The Openstack ID of the tenant in which to perform the delete - * @param cloudSiteId The cloud identifier (may be a region) from which to delete the stack. - * @return A StackInfo object - * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception. - * @throws MsoCloudSiteNotFound - */ - public DeploymentInfo uninstallAndDeleteDeployment(String cloudSiteId, String tenantId, String deploymentId, - int timeoutMinutes) throws MsoException { - // Obtain the cloud site information where we will create the stack - Optional<CloudSite> cloudSite = cloudConfig.getCloudSite(cloudSiteId); - if (!cloudSite.isPresent()) { - throw new MsoCloudSiteNotFound(cloudSiteId); - } - - Cloudify cloudify = getCloudifyClient(cloudSite.get()); - - logger.debug("Ready to Uninstall/Delete Deployment ({})", deploymentId); - - // Query first to save the trouble if deployment not found - try { - GetDeployment queryDeploymentRequest = cloudify.deployments().byId(deploymentId); - logger.debug(queryDeploymentRequest.toString()); - - // deployment = executeAndRecordCloudifyRequest (queryDeploymentRequest); - } catch (CloudifyResponseException e) { - // Since this came on the 'Create Deployment' command, nothing was changed - // in the cloud. Return the error as an exception. - if (e.getStatus() == 404) { - // Deployment doesn't exist. Return a "NOTFOUND" DeploymentInfo object - // TODO: Should return NULL? - logger.debug("Deployment requested for deletion does not exist: {}", deploymentId); - return new DeploymentInfoBuilder().withId(deploymentId).withStatus(DeploymentStatus.NOTFOUND).build(); - } else { - // Convert the CloudifyResponseException to an MsoOpenstackException - logger.debug("ERROR STATUS = {}, \n {}\n {}\n {}", e.getStatus(), e.getMessage(), - e.getLocalizedMessage(), e); - MsoException me = cloudifyExceptionToMsoException(e, DELETE_DEPLOYMENT); - me.setCategory(MsoExceptionCategory.INTERNAL); - throw me; - } - } catch (CloudifyConnectException e) { - // Error connecting to Cloudify instance. Convert to an MsoException - throw cloudifyExceptionToMsoException(e, DELETE_DEPLOYMENT); - } catch (RuntimeException e) { - // Catch-all - throw runtimeExceptionToMsoException(e, DELETE_DEPLOYMENT); - } - - /* - * Query the outputs before deleting so they can be returned as well - */ - // DeploymentOutputs outputs = getDeploymentOutputs (cloudify, deploymentId); - - /* - * Next execute the "uninstall" workflow. Note - this assumes there are no additional parameters required for - * the workflow. - */ - // TODO: No deletePollInterval that I'm aware of. Use the create interval - int deletePollInterval = - Integer.parseInt(this.environment.getProperty(deletePollIntervalProp, deletePollIntervalDefault)); - int pollTimeout = (timeoutMinutes * 60) + deletePollInterval; - - Execution uninstallWorkflow = null; - - try { - uninstallWorkflow = - executeWorkflow(cloudify, deploymentId, UNINSTALL, null, true, pollTimeout, deletePollInterval); - - if (uninstallWorkflow.getStatus().equals(TERMINATED)) { - // Successful uninstall. - logger.debug("Uninstall successful for deployment {}", deploymentId); - } else { - // The uninstall workflow completed with an error. Must fail the request, but will - // leave the deployment in an indeterminate state, as cloud resources may still exist. - MsoCloudifyException me = - new MsoCloudifyException(0, "Uninstall Workflow Failed", uninstallWorkflow.getError()); - me.addContext(DELETE_DEPLOYMENT); - - throw me; - } - } catch (MsoException me) { - // Uninstall workflow has failed. - // Must fail the deletion... may leave the deployment in an inconclusive state - me.addContext(DELETE_DEPLOYMENT); - - throw me; - } - - // At this point, the deployment has been successfully uninstalled. - // Next step is to delete the deployment itself - Deployment deployment; - try { - DeleteDeployment deleteRequest = cloudify.deployments().deleteByName(deploymentId); - logger.debug(deleteRequest.toString()); - - // The delete request returns the deleted deployment - deployment = deleteRequest.execute(); - - } catch (CloudifyConnectException ce) { - // Failed to delete. Must fail the request, but will leave the (uninstalled) - // deployment in Cloudify DB. - MsoCloudifyException me = new MsoCloudifyException(0, "Deployment Delete Failed", ce.getMessage(), ce); - me.addContext(DELETE_DEPLOYMENT); - - throw me; - } catch (CloudifyResponseException re) { - // Failed to delete. Must fail the request, but will leave the (uninstalled) - // deployment in the Cloudify DB. - MsoCloudifyException me = new MsoCloudifyException(re.getStatus(), re.getMessage(), re.getMessage(), re); - me.addContext(DELETE_DEPLOYMENT); - - throw me; - } catch (Exception e) { - // Catch-all - MsoAdapterException ae = new MsoAdapterException(e.getMessage(), e); - ae.addContext(DELETE_DEPLOYMENT); - - throw ae; - } - - // Return the deleted deployment info (with runtime outputs) along with the completed uninstall workflow status - return new DeploymentInfoBuilder().withId(deployment.getId()).withDeploymentInputs(deployment.getInputs()) - .withDeploymentOutputs(getDeploymentOutputs(cloudify, deploymentId).get()) - .fromExecution(uninstallWorkflow).build(); - } - - - /** - * Check if a blueprint is available for use at a targeted cloud site. This requires checking the Cloudify Manager - * which is servicing that cloud site to see if the specified blueprint has been loaded. - * - * @param cloudSiteId The cloud site where the blueprint is needed - * @param blueprintId The ID for the blueprint in Cloudify - */ - public boolean isBlueprintLoaded(String cloudSiteId, String blueprintId) throws MsoException { - // Obtain the cloud site information where we will load the blueprint - Optional<CloudSite> cloudSite = cloudConfig.getCloudSite(cloudSiteId); - if (!cloudSite.isPresent()) { - throw new MsoCloudSiteNotFound(cloudSiteId); - } - - Cloudify cloudify = getCloudifyClient(cloudSite.get()); - - GetBlueprint getRequest = cloudify.blueprints().getMetadataById(blueprintId); - try { - Blueprint bp = getRequest.execute(); - if (bp != null) { - logger.debug("Blueprint exists: {}", bp.getId()); - return true; - } else { - logger.debug("Null blueprint!"); - return false; - } - } catch (CloudifyResponseException ce) { - if (ce.getStatus() == 404) { - return false; - } else { - throw ce; - } - } - } - - /** - * Upload a blueprint to the Cloudify Manager that is servicing a Cloud Site. The blueprint currently must be - * structured as a single directory with all of the required files. One of those files is designated the "main file" - * for the blueprint. Files are provided as byte arrays, though expect only text files will be distributed from ASDC - * and stored by MSO. - * - * Cloudify requires a single root directory in its blueprint zip files. The requested blueprint ID will also be - * used as the directory. All of the files will be added to this directory in the zip file. - */ - public void uploadBlueprint(String cloudSiteId, String blueprintId, String mainFileName, - Map<String, byte[]> blueprintFiles, boolean failIfExists) throws MsoException { - // Obtain the cloud site information where we will load the blueprint - Optional<CloudSite> cloudSite = cloudConfig.getCloudSite(cloudSiteId); - if (!cloudSite.isPresent()) { - throw new MsoCloudSiteNotFound(cloudSiteId); - } - - Cloudify cloudify = getCloudifyClient(cloudSite.get()); - - boolean blueprintUploaded = uploadBlueprint(cloudify, blueprintId, mainFileName, blueprintFiles); - - if (!blueprintUploaded && failIfExists) { - throw new MsoAdapterException("Blueprint already exists"); - } - } - - /* - * Common method to load a blueprint. May be called from - */ - protected boolean uploadBlueprint(Cloudify cloudify, String blueprintId, String mainFileName, - Map<String, byte[]> blueprintFiles) throws MsoException { - // Check if it already exists. If so, return false. - GetBlueprint getRequest = cloudify.blueprints().getMetadataById(blueprintId); - try { - Blueprint bp = getRequest.execute(); - if (bp != null) { - logger.debug("Blueprint {} already exists.", bp.getId()); - return false; - } else { - logger.debug("Null blueprint!"); - } - } catch (CloudifyResponseException ce) { - if (ce.getStatus() == 404) { - // This is the expected result. - logger.debug("Verified that Blueprint doesn't exist yet"); - } else { - throw ce; - } - } - - // Create a blueprint ZIP file in memory - ByteArrayOutputStream zipBuffer = new ByteArrayOutputStream(); - ZipOutputStream zipOut = new ZipOutputStream(zipBuffer); - - try { - // Put the root directory - String rootDir = blueprintId + (blueprintId.endsWith("/") ? "" : "/"); - zipOut.putNextEntry(new ZipEntry(rootDir)); - zipOut.closeEntry(); - - for (String fileName : blueprintFiles.keySet()) { - ZipEntry ze = new ZipEntry(rootDir + fileName); - zipOut.putNextEntry(ze); - zipOut.write(blueprintFiles.get(fileName)); - zipOut.closeEntry(); - } - zipOut.close(); - } catch (IOException e) { - // Since we're writing to a byte array, this should never happen - } - logger.debug("Blueprint zip file size: {}", zipBuffer.size()); - - // Ready to upload the blueprint zip - - try (InputStream blueprintStream = new ByteArrayInputStream(zipBuffer.toByteArray())) { - UploadBlueprint uploadRequest = - cloudify.blueprints().uploadFromStream(blueprintId, mainFileName, blueprintStream); - Blueprint blueprint = uploadRequest.execute(); - logger.debug("Successfully uploaded blueprint {}", blueprint.getId()); - } catch (CloudifyResponseException | CloudifyConnectException e) { - throw cloudifyExceptionToMsoException(e, UPLOAD_BLUEPRINT); - } catch (RuntimeException e) { - // Catch-all - throw runtimeExceptionToMsoException(e, UPLOAD_BLUEPRINT); - } catch (IOException e) { - // for try-with-resources - throw ioExceptionToMsoException(e, UPLOAD_BLUEPRINT); - } - - return true; - } - - - - // --------------------------------------------------------------- - // PRIVATE FUNCTIONS FOR USE WITHIN THIS CLASS - - /** - * Get a Cloudify client for the specified cloud site. Everything that is required can be found in the Cloud Config. - * - * @param cloudSite - * @return a Cloudify object - */ - public Cloudify getCloudifyClient(CloudSite cloudSite) throws MsoException { - CloudifyManager cloudifyConfig = cloudConfig.getCloudifyManager(cloudSite.getCloudifyId()); - if (cloudifyConfig == null) { - throw new MsoCloudifyManagerNotFound(cloudSite.getId()); - } - - // Get a Cloudify client - // Set a Token Provider to fetch tokens from Cloudify itself. - String cloudifyUrl = cloudifyConfig.getCloudifyUrl(); - Cloudify cloudify = new Cloudify(cloudifyUrl); - cloudify.setTokenProvider(new CloudifyClientTokenProvider(cloudifyUrl, cloudifyConfig.getUsername(), - CryptoUtils.decryptCloudConfigPassword(cloudifyConfig.getPassword()))); - - return cloudify; - } - - - /* - * Query for a Cloudify Deployment. This function is needed in several places, so a common method is useful. This - * method takes an authenticated CloudifyClient (which internally identifies the cloud & tenant to search), and - * returns a Deployment object if found, Null if not found, or an MsoCloudifyException if the Cloudify API call - * fails. - * - * @param cloudifyClient an authenticated Cloudify client - * - * @param deploymentId the deployment to query - * - * @return a Deployment object or null if the requested deployment doesn't exist. - * - * @throws MsoCloudifyException Thrown if the Cloudify API call returns an exception - */ - protected Deployment queryDeployment(Cloudify cloudify, String deploymentId) throws MsoException { - if (deploymentId == null) { - return null; - } - try { - GetDeployment request = cloudify.deployments().byId(deploymentId); - return executeAndRecordCloudifyRequest(request); - } catch (CloudifyResponseException e) { - if (e.getStatus() == 404) { - logger.debug("queryDeployment - not found: {}", deploymentId); - return null; - } else { - // Convert the CloudifyResponseException to an MsoCloudifyException - throw cloudifyExceptionToMsoException(e, "QueryDeployment"); - } - } catch (CloudifyConnectException e) { - // Connection to Openstack failed - throw cloudifyExceptionToMsoException(e, "QueryDeployment"); - } - } - - - public void copyStringOutputsToInputs(Map<String, String> inputs, Map<String, Object> otherStackOutputs, - boolean overWrite) { - if (inputs == null || otherStackOutputs == null) - return; - - for (Map.Entry<String, Object> entry : otherStackOutputs.entrySet()) { - String key = entry.getKey(); - Object value = entry.getValue(); - - if (value instanceof JsonNode) { - // This is a bit of mess - but I think it's the least impacting - // let's convert it BACK to a string - then it will get converted back later - try { - inputs.put(key, this.convertNode((JsonNode) value)); - } catch (Exception e) { - logger.debug("WARNING: unable to convert JsonNode output value for {}", key); - // effect here is this value will not have been copied to the inputs - and therefore will error out - // downstream - } - } else if (value instanceof java.util.LinkedHashMap) { - logger.debug("LinkedHashMap - this is showing up as a LinkedHashMap instead of JsonNode"); - try { - inputs.put(key, JSON_MAPPER.writeValueAsString(value)); - } catch (Exception e) { - logger.debug("WARNING: unable to convert LinkedHashMap output value for {}", key); - } - } else { - // just try to cast it - could be an integer or some such - try { - inputs.put(key, (String) value); - } catch (Exception e) { - logger.debug("WARNING: unable to convert output value for {}", key); - // effect here is this value will not have been copied to the inputs - and therefore will error out - // downstream - } - } - } - return; - } - - /* - * Normalize an input value to an Object, based on the target parameter type. If the type is not recognized, it will - * just be returned unchanged (as a string). - */ - public Object convertInputValue(Object inputValue, HeatTemplateParam templateParam) { - String type = templateParam.getParamType(); - logger.debug("Parameter: {} is of type {}", templateParam.getParamName(), type); - - if (("number").equalsIgnoreCase(type)) { - try { - return Integer.valueOf(inputValue.toString()); - } catch (Exception e) { - logger.debug("Unable to convert {} to an integer!", inputValue); - return null; - } - } else if (("json").equalsIgnoreCase(type)) { - try { - if (inputValue instanceof String) { - return JSON_MAPPER.readTree(inputValue.toString()); - } - // will already marshal to json without intervention - return inputValue; - } catch (Exception e) { - logger.debug("Unable to convert {} to a JsonNode!", inputValue); - return null; - } - } else if (("boolean").equalsIgnoreCase(type)) { - return Boolean.valueOf(inputValue.toString()); - } - - // Nothing else matched. Return the original string - return inputValue; - } - - - private String convertNode(final JsonNode node) { - try { - final Object obj = JSON_MAPPER.treeToValue(node, Object.class); - return JSON_MAPPER.writeValueAsString(obj); - } catch (JsonParseException jpe) { - logger.debug("Error converting json to string {}", jpe); - } catch (Exception e) { - logger.debug("Error converting json to string {}", e); - } - return "[Error converting json to string]"; - } - - - /* - * Method to execute a Cloudify command and track its execution time. For the metrics log, a category of "Cloudify" - * is used along with a sub-category that identifies the specific call (using the real cloudify-client classname of - * the CloudifyRequest<T> parameter). - */ - - - protected <T> T executeAndRecordCloudifyRequest(CloudifyRequest<T> request) { - - String requestType; - if (request.getClass().getEnclosingClass() != null) { - requestType = - request.getClass().getEnclosingClass().getSimpleName() + "." + request.getClass().getSimpleName(); - } else { - requestType = request.getClass().getSimpleName(); - } - - int retryDelay = poConfig.getRetryDelay(); - int retryCount = poConfig.getRetryCount(); - String retryCodes = poConfig.getRetryCodes(); - - // Run the actual command. All exceptions will be propagated - while (true) { - try { - return request.execute(); - } catch (CloudifyResponseException e) { - boolean retry = false; - if (retryCodes != null) { - int code = e.getStatus(); - logger.debug("Config values RetryDelay: {} RetryCount:{} RetryCodes:{} ResponseCode:{}", retryDelay, - retryCount, retryCodes, code); - for (String rCode : retryCodes.split(",")) { - try { - if (retryCount > 0 && code == Integer.parseInt(rCode)) { - retryCount--; - retry = true; - logger.debug( - "CloudifyResponseException ResponseCode:{} request:{} Retry indicated. Attempts remaining:{}", - code, requestType, retryCount); - break; - } - } catch (NumberFormatException e1) { - logger.error("{} No retries. Exception in parsing retry code in config:{} {}", - MessageEnum.RA_CONFIG_EXC, rCode, ErrorCode.SchemaError.getValue()); - throw e; - } - } - } - if (retry) { - sleep(retryDelay * 1000L); - } else - throw e; // exceeded retryCount or code is not retryable - } catch (CloudifyConnectException e) { - // Connection to Cloudify failed - if (retryCount > 0) { - retryCount--; - logger.debug(" request: {} Retry indicated. Attempts remaining:{}", requestType, retryCount); - sleep(retryDelay * 1000L); - } else - throw e; - - } - } - } - - /* - * Convert an Exception on a Cloudify call to an MsoCloudifyException. This method supports - * CloudifyResponseException and CloudifyConnectException. - */ - protected MsoException cloudifyExceptionToMsoException(CloudifyBaseException e, String context) { - MsoException me = null; - - if (e instanceof CloudifyResponseException) { - CloudifyResponseException re = (CloudifyResponseException) e; - - try { - // Failed Cloudify calls return an error entity body. - CloudifyError error = re.getResponse().getErrorEntity(CloudifyError.class); - logger.error("{} {} {} Exception - Cloudify Error on {}: {}", MessageEnum.RA_CONNECTION_EXCEPTION, - CLOUDIFY, ErrorCode.DataError.getValue(), context, error.getErrorCode()); - String fullError = error.getErrorCode() + ": " + error.getMessage(); - logger.debug(fullError); - me = new MsoCloudifyException(re.getStatus(), re.getMessage(), fullError); - } catch (Exception e2) { - // Couldn't parse the body as a "CloudifyError". Report the original HTTP error. - logger.error("{} {} {} Exception - HTTP Error on {}: {}, {} ", MessageEnum.RA_CONNECTION_EXCEPTION, - CLOUDIFY, ErrorCode.DataError.getValue(), context, re.getStatus(), e.getMessage(), e2); - me = new MsoCloudifyException(re.getStatus(), re.getMessage(), ""); - } - - // Add the context of the error - me.addContext(context); - - // Generate an alarm for 5XX and higher errors. - if (re.getStatus() >= 500) { - - } - } else if (e instanceof CloudifyConnectException) { - CloudifyConnectException ce = (CloudifyConnectException) e; - - me = new MsoIOException(ce.getMessage()); - me.addContext(context); - - // Generate an alarm for all connection errors. - - logger.error("{} {} {} Cloudify connection error on {}: ", MessageEnum.RA_CONNECTION_EXCEPTION, CLOUDIFY, - ErrorCode.DataError.getValue(), context, e); - } - - return me; - } - - - - /******************************************************************************* - * - * Methods (and associated utilities) to implement the VduPlugin interface - * - *******************************************************************************/ - - /** - * VduPlugin interface for instantiate function. - * - * This one is a bit more complex, in that it will first upload the blueprint if needed, then create the Cloudify - * deployment and execute the install workflow. - * - * This implementation also merges any parameters defined in the ENV file with the other other input parameters for - * any undefined parameters). The basic MsoCloudifyUtils separates blueprint management from deploument actions, but - * the VduPlugin does not declare blueprint management operations. - */ - @Override - public VduInstance instantiateVdu(CloudInfo cloudInfo, String instanceName, Map<String, Object> inputs, - VduModelInfo vduModel, boolean rollbackOnFailure) throws VduException { - String cloudSiteId = cloudInfo.getCloudSiteId(); - String tenantId = cloudInfo.getTenantId(); - - // Translate the VDU ModelInformation structure to that which is needed for - // creating and uploading a blueprint. Use the model customization UUID as - // the blueprint identifier. - - String blueprintId = vduModel.getModelCustomizationUUID(); - - try { - - if (!isBlueprintLoaded(cloudSiteId, blueprintId)) { - logger.debug("Blueprint {} is not loaded. Will upload it now.", blueprintId); - - // Prepare the blueprint inputs. Need the set of blueprint templates and files, - // plus the main blueprint name. - Map<String, byte[]> blueprintFiles = new HashMap<>(); - String mainTemplate = ""; - - // Add all of the blueprint artifacts from the VDU model - List<VduArtifact> vduArtifacts = vduModel.getArtifacts(); - for (VduArtifact vduArtifact : vduArtifacts) { - // Add all artifacts to the blueprint, with one exception. - // ENVIRONMENT files will be processed later as additional parameters. - - ArtifactType artifactType = vduArtifact.getType(); - if (artifactType != ArtifactType.ENVIRONMENT) { - blueprintFiles.put(vduArtifact.getName(), vduArtifact.getContent()); - - if (artifactType == ArtifactType.MAIN_TEMPLATE) { - mainTemplate = vduArtifact.getName(); - } - } - } - - // Upload the blueprint package - uploadBlueprint(cloudSiteId, blueprintId, mainTemplate, blueprintFiles, false); - } - } catch (Exception e) { - throw new VduException("CloudifyUtils (instantiateVDU): blueprint Exception", e); - } - - - // Next, create and install a new deployment based on the blueprint. - // For Cloudify, the deploymentId is specified by the client. Just use the instance name - // as the ID. - - try { - // Query the Cloudify Deployment object and populate a VduInstance - DeploymentInfo deployment = - createAndInstallDeployment(cloudSiteId, tenantId, instanceName, blueprintId, inputs, true, // (poll - // for - // completion) - vduModel.getTimeoutMinutes(), rollbackOnFailure); - - return deploymentInfoToVduInstance(deployment); - } catch (Exception e) { - throw new VduException("CloudifyUtils (instantiateVDU): Create-and-install-deployment Exception", e); - } - } - - - /** - * VduPlugin interface for query function. - */ - @Override - public VduInstance queryVdu(CloudInfo cloudInfo, String instanceId) throws VduException { - String cloudSiteId = cloudInfo.getCloudSiteId(); - String tenantId = cloudInfo.getTenantId(); - - try { - // Query the Cloudify Deployment object and populate a VduInstance - DeploymentInfo deployment = queryDeployment(cloudSiteId, tenantId, instanceId); - - return deploymentInfoToVduInstance(deployment); - } catch (Exception e) { - throw new VduException("Query VDU Exception", e); - } - } - - - /** - * VduPlugin interface for delete function. - */ - @Override - public VduInstance deleteVdu(CloudInfo cloudInfo, String instanceId, int timeoutMinutes) throws VduException { - String cloudSiteId = cloudInfo.getCloudSiteId(); - String tenantId = cloudInfo.getTenantId(); - - try { - // Uninstall and delete the Cloudify Deployment - DeploymentInfo deployment = uninstallAndDeleteDeployment(cloudSiteId, tenantId, instanceId, timeoutMinutes); - - // Populate a VduInstance based on the deleted Cloudify Deployment object - return deploymentInfoToVduInstance(deployment); - } catch (Exception e) { - throw new VduException("Delete VDU Exception", e); - } - } - - - /** - * VduPlugin interface for update function. - * - * Update is currently not supported in the MsoCloudifyUtils implementation. Just return a VduException. - * - */ - @Override - public VduInstance updateVdu(CloudInfo cloudInfo, String instanceId, Map<String, Object> inputs, - VduModelInfo vduModel, boolean rollbackOnFailure) throws VduException { - throw new VduException("CloudifyUtils: updateVDU interface not supported"); - } - - - /* - * Convert the local DeploymentInfo object (Cloudify-specific) to a generic VduInstance object - */ - protected VduInstance deploymentInfoToVduInstance(DeploymentInfo deployment) { - VduInstance vduInstance = new VduInstance(); - - // only one ID in Cloudify, use for both VDU name and ID - vduInstance.setVduInstanceId(deployment.getId()); - vduInstance.setVduInstanceName(deployment.getId()); - - // Copy inputs and outputs - vduInstance.setInputs(deployment.getInputs()); - vduInstance.setOutputs(deployment.getOutputs()); - - // Translate the status elements - vduInstance.setStatus(deploymentStatusToVduStatus(deployment)); - - return vduInstance; - } - - protected VduStatus deploymentStatusToVduStatus(DeploymentInfo deployment) { - VduStatus vduStatus = new VduStatus(); - - // Determine the status based on last action & status - // DeploymentInfo object should be enhanced to report a better status internally. - DeploymentStatus status = deployment.getStatus(); - - if (status == null) { - vduStatus.setState(VduStateType.UNKNOWN); - } else if (status == DeploymentStatus.NOTFOUND) { - vduStatus.setState(VduStateType.NOTFOUND); - } else if (status == DeploymentStatus.INSTALLED) { - vduStatus.setState(VduStateType.INSTANTIATED); - } else if (status == DeploymentStatus.CREATED) { - // Deployment exists but is not installed. This shouldn't really happen, - // since create + install or uninstall + delete are always done together. - // But account for it anyway, assuming the operation is still in progress. - String lastAction = deployment.getLastAction(); - if (lastAction == null) - vduStatus.setState(VduStateType.INSTANTIATING); - else - vduStatus.setState(VduStateType.DELETING); - } else if (status == DeploymentStatus.FAILED) { - vduStatus.setState(VduStateType.FAILED); - } else { - vduStatus.setState(VduStateType.UNKNOWN); - } - - vduStatus.setErrorMessage(deployment.getErrorMessage()); - vduStatus.setLastAction(new PluginAction(deployment.getLastAction(), deployment.getActionStatus(), - deployment.getErrorMessage())); - - return vduStatus; - } - - /* - * Return an OpenstackConfig object as expected by Cloudify Openstack Plug-in. Base the values on the CloudSite - * definition. - */ - protected OpenstackConfig getOpenstackConfig(CloudSite cloudSite, String tenantId) { - OpenstackConfig openstackConfig = new OpenstackConfig(); - openstackConfig.setRegion(cloudSite.getRegionId()); - openstackConfig.setAuthUrl(cloudSite.getIdentityService().getIdentityUrl()); - openstackConfig.setUsername(cloudSite.getIdentityService().getMsoId()); - openstackConfig - .setPassword(CryptoUtils.decryptCloudConfigPassword(cloudSite.getIdentityService().getMsoPass())); - openstackConfig.setTenantName(tenantId); - return openstackConfig; - } - - /* - * Return an Azure object as expected by Cloudify Azure Plug-in. Base the values on the CloudSite definition. - */ - protected AzureConfig getAzureConfig(CloudSite cloudSite, String tenantId) { - AzureConfig azureConfig = new AzureConfig(); - // TODO: Use adminTenant for now, instead of adding another element - azureConfig.setSubscriptionId(cloudSite.getIdentityService().getAdminTenant()); - azureConfig.setTenantId(tenantId); - azureConfig.setClientId(cloudSite.getIdentityService().getMsoId()); - azureConfig.setClientSecret(cloudSite.getIdentityService().getMsoPass()); - return azureConfig; - } - - private void sleep(long time) { - try { - Thread.sleep(time); - } catch (InterruptedException e) { - logger.debug("Thread interrupted while sleeping!", e); - Thread.currentThread().interrupt(); - } - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateHeatResponse.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateHeatResponse.java index 16671bbe50..6eb7e3d56d 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateHeatResponse.java +++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateHeatResponse.java @@ -22,11 +22,11 @@ package org.onap.so.openstack.utils; import java.io.Serializable; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import org.apache.commons.lang.builder.ToStringBuilder; @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({"id", "links"}) diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateLinkResponse.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateLinkResponse.java index 1f55aa92a2..f9a8093de6 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateLinkResponse.java +++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateLinkResponse.java @@ -21,11 +21,11 @@ package org.onap.so.openstack.utils; import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import org.apache.commons.lang.builder.ToStringBuilder; @JsonInclude(JsonInclude.Include.NON_NULL) diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateResponse.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateResponse.java index 9fa4557a45..dcc4f50b45 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateResponse.java +++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateResponse.java @@ -21,13 +21,13 @@ package org.onap.so.openstack.utils; 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; -import org.apache.commons.lang.builder.ToStringBuilder; @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudQueryResponse.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudQueryResponse.java index c575304ade..ba5e449034 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudQueryResponse.java +++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudQueryResponse.java @@ -21,12 +21,12 @@ package org.onap.so.openstack.utils; import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; import com.fasterxml.jackson.annotation.JsonCreator; 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 org.apache.commons.lang.builder.ToStringBuilder; @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({"template_type", "workload_id", "workload_status", "workload_status_reason"}) diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudRequest.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudRequest.java index 95dd48caa6..d679b0303e 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudRequest.java +++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudRequest.java @@ -21,12 +21,12 @@ package org.onap.so.openstack.utils; 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; -import org.apache.commons.lang.builder.ToStringBuilder; @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({"generic-vnf-id", "vf-module-id", "vf-module-model-invariant-id", "vf-module-model-version-id", diff --git a/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/beans/DeploymentInfoBuilderTest.java b/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/beans/DeploymentInfoBuilderTest.java deleted file mode 100644 index 9fbb45a2c3..0000000000 --- a/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/beans/DeploymentInfoBuilderTest.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * ============LICENSE_START======================================================= ONAP : SO - * ================================================================================ Copyright (C) 2018 Nokia. - * ============================================================================= 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.cloudify.beans; - -import static org.assertj.core.api.Assertions.assertThat; -import com.google.common.collect.ImmutableMap; -import org.junit.Test; -import org.onap.so.cloudify.v3.model.Execution; - -public class DeploymentInfoBuilderTest { - - private static final String ERROR_MESSAGE = "something went wrong"; - private static final String INSTALL_WORKFLOW_ID = "install"; - private static final String UNINSTALL_WORKFLOW_ID = "uninstall"; - - @Test - public void shouldConstructDeploymentInfo_withBasicValues() { - DeploymentInfo deploymentInfo = new DeploymentInfoBuilder().withId("id").withStatus(DeploymentStatus.CREATED) - .withDeploymentOutputs(ImmutableMap.of()).withDeploymentInputs(ImmutableMap.of()) - .withActionStatus("started").withLastAction(INSTALL_WORKFLOW_ID).withErrorMessage(ERROR_MESSAGE) - .build(); - - assertThat(deploymentInfo.getId()).isEqualTo("id"); - assertThat(deploymentInfo.getStatus()).isEqualTo(DeploymentStatus.CREATED); - assertThat(deploymentInfo.getOutputs()).isEqualTo(ImmutableMap.of()); - assertThat(deploymentInfo.getInputs()).isEqualTo(ImmutableMap.of()); - assertThat(deploymentInfo.getActionStatus()).isEqualTo("started"); - assertThat(deploymentInfo.getLastAction()).isEqualTo(INSTALL_WORKFLOW_ID); - assertThat(deploymentInfo.getErrorMessage()).isEqualTo(ERROR_MESSAGE); - } - - @Test - public void shouldConstructDeploymentInfo_withCreateDeploymentStatus_fromNullExecution() { - DeploymentInfo deploymentInfo = new DeploymentInfoBuilder().fromExecution(null).build(); - - assertThat(deploymentInfo.getStatus()).isEqualTo(DeploymentStatus.CREATED); - } - - @Test - public void shouldConstructDeploymentInfo_withInstalledDeploymentStatus_fromTerminatedExecution() { - String workflowIdLastAction = INSTALL_WORKFLOW_ID; - String status = "terminated"; - DeploymentStatus expectedDeploymentStatus = DeploymentStatus.INSTALLED; - verifyDeploymentInfoConstruction(workflowIdLastAction, status, expectedDeploymentStatus); - } - - @Test - public void shouldConstructDeploymentInfo_withFailedDeploymentStatus_fromFailedInstallExecution() { - String workflowIdLastAction = INSTALL_WORKFLOW_ID; - String status = "failed"; - DeploymentStatus expectedDeploymentStatus = DeploymentStatus.FAILED; - verifyDeploymentInfoConstruction(workflowIdLastAction, status, expectedDeploymentStatus); - } - - @Test - public void shouldConstructDeploymentInfo_withInstallingDeploymentStatus_fromStartedExecution() { - String workflowIdLastAction = INSTALL_WORKFLOW_ID; - String status = "started"; - DeploymentStatus expectedDeploymentStatus = DeploymentStatus.INSTALLING; - verifyDeploymentInfoConstruction(workflowIdLastAction, status, expectedDeploymentStatus); - } - - @Test - public void shouldConstructDeploymentInfo_withInstallingDeploymentStatus_fromPendingExecution() { - String workflowIdLastAction = INSTALL_WORKFLOW_ID; - String status = "pending"; - DeploymentStatus expectedDeploymentStatus = DeploymentStatus.INSTALLING; - verifyDeploymentInfoConstruction(workflowIdLastAction, status, expectedDeploymentStatus); - } - - @Test - public void shouldConstructDeploymentInfo_withUnknownDeploymentStatus_fromUnmappableExecution() { - String workflowIdLastAction = INSTALL_WORKFLOW_ID; - String status = "strangeStatus"; - DeploymentStatus expectedDeploymentStatus = DeploymentStatus.UNKNOWN; - verifyDeploymentInfoConstruction(workflowIdLastAction, status, expectedDeploymentStatus); - } - - @Test - public void shouldConstructDeploymentInfo_withCreatedDeploymentStatus_fromTerminatedExecution() { - String workflowIdLastAction = UNINSTALL_WORKFLOW_ID; - String status = "terminated"; - DeploymentStatus expectedDeploymentStatus = DeploymentStatus.CREATED; - verifyDeploymentInfoConstruction(workflowIdLastAction, status, expectedDeploymentStatus); - } - - @Test - public void shouldConstructDeploymentInfo_withFailedDeploymentStatus_fromFailedUninstallExecution() { - String workflowIdLastAction = UNINSTALL_WORKFLOW_ID; - String status = "failed"; - DeploymentStatus expectedDeploymentStatus = DeploymentStatus.FAILED; - verifyDeploymentInfoConstruction(workflowIdLastAction, status, expectedDeploymentStatus); - } - - @Test - public void shouldConstructDeploymentInfo_withUninstallingDeploymentStatus_fromStartedUninstallExecution() { - String workflowIdLastAction = UNINSTALL_WORKFLOW_ID; - String status = "started"; - DeploymentStatus expectedDeploymentStatus = DeploymentStatus.UNINSTALLING; - verifyDeploymentInfoConstruction(workflowIdLastAction, status, expectedDeploymentStatus); - } - - @Test - public void shouldConstructDeploymentInfo_withUninstallingDeploymentStatus_fromPendingUninstallExecution() { - String workflowIdLastAction = UNINSTALL_WORKFLOW_ID; - String status = "pending"; - DeploymentStatus expectedDeploymentStatus = DeploymentStatus.UNINSTALLING; - verifyDeploymentInfoConstruction(workflowIdLastAction, status, expectedDeploymentStatus); - } - - @Test - public void shouldConstructDeploymentInfo_withUnknownDeploymentStatus_fromUnmappableUninstallExecution() { - String workflowIdLastAction = UNINSTALL_WORKFLOW_ID; - String status = "strangeStatus"; - DeploymentStatus expectedDeploymentStatus = DeploymentStatus.UNKNOWN; - verifyDeploymentInfoConstruction(workflowIdLastAction, status, expectedDeploymentStatus); - } - - @Test - public void shouldConstructDeploymentInfo_withUnknownDeploymentStatus_forUnknownExecutionWorkflowId() { - String workflowIdLastAction = "strangeWorkflowIdLastAction"; - String status = "strangeStatus"; - DeploymentStatus expectedDeploymentStatus = DeploymentStatus.UNKNOWN; - verifyDeploymentInfoConstruction(workflowIdLastAction, status, expectedDeploymentStatus); - } - - @Test - public void shouldSetEmptyOutputsMapWhenInputIsNull() { - DeploymentInfo deploymentInfo = new DeploymentInfoBuilder().withDeploymentOutputs(null).build(); - assertThat(deploymentInfo.getOutputs()).isEmpty(); - } - - private void verifyDeploymentInfoConstruction(String workflowIdLastAction, String actionStatus, - DeploymentStatus expectedDeploymentStatus) { - - Execution execution = new Execution(); - execution.setWorkflowId(workflowIdLastAction); - execution.setStatus(actionStatus); - execution.setError(ERROR_MESSAGE); - DeploymentInfo deploymentInfo = new DeploymentInfoBuilder().fromExecution(execution).build(); - - assertThat(deploymentInfo.getLastAction()).isEqualTo(workflowIdLastAction); - assertThat(deploymentInfo.getActionStatus()).isEqualTo(actionStatus); - assertThat(deploymentInfo.getErrorMessage()).isEqualTo(ERROR_MESSAGE); - assertThat(deploymentInfo.getStatus()).isEqualTo(expectedDeploymentStatus); - } -} diff --git a/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/exceptions/MsoCloudifyExceptionTest.java b/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/exceptions/MsoCloudifyExceptionTest.java deleted file mode 100644 index 1506fda817..0000000000 --- a/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/exceptions/MsoCloudifyExceptionTest.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * ============LICENSE_START======================================================= ONAP : SO - * ================================================================================ Copyright (C) 2018 TechMahindra - * ================================================================================ 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.cloudify.exceptions; - -import static org.junit.Assert.*; -import org.junit.Test; - -public class MsoCloudifyExceptionTest { - - @Test - public void test() { - Exception e = null; - boolean pendingWorkflow = true; - MsoCloudifyException mce = new MsoCloudifyException(200, "message", "detail"); - MsoCloudifyException mcl = new MsoCloudifyException(200, "message", "detail", e); - mce.setPendingWorkflow(pendingWorkflow); - assert (mcl.toString() != null); - assertNotNull(mce); - } - -} diff --git a/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/exceptions/MsoCloudifyTest.java b/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/exceptions/MsoCloudifyTest.java deleted file mode 100644 index 25dcae3c2c..0000000000 --- a/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/exceptions/MsoCloudifyTest.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * ============LICENSE_START======================================================= ONAP : SO - * ================================================================================ Copyright (C) 2018 TechMahindra - * ================================================================================ 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.cloudify.exceptions; - -import static org.junit.Assert.*; -import org.junit.Test; - -public class MsoCloudifyTest { - - @Test - public void test() { - MsoBlueprintAlreadyExists mbae = new MsoBlueprintAlreadyExists("blueprintId", "cloud"); - MsoCloudifyManagerNotFound mcm = new MsoCloudifyManagerNotFound("cloudSiteId"); - MsoDeploymentAlreadyExists mdae = new MsoDeploymentAlreadyExists("deploymentId", "cloud"); - assertNotNull((mbae)); - } - -} diff --git a/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/exceptions/MsoCloudifyTimeoutTest.java b/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/exceptions/MsoCloudifyTimeoutTest.java deleted file mode 100644 index dc74d83d04..0000000000 --- a/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/exceptions/MsoCloudifyTimeoutTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * ============LICENSE_START======================================================= ONAP : SO - * ================================================================================ Copyright (C) 2018 TechMahindra - * ================================================================================ 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.cloudify.exceptions; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.mock; -import org.junit.Test; -import org.onap.so.cloudify.v3.model.Execution; - -public class MsoCloudifyTimeoutTest { - - @Test - public void test() { - Execution execution = mock(Execution.class); - MsoCloudifyTimeout mct = new MsoCloudifyTimeout(execution); - mct.getExecution(); - assert (mct.toString() != null); - assertNotNull(mct); - } - -} diff --git a/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/exceptions/MsoCloudifyWorkflowExceptionTest.java b/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/exceptions/MsoCloudifyWorkflowExceptionTest.java deleted file mode 100644 index b8b2c97a65..0000000000 --- a/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/exceptions/MsoCloudifyWorkflowExceptionTest.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * ============LICENSE_START======================================================= ONAP : SO - * ================================================================================ Copyright (C) 2018 TechMahindra - * ================================================================================ 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.cloudify.exceptions; - -import static org.junit.Assert.*; -import org.junit.Test; - -public class MsoCloudifyWorkflowExceptionTest { - - @Test - public void test() { - MsoCloudifyWorkflowException mcw = - new MsoCloudifyWorkflowException("message", "id", "workflowId", "workflowStatus"); - mcw.getWorkflowStatus(); - assertFalse(mcw.isWorkflowStillRunning()); - - } - -} diff --git a/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/utils/MsoCloudifyUtilsTest.java b/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/utils/MsoCloudifyUtilsTest.java deleted file mode 100644 index d14115971c..0000000000 --- a/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloudify/utils/MsoCloudifyUtilsTest.java +++ /dev/null @@ -1,336 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Copyright (C) 2018 Nokia. - * ================================================================================ - * 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.cloudify.utils; - -import static com.shazam.shazamcrest.MatcherAssert.assertThat; -import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import org.junit.Assert; -import org.junit.Test; -import org.mockito.Mockito; -import org.onap.so.adapters.vdu.CloudInfo; -import org.onap.so.adapters.vdu.PluginAction; -import org.onap.so.adapters.vdu.VduArtifact; -import org.onap.so.adapters.vdu.VduArtifact.ArtifactType; -import org.onap.so.adapters.vdu.VduInstance; -import org.onap.so.adapters.vdu.VduModelInfo; -import org.onap.so.adapters.vdu.VduStateType; -import org.onap.so.adapters.vdu.VduStatus; -import org.onap.so.cloud.CloudConfig; -import org.onap.so.cloudify.beans.DeploymentInfo; -import org.onap.so.cloudify.beans.DeploymentInfoBuilder; -import org.onap.so.cloudify.beans.DeploymentStatus; -import org.onap.so.cloudify.v3.client.Cloudify; -import org.onap.so.cloudify.v3.model.AzureConfig; -import org.onap.so.db.catalog.beans.CloudIdentity; -import org.onap.so.db.catalog.beans.CloudSite; -import org.onap.so.db.catalog.beans.CloudifyManager; -import org.onap.so.db.catalog.beans.HeatTemplateParam; -import org.onap.so.openstack.exceptions.MsoAdapterException; -import org.onap.so.openstack.exceptions.MsoException; -import org.skyscreamer.jsonassert.JSONAssert; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -public class MsoCloudifyUtilsTest { - - private static final String CLOUD_SITE_ID = "cloudSiteIdTest"; - private static final String BLUEPRINT_ID = "bluePrintIdTest"; - private static final String FILE_NAME = "fileName"; - - @Test - public void instantiateVduTest() throws MsoException { - VduInstance expected = new VduInstance(); - expected.setVduInstanceId("id"); - expected.setVduInstanceName("id"); - VduStatus status = new VduStatus(); - status.setState(VduStateType.INSTANTIATED); - status.setLastAction(new PluginAction(null, null, null)); - expected.setStatus(status); - - MsoCloudifyUtils cloudify = Mockito.spy(MsoCloudifyUtils.class); - CloudSite site = new CloudSite(); - Optional<CloudSite> opSite = Optional.ofNullable(site); - CloudConfig config = Mockito.mock(CloudConfig.class); - cloudify.cloudConfig = config; - Cloudify cloudifyClient = new Cloudify("cloudSite"); - CloudInfo cloudInfo = new CloudInfo(); - cloudInfo.setCloudSiteId("cloudSiteId"); - cloudInfo.setTenantId("tenantId"); - VduModelInfo vduModel = new VduModelInfo(); - vduModel.setModelCustomizationUUID("blueprintId"); - vduModel.setTimeoutMinutes(1); - VduArtifact artifact = new VduArtifact(); - artifact.setName("name"); - artifact.setType(ArtifactType.MAIN_TEMPLATE); - byte[] content = new byte[1]; - artifact.setContent(content); - List<VduArtifact> artifacts = new ArrayList<>(); - artifacts.add(artifact); - vduModel.setArtifacts(artifacts); - DeploymentInfo deployment = - new DeploymentInfoBuilder().withId("id").withStatus(DeploymentStatus.INSTALLED).build(); - Map<String, byte[]> blueprintFiles = new HashMap<>(); - blueprintFiles.put(artifact.getName(), artifact.getContent()); - String instanceName = "instanceName"; - Map<String, Object> inputs = new HashMap<>(); - boolean rollbackOnFailure = true; - - when(config.getCloudSite(cloudInfo.getCloudSiteId())).thenReturn(opSite); - doReturn(false).when(cloudify).isBlueprintLoaded(cloudInfo.getCloudSiteId(), - vduModel.getModelCustomizationUUID()); - doReturn(cloudifyClient).when(cloudify).getCloudifyClient(site); - doReturn(true).when(cloudify).uploadBlueprint(cloudifyClient, vduModel.getModelCustomizationUUID(), - artifact.getName(), blueprintFiles); - doReturn(deployment).when(cloudify).createAndInstallDeployment(cloudInfo.getCloudSiteId(), - cloudInfo.getTenantId(), instanceName, vduModel.getModelCustomizationUUID(), inputs, true, - vduModel.getTimeoutMinutes(), rollbackOnFailure); - - VduInstance actual = cloudify.instantiateVdu(cloudInfo, instanceName, inputs, vduModel, rollbackOnFailure); - assertThat(actual, sameBeanAs(expected)); - } - - @Test - public void queryVduTest() throws MsoException { - VduInstance expected = new VduInstance(); - expected.setVduInstanceId("id"); - expected.setVduInstanceName("id"); - VduStatus status = new VduStatus(); - status.setState(VduStateType.INSTANTIATED); - status.setLastAction(new PluginAction(null, null, null)); - expected.setStatus(status); - - CloudInfo cloudInfo = new CloudInfo(); - cloudInfo.setCloudSiteId("cloudSiteId"); - cloudInfo.setTenantId("tenantId"); - DeploymentInfo deployment = - new DeploymentInfoBuilder().withId("id").withStatus(DeploymentStatus.INSTALLED).build(); - String instanceId = "instanceId"; - - MsoCloudifyUtils cloudify = Mockito.spy(MsoCloudifyUtils.class); - - doReturn(deployment).when(cloudify).queryDeployment(cloudInfo.getCloudSiteId(), cloudInfo.getTenantId(), - instanceId); - - VduInstance actual = cloudify.queryVdu(cloudInfo, instanceId); - - assertThat(actual, sameBeanAs(expected)); - } - - @Test - public void deleteVduTest() throws MsoException { - VduInstance expected = new VduInstance(); - expected.setVduInstanceId("id"); - expected.setVduInstanceName("id"); - VduStatus status = new VduStatus(); - status.setState(VduStateType.DELETING); - status.setLastAction(new PluginAction("deleting", null, null)); - expected.setStatus(status); - - CloudInfo cloudInfo = new CloudInfo(); - cloudInfo.setCloudSiteId("cloudSiteId"); - cloudInfo.setTenantId("tenantId"); - String instanceId = "instanceId"; - int timeoutMinutes = 1; - DeploymentInfo deploymentInfo = new DeploymentInfoBuilder().withId("id").withStatus(DeploymentStatus.CREATED) - .withLastAction("deleting").build(); - MsoCloudifyUtils cloudify = Mockito.spy(MsoCloudifyUtils.class); - doReturn(deploymentInfo).when(cloudify).uninstallAndDeleteDeployment(cloudInfo.getCloudSiteId(), - cloudInfo.getTenantId(), instanceId, timeoutMinutes); - - VduInstance actual = cloudify.deleteVdu(cloudInfo, instanceId, timeoutMinutes); - - assertThat(actual, sameBeanAs(expected)); - } - - @Test - public void deploymentInfoToVduInstanceTest() { - VduInstance expected = new VduInstance(); - expected.setVduInstanceId("id"); - expected.setVduInstanceName("id"); - VduStatus status = new VduStatus(); - status.setState(VduStateType.DELETING); - status.setLastAction(new PluginAction("deleting", null, null)); - expected.setStatus(status); - - DeploymentInfo deploymentInfo = new DeploymentInfoBuilder().withId("id").withStatus(DeploymentStatus.CREATED) - .withLastAction("deleting").build(); - - MsoCloudifyUtils cloudify = new MsoCloudifyUtils(); - - VduInstance actual = cloudify.deploymentInfoToVduInstance(deploymentInfo); - - assertThat(actual, sameBeanAs(expected)); - } - - @Test - public void deploymentStatusToVduStatusTest() { - VduStatus expected = new VduStatus(); - expected.setState(VduStateType.DELETING); - expected.setLastAction(new PluginAction("deleting", null, null)); - - DeploymentInfo deploymentInfo = new DeploymentInfoBuilder().withId("id").withStatus(DeploymentStatus.CREATED) - .withLastAction("deleting").build(); - - MsoCloudifyUtils cloudify = new MsoCloudifyUtils(); - - VduStatus actual = cloudify.deploymentStatusToVduStatus(deploymentInfo); - - assertThat(actual, sameBeanAs(expected)); - } - - @Test - public void getAzureConfigTest() { - AzureConfig expected = new AzureConfig(); - expected.setSubscriptionId("subscriptionId"); - expected.setTenantId("tenantId"); - expected.setClientId("msoId"); - expected.setClientSecret("msoPass"); - - MsoCloudifyUtils cloudify = new MsoCloudifyUtils(); - CloudSite cloudSite = Mockito.mock(CloudSite.class); - CloudIdentity cloudIdentity = Mockito.mock(CloudIdentity.class); - when(cloudSite.getIdentityService()).thenReturn(cloudIdentity); - when(cloudIdentity.getAdminTenant()).thenReturn("subscriptionId"); - when(cloudIdentity.getMsoId()).thenReturn("msoId"); - when(cloudIdentity.getMsoPass()).thenReturn("msoPass"); - String tenantId = "tenantId"; - AzureConfig actual = cloudify.getAzureConfig(cloudSite, tenantId); - - assertThat(actual, sameBeanAs(expected)); - } - - @Test - public void uploadBlueprintSuccessful() throws MsoException { - // given - MsoCloudifyUtils testedObjectSpy = spy(MsoCloudifyUtils.class); - testedObjectSpy.cloudConfig = mock(CloudConfig.class); - Map<String, byte[]> blueprints = new HashMap<>(); - - mockCloudConfig(testedObjectSpy); - doReturn(true).when(testedObjectSpy).uploadBlueprint(any(Cloudify.class), eq(BLUEPRINT_ID), eq(FILE_NAME), - eq(blueprints)); - // when - testedObjectSpy.uploadBlueprint(CLOUD_SITE_ID, BLUEPRINT_ID, FILE_NAME, blueprints, true); - // then - verify(testedObjectSpy).uploadBlueprint(any(Cloudify.class), eq(BLUEPRINT_ID), eq(FILE_NAME), eq(blueprints)); - } - - @Test - public void uploadBlueprint_exceptionThrown_blueprintExists() throws MsoException { - // given - MsoCloudifyUtils testedObjectSpy = spy(MsoCloudifyUtils.class); - testedObjectSpy.cloudConfig = mock(CloudConfig.class); - Map<String, byte[]> blueprints = new HashMap<>(); - - mockCloudConfig(testedObjectSpy); - doReturn(false).when(testedObjectSpy).uploadBlueprint(any(Cloudify.class), eq(BLUEPRINT_ID), eq(FILE_NAME), - eq(blueprints)); - // when - try { - testedObjectSpy.uploadBlueprint(CLOUD_SITE_ID, BLUEPRINT_ID, FILE_NAME, blueprints, true); - // then - fail("MsoAdapterException should be thrown"); - } catch (MsoAdapterException e) { - Assert.assertEquals(e.getMessage(), "Blueprint already exists"); - } - verify(testedObjectSpy).uploadBlueprint(any(Cloudify.class), eq(BLUEPRINT_ID), eq(FILE_NAME), eq(blueprints)); - } - - @Test - public void convertInputValueTest() throws JsonParseException, JsonMappingException, IOException { - MsoCloudifyUtils utils = new MsoCloudifyUtils(); - ObjectMapper mapper = new ObjectMapper(); - HeatTemplateParam paramNum = new HeatTemplateParam(); - paramNum.setParamType("number"); - paramNum.setParamName("my-number"); - - HeatTemplateParam paramString = new HeatTemplateParam(); - paramString.setParamType("string"); - paramString.setParamName("my-string"); - - HeatTemplateParam paramJson = new HeatTemplateParam(); - paramJson.setParamType("json"); - paramJson.setParamName("my-json"); - - HeatTemplateParam paramJsonEscaped = new HeatTemplateParam(); - paramJsonEscaped.setParamType("json"); - paramJsonEscaped.setParamName("my-json-escaped"); - - Map<String, Object> jsonMap = - mapper.readValue(getJson("free-form.json"), new TypeReference<Map<String, Object>>() {}); - - assertEquals(3, utils.convertInputValue("3", paramNum)); - assertEquals("hello", utils.convertInputValue("hello", paramString)); - assertTrue("expect no change in type", utils.convertInputValue(jsonMap, paramJson) instanceof Map); - assertTrue("expect string to become jsonNode", - utils.convertInputValue(getJson("free-form.json"), paramJsonEscaped) instanceof JsonNode); - - JSONAssert.assertEquals(getJson("free-form.json"), - mapper.writeValueAsString(utils.convertInputValue(getJson("free-form.json"), paramJsonEscaped)), false); - - } - - private String getJson(String filename) throws IOException { - return new String(Files.readAllBytes(Paths.get("src/test/resources/__files/MsoHeatUtils/" + filename))); - } - - private void mockCloudConfig(MsoCloudifyUtils testedObjectSpy) { - CloudifyManager cloudifyManager = createCloudifyManager(); - when(testedObjectSpy.cloudConfig.getCloudSite(CLOUD_SITE_ID)).thenReturn(Optional.of(createCloudSite())); - when(testedObjectSpy.cloudConfig.getCloudifyManager(CLOUD_SITE_ID)).thenReturn(cloudifyManager); - } - - private CloudifyManager createCloudifyManager() { - CloudifyManager cloudifyManager = new CloudifyManager(); - cloudifyManager.setCloudifyUrl("cloudUrlTest"); - cloudifyManager.setPassword("546573746F736973546573746F736973"); - return cloudifyManager; - } - - private CloudSite createCloudSite() { - CloudSite cloudSite = new CloudSite(); - cloudSite.setCloudifyId(CLOUD_SITE_ID); - return cloudSite; - } - -} diff --git a/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V1.1__Initial_Recipe_Setup.sql b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V1.1__Initial_Recipe_Setup.sql index 388d3c8b49..c5a3701a82 100644 --- a/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V1.1__Initial_Recipe_Setup.sql +++ b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V1.1__Initial_Recipe_Setup.sql @@ -45,6 +45,16 @@ INSERT INTO `service` (`MODEL_UUID`, `MODEL_NAME`, `MODEL_INVARIANT_UUID`, `MODE INSERT INTO `service_recipe` (`id`, `ACTION`, `VERSION_STR`, `DESCRIPTION`, `ORCHESTRATION_URI`, `SERVICE_PARAM_XSD`, `RECIPE_TIMEOUT`, `SERVICE_TIMEOUT_INTERIM`, `CREATION_TIMESTAMP`, `SERVICE_MODEL_UUID`) VALUES (11,'createInstance','1','Custom recipe to create E2E service-instance if no custom BPMN flow is found','/mso/async/services/CreateCustomE2EServiceInstance',NULL,180,NULL,'2017-10-05 18:52:03','dfcd7471-16c7-444e-8268-d4c50d90593a'); INSERT INTO `service_recipe` (`id`, `ACTION`, `VERSION_STR`, `DESCRIPTION`, `ORCHESTRATION_URI`, `SERVICE_PARAM_XSD`, `RECIPE_TIMEOUT`, `SERVICE_TIMEOUT_INTERIM`, `CREATION_TIMESTAMP`, `SERVICE_MODEL_UUID`) VALUES (12,'deleteInstance','1','Custom recipe to delete E2E service-instance if no custom BPMN flow is found','/mso/async/services/DeleteCustomE2EServiceInstance',NULL,180,NULL,'2017-10-05 18:52:03','dfcd7471-16c7-444e-8268-d4c50d90593a'); +-- Recipe for onap3gppServiceInstances + +INSERT INTO `service` (`MODEL_UUID`, `MODEL_NAME`, `MODEL_INVARIANT_UUID`, `MODEL_VERSION`, `DESCRIPTION`, `CREATION_TIMESTAMP`, `TOSCA_CSAR_ARTIFACT_UUID`) VALUES ('3d30a774-e149-11ea-87d0-0242ac130003','COMMON_SS_DEFAULT','3d30a774-e149-11ea-87d0-0242ac130003','1.0','Default service for common NSSMF','2020-08-18 17:40:03',NULL); + +INSERT INTO `service_recipe` (`id`, `ACTION`, `VERSION_STR`, `DESCRIPTION`, `ORCHESTRATION_URI`, `SERVICE_PARAM_XSD`, `RECIPE_TIMEOUT`, `SERVICE_TIMEOUT_INTERIM`, `CREATION_TIMESTAMP`, `SERVICE_MODEL_UUID`) VALUES (17,'createInstance','1','Custom recipe to allocate 3gpp service-instance if no custom BPMN flow is found','/mso/async/services/AllocateSliceSubnet',NULL,180,NULL,'2020-08-18 17:40:03','3d30a774-e149-11ea-87d0-0242ac130003'); +INSERT INTO `service_recipe` (`id`, `ACTION`, `VERSION_STR`, `DESCRIPTION`, `ORCHESTRATION_URI`, `SERVICE_PARAM_XSD`, `RECIPE_TIMEOUT`, `SERVICE_TIMEOUT_INTERIM`, `CREATION_TIMESTAMP`, `SERVICE_MODEL_UUID`) VALUES (18,'deleteInstance','1','Custom recipe to deallocate 3gpp service-instance if no custom BPMN flow is found','/mso/async/services/DeAllocateSliceSubnet',NULL,180,NULL,'2020-08-18 18:40:03','3d30a774-e149-11ea-87d0-0242ac130003'); +INSERT INTO `service_recipe` (`id`, `ACTION`, `VERSION_STR`, `DESCRIPTION`, `ORCHESTRATION_URI`, `SERVICE_PARAM_XSD`, `RECIPE_TIMEOUT`, `SERVICE_TIMEOUT_INTERIM`, `CREATION_TIMESTAMP`, `SERVICE_MODEL_UUID`) VALUES (19,'updateInstance','1','Custom recipe to modify 3gpp service-instance if no custom BPMN flow is found','/mso/async/services/ModifySliceSubnet',NULL,180,NULL,'2020-08-18 18:40:03','3d30a774-e149-11ea-87d0-0242ac130003'); +INSERT INTO `service_recipe` (`id`, `ACTION`, `VERSION_STR`, `DESCRIPTION`, `ORCHESTRATION_URI`, `SERVICE_PARAM_XSD`, `RECIPE_TIMEOUT`, `SERVICE_TIMEOUT_INTERIM`, `CREATION_TIMESTAMP`, `SERVICE_MODEL_UUID`) VALUES (20,'activateInstance','1','Custom recipe to activate/deactivate 3gpp service-instance if no custom BPMN flow is found','/mso/async/services/ActivateSliceSubnet',NULL,180,NULL,'2020-08-18 18:40:03','3d30a774-e149-11ea-87d0-0242ac130003'); +INSERT INTO `service_recipe` (`id`, `ACTION`, `VERSION_STR`, `DESCRIPTION`, `ORCHESTRATION_URI`, `SERVICE_PARAM_XSD`, `RECIPE_TIMEOUT`, `SERVICE_TIMEOUT_INTERIM`, `CREATION_TIMESTAMP`, `SERVICE_MODEL_UUID`) VALUES (21,'deactivateInstance','1','Custom recipe to activate/deactivate 3gpp service-instance if no custom BPMN flow is found','/mso/async/services/ActivateSliceSubnet',NULL,180,NULL,'2020-08-18 18:40:03','3d30a774-e149-11ea-87d0-0242ac130003'); + -- Recipe for E2E service update (R2 just support adding/deleting network service) INSERT INTO `service_recipe` (`id`, `ACTION`, `VERSION_STR`, `DESCRIPTION`, `ORCHESTRATION_URI`, `SERVICE_PARAM_XSD`, `RECIPE_TIMEOUT`, `SERVICE_TIMEOUT_INTERIM`, `CREATION_TIMESTAMP`, `SERVICE_MODEL_UUID`) VALUES (15,'updateInstance','1','Custom recipe to update E2E service-instance if no custom BPMN flow is found','/mso/async/services/UpdateCustomE2EServiceInstance',NULL,180,NULL,'2018-03-05 10:52:03','dfcd7471-16c7-444e-8268-d4c50d90593a'); INSERT INTO `service_recipe` (`id`, `ACTION`, `VERSION_STR`, `DESCRIPTION`, `ORCHESTRATION_URI`, `SERVICE_PARAM_XSD`, `RECIPE_TIMEOUT`, `SERVICE_TIMEOUT_INTERIM`, `CREATION_TIMESTAMP`, `SERVICE_MODEL_UUID`) VALUES (16,'scaleInstance','1','Custom recipe to scale E2E service-instance if no custom BPMN flow is found','/mso/async/services/ScaleCustomE2EServiceInstance',NULL,180,NULL,'2018-05-15 18:52:03','dfcd7471-16c7-444e-8268-d4c50d90593a'); diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/external/ExternalAnNssmfManager.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/external/ExternalAnNssmfManager.java index ef979a660f..bc7a3d0bb7 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/external/ExternalAnNssmfManager.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/external/ExternalAnNssmfManager.java @@ -33,12 +33,15 @@ import org.onap.so.beans.nsmf.NssmfAdapterNBIRequest; import org.onap.so.db.request.beans.ResourceOperationStatus; import java.util.HashMap; import java.util.Map; +import java.util.UUID; import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.marshal; import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.unMarshal; public class ExternalAnNssmfManager extends ExternalNssmfManager { + private Map<String, String> bodyParams = new HashMap<>(); // request body params + @Override protected String doWrapExtAllocateReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { Map<String, Object> request = new HashMap<>(); @@ -49,13 +52,17 @@ public class ExternalAnNssmfManager extends ExternalNssmfManager { @Override protected void doAfterRequest() throws ApplicationException { if (ActionType.ALLOCATE.equals(actionType) || ActionType.DEALLOCATE.equals(actionType)) { - @SuppressWarnings("unchecked") - Map<String, String> response = unMarshal(restResponse.getResponseContent(), Map.class); - - String nssiId = response.get("nSSId"); + String nssiId; + if (ActionType.ALLOCATE.equals(actionType)) { + @SuppressWarnings("unchecked") + Map<String, String> response = unMarshal(restResponse.getResponseContent(), Map.class); + nssiId = response.get("href"); + } else { + nssiId = this.bodyParams.get("nssiId"); + } NssiResponse resp = new NssiResponse(); - resp.setJobId(nssiId); + resp.setJobId(UUID.randomUUID().toString()); resp.setNssiId(nssiId); RestResponse returnRsp = new RestResponse(); @@ -82,6 +89,9 @@ public class ExternalAnNssmfManager extends ExternalNssmfManager { @Override protected String doWrapDeAllocateReqBody(DeAllocateNssi deAllocateNssi) throws ApplicationException { + this.bodyParams.clear(); + this.bodyParams.put("nssiId", deAllocateNssi.getNssiId()); + Map<String, String> request = new HashMap<>(); request.put("nSSId", deAllocateNssi.getNssiId()); return marshal(request); diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java index 10f39f717f..7e25ed600f 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java @@ -508,13 +508,14 @@ public class HeatBridgeImpl implements HeatBridgeApi { } } - private void updateLInterfaceIps(final Port port, final LInterface lIf) { + protected void updateLInterfaceIps(final Port port, final LInterface lIf) { for (IP ip : port.getFixedIps()) { String ipAddress = ip.getIpAddress(); if (InetAddressValidator.getInstance().isValidInet4Address(ipAddress)) { Subnet subnet = osClient.getSubnetById(ip.getSubnetId()); IPAddressString cidr = new IPAddressString(subnet.getCidr()); L3InterfaceIpv4AddressList lInterfaceIp = new L3InterfaceIpv4AddressList(); + lInterfaceIp.setIsFloating(false); lInterfaceIp.setL3InterfaceIpv4Address(ipAddress); lInterfaceIp.setNeutronNetworkId(port.getNetworkId()); lInterfaceIp.setNeutronSubnetId(ip.getSubnetId()); @@ -529,6 +530,7 @@ public class HeatBridgeImpl implements HeatBridgeApi { Subnet subnet = osClient.getSubnetById(ip.getSubnetId()); IPAddressString cidr = new IPAddressString(subnet.getCidr()); L3InterfaceIpv6AddressList ipv6 = new L3InterfaceIpv6AddressList(); + ipv6.setIsFloating(false); ipv6.setL3InterfaceIpv6Address(ipAddress); ipv6.setNeutronNetworkId(port.getNetworkId()); ipv6.setNeutronSubnetId(ip.getSubnetId()); diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java index 03f6c737f3..18348f19d7 100644 --- a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java +++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java @@ -32,9 +32,12 @@ */ package org.onap.so.heatbridge; +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; @@ -65,6 +68,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; +import org.onap.aai.domain.yang.L3InterfaceIpv6AddressList; import org.onap.aai.domain.yang.LInterface; import org.onap.aai.domain.yang.PInterface; import org.onap.aai.domain.yang.SriovPf; @@ -73,6 +77,8 @@ import org.onap.aaiclient.client.aai.AAIResourcesClient; import org.onap.aaiclient.client.aai.AAISingleTransactionClient; import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri; import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory; +import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder; +import org.onap.aaiclient.client.graphinventory.GraphInventoryCommonObjectMapperProvider; import org.onap.aaiclient.client.graphinventory.exceptions.BulkProcessFailed; import org.onap.so.db.catalog.beans.CloudIdentity; import org.onap.so.heatbridge.constants.HeatBridgeConstants; @@ -93,8 +99,11 @@ import org.openstack4j.model.network.Subnet; import org.openstack4j.openstack.heat.domain.HeatResource; import org.openstack4j.openstack.heat.domain.HeatResource.Resources; import org.springframework.core.env.Environment; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; +import inet.ipaddr.IPAddressString; @RunWith(MockitoJUnitRunner.class) @@ -529,6 +538,54 @@ public class HeatBridgeImplTest { } @Test + public void testUpdateLInterfaceIps() + throws HeatBridgeException, JsonParseException, JsonMappingException, IOException { + + Port port = mock(Port.class); + when(port.getNetworkId()).thenReturn("890a203a-23gg-56jh-df67-731656a8f13a"); + when(port.getDeviceId()).thenReturn("test-device-id"); + + IP ip = mock(IP.class); + + Set<IP> ipSet = new HashSet<>(); + ipSet.add(ip); + when(ip.getIpAddress()).thenReturn("2606:ae00:2e60:100::226"); + when(ip.getSubnetId()).thenReturn("testSubnetId"); + when(port.getFixedIps()).thenAnswer(x -> ipSet); + + Subnet subnet = mock(Subnet.class); + when(subnet.getCidr()).thenReturn("169.254.100.0/24"); + when(osClient.getSubnetById("testSubnetId")).thenReturn(subnet); + + LInterface lIf = new LInterface(); + lIf.setInterfaceName("test-port-name"); + + // Act + heatbridge.updateLInterfaceIps(port, lIf); + + L3InterfaceIpv6AddressList ipv6 = new L3InterfaceIpv6AddressList(); + ipv6.setIsFloating(false); + ipv6.setL3InterfaceIpv6Address("2606:ae00:2e60:100::226"); + ipv6.setNeutronNetworkId(port.getNetworkId()); + ipv6.setNeutronSubnetId(ip.getSubnetId()); + ipv6.setL3InterfaceIpv6PrefixLength(Long.parseLong("24")); + + ArgumentCaptor<Optional> argument = ArgumentCaptor.forClass(Optional.class); + + // Assert + verify(transaction).createIfNotExists( + eq(AAIUriFactory.createResourceUri( + AAIFluentTypeBuilder.cloudInfrastructure().cloudRegion("CloudOwner", "RegionOne") + .tenant("7320ec4a5b9d4589ba7c4412ccfd290f").vserver("test-device-id") + .lInterface("test-port-name").l3InterfaceIpv6AddressList("2606:ae00:2e60:100::226"))), + argument.capture()); + + assertTrue(argument.getValue().isPresent()); + + assertThat((L3InterfaceIpv6AddressList) argument.getValue().get(), sameBeanAs(ipv6)); + } + + @Test public void testUpdateVserverLInterfacesToAai_skipVlans() throws HeatBridgeException { // Arrange List<Resource> stackResources = (List<Resource>) extractTestStackResources(); |