diff options
Diffstat (limited to 'adapters')
126 files changed, 6068 insertions, 3162 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/cloud/authentication/AuthenticationMethodFactory.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/AuthenticationMethodFactory.java index 59c6becfbd..ab0239057a 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/AuthenticationMethodFactory.java +++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/AuthenticationMethodFactory.java @@ -89,4 +89,32 @@ public final class AuthenticationMethodFactory { v3Auth.setScope(scope); return v3Auth; } + + public final com.woorea.openstack.keystone.v3.model.Authentication getAuthenticationForV3ByName( + CloudIdentity cloudIdentity, String name) { + Identity identity = new Identity(); + Password password = new Password(); + User user = new User(); + Domain userDomain = new Domain(); + Scope scope = new Scope(); + Project project = new Project(); + Project.Domain projectDomain = new Project.Domain(); + userDomain.setName(cloudIdentity.getUserDomainName()); + projectDomain.setName(cloudIdentity.getProjectDomainName()); + user.setName(cloudIdentity.getMsoId()); + user.setPassword(CryptoUtils.decryptCloudConfigPassword(cloudIdentity.getMsoPass())); + user.setDomain(userDomain); + password.setUser(user); + project.setDomain(projectDomain); + project.setName(name); + scope.setProject(project); + identity.setPassword(password); + identity.setMethods(Collections.singletonList("password")); + com.woorea.openstack.keystone.v3.model.Authentication v3Auth = + new com.woorea.openstack.keystone.v3.model.Authentication(); + v3Auth.setIdentity(identity); + v3Auth.setScope(scope); + return v3Auth; + } + } diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/KeystoneV3Authentication.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/KeystoneV3Authentication.java index 16906957a7..3564b8f0a7 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/KeystoneV3Authentication.java +++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/KeystoneV3Authentication.java @@ -107,7 +107,7 @@ public class KeystoneV3Authentication { return policy; } - protected String findEndpointURL(List<Service> serviceCatalog, String type, String region, String facing) { + public String findEndpointURL(List<Service> serviceCatalog, String type, String region, String facing) { for (Service service : serviceCatalog) { if (type.equals(service.getType())) { for (Service.Endpoint endpoint : service.getEndpoints()) { 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/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/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/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/MsoCommonUtils.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoCommonUtils.java index 50ebcc66ee..6800428a62 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoCommonUtils.java +++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoCommonUtils.java @@ -97,7 +97,7 @@ public class MsoCommonUtils { * openstack-java-sdk classname of the OpenStackRequest<T> parameter). */ - protected <T> T executeAndRecordOpenstackRequest(OpenStackRequest<T> request) { + public <T> T executeAndRecordOpenstackRequest(OpenStackRequest<T> request) { return executeAndRecordOpenstackRequest(request, true); } @@ -174,7 +174,7 @@ public class MsoCommonUtils { * Convert an Openstack Exception on a Keystone call to an MsoException. This method supports both * OpenstackResponseException and OpenStackConnectException. */ - protected MsoException keystoneErrorToMsoException(OpenStackBaseException e, String context) { + public MsoException keystoneErrorToMsoException(OpenStackBaseException e, String context) { MsoException me = null; if (e instanceof OpenStackResponseException) { @@ -455,15 +455,16 @@ public class MsoCommonUtils { */ protected KeystoneAuthHolder getKeystoneAuthHolder(String cloudSiteId, String tenantId, String serviceName) throws MsoException { - CloudSite cloudSite = - cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId)); - String cloudId = cloudSite.getId(); - String region = cloudSite.getRegionId(); - CloudIdentity cloudIdentity = cloudSite.getIdentityService(); - MsoTenantUtils tenantUtils = - tenantUtilsFactory.getTenantUtilsByServerType(cloudIdentity.getIdentityServerType()); - String keystoneUrl = tenantUtils.getKeystoneUrl(cloudId, cloudIdentity); + CloudIdentity cloudIdentity = null; try { + CloudSite cloudSite = + cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId)); + String cloudId = cloudSite.getId(); + String region = cloudSite.getRegionId(); + cloudIdentity = cloudSite.getIdentityService(); + MsoTenantUtils tenantUtils = + tenantUtilsFactory.getTenantUtilsByServerType(cloudIdentity.getIdentityServerType()); + String keystoneUrl = tenantUtils.getKeystoneUrl(cloudId, cloudIdentity); if (ServerType.KEYSTONE.equals(cloudIdentity.getIdentityServerType())) { Access access = getKeystone(tenantId, cloudIdentity, keystoneUrl); try { 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/main/java/org/onap/so/openstack/utils/NovaClient.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/NovaClient.java index c5eeb34157..968e7864b3 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/NovaClient.java +++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/NovaClient.java @@ -49,4 +49,6 @@ public class NovaClient extends MsoCommonUtils { novaClient.token(keystone.getId()); return novaClient; } + + } 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/java/org/onap/so/adapters/catalogdb/catalogrest/QueryServiceMacroHolder.java b/adapters/mso-catalog-db-adapter/src/main/java/org/onap/so/adapters/catalogdb/catalogrest/QueryServiceMacroHolder.java index 305d52a997..89fd9a0147 100644 --- a/adapters/mso-catalog-db-adapter/src/main/java/org/onap/so/adapters/catalogdb/catalogrest/QueryServiceMacroHolder.java +++ b/adapters/mso-catalog-db-adapter/src/main/java/org/onap/so/adapters/catalogdb/catalogrest/QueryServiceMacroHolder.java @@ -37,10 +37,11 @@ public class QueryServiceMacroHolder extends CatalogQuery { + "\t\t\"modelUuid\" : <SERVICE_MODEL_UUID>,\n" + "\t\t\"modelInvariantUuid\" : <SERVICE_MODEL_INVARIANT_ID>,\n" + "\t\t\"modelVersion\" : <SERVICE_MODEL_VERSION>\n" + "\t},\n" - + "\t\"serviceType\" : <SERVICE_TYPE>,\n" + "\t\"serviceRole\" : <SERVICE_ROLE>,\n" - + "\t\"environmentContext\" : <ENVIRONMENT_CONTEXT>,\n" + "\t\"resourceOrder\" : <RESOURCE_ORDER>,\n" - + "\t\"workloadContext\" : <WORKLOAD_CONTEXT>,\n" + "<_SERVICEVNFS_>,\n" + "<_SERVICENETWORKS_>,\n" - + "<_SERVICEINFO_>,\n" + "<_SERVICEPROXY_>,\n" + "<_SERVICEALLOTTEDRESOURCES_>\n" + "\t}}"; + + "\t\"serviceCategory\" : <SERVICE_CATEGORY>,\n" + "\t\"serviceType\" : <SERVICE_TYPE>,\n" + + "\t\"serviceRole\" : <SERVICE_ROLE>,\n" + "\t\"environmentContext\" : <ENVIRONMENT_CONTEXT>,\n" + + "\t\"resourceOrder\" : <RESOURCE_ORDER>,\n" + "\t\"workloadContext\" : <WORKLOAD_CONTEXT>,\n" + + "<_SERVICEVNFS_>,\n" + "<_SERVICENETWORKS_>,\n" + "<_SERVICEINFO_>,\n" + "<_SERVICEPROXY_>,\n" + + "<_SERVICEALLOTTEDRESOURCES_>\n" + "\t}}"; public QueryServiceMacroHolder() { super(); @@ -80,6 +81,7 @@ public class QueryServiceMacroHolder extends CatalogQuery { put(valueMap, "SERVICE_MODEL_VERSION", service.getModelVersion()); put(valueMap, "SERVICE_TYPE", service.getServiceType()); put(valueMap, "SERVICE_ROLE", service.getServiceRole()); + put(valueMap, "SERVICE_CATEGORY", service.getCategory()); put(valueMap, "ENVIRONMENT_CONTEXT", service.getEnvironmentContext()); put(valueMap, "WORKLOAD_CONTEXT", service.getWorkloadContext()); put(valueMap, "RESOURCE_ORDER", service.getResourceOrder()); diff --git a/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/R__MacroData.sql b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/R__MacroData.sql index ea371f54f7..e4810840f1 100644 --- a/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/R__MacroData.sql +++ b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/R__MacroData.sql @@ -33,6 +33,12 @@ INSERT INTO northbound_request_ref_lookup(MACRO_ACTION, ACTION, REQUEST_SCOPE, I ('VNF-InPlaceUpdate', 'inPlaceSoftwareUpdate', 'Vnf', true, true, '7','7', 'DEFAULT', '*'), ('VNF-Config-Update', 'applyUpdatedConfig', 'Vnf', true, true, '7','7', 'DEFAULT', '*'); +-- +-- northbound_request_ref_lookup for updateInstance (Macro Flow) +-- +INSERT INTO northbound_request_ref_lookup(ID, REQUEST_SCOPE, MACRO_ACTION, ACTION, IS_ALACARTE, MIN_API_VERSION, MAX_API_VERSION, IS_TOPLEVELFLOW, CLOUD_OWNER, SERVICE_TYPE) +VALUES (500, 'Vnf', 'VNF-Macro-Modify', 'updateInstance', 0, 7, 7, 1, 'k8scloudowner4', '*'); + INSERT INTO orchestration_flow_reference(COMPOSITE_ACTION, SEQ_NO, FLOW_NAME, FLOW_VERSION, NB_REQ_REF_LOOKUP_ID) VALUES ('Service-Create', '1', 'AssignServiceInstanceBB', 1.0,(SELECT id from northbound_request_ref_lookup WHERE MACRO_ACTION = 'Service-Create' and CLOUD_OWNER = 'DEFAULT')), @@ -211,6 +217,15 @@ INSERT INTO orchestration_flow_reference(COMPOSITE_ACTION, SEQ_NO, FLOW_NAME, FL ('VNF-Config-Update', '8', 'VNFUnsetInMaintFlagActivity', 1.0,(SELECT id from northbound_request_ref_lookup WHERE MACRO_ACTION = 'VNF-Config-Update' and CLOUD_OWNER = 'DEFAULT')), ('VNF-Config-Update', '9', 'VNFUnsetClosedLoopDisabledFlagActivity', 1.0,(SELECT id from northbound_request_ref_lookup WHERE MACRO_ACTION = 'VNF-Config-Update' and CLOUD_OWNER = 'DEFAULT')); +-- +-- orchestration_flow_reference for updateInstance (Macro Flow) +-- +insert into orchestration_flow_reference (id,COMPOSITE_ACTION,SEQ_NO,FLOW_NAME,FLOW_VERSION,NB_REQ_REF_LOOKUP_ID,SCOPE,ACTION) +values (901, 'VNF-Macro-Modify',1,'ControllerExecutionBB',1,500,'vnf','config-assign'); +insert into orchestration_flow_reference (id,COMPOSITE_ACTION,SEQ_NO,FLOW_NAME,FLOW_VERSION,NB_REQ_REF_LOOKUP_ID,SCOPE,ACTION) +values (902, 'VNF-Macro-Modify',2,'ControllerExecutionBB',1,500,'vnf','config-deploy'); + + INSERT INTO orchestration_flow_reference(COMPOSITE_ACTION, SEQ_NO, FLOW_NAME, FLOW_VERSION, NB_REQ_REF_LOOKUP_ID, SCOPE, ACTION) VALUES ('Service-Macro-Create', '10', 'ControllerExecutionBB', 1.0,(SELECT id from northbound_request_ref_lookup WHERE MACRO_ACTION = 'Service-Macro-Create' and CLOUD_OWNER = 'DEFAULT'), 'pnf', 'config-assign'); 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 1663fdd6a8..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 @@ -33,6 +33,8 @@ INSERT INTO `service_recipe` (`id`, `ACTION`, `VERSION_STR`, `DESCRIPTION`, `ORC 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 (2,'deleteInstance','1','VID_DEFAULT recipe to delete service-instance if no custom BPMN flow is found','/mso/async/services/DeleteGenericALaCarteServiceInstance',NULL,180,NULL,'2017-10-05 18:52:03','48cc36cc-a9fe-11e7-8b4b-0242ac120002'); 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 (3,'createInstance','1','DEFAULT recipe to create service-instance if no custom BPMN flow is found','/mso/async/services/CreateGenericALaCarteServiceInstance',NULL,180,NULL,'2017-10-05 18:52:03','48cc3acd-a9fe-11e7-8b4b-0242ac120002'); 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 (4,'deleteInstance','1','DEFAULT recipe to delete service-instance if no custom BPMN flow is found','/mso/async/services/DeleteGenericALaCarteServiceInstance',NULL,180,NULL,'2017-10-05 18:52:03','48cc3acd-a9fe-11e7-8b4b-0242ac120002'); +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 (500,'updateInstance','1.0','Gr api recipe to update service-instance', '/mso/async/services/WorkflowActionBB', NULL, 180, NULL, '2017-10-05 18:52:03', 'd88da85c-d9e8-4f73-b837-3a72a431622b'); + -- -- Custom Reciepe for the VoLTE service added temporarily @@ -43,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'); @@ -60,6 +72,7 @@ INSERT INTO `vnf_components_recipe` (`id`, `VNF_TYPE`, `VNF_COMPONENT_TYPE`, `VF INSERT INTO `vnf_components_recipe` (`id`, `VNF_TYPE`, `VNF_COMPONENT_TYPE`, `VF_MODULE_MODEL_UUID`, `ACTION`, `SERVICE_TYPE`, `VERSION`, `DESCRIPTION`, `ORCHESTRATION_URI`, `VNF_COMPONENT_PARAM_XSD`, `RECIPE_TIMEOUT`, `CREATION_TIMESTAMP`) VALUES (11,NULL,'vfModule','VID_DEFAULT','deleteInstance',NULL,'1','VID_DEFAULT recipe t','/mso/async/services/DeleteVfModuleInfra',null,180,'2017-10-05 18:52:03'); INSERT INTO `vnf_components_recipe` (`id`, `VNF_TYPE`, `VNF_COMPONENT_TYPE`, `VF_MODULE_MODEL_UUID`, `ACTION`, `SERVICE_TYPE`, `VERSION`, `DESCRIPTION`, `ORCHESTRATION_URI`, `VNF_COMPONENT_PARAM_XSD`, `RECIPE_TIMEOUT`, `CREATION_TIMESTAMP`) VALUES (12,NULL,'vfModule','VID_DEFAULT','updateInstance',NULL,'1','VID_DEFAULT recipe t','/mso/async/services/UpdateVfModuleInfra',null,180,'2017-10-05 18:52:03'); + -- -- Default Reciepe for the VNF componnets added start #SO-334, to unblock the VNF operations -- diff --git a/adapters/mso-cnf-adapter/pom.xml b/adapters/mso-cnf-adapter/pom.xml index fb25157a96..0928da084e 100644 --- a/adapters/mso-cnf-adapter/pom.xml +++ b/adapters/mso-cnf-adapter/pom.xml @@ -110,11 +110,11 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> - <!-- <dependency> + <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> - </dependency> --> + </dependency> <!-- <dependency> <groupId>org.onap.so</groupId> <artifactId>mso-requests-db</artifactId> diff --git a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/MSOCnfApplication.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/MSOCnfApplication.java index e94c283a98..0ba40e2700 100644 --- a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/MSOCnfApplication.java +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/MSOCnfApplication.java @@ -28,8 +28,10 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerA import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; @SpringBootApplication @ComponentScan(basePackages = {"org.onap.so.adapters.cnf"}) @@ -42,4 +44,9 @@ public class MSOCnfApplication { public static void main(String... args) { SpringApplication.run(MSOCnfApplication.class, args); } + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } } diff --git a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/exceptions/ApplicationException.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/exceptions/ApplicationException.java new file mode 100644 index 0000000000..c950cf6b2a --- /dev/null +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/exceptions/ApplicationException.java @@ -0,0 +1,66 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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.adapters.cnf.exceptions; + +import static org.onap.so.adapters.cnf.util.CNfAdapterUtil.marshal; +import org.onap.so.adapters.cnf.model.ErrorResponse; +import org.springframework.http.ResponseEntity; + +public class ApplicationException extends Exception { + + private static final long serialVersionUID = 1L; + + private int errorCode; + + private String errorMsg; + + public ApplicationException(int errorCode, String errorMsg) { + this.errorCode = errorCode; + this.errorMsg = errorMsg; + } + + public int getErrorCode() { + return errorCode; + } + + public void setErrorCode(int errorCode) { + this.errorCode = errorCode; + } + + public String getErrorMsg() { + return errorMsg; + } + + public void setErrorMsg(String errorMsg) { + this.errorMsg = errorMsg; + } + + public ResponseEntity buildErrorResponse() { + String message; + try { + ErrorResponse err = new ErrorResponse(errorCode, errorMsg); + message = marshal(err); + } catch (ApplicationException e) { + return ResponseEntity.status(500).body("Internal Server Error"); + } + return ResponseEntity.status(errorCode).body(message); + } +} diff --git a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/BpmnInstanceRequest.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/BpmnInstanceRequest.java new file mode 100644 index 0000000000..2e76d51da2 --- /dev/null +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/BpmnInstanceRequest.java @@ -0,0 +1,87 @@ +package org.onap.so.adapters.cnf.model; + +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(value = "true") +public class BpmnInstanceRequest { + + @JsonProperty(value = "modelInvariantId") + private String modelInvariantId; + + @JsonProperty(value = "modelVersionId") + private String modelVersionId; + + @JsonProperty(value = "k8sRBProfileName") + private String k8sRBProfileName; + + @JsonProperty(value = "cloudRegionId") + private String cloudRegionId; + + @JsonProperty(value = "vfModuleUUID") + private String vfModuleUUID; + + @JsonProperty(value = "labels") + private Map<String, String> labels; + + @JsonProperty(value = "overrideValues") + private Map<String, String> overrideValues; + + public String getModelInvariantId() { + return modelInvariantId; + } + + public void setModelInvariantId(String modelInvariantId) { + this.modelInvariantId = modelInvariantId; + } + + public String getModelVersionId() { + return modelVersionId; + } + + public void setModelVersionId(String modelVersionId) { + this.modelVersionId = modelVersionId; + } + + public String getK8sRBProfileName() { + return k8sRBProfileName; + } + + public void setK8sRBProfileName(String k8sRBProfileName) { + this.k8sRBProfileName = k8sRBProfileName; + } + + public String getCloudRegionId() { + return cloudRegionId; + } + + public void setCloudRegionId(String cloudRegionId) { + this.cloudRegionId = cloudRegionId; + } + + public String getVfModuleUUID() { + return vfModuleUUID; + } + + public void setVfModuleUUID(String vfModuleUUID) { + this.vfModuleUUID = vfModuleUUID; + } + + public Map<String, String> getLabels() { + return labels; + } + + public void setLabels(Map<String, String> labels) { + this.labels = labels; + } + + public Map<String, String> getOverrideValues() { + return overrideValues; + } + + public void setOverrideValues(Map<String, String> overrideValues) { + this.overrideValues = overrideValues; + } + +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/model/ErrorResponse.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/ErrorResponse.java index 188349c0bf..135adcc143 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/model/ErrorResponse.java +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/ErrorResponse.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.so.adapters.nssmf.model; +package org.onap.so.adapters.cnf.model; public class ErrorResponse { diff --git a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/GroupVersionKind.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/GroupVersionKind.java new file mode 100644 index 0000000000..bfa5505ccc --- /dev/null +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/GroupVersionKind.java @@ -0,0 +1,66 @@ + +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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.adapters.cnf.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({"Group", "Version", "Kind"}) +public class GroupVersionKind { + @JsonProperty("Group") + private String group; + @JsonProperty("Version") + private String version; + @JsonProperty("Kind") + private String kind; + + @JsonProperty("Group") + public String getGroup() { + return group; + } + + @JsonProperty("Group") + public void setGroup(String group) { + this.group = group; + } + + @JsonProperty("Version") + public String getVersion() { + return version; + } + + @JsonProperty("Version") + public void setVersion(String version) { + this.version = version; + } + + @JsonProperty("Kind") + public String getKind() { + return kind; + } + + @JsonProperty("Kind") + public void setKind(String kind) { + this.kind = kind; + } +} diff --git a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/InstanceMiniResponse.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/InstanceMiniResponse.java new file mode 100644 index 0000000000..58040826dd --- /dev/null +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/InstanceMiniResponse.java @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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.adapters.cnf.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(value = "true") +public class InstanceMiniResponse extends Response { + + private String id; + private MulticloudInstanceRequest request; + private String nameSpace; + + public InstanceMiniResponse(String errorMsg) { + super(errorMsg); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public MulticloudInstanceRequest getRequest() { + return request; + } + + public void setRequest(MulticloudInstanceRequest request) { + this.request = request; + } + + public String getNameSpace() { + return nameSpace; + } + + public void setNameSpace(String nameSpace) { + this.nameSpace = nameSpace; + } + +} diff --git a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/InstanceMiniResponseList.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/InstanceMiniResponseList.java new file mode 100644 index 0000000000..ad70fbb7d0 --- /dev/null +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/InstanceMiniResponseList.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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.adapters.cnf.model; + +import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(value = "true") +public class InstanceMiniResponseList extends Response { + + public InstanceMiniResponseList(String errorMsg) { + super(errorMsg); + } + + private List<InstanceMiniResponse> instancList; + + public List<InstanceMiniResponse> getInstancList() { + return instancList; + } + + public void setInstancList(List<InstanceMiniResponse> instancList) { + this.instancList = instancList; + } + +} diff --git a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/InstanceResponse.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/InstanceResponse.java new file mode 100644 index 0000000000..effaaf5f78 --- /dev/null +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/InstanceResponse.java @@ -0,0 +1,87 @@ + +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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.adapters.cnf.model; + +import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({"id", "request", "namespace", "resources"}) +@JsonIgnoreProperties(value = "true") +public class InstanceResponse extends Response { + + @JsonProperty("id") + private String id; + @JsonProperty("request") + private MulticloudInstanceRequest request; + @JsonProperty("namespace") + private String namespace; + @JsonProperty("resources") + private List<Resource> resources = null; + + public InstanceResponse(String errorMsg) { + super(errorMsg); + } + + @JsonProperty("id") + public String getId() { + return id; + } + + @JsonProperty("id") + public void setId(String id) { + this.id = id; + } + + @JsonProperty("request") + public MulticloudInstanceRequest getRequest() { + return request; + } + + @JsonProperty("request") + public void setRequest(MulticloudInstanceRequest request) { + this.request = request; + } + + @JsonProperty("namespace") + public String getNamespace() { + return namespace; + } + + @JsonProperty("namespace") + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + @JsonProperty("resources") + public List<Resource> getResources() { + return resources; + } + + @JsonProperty("resources") + public void setResources(List<Resource> resources) { + this.resources = resources; + } + +} diff --git a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/InstanceStatusResponse.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/InstanceStatusResponse.java new file mode 100644 index 0000000000..2472684bc0 --- /dev/null +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/InstanceStatusResponse.java @@ -0,0 +1,84 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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.adapters.cnf.model; + +import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(value = "true") +public class InstanceStatusResponse extends Response { + + public InstanceStatusResponse(String errorMsg) { + super(errorMsg); + } + + private MulticloudInstanceRequest request; + + private boolean ready; + + private String resourceCount; + + private List<PodStatus> podStatuses; + + private List<?> servicesStatuses; + + public MulticloudInstanceRequest getRequest() { + return request; + } + + public void setRequest(MulticloudInstanceRequest request) { + this.request = request; + } + + public boolean isReady() { + return ready; + } + + public void setReady(boolean ready) { + this.ready = ready; + } + + public String getResourceCount() { + return resourceCount; + } + + public void setResourceCount(String resourceCount) { + this.resourceCount = resourceCount; + } + + public List<PodStatus> getPodStatuses() { + return podStatuses; + } + + public void setPodStatuses(List<PodStatus> podStatuses) { + this.podStatuses = podStatuses; + } + + public List<?> getServicesStatuses() { + return servicesStatuses; + } + + public void setServicesStatuses(List<?> servicesStatuses) { + this.servicesStatuses = servicesStatuses; + } + +} diff --git a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/InstanceEntity.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/MulticloudInstanceRequest.java index 04f2f9d030..b1719cbd7d 100644 --- a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/InstanceEntity.java +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/MulticloudInstanceRequest.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; @JsonIgnoreProperties(value = "true") -public class InstanceEntity { +public class MulticloudInstanceRequest { @JsonProperty(value = "cloud-region") private String cloudRegion; @@ -25,6 +25,9 @@ public class InstanceEntity { @JsonProperty(value = "override-values") private Map<String, String> overrideValues; + @JsonProperty(value = "release-name") + private String vfModuleUuid; + public String getCloudRegion() { return cloudRegion; } @@ -73,4 +76,12 @@ public class InstanceEntity { this.overrideValues = overrideValues; } + public String getVfModuleUuid() { + return vfModuleUuid; + } + + public void setVfModuleUuid(String vfModuleUuid) { + this.vfModuleUuid = vfModuleUuid; + } + } diff --git a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/PodStatus.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/PodStatus.java new file mode 100644 index 0000000000..ed04601b2c --- /dev/null +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/PodStatus.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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.adapters.cnf.model; + +public class PodStatus { + + private String name; + private String nameSpace; + private boolean ready; + private String status; + private String[] ipAddresses; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNameSpace() { + return nameSpace; + } + + public void setNameSpace(String nameSpace) { + this.nameSpace = nameSpace; + } + + public boolean isReady() { + return ready; + } + + public void setReady(boolean ready) { + this.ready = ready; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String[] getIpAddresses() { + return ipAddresses; + } + + public void setIpAddresses(String[] ipAddresses) { + this.ipAddresses = ipAddresses; + } + +} diff --git a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/Resource.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/Resource.java new file mode 100644 index 0000000000..d18cd76039 --- /dev/null +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/Resource.java @@ -0,0 +1,54 @@ + +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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.adapters.cnf.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({"GVK", "Name"}) +public class Resource { + @JsonProperty("GVK") + private GroupVersionKind gVK; + @JsonProperty("Name") + private String name; + + @JsonProperty("GVK") + public GroupVersionKind getGVK() { + return gVK; + } + + @JsonProperty("GVK") + public void setGVK(GroupVersionKind gVK) { + this.gVK = gVK; + } + + @JsonProperty("Name") + public String getName() { + return name; + } + + @JsonProperty("Name") + public void setName(String name) { + this.name = name; + } +} diff --git a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/Response.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/Response.java new file mode 100644 index 0000000000..423022393c --- /dev/null +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/model/Response.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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.adapters.cnf.model; + +public class Response { + + private String errorMsg; + + public Response(String errorMsg) { + this.errorMsg = errorMsg; + } + + public String getErrorMsg() { + return errorMsg; + } + + public void setErrorMsg(String errorMsg) { + this.errorMsg = errorMsg; + } + +} diff --git a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/rest/CnfAdapterRest.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/rest/CnfAdapterRest.java index 952edef7f6..825778b89a 100644 --- a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/rest/CnfAdapterRest.java +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/rest/CnfAdapterRest.java @@ -1,27 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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.adapters.cnf.rest; +import java.io.File; +import java.io.IOException; +import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; +import org.onap.so.adapters.cnf.model.BpmnInstanceRequest; import org.onap.so.adapters.cnf.model.ConfigTemplateEntity; import org.onap.so.adapters.cnf.model.ConfigurationEntity; +import org.onap.so.adapters.cnf.model.ConfigurationRollbackEntity; import org.onap.so.adapters.cnf.model.ConnectivityInfo; -import org.onap.so.adapters.cnf.model.InstanceEntity; +import org.onap.so.adapters.cnf.model.InstanceMiniResponseList; +import org.onap.so.adapters.cnf.model.InstanceResponse; +import org.onap.so.adapters.cnf.model.InstanceStatusResponse; import org.onap.so.adapters.cnf.model.ProfileEntity; import org.onap.so.adapters.cnf.model.ResourceBundleEntity; +import org.onap.so.adapters.cnf.model.Tag; +import org.onap.so.adapters.cnf.service.CnfAdapterService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; @@ -31,23 +71,78 @@ public class CnfAdapterRest { private static final Logger logger = LoggerFactory.getLogger(CnfAdapterRest.class); private final CloseableHttpClient httpClient = HttpClients.createDefault(); + @Autowired + private CnfAdapterService cnfAdapterService; + @ResponseBody - @RequestMapping(value = {"/api/multicloud-k8s/v1/healthcheck"}, method = RequestMethod.GET, + @RequestMapping(value = {"/api/cnf-adapter/v1/healthcheck"}, method = RequestMethod.GET, produces = "application/json") - public String healthCheck() throws Exception { + public ResponseEntity<String> healthCheck() throws Exception { - logger.info("health check called."); + logger.info("healthCheck called."); + return cnfAdapterService.healthCheck(); + + } + + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/instance"}, method = RequestMethod.POST, + produces = "application/json", consumes = "application/json") + public ResponseEntity<InstanceResponse> createInstance(@RequestBody BpmnInstanceRequest bpmnInstanceRequest) + throws JsonParseException, JsonMappingException, IOException { + + logger.info("createInstance called."); + return cnfAdapterService.createInstance(bpmnInstanceRequest); + } + + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/instance/{instID}"}, method = RequestMethod.GET, + produces = "application/json") + public ResponseEntity<InstanceResponse> getInstanceByInstanceId(@PathVariable("instID") String instanceId) + throws JsonParseException, JsonMappingException, IOException { + + logger.info("getInstanceByInstanceId called."); + + return cnfAdapterService.getInstanceByInstanceId(instanceId); - // TODO - HttpGet req = new HttpGet("https://localhost:32780/api/multicloud-k8s/v1/healthcheck"); - try (CloseableHttpResponse response = httpClient.execute(req)) { - logger.info("response:" + response.getEntity()); - return EntityUtils.toString(response.getEntity()); - } } @ResponseBody - @RequestMapping(value = {"/api/multicloud-k8s/v1/v1/rb/definition"}, method = RequestMethod.POST, + @RequestMapping(value = {"/api/cnf-adapter/v1/instance/{instID}/status"}, method = RequestMethod.GET, + produces = "application/json") + public ResponseEntity<InstanceStatusResponse> getInstanceStatusByInstanceId( + @PathVariable("instID") String instanceId) throws JsonParseException, JsonMappingException, IOException { + + logger.info("getInstanceStatusByInstanceId called."); + + return cnfAdapterService.getInstanceStatusByInstanceId(instanceId); + + } + + @RequestMapping(value = {"/api/cnf-adapter/v1/instance"}, method = RequestMethod.GET, produces = "application/json") + public ResponseEntity<InstanceMiniResponseList> getInstanceByRBNameOrRBVersionOrProfileName( + @RequestParam(value = "rb-name", required = false) String rbName, + @RequestParam(value = "rb-version", required = false) String rbVersion, + @RequestParam(value = "profile-name", required = false) String profileName) + throws JsonParseException, JsonMappingException, IOException { + + logger.info("getInstanceByRBNameOrRBVersionOrProfileName called."); + return cnfAdapterService.getInstanceByRBNameOrRBVersionOrProfileName(rbName, rbVersion, profileName); + + } + + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/instance/{instID}"}, method = RequestMethod.DELETE, + produces = "application/json") + public ResponseEntity<String> deleteInstanceByInstanceId(@PathVariable("instID") String instanceID) + throws JsonParseException, JsonMappingException, IOException { + + logger.info("deleteInstanceByInstanceId called."); + return cnfAdapterService.deleteInstanceByInstanceId(instanceID); + + } + + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition"}, method = RequestMethod.POST, produces = "application/json") public String createRB(@RequestBody ResourceBundleEntity rB) throws Exception { @@ -55,7 +150,7 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpPost post = new HttpPost("https://localhost:32780/api/multicloud-k8s/v1/v1/rb/definition"); + HttpPost post = new HttpPost("http://multicloud-k8s:9015/v1/rb/definition"); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); String requestBody = objectMapper.writeValueAsString(rB); @@ -70,8 +165,8 @@ public class CnfAdapterRest { } @ResponseBody - @RequestMapping(value = {"/api/multicloud-k8s/v1/v1/rb/definition/{rb-name}/{rb-version}"}, - method = RequestMethod.GET, produces = "application/json") + @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}"}, method = RequestMethod.GET, + produces = "application/json") public String getRB(@PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion) throws Exception { @@ -79,16 +174,101 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpGet req = new HttpGet( - "https://localhost:32780/api/multicloud-k8s/v1/v1/rb/definition/" + rbName + "/" + rbVersion); + HttpGet req = new HttpGet("http://multicloud-k8s:9015/v1/rb/definition/" + rbName + "/" + rbVersion); + try (CloseableHttpResponse response = httpClient.execute(req)) { + logger.info("response:" + response.getEntity()); + return EntityUtils.toString(response.getEntity()); + } + } + + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}"}, method = RequestMethod.DELETE, + produces = "application/json") + public String deleteRB(@PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion) + throws Exception { + + logger.info("delete RB called."); + + // TODO + // Below URL should be changed as appropriate multicloud URL. + HttpDelete req = new HttpDelete("http://multicloud-k8s:9015/v1/rb/definition/" + rbName + "/" + rbVersion); + + try (CloseableHttpResponse response = httpClient.execute(req)) { + logger.info("response:" + response.getEntity()); + return EntityUtils.toString(response.getEntity()); + } + + } + + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}"}, method = RequestMethod.GET, + produces = "application/json") + public String getListOfRB(@PathVariable("rb-name") String rbName) throws Exception { + + logger.info("getListOfRB called."); + + // TODO + // Below URL should be changed as appropriate multicloud URL. + HttpGet req = new HttpGet("http://multicloud-k8s:9015/v1/rb/definition/" + rbName); + + try (CloseableHttpResponse response = httpClient.execute(req)) { + logger.info("response:" + response.getEntity()); + return EntityUtils.toString(response.getEntity()); + } + + } + + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition"}, method = RequestMethod.GET, + produces = "application/json") + public String getListOfRBWithoutUsingRBName() throws Exception { + + logger.info("getListOfRBWithoutUsingRBName called."); + + // TODO + // Below URL should be changed as appropriate multicloud URL. + HttpGet req = new HttpGet("http://multicloud-k8s:9015/v1/rb/definition"); + try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } + } @ResponseBody - @RequestMapping(value = {"/api/multicloud-k8s/v1/v1/rb/definition/{rb-name}/{rb-version}/profile"}, + @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/content"}, + method = RequestMethod.POST, produces = "multipart/form-data") + public String uploadArtifactForRB(@RequestParam("file") MultipartFile file, @PathVariable("rb-name") String rbName, + @PathVariable("rb-version") String rbVersion) throws Exception { + + logger.info("Upload Artifact For RB called."); + + File convFile = new File(file.getOriginalFilename()); + file.transferTo(convFile); + FileBody fileBody = new FileBody(convFile, ContentType.DEFAULT_BINARY); + MultipartEntityBuilder builder = MultipartEntityBuilder.create(); + builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); + builder.addPart("file", fileBody); + HttpEntity entity = builder.build(); + + // TODO + // Below URL should be changed as appropriate multicloud URL. + HttpPost post = + new HttpPost("http://multicloud-k8s:9015/v1/rb/definition/" + rbName + "/" + rbVersion + "/content"); + post.setHeader("Content-Type", "multipart/form-data"); + logger.info(String.valueOf(post)); + post.setEntity(entity); + + try (CloseableHttpClient httpClient = HttpClients.createDefault(); + CloseableHttpResponse response = httpClient.execute(post)) { + logger.info("response:" + response.getEntity()); + return EntityUtils.toString(response.getEntity()); + } + } + + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/profile"}, method = RequestMethod.POST, produces = "application/json") public String createProfile(@RequestBody ProfileEntity fE, @PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion) throws Exception { @@ -97,8 +277,8 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpPost post = new HttpPost("http://localhost:32780/api/multicloud-k8s/v1/v1/rb/definition/" + rbName + "/" - + rbVersion + "/profile"); + HttpPost post = + new HttpPost("http://multicloud-k8s:9015/v1/rb/definition/" + rbName + "/" + rbVersion + "/profile"); ObjectMapper objectMapper = new ObjectMapper(); String requestBody = objectMapper.writeValueAsString(fE); StringEntity requestEntity = new StringEntity(requestBody, ContentType.APPLICATION_JSON); @@ -112,7 +292,7 @@ public class CnfAdapterRest { } @ResponseBody - @RequestMapping(value = {"/api/multicloud-k8s/v1/v1/rb/definition/{rb-name}/{rb-version}/profile/{pr-name}"}, + @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/profile/{pr-name}"}, method = RequestMethod.GET, produces = "application/json") public String getProfile(@PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, @PathVariable("pr-name") String prName) throws Exception { @@ -121,8 +301,8 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpGet req = new HttpGet("https://localhost:32780/api/multicloud-k8s/v1/v1/rb/definition/" + rbName + "/" - + rbVersion + "/profile/" + prName); + HttpGet req = new HttpGet( + "http://multicloud-k8s:9015/v1/rb/definition/" + rbName + "/" + rbVersion + "/profile/" + prName); try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); @@ -131,48 +311,79 @@ public class CnfAdapterRest { } @ResponseBody - @RequestMapping(value = {"/api/multicloud-k8s/v1/v1/instance"}, method = RequestMethod.POST, - produces = "application/json") - public String createInstance(@RequestBody InstanceEntity iE) throws Exception { + @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/profile"}, + method = RequestMethod.GET, produces = "application/json") + public String getListOfProfile(@PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion) + throws Exception { - logger.info("create Instance called."); + logger.info("getListOfProfile called."); // TODO // Below URL should be changed as appropriate multicloud URL. - HttpPost post = new HttpPost("https://localhost:32780/api/multicloud-k8s/v1/v1/instance"); - ObjectMapper objectMapper = new ObjectMapper(); + HttpGet req = + new HttpGet("http://multicloud-k8s:9015/v1/rb/definition/" + rbName + "/" + rbVersion + "/profile"); - objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - String requestBody = objectMapper.writeValueAsString(iE); - StringEntity requestEntity = new StringEntity(requestBody, ContentType.APPLICATION_JSON); - post.setEntity(requestEntity); - - try (CloseableHttpClient httpClient = HttpClients.createDefault(); - CloseableHttpResponse response = httpClient.execute(post)) { + try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } } @ResponseBody - @RequestMapping(value = {"/api/multicloud-k8s/v1/v1/instance/{instID}"}, method = RequestMethod.GET, - produces = "application/json") - public String getInstance(@PathVariable("instID") String instanceId) throws Exception { + @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/profile/{pr-name}"}, + method = RequestMethod.DELETE, produces = "application/json") + public String deleteProfile(@PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, + @PathVariable("pr-name") String prName) throws Exception { + + logger.info("delete Profile called."); - logger.info("get Instance called."); // TODO // Below URL should be changed as appropriate multicloud URL. - HttpGet req = new HttpGet("https://localhost:32780/api/multicloud-k8s/v1/v1/instance/" + instanceId); + HttpDelete req = new HttpDelete( + "http://multicloud-k8s:9015/v1/rb/definition/" + rbName + "/" + rbVersion + "/profile/" + prName); try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } + } @ResponseBody - @RequestMapping( - value = {"/api/multicloud-k8s/v1/v1/definition/{rb-name}/{rb-version}/profile/{profile-name}/config"}, + @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/profile/{pr-name}/content"}, + method = RequestMethod.POST, produces = "multipart/form-data") + public String uploadArtifactForProfile(@RequestParam("file") MultipartFile file, + @PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, + @PathVariable("pr-name") String prName) throws Exception { + + logger.info("Upload Artifact For Profile called."); + + File convFile = new File(file.getOriginalFilename()); + file.transferTo(convFile); + FileBody fileBody = new FileBody(convFile, ContentType.DEFAULT_BINARY); + MultipartEntityBuilder builder = MultipartEntityBuilder.create(); + builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); + builder.addPart("file", fileBody); + HttpEntity entity = builder.build(); + + // TODO + // Below URL should be changed as appropriate multicloud URL. + HttpPost post = new HttpPost("http://multicloud-k8s:9015/v1/rb/definition/" + rbName + "/" + rbVersion + + "/profile/" + prName + "/content"); + post.setHeader("Content-Type", "multipart/form-data"); + + logger.info(String.valueOf(post)); + post.setEntity(entity); + + try (CloseableHttpClient httpClient = HttpClients.createDefault(); + CloseableHttpResponse response = httpClient.execute(post)) { + logger.info("response:" + response.getEntity()); + return EntityUtils.toString(response.getEntity()); + } + } + + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/definition/{rb-name}/{rb-version}/profile/{profile-name}/config"}, method = RequestMethod.POST, produces = "application/json") public String createConfiguration(@RequestBody ConfigurationEntity cE, @PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, @PathVariable("profile-name") String prName) @@ -182,8 +393,8 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpPost post = new HttpPost("https://localhost:32780/api/multicloud-k8s/v1/v1/definition/" + rbName + "/" - + rbVersion + "/profile/" + prName + "/config"); + HttpPost post = new HttpPost("http://multicloud-k8s:9015/v1/definition/" + rbName + "/" + rbVersion + + "/profile/" + prName + "/config"); ObjectMapper objectMapper = new ObjectMapper(); String requestBody = objectMapper.writeValueAsString(cE); StringEntity requestEntity = new StringEntity(requestBody, ContentType.APPLICATION_JSON); @@ -197,8 +408,8 @@ public class CnfAdapterRest { } @ResponseBody - @RequestMapping(value = { - "/api/multicloud-k8s/v1/v1/definition/{rb-name}/{rb-version}/profile/{profile-name}/config/{cfg-name}"}, + @RequestMapping( + value = {"/api/cnf-adapter/v1/definition/{rb-name}/{rb-version}/profile/{profile-name}/config/{cfg-name}"}, method = RequestMethod.GET, produces = "application/json") public String getConfiguration(@PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, @PathVariable("profile-name") String prName, @PathVariable("cfg-name") String cfgName) throws Exception { @@ -207,17 +418,89 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpGet req = new HttpGet("https://localhost:32780/api/multicloud-k8s/v1/v1/definition/" + rbName + "/" - + rbVersion + "/profile/" + prName + "/config/" + cfgName); + HttpGet req = new HttpGet("http://multicloud-k8s:9015/v1/definition/" + rbName + "/" + rbVersion + "/profile/" + + prName + "/config/" + cfgName); + + try (CloseableHttpResponse response = httpClient.execute(req)) { + logger.info("response:" + response.getEntity()); + return EntityUtils.toString(response.getEntity()); + } + } + + @ResponseBody + @RequestMapping( + value = {"/api/cnf-adapter/v1/definition/{rb-name}/{rb-version}/profile/{profile-name}/config/{cfg-name}"}, + method = RequestMethod.DELETE, produces = "application/json") + public String deleteConfiguration(@PathVariable("rb-name") String rbName, + @PathVariable("rb-version") String rbVersion, @PathVariable("profile-name") String prName, + @PathVariable("cfg-name") String cfgName) throws Exception { + + logger.info("delete Configuration called."); + + // TODO + // Below URL should be changed as appropriate multicloud URL. + HttpDelete req = new HttpDelete("http://multicloud-k8s:9015/v1/definition/" + rbName + "/" + rbVersion + + "/profile/" + prName + "/config/" + cfgName); try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } + + } + + @ResponseBody + @RequestMapping( + value = {"/api/cnf-adapter/v1/definition/{rb-name}/{rb-version}/profile/{profile-name}/config/{cfg-name}"}, + method = RequestMethod.PUT, produces = "application/json") + public String updateConfiguration(@RequestBody ConfigurationEntity cE, @PathVariable("rb-name") String rbName, + @PathVariable("rb-version") String rbVersion, @PathVariable("profile-name") String prName, + @PathVariable("cfg-name") String cfgName) throws Exception { + + logger.info("update Configuration called."); + + // TODO + // Below URL should be changed as appropriate multicloud URL. + HttpPut post = new HttpPut("http://multicloud-k8s:9015/v1/definition/" + rbName + "/" + rbVersion + "/profile/" + + prName + "/config/" + cfgName); + ObjectMapper objectMapper = new ObjectMapper(); + String requestBody = objectMapper.writeValueAsString(cE); + StringEntity requestEntity = new StringEntity(requestBody, ContentType.APPLICATION_JSON); + post.setEntity(requestEntity); + + try (CloseableHttpClient httpClient = HttpClients.createDefault(); + CloseableHttpResponse response = httpClient.execute(post)) { + logger.info("response:" + response.getEntity()); + return EntityUtils.toString(response.getEntity()); + } + } + + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/definition/{rb-name}/{rb-version}/profile/{profile-name}/tagit"}, + method = RequestMethod.POST, produces = "application/json") + public String tagConfigurationValue(@RequestBody Tag tag, @PathVariable("rb-name") String rbName, + @PathVariable("rb-version") String rbVersion, @PathVariable("pr-name") String prName) throws Exception { + logger.info("Tag Configuration called."); + + // TODO + // Below URL should be changed as appropriate multicloud URL. + HttpPost post = new HttpPost("http://multicloud-k8s:9015/v1/definition/" + rbName + "/" + rbVersion + + "/profile/" + prName + "/config/tagit"); + + ObjectMapper objectMapper = new ObjectMapper(); + String requestBody = objectMapper.writeValueAsString(tag); + StringEntity requestEntity = new StringEntity(requestBody, ContentType.APPLICATION_JSON); + post.setEntity(requestEntity); + + try (CloseableHttpClient httpClient = HttpClients.createDefault(); + CloseableHttpResponse response = httpClient.execute(post)) { + logger.info("response:" + response.getEntity()); + return EntityUtils.toString(response.getEntity()); + } } @ResponseBody - @RequestMapping(value = {"/api/multicloud-k8s/v1/v1/connectivity-info"}, method = RequestMethod.POST, + @RequestMapping(value = {"/api/cnf-adapter/v1/connectivity-info"}, method = RequestMethod.POST, produces = "application/json") public String createConnectivityInfo(@RequestBody ConnectivityInfo cIE) throws Exception { @@ -225,7 +508,7 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpPost post = new HttpPost("https://localhost:32780/api/multicloud-k8s/v1/v1/connectivity-info"); + HttpPost post = new HttpPost("http://multicloud-k8s:9015/v1/connectivity-info"); ObjectMapper objectMapper = new ObjectMapper(); String requestBody = objectMapper.writeValueAsString(cIE); StringEntity requestEntity = new StringEntity(requestBody, ContentType.APPLICATION_JSON); @@ -239,7 +522,7 @@ public class CnfAdapterRest { } @ResponseBody - @RequestMapping(value = {"/api/multicloud-k8s/v1/v1/connectivity-info/{connname}"}, method = RequestMethod.GET, + @RequestMapping(value = {"/api/cnf-adapter/v1/connectivity-info/{connname}"}, method = RequestMethod.GET, produces = "application/json") public String getConnectivityInfo(@PathVariable("connname") String connName) throws Exception { @@ -247,16 +530,34 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpGet req = new HttpGet("https://localhost:32780/api/multicloud-k8s/v1/v1/connectivity-info/" + connName); + HttpGet req = new HttpGet("http://multicloud-k8s:9015/v1/connectivity-info/" + connName); + + try (CloseableHttpResponse response = httpClient.execute(req)) { + logger.info("response:" + response.getEntity()); + return EntityUtils.toString(response.getEntity()); + } + } + + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/connectivity-info/{connname}"}, method = RequestMethod.DELETE, + produces = "application/json") + public String deleteConnectivityInfo(@PathVariable("connname") String connName) throws Exception { + + logger.info("delete Connectivity Info called."); + + // TODO + // Below URL should be changed as appropriate multicloud URL. + HttpDelete req = new HttpDelete("http://multicloud-k8s:9015/v1/connectivity-info/" + connName); try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } + } @ResponseBody - @RequestMapping(value = {"/api/multicloud-k8s/v1/v1/rb/definition/{rb-name}/{rb-version}/config-template"}, + @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/config-template"}, method = RequestMethod.POST, produces = "application/json") public String createConfigTemplate(@RequestBody ConfigTemplateEntity tE, @PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion) throws Exception { @@ -265,8 +566,8 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpPost post = new HttpPost("http://localhost:32780/api/multicloud-k8s/v1/v1/rb/definition/" + rbName + "/" - + rbVersion + "/config-template"); + HttpPost post = new HttpPost( + "http://multicloud-k8s:9015/v1/rb/definition/" + rbName + "/" + rbVersion + "/config-template"); ObjectMapper objectMapper = new ObjectMapper(); String requestBody = objectMapper.writeValueAsString(tE); StringEntity requestEntity = new StringEntity(requestBody, ContentType.APPLICATION_JSON); @@ -280,7 +581,7 @@ public class CnfAdapterRest { } @ResponseBody - @RequestMapping(value = {"/api/multicloud-k8s/v1/v1/rb/definition/{rb-name}/{rb-version}/config-template/{tname}"}, + @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/config-template/{tname}"}, method = RequestMethod.GET, produces = "application/json") public String getConfigTemplate(@PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, @PathVariable("tname") String tName) throws Exception { @@ -289,8 +590,8 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpGet req = new HttpGet("https://localhost:32780/api/multicloud-k8s/v1/v1/rb/definition/" + rbName + "/" - + rbVersion + "/config-template/" + tName); + HttpGet req = new HttpGet("http://multicloud-k8s:9015/v1/rb/definition/" + rbName + "/" + rbVersion + + "/config-template/" + tName); try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); @@ -298,4 +599,83 @@ public class CnfAdapterRest { } } + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/config-template/{tname}"}, + method = RequestMethod.DELETE, produces = "application/json") + public String deleteTemplate(@PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, + @PathVariable("tname") String tName) throws Exception { + + logger.info("deleteTemplate called."); + + // TODO + // Below URL should be changed as appropriate multicloud URL. + HttpDelete req = new HttpDelete("http://multicloud-k8s:9015/v1/rb/definition/" + rbName + "/" + rbVersion + + "/config-template/" + tName); + + try (CloseableHttpResponse response = httpClient.execute(req)) { + logger.info("response:" + response.getEntity()); + return EntityUtils.toString(response.getEntity()); + } + + } + + @ResponseBody + @RequestMapping( + value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/config-template/{tname}/content"}, + method = RequestMethod.POST, produces = "multipart/form-data") + public String uploadTarFileForTemplate(@RequestParam("file") MultipartFile file, + @PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, + @PathVariable("tname") String tName) throws Exception { + + logger.info("uploadTarFileForTemplate called."); + + File convFile = new File(file.getOriginalFilename()); + file.transferTo(convFile); + FileBody fileBody = new FileBody(convFile, ContentType.DEFAULT_BINARY); + MultipartEntityBuilder builder = MultipartEntityBuilder.create(); + builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); + builder.addPart("file", fileBody); + HttpEntity entity = builder.build(); + + // TODO + // Below URL should be changed as appropriate multicloud URL. + HttpPost post = new HttpPost("http://multicloud-k8s:9015/v1/rb/definition/" + rbName + "/" + rbVersion + + "/config-template/" + tName + "/content"); + post.setHeader("Content-Type", "multipart/form-data"); + + logger.info(String.valueOf(post)); + post.setEntity(entity); + + try (CloseableHttpClient httpClient = HttpClients.createDefault(); + CloseableHttpResponse response = httpClient.execute(post)) { + logger.info("response:" + response.getEntity()); + return EntityUtils.toString(response.getEntity()); + } + } + + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/definition/{rbName}/{rbVersion}/profile/{prName}/config/rollback"}, + method = RequestMethod.DELETE, produces = "application/json") + public String rollbackConfiguration(@RequestBody ConfigurationRollbackEntity rE, + @PathVariable("rbName") String rbName, @PathVariable("rbVersion") String rbVersion, + @PathVariable("prName") String prName) throws Exception { + logger.info("rollbackConfiguration called."); + + // TODO + // Below URL should be changed as appropriate multicloud URL. + HttpPost post = new HttpPost("http://multicloud-k8s:9015/v1/definition/" + rbName + "/" + rbVersion + + "/profile/" + prName + "/config/rollback"); + + ObjectMapper objectMapper = new ObjectMapper(); + String requestBody = objectMapper.writeValueAsString(rE); + StringEntity requestEntity = new StringEntity(requestBody, ContentType.APPLICATION_JSON); + post.setEntity(requestEntity); + + try (CloseableHttpClient httpClient = HttpClients.createDefault(); + CloseableHttpResponse response = httpClient.execute(post)) { + logger.info("response:" + response.getEntity()); + return EntityUtils.toString(response.getEntity()); + } + } + } diff --git a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/service/CnfAdapterService.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/service/CnfAdapterService.java new file mode 100644 index 0000000000..06c09e3431 --- /dev/null +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/service/CnfAdapterService.java @@ -0,0 +1,269 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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.adapters.cnf.service; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import javax.persistence.EntityNotFoundException; +import javax.ws.rs.core.UriBuilder; +import org.apache.http.HttpStatus; +import org.onap.so.adapters.cnf.model.BpmnInstanceRequest; +import org.onap.so.adapters.cnf.model.InstanceMiniResponse; +import org.onap.so.adapters.cnf.model.InstanceMiniResponseList; +import org.onap.so.adapters.cnf.model.InstanceResponse; +import org.onap.so.adapters.cnf.model.InstanceStatusResponse; +import org.onap.so.adapters.cnf.model.MulticloudInstanceRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpStatusCodeException; +import org.springframework.web.client.RestTemplate; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + +@Service +public class CnfAdapterService { + private static final Logger logger = LoggerFactory.getLogger(CnfAdapterService.class); + @Autowired + private RestTemplate restTemplate; + private static final String INSTANCE_CREATE_PATH = "/v1/instance"; + private static final String HEALTH_CHECK = "/v1/healthcheck"; + + public ResponseEntity<String> healthCheck() { + + logger.info("CnfAdapterService createInstance called"); + ResponseEntity<String> result = null; + try { + + logger.info("CnfAdapterService createInstance called"); + + // String uri = env.getRequiredProperty("multicloud.endpoint"); //TODO: + // This needs to be added as well + // for configuration + String uri = "http://multicloud-k8s:9015"; // TODO: What is the correct uri? + String endpoint = UriBuilder.fromUri(uri).path(HEALTH_CHECK).build().toString(); + HttpEntity<?> requestEntity = new HttpEntity<>(getHttpHeaders()); + result = restTemplate.exchange(endpoint, HttpMethod.GET, requestEntity, String.class); + return result; + } catch (HttpClientErrorException e) { + logger.error("Error Calling Multicloud, e"); + if (HttpStatus.SC_NOT_FOUND == e.getStatusCode().value()) { + throw new EntityNotFoundException(e.getResponseBodyAsString()); + } + throw e; + } catch (HttpStatusCodeException e) { + logger.error("Error in Multicloud, e"); + String responseString = e.getResponseBodyAsString(); + return ResponseEntity.status(e.getStatusCode()).body(responseString); + } + } + + public ResponseEntity<InstanceResponse> createInstance(BpmnInstanceRequest bpmnInstanceRequest) + throws JsonParseException, JsonMappingException, IOException { + try { + logger.info("CnfAdapterService createInstance called"); + MulticloudInstanceRequest multicloudInstanceRequest = new MulticloudInstanceRequest(); + ResponseEntity<InstanceResponse> instanceResponse = null; + if (bpmnInstanceRequest.getK8sRBProfileName() != null) { + multicloudInstanceRequest.setCloudRegion(bpmnInstanceRequest.getCloudRegionId()); + multicloudInstanceRequest.setLabels(bpmnInstanceRequest.getLabels()); + multicloudInstanceRequest.setOverrideValues(bpmnInstanceRequest.getOverrideValues()); + multicloudInstanceRequest.setProfileName(bpmnInstanceRequest.getK8sRBProfileName()); + multicloudInstanceRequest.setRbName(bpmnInstanceRequest.getModelInvariantId()); + multicloudInstanceRequest.setRbVersion(bpmnInstanceRequest.getModelVersionId()); + multicloudInstanceRequest.setVfModuleUuid(bpmnInstanceRequest.getVfModuleUUID()); + } else { + logger.error("k8sProfileName should not be null"); + return instanceResponse; + } + // String uri = env.getRequiredProperty("multicloud.endpoint"); //TODO: + // This needs to be added as well + // for configuration + String uri = "http://multicloud-k8s:9015"; // TODO: What is the correct uri? + String endpoint = UriBuilder.fromUri(uri).path(INSTANCE_CREATE_PATH).build().toString(); + HttpEntity<?> entity = getHttpEntity(multicloudInstanceRequest); + instanceResponse = restTemplate.exchange(endpoint, HttpMethod.POST, entity, InstanceResponse.class); + return instanceResponse; + } catch (HttpClientErrorException e) { + logger.error("Error Calling Multicloud, e"); + if (HttpStatus.SC_NOT_FOUND == e.getStatusCode().value()) { + throw new EntityNotFoundException(e.getResponseBodyAsString()); + } + throw e; + } catch (HttpStatusCodeException e) { + logger.error("Error in Multicloud, e"); + String responseString = e.getResponseBodyAsString(); + InstanceResponse result = new InstanceResponse(responseString.trim()); + return ResponseEntity.status(e.getStatusCode()).body(result); + } + } + + public ResponseEntity<InstanceResponse> getInstanceByInstanceId(String instanceId) + throws JsonParseException, JsonMappingException, IOException { + + logger.info("CnfAdapterService createInstance called"); + ResponseEntity<InstanceResponse> instanceResponse = null; + try { + + // String uri = env.getRequiredProperty("multicloud.endpoint"); //TODO: + // This needs to be added as well + // for configuration + String uri = "http://multicloud-k8s:9015"; // TODO: What is the correct uri? + String path = "/v1/instance/" + instanceId; + String endpoint = UriBuilder.fromUri(uri).path(path).build().toString(); + HttpEntity<?> requestEntity = new HttpEntity<>(getHttpHeaders()); + instanceResponse = restTemplate.exchange(endpoint, HttpMethod.GET, requestEntity, InstanceResponse.class); + return instanceResponse; + } catch (HttpClientErrorException e) { + logger.error("Error Calling Multicloud, e"); + if (HttpStatus.SC_NOT_FOUND == e.getStatusCode().value()) { + throw new EntityNotFoundException(e.getResponseBodyAsString()); + } + throw e; + } catch (HttpStatusCodeException e) { + logger.error("Error in Multicloud, e"); + String responseString = e.getResponseBodyAsString(); + InstanceResponse result = new InstanceResponse(responseString.trim()); + return ResponseEntity.status(e.getStatusCode()).body(result); + } + } + + public ResponseEntity<InstanceStatusResponse> getInstanceStatusByInstanceId(String instanceId) + throws JsonParseException, JsonMappingException, IOException { + + logger.info("CnfAdapterService createInstance called"); + ResponseEntity<InstanceStatusResponse> instanceResponse = null; + try { + + // String uri = env.getRequiredProperty("multicloud.endpoint"); //TODO: + // This needs to be added as well + // for configuration + String uri = "http://multicloud-k8s:9015"; // TODO: What is the correct uri? + String path = "/v1/instance/" + instanceId + "/status"; + String endpoint = UriBuilder.fromUri(uri).path(path).build().toString(); + HttpEntity<?> requestEntity = new HttpEntity<>(getHttpHeaders()); + instanceResponse = + restTemplate.exchange(endpoint, HttpMethod.GET, requestEntity, InstanceStatusResponse.class); + return instanceResponse; + } catch (HttpClientErrorException e) { + logger.error("Error Calling Multicloud, e"); + if (HttpStatus.SC_NOT_FOUND == e.getStatusCode().value()) { + throw new EntityNotFoundException(e.getResponseBodyAsString()); + } + throw e; + } catch (HttpStatusCodeException e) { + logger.error("Error in Multicloud, e"); + String responseString = e.getResponseBodyAsString(); + InstanceStatusResponse result = new InstanceStatusResponse(responseString.trim()); + return ResponseEntity.status(e.getStatusCode()).body(result); + } + + } + + public ResponseEntity<InstanceMiniResponseList> getInstanceByRBNameOrRBVersionOrProfileName(String rbName, + String rbVersion, String profileName) throws JsonParseException, JsonMappingException, IOException { + + logger.info("CnfAdapterService createInstance called"); + ResponseEntity<InstanceMiniResponseList> instanceMiniResponseList = null; + try { + + // String uri = env.getRequiredProperty("multicloud.endpoint"); //TODO: + // This needs to be added as well + // for configuration + String uri = "http://multicloud-k8s:9015"; // TODO: What is the correct uri? + String path = + "/v1/instance" + "?rb-name=" + rbName + "&rb-version=" + rbVersion + "&profile-name=" + profileName; + String endPoint = uri + path; + HttpEntity<?> requestEntity = new HttpEntity<>(getHttpHeaders()); + instanceMiniResponseList = + restTemplate.exchange(endPoint, HttpMethod.GET, requestEntity, InstanceMiniResponseList.class); + return instanceMiniResponseList; + } catch (HttpClientErrorException e) { + logger.error("Error Calling Multicloud, e"); + if (HttpStatus.SC_NOT_FOUND == e.getStatusCode().value()) { + throw new EntityNotFoundException(e.getResponseBodyAsString()); + } + throw e; + } catch (HttpStatusCodeException e) { + logger.error("Error in Multicloud, e"); + String responseString = e.getResponseBodyAsString(); + InstanceMiniResponseList result = new InstanceMiniResponseList(responseString.trim()); + return ResponseEntity.status(e.getStatusCode()).body(result); + } + } + + public ResponseEntity<String> deleteInstanceByInstanceId(String instanceId) + throws JsonParseException, JsonMappingException, IOException { + + logger.info("CnfAdapterService createInstance called"); + ResponseEntity<String> result = null; + try { + + // String uri = env.getRequiredProperty("multicloud.endpoint"); //TODO: + // This needs to be added as well + // for configuration + String uri = "http://multicloud-k8s:9015"; // TODO: What is the correct uri? + String path = "/v1/instance/" + instanceId; + String endpoint = UriBuilder.fromUri(uri).path(path).build().toString(); + HttpEntity<?> requestEntity = new HttpEntity<>(getHttpHeaders()); + result = restTemplate.exchange(endpoint, HttpMethod.DELETE, requestEntity, String.class); + return result; + } catch (HttpClientErrorException e) { + logger.error("Error Calling Multicloud, e"); + if (HttpStatus.SC_NOT_FOUND == e.getStatusCode().value()) { + throw new EntityNotFoundException(e.getResponseBodyAsString()); + } + throw e; + } catch (HttpStatusCodeException e) { + logger.error("Error in Multicloud, e"); + String responseString = e.getResponseBodyAsString(); + return ResponseEntity.status(e.getStatusCode()).body(responseString); + } + } + + protected HttpHeaders getHttpHeaders() { + HttpHeaders headers = new HttpHeaders(); + List<MediaType> acceptableMediaTypes = new ArrayList<>(); + acceptableMediaTypes.add(MediaType.APPLICATION_JSON); + headers.setAccept(acceptableMediaTypes); + headers.setContentType(MediaType.APPLICATION_JSON); + /* + * try { String userCredentials = CryptoUtils.decrypt(env.getRequiredProperty("mso.cnf.adapter.auth"), + * env.getRequiredProperty("mso.msoKey")); if (userCredentials != null) { headers.add(HttpHeaders.AUTHORIZATION, + * "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes())); } } catch + * (GeneralSecurityException e) { logger.error("Security exception", e); } + */ + return headers; + } + + protected HttpEntity<?> getHttpEntity(MulticloudInstanceRequest request) { + HttpHeaders headers = getHttpHeaders(); + return new HttpEntity<>(request, headers); + } +} diff --git a/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/util/CNfAdapterUtil.java b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/util/CNfAdapterUtil.java new file mode 100644 index 0000000000..25e506c55e --- /dev/null +++ b/adapters/mso-cnf-adapter/src/main/java/org/onap/so/adapters/cnf/util/CNfAdapterUtil.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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.adapters.cnf.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import org.onap.so.adapters.cnf.exceptions.ApplicationException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.onap.logging.filter.base.ErrorCode; +import static org.onap.so.logger.LoggingAnchor.THREE; +import static org.onap.so.logger.MessageEnum.RA_NS_EXC; + +public class CNfAdapterUtil { + + private static final Logger LOGGER = LoggerFactory.getLogger(CNfAdapterUtil.class); + + public static final int BAD_REQUEST = 400; + + private static final String UNMARSHAL_FAIL_MSG = "Failed to unmarshal json"; + + private static final String MARSHAL_FAIL_MSG = "Failed to marshal object"; + + private static final ObjectMapper MAPPER = new ObjectMapper(); + + public static class StatusDesc { + + public static final String ALLOCATE_NSS_SUCCESS = "Allocating nss is " + "successful"; + + public static final String CREATE_NSS_SUCCESS = "Creating nss is " + "successful"; + + public static final String DEALLOCATE_NSS_SUCCESS = "Deallocate nss " + "is successful"; + + public static final String ACTIVATE_NSS_SUCCESS = "Activate nss " + "is successful"; + + public static final String DEACTIVATE_NSS_SUCCESS = "Deactivate nss " + "is successful"; + + public static final String QUERY_JOB_STATUS_FAILED = "Query job " + "status failed"; + + public static final String QUERY_JOB_STATUS_SUCCESS = "Query job " + "status is successful"; + + private StatusDesc() { + + } + } + + private CNfAdapterUtil() { + + } + + public static void assertObjectNotNull(Object object) throws ApplicationException { + if (null == object) { + LOGGER.error("Object is null."); + throw new ApplicationException(BAD_REQUEST, "An object is null."); + } + } + + public static <T> T unMarshal(String jsonstr, Class<T> type) throws ApplicationException { + try { + return MAPPER.readValue(jsonstr, type); + } catch (IOException e) { + LOGGER.error(THREE, RA_NS_EXC.toString(), ErrorCode.BusinessProcessError.getValue(), UNMARSHAL_FAIL_MSG, e); + throw new ApplicationException(BAD_REQUEST, UNMARSHAL_FAIL_MSG); + } + } + + public static String marshal(Object srcObj) throws ApplicationException { + try { + return MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(srcObj); + } catch (IOException e) { + LOGGER.error(THREE, RA_NS_EXC.toString(), ErrorCode.BusinessProcessError.getValue(), MARSHAL_FAIL_MSG, e); + throw new ApplicationException(BAD_REQUEST, MARSHAL_FAIL_MSG); + } + } + +} diff --git a/adapters/mso-cnf-adapter/src/main/resources/META-INF/services/org.onap.so.client.RestProperties b/adapters/mso-cnf-adapter/src/main/resources/META-INF/services/org.onap.so.client.RestProperties index f93ec63f37..bccd43aea7 100644 --- a/adapters/mso-cnf-adapter/src/main/resources/META-INF/services/org.onap.so.client.RestProperties +++ b/adapters/mso-cnf-adapter/src/main/resources/META-INF/services/org.onap.so.client.RestProperties @@ -1 +1 @@ -org.onap.so.adapters.nssmf.extclients.aai.AaiClientPropertiesImpl
\ No newline at end of file +org.onap.so.adapters.cnf.extclients.aai.AaiClientPropertiesImpl
\ No newline at end of file diff --git a/adapters/mso-cnf-adapter/src/main/resources/application.yaml b/adapters/mso-cnf-adapter/src/main/resources/application.yaml index 30b1b626a5..5a9adbfd04 100644 --- a/adapters/mso-cnf-adapter/src/main/resources/application.yaml +++ b/adapters/mso-cnf-adapter/src/main/resources/application.yaml @@ -38,14 +38,14 @@ # naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy # enable-lazy-load-no-trans: true server: - port: 9013 + port: 9012 tomcat: max-threads: 50 #mso: # key: 07a7159d3bf51a0e53be7a8f89699be7 # site-name: localSite -# logPath: ./logs/nssmf +# logPath: ./logs/cnf # msb-ip: msb-iag.{{ include "common.namespace" . }} # msb-port: 80 # adapters: diff --git a/adapters/mso-cnf-adapter/src/test/java/org/onap/so/adapters/cnf/CnfAdapterRestTest.java b/adapters/mso-cnf-adapter/src/test/java/org/onap/so/adapters/cnf/CnfAdapterRestTest.java new file mode 100644 index 0000000000..ee7a771034 --- /dev/null +++ b/adapters/mso-cnf-adapter/src/test/java/org/onap/so/adapters/cnf/CnfAdapterRestTest.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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.adapters.cnf; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.onap.so.adapters.cnf.model.BpmnInstanceRequest; +import org.onap.so.adapters.cnf.rest.CnfAdapterRest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +public class CnfAdapterRestTest { + + @InjectMocks + CnfAdapterRest cnfAdapterRest; + + @Test + public void createInstanceTest() throws Exception { + + Map<String, String> labels = new HashMap<String, String>(); + labels.put("custom-label-1", "label1"); + Map<String, String> overrideValues = new HashMap<String, String>(); + labels.put("image.tag", "latest"); + labels.put("dcae_collector_ip", "1.2.3.4"); + BpmnInstanceRequest bpmnInstanceRequest = new BpmnInstanceRequest(); + bpmnInstanceRequest.setCloudRegionId("v1"); + bpmnInstanceRequest.setLabels(labels); + bpmnInstanceRequest.setModelInvariantId("krd"); + bpmnInstanceRequest.setModelVersionId("p1"); + bpmnInstanceRequest.setOverrideValues(overrideValues); + bpmnInstanceRequest.setVfModuleUUID("20200824"); + + String mockedResponse = "K8sRBProfileName is required"; + String actualResponse = cnfAdapterRest.createInstance(bpmnInstanceRequest); + assertNotNull(actualResponse); + assertEquals(mockedResponse, actualResponse); + } + +} +*/ diff --git a/adapters/mso-cnf-adapter/src/test/java/org/onap/so/adapters/cnf/rest/CnfAdapterRestTest.java b/adapters/mso-cnf-adapter/src/test/java/org/onap/so/adapters/cnf/rest/CnfAdapterRestTest.java new file mode 100644 index 0000000000..df21a4212f --- /dev/null +++ b/adapters/mso-cnf-adapter/src/test/java/org/onap/so/adapters/cnf/rest/CnfAdapterRestTest.java @@ -0,0 +1,161 @@ + +/* + * ============LICENSE_START======================================================= ONAP - SO + * ================================================================================ Copyright (C) 2020 Huawei + * Technologies Co., Ltd. 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.adapters.cnf.rest; + + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.onap.so.adapters.cnf.model.BpmnInstanceRequest; +import org.onap.so.adapters.cnf.model.InstanceMiniResponse; +import org.onap.so.adapters.cnf.model.InstanceMiniResponseList; +import org.onap.so.adapters.cnf.model.InstanceResponse; +import org.onap.so.adapters.cnf.model.InstanceStatusResponse; +import org.onap.so.adapters.cnf.model.MulticloudInstanceRequest; +import org.onap.so.adapters.cnf.model.Resource; +import org.onap.so.adapters.cnf.service.CnfAdapterService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + + +@RunWith(SpringRunner.class) +public class CnfAdapterRestTest { + + @InjectMocks + CnfAdapterRest cnfAdapterRest; + + @Mock + CnfAdapterService cnfAdapterService; + + @Mock + ResponseEntity<InstanceResponse> createInstanceResponse; + + @Mock + ResponseEntity<InstanceMiniResponseList> instacneMiniResponseList; + + @Mock + ResponseEntity<InstanceStatusResponse> instanceStatusResponse; + + @Test + public void healthCheckTest() throws Exception { + + ResponseEntity<String> response = new ResponseEntity<String>(HttpStatus.OK); + CnfAdapterService cnfAdapterService = Mockito.mock(CnfAdapterService.class); + Mockito.when(cnfAdapterService.healthCheck()).thenReturn(response); + cnfAdapterRest.healthCheck(); + Assert.assertNotNull(response); + Assert.assertEquals(HttpStatus.OK, response.getStatusCode()); + } + + @Test + public void createInstanceTest() throws Exception { + + Map<String, String> labels = new HashMap<String, String>(); + labels.put("custom-label-1", "label1"); + Map<String, String> overrideValues = new HashMap<String, String>(); + labels.put("image.tag", "latest"); + labels.put("dcae_collector_ip", "1.2.3.4"); + BpmnInstanceRequest bpmnInstanceRequest = new BpmnInstanceRequest(); + bpmnInstanceRequest.setCloudRegionId("v1"); + bpmnInstanceRequest.setLabels(labels); + bpmnInstanceRequest.setModelInvariantId("krd"); + bpmnInstanceRequest.setModelVersionId("p1"); + bpmnInstanceRequest.setOverrideValues(overrideValues); + bpmnInstanceRequest.setVfModuleUUID("20200824"); + List<Resource> resourceList = new ArrayList<Resource>(); + InstanceResponse instanceResponse = new InstanceResponse(HttpStatus.CREATED.toString()); + instanceResponse.setId("123"); + instanceResponse.setNamespace("testNamespace"); + instanceResponse.setRequest(new MulticloudInstanceRequest()); + instanceResponse.setResources(resourceList); + createInstanceResponse = new ResponseEntity<InstanceResponse>(instanceResponse, HttpStatus.CREATED); + CnfAdapterService cnfAdapterService = Mockito.mock(CnfAdapterService.class); + Mockito.when(cnfAdapterService.createInstance(bpmnInstanceRequest)).thenReturn(createInstanceResponse); + cnfAdapterRest.createInstance(bpmnInstanceRequest); + Assert.assertNotNull(createInstanceResponse); + Assert.assertEquals(HttpStatus.CREATED, createInstanceResponse.getStatusCode()); + } + + @Test + public void getInstanceByInstanceIdTest() throws Exception { + + String instanceId = "123"; + createInstanceResponse = new ResponseEntity<InstanceResponse>(HttpStatus.OK); + CnfAdapterService cnfAdapterService = Mockito.mock(CnfAdapterService.class); + Mockito.when(cnfAdapterService.getInstanceByInstanceId(instanceId)).thenReturn(createInstanceResponse); + cnfAdapterRest.getInstanceByInstanceId(instanceId); + Assert.assertNotNull(createInstanceResponse); + Assert.assertEquals(HttpStatus.OK, createInstanceResponse.getStatusCode()); + } + + @Test + public void deleteInstanceByInstanceIdTest() throws Exception { + + String instanceId = "123"; + ResponseEntity<String> response = new ResponseEntity<String>(HttpStatus.OK); + CnfAdapterService cnfAdapterService = Mockito.mock(CnfAdapterService.class); + Mockito.when(cnfAdapterService.deleteInstanceByInstanceId(instanceId)).thenReturn(response); + cnfAdapterRest.deleteInstanceByInstanceId(instanceId); + Assert.assertNotNull(response); + Assert.assertEquals(HttpStatus.OK, response.getStatusCode()); + } + + @Test + public void getInstanceStatusByInstanceIdTest() throws Exception { + + String instanceId = "123"; + instanceStatusResponse = new ResponseEntity<InstanceStatusResponse>(HttpStatus.OK); + CnfAdapterService cnfAdapterService = Mockito.mock(CnfAdapterService.class); + Mockito.when(cnfAdapterService.getInstanceStatusByInstanceId(instanceId)).thenReturn(instanceStatusResponse); + cnfAdapterRest.getInstanceStatusByInstanceId(instanceId); + Assert.assertNotNull(instanceStatusResponse); + Assert.assertEquals(HttpStatus.OK, instanceStatusResponse.getStatusCode()); + } + + @Test + public void getInstanceByRBNameOrRBVersionOrProfileNameTest() throws Exception { + + String rbName = "xyz"; + String rbVersion = "v1"; + String profileName = "p1"; + InstanceMiniResponse instanceMiniResponse = new InstanceMiniResponse(HttpStatus.OK.toString()); + List<InstanceMiniResponse> instancList = new ArrayList<InstanceMiniResponse>(); + instancList.add(instanceMiniResponse); + InstanceMiniResponseList instanceMiniRespList = new InstanceMiniResponseList(HttpStatus.OK.toString()); + instanceMiniRespList.setInstancList(instancList); + instanceMiniRespList.setErrorMsg(HttpStatus.OK.toString()); + ResponseEntity<InstanceMiniResponseList> respone = + new ResponseEntity<InstanceMiniResponseList>(instanceMiniRespList, HttpStatus.OK); + CnfAdapterService cnfAdapterService = Mockito.mock(CnfAdapterService.class); + Mockito.when(cnfAdapterService.getInstanceByRBNameOrRBVersionOrProfileName(rbName, rbVersion, profileName)) + .thenReturn(instacneMiniResponseList); + cnfAdapterRest.getInstanceByRBNameOrRBVersionOrProfileName(rbName, rbVersion, profileName); + Assert.assertNotNull(instacneMiniResponseList); + Assert.assertEquals(HttpStatus.OK.toString(), instanceMiniRespList.getErrorMsg()); + } + +} + diff --git a/adapters/mso-cnf-adapter/src/test/java/org/onap/so/adapters/cnf/service/CnfAdapterServiceTest.java b/adapters/mso-cnf-adapter/src/test/java/org/onap/so/adapters/cnf/service/CnfAdapterServiceTest.java new file mode 100644 index 0000000000..0d3d8598bb --- /dev/null +++ b/adapters/mso-cnf-adapter/src/test/java/org/onap/so/adapters/cnf/service/CnfAdapterServiceTest.java @@ -0,0 +1,139 @@ +package org.onap.so.adapters.cnf.service; + +import javax.ws.rs.InternalServerErrorException; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.onap.so.adapters.cnf.model.BpmnInstanceRequest; +import org.onap.so.adapters.cnf.model.InstanceMiniResponseList; +import org.onap.so.adapters.cnf.model.InstanceResponse; +import org.onap.so.adapters.cnf.model.InstanceStatusResponse; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +@RunWith(SpringRunner.class) +public class CnfAdapterServiceTest { + + @InjectMocks + CnfAdapterService cnfAdapterService; + + @Mock + ResponseEntity<InstanceResponse> createInstanceResponse; + + @Mock + ResponseEntity<InstanceMiniResponseList> instacneMiniResponseList; + + @Mock + ResponseEntity<InstanceStatusResponse> instanceStatusResponse; + + @Mock + private RestTemplate restTemplate; + + @Test + public void healthCheckTest() throws Exception { + + ResponseEntity<String> response = new ResponseEntity<String>(HttpStatus.OK); + + Mockito.when(restTemplate.exchange(Matchers.anyString(), Matchers.any(HttpMethod.class), + Matchers.<HttpEntity<?>>any(), Matchers.<Class<String>>any())).thenReturn(response); + + ResponseEntity<String> actualResponse = cnfAdapterService.healthCheck(); + Assert.assertNotNull(actualResponse); + Assert.assertEquals(HttpStatus.OK, actualResponse.getStatusCode()); + + } + + @Test + public void createInstanceTest() throws Exception { + + ResponseEntity<InstanceResponse> response = new ResponseEntity<InstanceResponse>(HttpStatus.OK); + BpmnInstanceRequest bpmnInstanceRequest = new BpmnInstanceRequest(); + bpmnInstanceRequest.setK8sRBProfileName("k8sRBProfileName"); + Mockito.when(restTemplate.exchange(Matchers.anyString(), Matchers.any(HttpMethod.class), + Matchers.<HttpEntity<?>>any(), Matchers.<Class<InstanceResponse>>any())).thenReturn(response); + + ResponseEntity<InstanceResponse> actualResponse = cnfAdapterService.createInstance(bpmnInstanceRequest); + Assert.assertNotNull(response); + Assert.assertEquals(actualResponse.getStatusCode(), response.getStatusCode()); + + } + + @Test + public void createInstanceExceptionTest() throws Exception { + + BpmnInstanceRequest bpmnInstanceRequest = new BpmnInstanceRequest(); + ResponseEntity<InstanceResponse> response = cnfAdapterService.createInstance(bpmnInstanceRequest); + Assert.assertNull(response); + + } + + @Test + public void getInstanceByInstanceIdTest() throws Exception { + + ResponseEntity<InstanceResponse> response = new ResponseEntity<InstanceResponse>(HttpStatus.OK); + String instanceId = "123"; + Mockito.when(restTemplate.exchange(Matchers.anyString(), Matchers.any(HttpMethod.class), + Matchers.<HttpEntity<?>>any(), Matchers.<Class<InstanceResponse>>any())).thenReturn(response); + + ResponseEntity<InstanceResponse> actualResponse = cnfAdapterService.getInstanceByInstanceId(instanceId); + Assert.assertNotNull(actualResponse); + Assert.assertEquals(HttpStatus.OK, actualResponse.getStatusCode()); + + } + + @Test + public void getInstanceStatusByInstanceIdTest() throws Exception { + + ResponseEntity<InstanceStatusResponse> response = new ResponseEntity<InstanceStatusResponse>(HttpStatus.OK); + String instanceId = "123"; + Mockito.when(restTemplate.exchange(Matchers.anyString(), Matchers.any(HttpMethod.class), + Matchers.<HttpEntity<?>>any(), Matchers.<Class<InstanceStatusResponse>>any())).thenReturn(response); + + ResponseEntity<InstanceStatusResponse> actualResponse = + cnfAdapterService.getInstanceStatusByInstanceId(instanceId); + Assert.assertNotNull(actualResponse); + Assert.assertEquals(HttpStatus.OK, response.getStatusCode()); + + } + + @Test + public void getInstanceByRBNameOrRBVersionOrProfileNameTest() throws Exception { + + ResponseEntity<InstanceMiniResponseList> response = new ResponseEntity<InstanceMiniResponseList>(HttpStatus.OK); + String rbName = "xyz"; + String rbVersion = "v1"; + String profileName = "p1"; + + Mockito.when(restTemplate.exchange(Matchers.anyString(), Matchers.any(HttpMethod.class), + Matchers.<HttpEntity<?>>any(), Matchers.<Class<InstanceMiniResponseList>>any())).thenReturn(response); + + ResponseEntity<InstanceMiniResponseList> actualResponse = + cnfAdapterService.getInstanceByRBNameOrRBVersionOrProfileName(rbName, rbVersion, profileName); + Assert.assertNotNull(actualResponse); + Assert.assertEquals(HttpStatus.OK, actualResponse.getStatusCode()); + + } + + @Test + public void deleteInstanceByInstanceIdTest() throws Exception { + + ResponseEntity<String> response = new ResponseEntity<String>(HttpStatus.OK); + String instanceId = "123"; + Mockito.when(restTemplate.exchange(Matchers.anyString(), Matchers.any(HttpMethod.class), + Matchers.<HttpEntity<?>>any(), Matchers.<Class<String>>any())).thenReturn(response); + + ResponseEntity<String> actualResponse = cnfAdapterService.deleteInstanceByInstanceId(instanceId); + Assert.assertNotNull(response); + Assert.assertEquals(HttpStatus.OK, response.getStatusCode()); + + } + +} diff --git a/adapters/mso-nssmf-adapter/pom.xml b/adapters/mso-nssmf-adapter/pom.xml index db791826c3..45fe77eecc 100644 --- a/adapters/mso-nssmf-adapter/pom.xml +++ b/adapters/mso-nssmf-adapter/pom.xml @@ -162,7 +162,6 @@ <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> - <version>1.18.2</version> </dependency> </dependencies> </project> diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/MSONssmfApplication.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/MSONssmfApplication.java index cd011e6437..83a09dc343 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/MSONssmfApplication.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/MSONssmfApplication.java @@ -20,6 +20,7 @@ package org.onap.so.adapters.nssmf; + import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/annotation/ServiceLogger.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/annotation/ServiceLogger.java new file mode 100644 index 0000000000..1de29bcc2b --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/annotation/ServiceLogger.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.annotation; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ServiceLogger { + + String value() default ""; + + boolean ignore() default false; +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/config/NssmfAdapterConfig.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/config/NssmfAdapterConfig.java new file mode 100644 index 0000000000..6a592448a6 --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/config/NssmfAdapterConfig.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.config; + +import lombok.Getter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +@Configuration +@Getter +public class NssmfAdapterConfig { + + @Value("${mso.infra.endpoint}") + private String infraEndpoint; + + @Value("${mso.infra.auth}") + private String infraAuth; +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/RequestDbConfig.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/config/RequestDbConfig.java index 484f7624aa..dcb5d6198c 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/RequestDbConfig.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/config/RequestDbConfig.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.so.adapters.nssmf; +package org.onap.so.adapters.nssmf.config; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/WebSecurityConfig.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/config/WebSecurityConfig.java index 1522ca9c6d..dfb2b61978 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/WebSecurityConfig.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/config/WebSecurityConfig.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.so.adapters.nssmf; +package org.onap.so.adapters.nssmf.config; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/consts/NssmfAdapterConsts.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/consts/NssmfAdapterConsts.java new file mode 100644 index 0000000000..28789f2a98 --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/consts/NssmfAdapterConsts.java @@ -0,0 +1,187 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.consts; + +import org.onap.so.adapters.nssmf.entity.NssmfUrlInfo; +import org.onap.so.adapters.nssmf.enums.ActionType; +import org.onap.so.adapters.nssmf.enums.ExecutorType; +import org.onap.so.adapters.nssmf.enums.HttpMethod; +import org.onap.so.beans.nsmf.NetworkType; +import java.util.HashMap; +import java.util.Map; + +public class NssmfAdapterConsts { + + public final static String ONAP_INTERNAL_TAG = "ONAP_internal"; + + public final static String CURRENT_INTERNAL_NSSMF_API_VERSION = "v1"; + + private static Map<String, NssmfUrlInfo> urlInfoMap = new HashMap<>(); + + private final static String EXTERNAL_CN_ALLOCATE_URL = "/api/rest/provMns/{apiVersion}/NSS/SliceProfiles"; + + private final static String EXTERNAL_TN_ALLOCATE_URL = "/api/rest/provMns/{apiVersion}/tn/NSS/SliceProfiles"; + + private final static String EXTERNAL_AN_ALLOCATE_URL = "/ObjectManagement/NSS/SliceProfiles"; + + private final static String INTERNAL_ALLOCATE_URL = "/onap/so/infra/3gppservices/{apiVersion}/allocate"; + + private final static String EXTERNAL_CN_DEALLOCATE_URL = + "/api/rest/provMns/{apiVersion}/NSS/SliceProfiles/{sliceProfileId}"; + + private final static String EXTERNAL_TN_DEALLOCATE_URL = + "/api/rest/provMns/{apiVersion}/tn/NSS/SliceProfiles/{sliceProfileId}"; + + private final static String EXTERNAL_AN_DEALLOCATE_URL = "/ObjectManagement/NSS/SliceProfiles/{sliceProfileId}"; + + private final static String INTERNAL_DEALLOCATE_URL = "/onap/so/infra/3gppservices/{apiVersion}/deAllocate"; + + private final static String EXTERNAL_CN_ACTIVATE_URL = "/api/rest/provMns/{apiVersion}/NSS/{snssai}/activation"; + + private final static String EXTERNAL_TN_ACTIVATE_URL = "/api/rest/provMns/{apiVersion}/tn/NSS/{snssai}/activation"; + + private final static String EXTERNAL_AN_ACTIVATE_URL = "/api/rest/provMns/{apiVersion}/an/NSS/{snssai}/activations"; + + private final static String INTERNAL_ACTIVATE_URL = "/onap/so/infra/3gppservices/{apiVersion}/activate"; + + private final static String EXTERNAL_CN_DEACTIVATE_URL = "/api/rest/provMns/{apiVersion}/NSS/{snssai}/deactivation"; + + private final static String EXTERNAL_TN_DEACTIVATE_URL = + "/api/rest/provMns/{apiVersion}/tn/NSS/{snssai}/deactivation"; + + private final static String EXTERNAL_AN_DEACTIVATE_URL = + "/api/rest/provMns/{apiVersion}/an/NSS/{snssai}/deactivation"; + + private final static String INTERNAL_DEACTIVATE_URL = "/onap/so/infra/3gppservices/{apiVersion}/deActivate"; + + // + private final static String EXTERNAL_CN_TERMINATE_URL = + "/api/rest/provMns/{apiVersion}/NSS/SliceProfiles/{SliceProfileId}"; + + private final static String EXTERNAL_TN_TERMINATE_URL = + "/api/rest/provMns/{apiVersion}/tn/NSS/SliceProfiles/{SliceProfileId}"; + + private final static String EXTERNAL_AN_TERMINATE_URL = + "/api/rest/provMns/{apiVersion}/an/NSS/SliceProfiles/{SliceProfileId}"; + + private final static String INTERNAL_TERMINATE_URL = "/onap/so/infra/3gppservices/{apiVersion}/terminate"; + + // + private final static String EXTERNAL_AN_MODIFY_URL = + "/api/rest/provMns/{apiVersion}/an/NSS/SliceProfiles/{SliceProfileId}"; + + private final static String INTERNAL_MODIFY_URL = "/onap/so/infra/3gppservices/{apiVersion}/modify"; + + // + private final static String EXTERNAL_QUERY_JOB_STATUS = + "/api/rest/provMns/{apiVersion}/NSS/jobs/{jobId}?responseId={responseId}"; + + private final static String INTERNAL_QUERY_SUB_NET_CAPABILITY = + "/onap/so/infra/3gppservices/{apiVersion}/subnetCapabilityQuery"; + + static { + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.ACCESS, ActionType.ALLOCATE), + new NssmfUrlInfo(EXTERNAL_AN_ALLOCATE_URL, HttpMethod.POST)); + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.TRANSPORT, ActionType.ALLOCATE), + new NssmfUrlInfo(EXTERNAL_TN_ALLOCATE_URL, HttpMethod.POST)); + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.CORE, ActionType.ALLOCATE), + new NssmfUrlInfo(EXTERNAL_CN_ALLOCATE_URL, HttpMethod.POST)); + urlInfoMap.put(generateKey(ExecutorType.INTERNAL, null, ActionType.ALLOCATE), + new NssmfUrlInfo(INTERNAL_ALLOCATE_URL, HttpMethod.POST)); + + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.ACCESS, ActionType.DEALLOCATE), + new NssmfUrlInfo(EXTERNAL_AN_DEALLOCATE_URL, HttpMethod.DELETE)); + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.TRANSPORT, ActionType.DEALLOCATE), + new NssmfUrlInfo(EXTERNAL_TN_DEALLOCATE_URL, HttpMethod.DELETE)); + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.CORE, ActionType.DEALLOCATE), + new NssmfUrlInfo(EXTERNAL_CN_DEALLOCATE_URL, HttpMethod.DELETE)); + urlInfoMap.put(generateKey(ExecutorType.INTERNAL, null, ActionType.DEALLOCATE), + new NssmfUrlInfo(INTERNAL_DEALLOCATE_URL, HttpMethod.DELETE)); + + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.ACCESS, ActionType.ACTIVATE), + new NssmfUrlInfo(EXTERNAL_AN_ACTIVATE_URL, HttpMethod.PUT)); + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.TRANSPORT, ActionType.ACTIVATE), + new NssmfUrlInfo(EXTERNAL_TN_ACTIVATE_URL, HttpMethod.PUT)); + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.CORE, ActionType.ACTIVATE), + new NssmfUrlInfo(EXTERNAL_CN_ACTIVATE_URL, HttpMethod.PUT)); + urlInfoMap.put(generateKey(ExecutorType.INTERNAL, null, ActionType.ACTIVATE), + new NssmfUrlInfo(INTERNAL_ACTIVATE_URL, HttpMethod.PUT)); + + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.ACCESS, ActionType.DEACTIVATE), + new NssmfUrlInfo(EXTERNAL_AN_DEACTIVATE_URL, HttpMethod.PUT)); + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.TRANSPORT, ActionType.DEACTIVATE), + new NssmfUrlInfo(EXTERNAL_TN_DEACTIVATE_URL, HttpMethod.PUT)); + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.CORE, ActionType.DEACTIVATE), + new NssmfUrlInfo(EXTERNAL_CN_DEACTIVATE_URL, HttpMethod.PUT)); + urlInfoMap.put(generateKey(ExecutorType.INTERNAL, null, ActionType.DEACTIVATE), + new NssmfUrlInfo(INTERNAL_DEACTIVATE_URL, HttpMethod.PUT)); + + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.ACCESS, ActionType.TERMINATE), + new NssmfUrlInfo(EXTERNAL_AN_TERMINATE_URL, HttpMethod.DELETE)); + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.TRANSPORT, ActionType.TERMINATE), + new NssmfUrlInfo(EXTERNAL_TN_TERMINATE_URL, HttpMethod.DELETE)); + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.CORE, ActionType.TERMINATE), + new NssmfUrlInfo(EXTERNAL_CN_TERMINATE_URL, HttpMethod.DELETE)); + urlInfoMap.put(generateKey(ExecutorType.INTERNAL, null, ActionType.TERMINATE), + new NssmfUrlInfo(INTERNAL_TERMINATE_URL, HttpMethod.DELETE)); + + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.ACCESS, ActionType.MODIFY), + new NssmfUrlInfo(EXTERNAL_AN_MODIFY_URL, HttpMethod.PUT)); + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.CORE, ActionType.MODIFY), + new NssmfUrlInfo(EXTERNAL_CN_ALLOCATE_URL, HttpMethod.PUT)); + urlInfoMap.put(generateKey(ExecutorType.INTERNAL, null, ActionType.MODIFY), + new NssmfUrlInfo(INTERNAL_MODIFY_URL, HttpMethod.PUT)); + + + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.CORE, ActionType.QUERY_JOB_STATUS), + new NssmfUrlInfo(EXTERNAL_QUERY_JOB_STATUS, HttpMethod.GET)); + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.ACCESS, ActionType.QUERY_JOB_STATUS), + new NssmfUrlInfo(EXTERNAL_QUERY_JOB_STATUS, HttpMethod.GET)); + urlInfoMap.put(generateKey(ExecutorType.EXTERNAL, NetworkType.TRANSPORT, ActionType.QUERY_JOB_STATUS), + new NssmfUrlInfo(EXTERNAL_QUERY_JOB_STATUS, HttpMethod.GET)); + + urlInfoMap.put(generateKey(ExecutorType.INTERNAL, null, ActionType.QUERY_SUB_NET_CAPABILITY), + new NssmfUrlInfo(INTERNAL_QUERY_SUB_NET_CAPABILITY, HttpMethod.POST)); + } + + /** + * get nssmf url info from consts + * + * @param executorType {@link ExecutorType} + * @param networkType {@link NetworkType} + * @param actionType {@link ActionType} + * @return {@link NssmfUrlInfo} + */ + public static NssmfUrlInfo getNssmfUrlInfo(ExecutorType executorType, NetworkType networkType, + ActionType actionType) { + + return urlInfoMap.get(generateKey(executorType, networkType, actionType)); + } + + private static String generateKey(ExecutorType executorType, NetworkType networkType, ActionType actionType) { + if (ExecutorType.EXTERNAL.equals(executorType)) { + return executorType.name() + "_" + networkType.name() + "_" + actionType.name(); + } + return executorType.name() + "_" + actionType.name(); + } + + +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/controller/NssmfAdapterController.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/controller/NssmfAdapterController.java new file mode 100644 index 0000000000..02d7468a0c --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/controller/NssmfAdapterController.java @@ -0,0 +1,57 @@ +package org.onap.so.adapters.nssmf.controller; + +import org.onap.so.adapters.nssmf.service.NssmfManagerService; +import org.onap.so.beans.nsmf.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +@RestController +@RequestMapping(value = "/api/rest/provMns/v1", produces = {APPLICATION_JSON}, consumes = {APPLICATION_JSON}) +public class NssmfAdapterController { + + @Autowired + private NssmfManagerService nssmfManagerService; + + @PostMapping(value = "/NSS/SliceProfiles") + public ResponseEntity allocateNssi(@RequestBody NssmfAdapterNBIRequest nbiRequest) { + return nssmfManagerService.allocateNssi(nbiRequest); + } + + @PostMapping(value = "/NSS/SliceProfiles/{sliceProfileId}") + public ResponseEntity deAllocateNssi(@RequestBody NssmfAdapterNBIRequest nbiRequest, + @PathVariable("sliceProfileId") final String sliceProfileId) { + return nssmfManagerService.deAllocateNssi(nbiRequest, sliceProfileId); + } + + + @PostMapping(value = "/NSS/{snssai}/activation") + public ResponseEntity activateNssi(@RequestBody NssmfAdapterNBIRequest nbiRequest, + @PathVariable("snssai") String snssai) { + return nssmfManagerService.activateNssi(nbiRequest, snssai); + } + + @PostMapping(value = "/NSS/{snssai}/deactivation") + public ResponseEntity deactivateNssi(@RequestBody NssmfAdapterNBIRequest nbiRequest, + @PathVariable("snssai") String snssai) { + return nssmfManagerService.deActivateNssi(nbiRequest, snssai); + } + + @PostMapping(value = "/NSS/jobs/{jobId}") + public ResponseEntity queryJobStatus(@RequestBody NssmfAdapterNBIRequest nbiRequest, + @PathVariable("jobId") String jobId) { + return nssmfManagerService.queryJobStatus(nbiRequest, jobId); + } + + @PostMapping(value = "/NSS/NSSISelectionCapability") + public ResponseEntity queryNSSISelectionCapability(@RequestBody NssmfAdapterNBIRequest nbiRequest) { + return nssmfManagerService.queryNSSISelectionCapability(nbiRequest); + } + + @PostMapping(value = "/NSS/subnetCapabilityQuery") + public ResponseEntity querySubnetCapability(@RequestBody NssmfAdapterNBIRequest nbiRequest) { + return nssmfManagerService.querySubnetCapability(nbiRequest); + } + +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/entity/ErrorResponse.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/entity/ErrorResponse.java new file mode 100644 index 0000000000..a8653f8d73 --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/entity/ErrorResponse.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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.adapters.nssmf.entity; + +public class ErrorResponse { + + private int status; + + private String error; + + private String message; + + public ErrorResponse(int status, String message) { + this.status = status; + this.message = message; + this.error = "Bad Request"; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getError() { + if (status == 500) { + this.error = "Internal Server Error"; + } + return error; + } + + public void setError(String error) { + this.error = error; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/beans/DeploymentStatus.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/entity/NssmfInfo.java index f7d6a9d214..af26264074 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/beans/DeploymentStatus.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/entity/NssmfInfo.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP - SO * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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. @@ -18,14 +18,24 @@ * ============LICENSE_END========================================================= */ -package org.onap.so.cloudify.beans; +package org.onap.so.adapters.nssmf.entity; +import lombok.Data; -/* - * 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 -} +@Data +public class NssmfInfo { + + private String url; + + private String ipAddress; + + private String port; + private String insecure; + + private String cacert; + + private String userName; + + private String password; +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/entity/NssmfUrlInfo.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/entity/NssmfUrlInfo.java new file mode 100644 index 0000000000..f55ff10f1c --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/entity/NssmfUrlInfo.java @@ -0,0 +1,17 @@ +package org.onap.so.adapters.nssmf.entity; + +import lombok.Data; +import org.onap.so.adapters.nssmf.enums.HttpMethod; + +@Data +public class NssmfUrlInfo { + + private String url; + + private HttpMethod httpMethod; + + public NssmfUrlInfo(String url, HttpMethod httpMethod) { + this.url = url; + this.httpMethod = httpMethod; + } +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/RestResponse.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/entity/RestResponse.java index cc047e45c7..218867c1ab 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/RestResponse.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/entity/RestResponse.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.so.adapters.nssmf.rest; +package org.onap.so.adapters.nssmf.entity; import java.util.Map; diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/model/TokenRequest.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/entity/TokenRequest.java index 3590c683e6..bfcb875290 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/model/TokenRequest.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/entity/TokenRequest.java @@ -18,8 +18,11 @@ * ============LICENSE_END========================================================= */ -package org.onap.so.adapters.nssmf.model; +package org.onap.so.adapters.nssmf.entity; +import lombok.Data; + +@Data public class TokenRequest { private String grantType; @@ -27,28 +30,4 @@ public class TokenRequest { private String userName; private String value; - - public String getGrantType() { - return grantType; - } - - public void setGrantType(String grantType) { - this.grantType = grantType; - } - - public String getUserName() { - return userName; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } } diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/model/TokenResponse.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/entity/TokenResponse.java index 8007075e04..552612a6fb 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/model/TokenResponse.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/entity/TokenResponse.java @@ -18,27 +18,15 @@ * ============LICENSE_END========================================================= */ -package org.onap.so.adapters.nssmf.model; +package org.onap.so.adapters.nssmf.entity; + +import lombok.Data; + +@Data public class TokenResponse { private String accessToken; private int expires; - - public String getAccessToken() { - return accessToken; - } - - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; - } - - public int getExpires() { - return expires; - } - - public void setExpires(int expires) { - this.expires = expires; - } } diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/enums/ActionType.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/enums/ActionType.java new file mode 100644 index 0000000000..9df20bac1c --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/enums/ActionType.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.enums; + +import lombok.Getter; + +@Getter +public enum ActionType { + ALLOCATE("allocate"), + + DEALLOCATE("deallocate"), + + CREATE("create"), + + TERMINATE("terminate"), + + ACTIVATE("activate"), + + DEACTIVATE("deactivate"), + + QUERY_JOB_STATUS("query_job_status"), + + MODIFY_BY_ID("modify_by_id"), + + MODIFY("modify"), + + QUERY_NSSI_SELECTION_CAPABILITY("query_nssi_selection_capability"), + + QUERY_SUB_NET_CAPABILITY("query_sub_net_capability"),; + + private String type; + + + ActionType(String type) { + this.type = type; + } +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/enums/ExecutorType.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/enums/ExecutorType.java new file mode 100644 index 0000000000..a76a54c348 --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/enums/ExecutorType.java @@ -0,0 +1,25 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.enums; + +public enum ExecutorType { + INTERNAL, EXTERNAL +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/HttpMethod.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/enums/HttpMethod.java index f6abd98794..9271bb50b3 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/HttpMethod.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/enums/HttpMethod.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.so.adapters.nssmf.rest; +package org.onap.so.adapters.nssmf.enums; public enum HttpMethod { GET, POST, PUT, DELETE, PATCH; diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/JobStatus.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/enums/JobStatus.java index f2e651fd6e..d5cc1df377 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/JobStatus.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/enums/JobStatus.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.so.adapters.nssmf.rest; +package org.onap.so.adapters.nssmf.enums; import org.onap.so.adapters.nssmf.exceptions.ApplicationException; diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/enums/SelectionType.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/enums/SelectionType.java new file mode 100644 index 0000000000..420dfdce49 --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/enums/SelectionType.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.enums; + +public enum SelectionType { + NSSMF, + + NSMF +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/exceptions/ApplicationException.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/exceptions/ApplicationException.java index f63ba356a1..2461f5ca78 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/exceptions/ApplicationException.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/exceptions/ApplicationException.java @@ -20,7 +20,7 @@ package org.onap.so.adapters.nssmf.exceptions; -import org.onap.so.adapters.nssmf.model.ErrorResponse; +import org.onap.so.adapters.nssmf.entity.ErrorResponse; import org.springframework.http.ResponseEntity; import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.marshal; diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/extclients/aai/AaiServiceProvider.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/extclients/aai/AaiServiceProvider.java index c737ba6440..665b111e03 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/extclients/aai/AaiServiceProvider.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/extclients/aai/AaiServiceProvider.java @@ -22,6 +22,7 @@ package org.onap.so.adapters.nssmf.extclients.aai; import org.onap.aai.domain.yang.EsrSystemInfoList; import org.onap.aai.domain.yang.EsrThirdpartySdncList; +import org.onap.aai.domain.yang.ServiceInstance; public interface AaiServiceProvider { @@ -29,4 +30,7 @@ public interface AaiServiceProvider { EsrSystemInfoList invokeGetThirdPartySdncEsrSystemInfo(String sdncId); + void invokeCreateServiceInstance(ServiceInstance nssiInstance, String globalSubscriberId, String serviceType, + String serviceInstanceId); + } diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/extclients/aai/AaiServiceProviderImpl.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/extclients/aai/AaiServiceProviderImpl.java index 8cb47ebf38..3f2e5b23f2 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/extclients/aai/AaiServiceProviderImpl.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/extclients/aai/AaiServiceProviderImpl.java @@ -23,7 +23,9 @@ package org.onap.so.adapters.nssmf.extclients.aai; import org.onap.aai.domain.yang.EsrSystemInfoList; import org.onap.aai.domain.yang.EsrThirdpartySdncList; +import org.onap.aai.domain.yang.ServiceInstance; import org.onap.aaiclient.client.aai.AAIObjectType; +import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri; import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,4 +65,12 @@ public class AaiServiceProviderImpl implements AaiServiceProvider { }); } + + @Override + public void invokeCreateServiceInstance(ServiceInstance nssiInstance, String globalSubscriberId, String serviceType, + String serviceInstanceId) { + AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, globalSubscriberId, + serviceType, serviceInstanceId); + aaiClientProvider.getAaiClient().create(uri, nssiInstance); + } } diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/interceptor/LoggerInterceptor.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/interceptor/LoggerInterceptor.java new file mode 100644 index 0000000000..ea6a1250d9 --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/interceptor/LoggerInterceptor.java @@ -0,0 +1,92 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.nssmf.interceptor; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.onap.so.adapters.nssmf.annotation.ServiceLogger; +import org.onap.so.adapters.nssmf.util.NssmfAdapterUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import java.lang.reflect.Method; + +/** + * support to print logger of service method + */ +@Aspect +@Order(100) +@Component +public class LoggerInterceptor { + + private static final Logger logger = LoggerFactory.getLogger(LoggerInterceptor.class); + + @Pointcut("execution(* org.onap.so.adapters.nssmf.service..*(..))") + public void serviceLogger() { + + } + + @Around("serviceLogger()") + public Object around(ProceedingJoinPoint joinPoint) { + try { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + + Class<?> targetClass = method.getDeclaringClass(); + + StringBuilder classAndMethod = new StringBuilder(); + ServiceLogger classAnnotation = targetClass.getAnnotation(ServiceLogger.class); + ServiceLogger methodAnnotation = method.getAnnotation(ServiceLogger.class); + + if (classAnnotation == null && methodAnnotation == null) { + return joinPoint.proceed(); + } + + if (classAnnotation != null) { + if (classAnnotation.ignore()) { + return joinPoint.proceed(); + } + classAndMethod.append(classAnnotation.value()).append("-"); + } + + String target = targetClass.getName() + "#" + method.getName(); + + String params = NssmfAdapterUtil.marshal(joinPoint.getArgs()); + + logger.info("{} Start: Method = {} \nParams = {}", classAndMethod.toString(), target, params); + + long start = System.currentTimeMillis(); + Object result = joinPoint.proceed(); + long timeConsuming = System.currentTimeMillis() - start; + + logger.info("\n{} End: Method = {}, Spend time = {}ms \nResult = {}", classAndMethod.toString(), target, + timeConsuming, NssmfAdapterUtil.marshal(result)); + return result; + + } catch (Throwable e) { + logger.error(e.getMessage(), e); + } + return null; + } +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/NssmfManager.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/NssmfManager.java new file mode 100644 index 0000000000..54ef1e09dd --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/NssmfManager.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.manager; + +import org.onap.so.adapters.nssmf.exceptions.ApplicationException; +import org.onap.so.adapters.nssmf.entity.RestResponse; +import org.onap.so.beans.nsmf.*; + +public interface NssmfManager { + + RestResponse allocateNssi(NssmfAdapterNBIRequest nssmfRequest) throws ApplicationException; + + RestResponse deAllocateNssi(NssmfAdapterNBIRequest nssmfRequest, String sliceId) throws ApplicationException; + + RestResponse activateNssi(NssmfAdapterNBIRequest nssmfRequest, String snssai) throws ApplicationException; + + RestResponse deActivateNssi(NssmfAdapterNBIRequest nssmfRequest, String snssai) throws ApplicationException; + + RestResponse queryJobStatus(NssmfAdapterNBIRequest jobReq, String jobId) throws ApplicationException; + + RestResponse queryNSSISelectionCapability(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException; + + RestResponse querySubnetCapability(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException; + + RestResponse modifyNssi(NssmfAdapterNBIRequest modifyRequest) throws ApplicationException; +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/NssmfManagerBuilder.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/NssmfManagerBuilder.java new file mode 100644 index 0000000000..0b332af607 --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/NssmfManagerBuilder.java @@ -0,0 +1,125 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.manager; + +import org.onap.so.adapters.nssmf.config.NssmfAdapterConfig; +import org.onap.so.adapters.nssmf.consts.NssmfAdapterConsts; +import org.onap.so.adapters.nssmf.enums.ActionType; +import org.onap.so.adapters.nssmf.enums.ExecutorType; +import org.onap.so.adapters.nssmf.exceptions.ApplicationException; +import org.onap.so.adapters.nssmf.manager.impl.external.ExternalAnNssmfManager; +import org.onap.so.adapters.nssmf.manager.impl.external.ExternalCnNssmfManager; +import org.onap.so.adapters.nssmf.manager.impl.internal.InternalAnNssmfManager; +import org.onap.so.adapters.nssmf.manager.impl.internal.InternalCnNssmfManager; +import org.onap.so.adapters.nssmf.manager.impl.internal.InternalTnNssmfManager; +import org.onap.so.adapters.nssmf.manager.impl.*; +import org.onap.so.adapters.nssmf.util.RestUtil; +import org.onap.so.beans.nsmf.EsrInfo; +import org.onap.so.beans.nsmf.NetworkType; +import org.onap.so.beans.nsmf.ServiceInfo; +import org.onap.so.db.request.data.repository.ResourceOperationStatusRepository; + +public class NssmfManagerBuilder { + + private BaseNssmfManager nssmfManger; + + private RestUtil restUtil; + + private ActionType actionType; + + private ResourceOperationStatusRepository repository; + + private ServiceInfo serviceInfo; + + private NssmfAdapterConfig adapterConfig; + + public NssmfManagerBuilder(EsrInfo esrInfo) throws ApplicationException { + + ExecutorType executorType = getExecutorType(esrInfo); + NetworkType networkType = esrInfo.getNetworkType(); + + if (ExecutorType.INTERNAL.equals(executorType) && NetworkType.CORE.equals(networkType)) { + this.nssmfManger = new InternalCnNssmfManager().setEsrInfo(esrInfo).setExecutorType(executorType); + return; + } + + if (ExecutorType.INTERNAL.equals(executorType) && NetworkType.TRANSPORT.equals(networkType)) { + this.nssmfManger = new InternalTnNssmfManager().setEsrInfo(esrInfo).setExecutorType(executorType); + return; + } + + if (ExecutorType.INTERNAL.equals(executorType) && NetworkType.ACCESS.equals(networkType)) { + this.nssmfManger = new InternalAnNssmfManager().setEsrInfo(esrInfo).setExecutorType(executorType); + return; + } + + if (ExecutorType.EXTERNAL.equals(executorType) && NetworkType.CORE.equals(networkType)) { + this.nssmfManger = new ExternalCnNssmfManager().setEsrInfo(esrInfo).setExecutorType(executorType) + .setInitStatus("deactivated"); + return; + } + + if (ExecutorType.EXTERNAL.equals(executorType) && NetworkType.ACCESS.equals(networkType)) { + this.nssmfManger = new ExternalAnNssmfManager().setEsrInfo(esrInfo).setExecutorType(executorType) + .setInitStatus("activated"); + return; + } + + throw new ApplicationException(404, "invalid domain and simulator"); + } + + private ExecutorType getExecutorType(EsrInfo esrInfo) { + if (NssmfAdapterConsts.ONAP_INTERNAL_TAG.equals(esrInfo.getVendor())) { + return ExecutorType.INTERNAL; + } + return ExecutorType.EXTERNAL; + } + + public NssmfManagerBuilder setRestUtil(RestUtil restUtil) { + this.restUtil = restUtil; + return this; + } + + public NssmfManagerBuilder setActionType(ActionType actionType) { + this.actionType = actionType; + return this; + } + + public NssmfManagerBuilder setRepository(ResourceOperationStatusRepository repository) { + this.repository = repository; + return this; + } + + public NssmfManagerBuilder setServiceInfo(ServiceInfo serviceInfo) { + this.serviceInfo = serviceInfo; + return this; + } + + public NssmfManagerBuilder setAdapterConfig(NssmfAdapterConfig adapterConfig) { + this.adapterConfig = adapterConfig; + return this; + } + + public NssmfManager build() { + return this.nssmfManger.setRestUtil(restUtil).setAdapterConfig(adapterConfig).setRepository(repository) + .setActionType(actionType).setServiceInfo(serviceInfo); + } +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/BaseNssmfManager.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/BaseNssmfManager.java new file mode 100644 index 0000000000..97a4c5e889 --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/BaseNssmfManager.java @@ -0,0 +1,267 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.manager.impl; + +import org.onap.so.adapters.nssmf.config.NssmfAdapterConfig; +import org.onap.so.adapters.nssmf.consts.NssmfAdapterConsts; +import org.onap.so.adapters.nssmf.entity.NssmfUrlInfo; +import org.onap.so.adapters.nssmf.enums.*; +import org.onap.so.adapters.nssmf.exceptions.ApplicationException; +import org.onap.so.adapters.nssmf.entity.RestResponse; +import org.onap.so.adapters.nssmf.manager.NssmfManager; +import org.onap.so.adapters.nssmf.util.RestUtil; +import org.onap.so.beans.nsmf.*; +import org.onap.so.db.request.beans.ResourceOperationStatus; +import org.onap.so.db.request.data.repository.ResourceOperationStatusRepository; +import org.springframework.data.domain.Example; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.marshal; + +public abstract class BaseNssmfManager implements NssmfManager { + + protected RestUtil restUtil; + + protected ResourceOperationStatusRepository repository; + + protected NssmfAdapterConfig adapterConfig; + + protected ActionType actionType; + + protected EsrInfo esrInfo; + + protected String nssmfUrl; + + protected HttpMethod httpMethod; + + protected String initStatus; + + protected ServiceInfo serviceInfo; + + protected RestResponse restResponse; + + private ExecutorType executorType = ExecutorType.INTERNAL; + + private Map<String, String> params = new HashMap<>(); // request params + + @Override + public RestResponse allocateNssi(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + + this.params.clear(); + this.urlHandler(); + String requestBody = wrapAllocateReqBody(nbiRequest); + + this.restResponse = sendRequest(requestBody); + + this.afterRequest(); + + return restResponse; + } + + protected abstract String wrapAllocateReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException; + + @Override + public RestResponse modifyNssi(NssmfAdapterNBIRequest modifyRequest) throws ApplicationException { + this.params.clear(); + this.urlHandler(); + String requestBody = wrapModifyReqBody(modifyRequest); + + this.restResponse = sendRequest(requestBody); + + this.afterRequest(); + + return restResponse; + } + + protected abstract String wrapModifyReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException; + + @Override + public RestResponse deAllocateNssi(NssmfAdapterNBIRequest nbiRequest, String sliceId) throws ApplicationException { + this.params.clear(); + this.params.put("sliceProfileId", sliceId); + + this.urlHandler(); + + String reqBody = wrapDeAllocateReqBody(nbiRequest.getDeAllocateNssi()); + + this.restResponse = sendRequest(reqBody); + + this.afterRequest(); + + return restResponse; + } + + protected abstract String wrapDeAllocateReqBody(DeAllocateNssi deAllocateNssi) throws ApplicationException; + + protected abstract String wrapReqBody(Object object) throws ApplicationException; + + @Override + public RestResponse activateNssi(NssmfAdapterNBIRequest nbiRequest, String snssai) throws ApplicationException { + this.params.clear(); + this.params.put("snssai", snssai); + + this.urlHandler(); + + String reqBody = wrapActDeActReqBody(nbiRequest.getActDeActNssi()); + + this.restResponse = sendRequest(reqBody); + + this.afterRequest(); + + return restResponse; + } + + @Override + public RestResponse deActivateNssi(NssmfAdapterNBIRequest nbiRequest, String snssai) throws ApplicationException { + return activateNssi(nbiRequest, snssai); + } + + protected abstract String wrapActDeActReqBody(ActDeActNssi actDeActNssi) throws ApplicationException; + + @Override + public RestResponse queryJobStatus(NssmfAdapterNBIRequest jobReq, String jobId) throws ApplicationException { + this.params.clear(); + this.params.put("jobId", jobId); + this.params.put("responseId", jobReq.getResponseId()); + this.urlHandler(); + + /** + * find by jobId and nsiId jobId -> OperationId nsiId -> ServiceId serviceUuid -> resourceTemplateUUID + */ + ResourceOperationStatus status = + getOperationStatus(serviceInfo.getNsiId(), jobId, serviceInfo.getServiceUuid()); + + this.restResponse = doQueryJobStatus(status); + + afterQueryJobStatus(status); + return restResponse; + } + + protected abstract RestResponse doQueryJobStatus(ResourceOperationStatus status) throws ApplicationException; + + + protected abstract void afterQueryJobStatus(ResourceOperationStatus status); + + private ResourceOperationStatus getOperationStatus(String nsiId, String jobId, String serviceUuid) { + + ResourceOperationStatus status = new ResourceOperationStatus(nsiId, jobId, serviceUuid); + + Optional<ResourceOperationStatus> optional = repository.findOne(Example.of(status)); + + return optional.orElse(null); + } + + @Override + public RestResponse queryNSSISelectionCapability(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + SelectionType res = doQueryNSSISelectionCapability(); + HashMap<String, String> hashMap = new HashMap<>(); + hashMap.put("selection", res.name()); + RestResponse restResponse = new RestResponse(); + restResponse.setStatus(200); + restResponse.setResponseContent(marshal(hashMap)); + return restResponse; + } + + protected abstract SelectionType doQueryNSSISelectionCapability(); + + @Override + public RestResponse querySubnetCapability(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + this.params.clear(); + this.urlHandler(); + + return doQuerySubnetCapability(nbiRequest.getSubnetCapabilityQuery()); + } + + protected abstract RestResponse doQuerySubnetCapability(String req) throws ApplicationException; + + /** + * send request to nssmf + * + * @param content request body + * @return response + * @throws ApplicationException + */ + protected abstract RestResponse sendRequest(String content) throws ApplicationException; + + /** + * handle the url before request to nssmf, include get the nssmf request url, replace the path variable + */ + private void urlHandler() { + NssmfUrlInfo nssmfUrlInfo = + NssmfAdapterConsts.getNssmfUrlInfo(this.executorType, this.esrInfo.getNetworkType(), actionType); + this.nssmfUrl = nssmfUrlInfo.getUrl(); + this.httpMethod = nssmfUrlInfo.getHttpMethod(); + this.nssmfUrl = nssmfUrl.replaceAll("\\{apiVersion}", getApiVersion()); + this.params.forEach((k, v) -> this.nssmfUrl = this.nssmfUrl.replaceAll("\\{" + k + "}", v)); + } + + /** + * after request + */ + protected abstract void afterRequest() throws ApplicationException; + + protected abstract String getApiVersion(); + + public RestUtil getRestUtil() { + return restUtil; + } + + public BaseNssmfManager setEsrInfo(EsrInfo esrInfo) { + this.esrInfo = esrInfo; + return this; + } + + public BaseNssmfManager setExecutorType(ExecutorType executorType) { + this.executorType = executorType; + return this; + } + + public BaseNssmfManager setRestUtil(RestUtil restUtil) { + this.restUtil = restUtil; + return this; + } + + public BaseNssmfManager setActionType(ActionType actionType) { + this.actionType = actionType; + return this; + } + + public BaseNssmfManager setRepository(ResourceOperationStatusRepository repository) { + this.repository = repository; + return this; + } + + public BaseNssmfManager setServiceInfo(ServiceInfo serviceInfo) { + this.serviceInfo = serviceInfo; + return this; + } + + public BaseNssmfManager setInitStatus(String initStatus) { + this.initStatus = initStatus; + return this; + } + + public BaseNssmfManager setAdapterConfig(NssmfAdapterConfig adapterConfig) { + this.adapterConfig = adapterConfig; + return this; + } +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/ExternalNssmfManager.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/ExternalNssmfManager.java new file mode 100644 index 0000000000..d8a9088a42 --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/ExternalNssmfManager.java @@ -0,0 +1,187 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.manager.impl; + +import org.apache.http.Header; +import org.apache.http.message.BasicHeader; +import org.onap.aai.domain.yang.ServiceInstance; +import org.onap.so.adapters.nssmf.entity.NssmfInfo; +import org.onap.so.adapters.nssmf.entity.RestResponse; +import org.onap.so.adapters.nssmf.enums.JobStatus; +import org.onap.so.adapters.nssmf.exceptions.ApplicationException; +import org.onap.so.adapters.nssmf.util.NssmfAdapterUtil; +import org.onap.so.beans.nsmf.*; +import org.onap.so.db.request.beans.ResourceOperationStatus; +import static java.lang.String.valueOf; +import static org.onap.so.adapters.nssmf.enums.JobStatus.*; +import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.StatusDesc.*; +import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.marshal; +import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.unMarshal; + +public abstract class ExternalNssmfManager extends BaseNssmfManager { + + @Override + protected String wrapAllocateReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + return doWrapExtAllocateReqBody(nbiRequest); + } + + protected abstract String doWrapExtAllocateReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException; + + @Override + protected String wrapModifyReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + return doWrapModifyReqBody(nbiRequest); + } + + protected abstract String doWrapModifyReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException; + + @Override + protected String wrapDeAllocateReqBody(DeAllocateNssi deAllocateNssi) throws ApplicationException { + return doWrapDeAllocateReqBody(deAllocateNssi); + } + + protected abstract String doWrapDeAllocateReqBody(DeAllocateNssi deAllocateNssi) throws ApplicationException; + + @Override + protected void afterQueryJobStatus(ResourceOperationStatus status) { + if (Integer.parseInt(status.getProgress()) == 100) { + + ServiceInstance nssiInstance = new ServiceInstance(); + nssiInstance.setServiceInstanceId(serviceInfo.getNssiId()); + nssiInstance.setServiceInstanceName(serviceInfo.getNssiName()); + nssiInstance.setServiceType(serviceInfo.getSST()); + + nssiInstance.setOrchestrationStatus(initStatus); + nssiInstance.setModelInvariantId(serviceInfo.getServiceInvariantUuid()); + nssiInstance.setModelVersionId(serviceInfo.getServiceUuid()); + nssiInstance.setServiceInstanceLocationId(serviceInfo.getPLMNIdList()); + nssiInstance.setEnvironmentContext(esrInfo.getNetworkType().getNetworkType()); + nssiInstance.setServiceRole("nssi"); + + restUtil.createServiceInstance(nssiInstance, serviceInfo); + } + } + + + + @Override + protected String wrapActDeActReqBody(ActDeActNssi actDeActNssi) throws ApplicationException { + return marshal(actDeActNssi); + } + + protected RestResponse doQueryJobStatus(ResourceOperationStatus status) throws ApplicationException { + return doResponseStatus(status); + } + + private RestResponse doResponseStatus(ResourceOperationStatus status) throws ApplicationException { + RestResponse restResponse = sendRequest(null); + JobStatusResponse jobStatusResponse = unMarshal(restResponse.getResponseContent(), JobStatusResponse.class); + + ResponseDescriptor rspDesc = jobStatusResponse.getResponseDescriptor(); + rspDesc.setNssiId(status.getResourceInstanceID()); + + jobStatusResponse.setResponseDescriptor(rspDesc); + restResponse.setResponseContent(marshal(jobStatusResponse)); + updateRequestDbJobStatus(rspDesc, status, restResponse); + return restResponse; + } + + @Override + protected String wrapReqBody(Object object) throws ApplicationException { + return marshal(object); + } + + @Override + protected RestResponse sendRequest(String content) throws ApplicationException { + return sendExternalRequest(content); + } + + @Override + protected String getApiVersion() { + return "v1"; + } + + + // external + protected RestResponse sendExternalRequest(String content) throws ApplicationException { + NssmfInfo nssmfInfo = restUtil.getNssmfHost(esrInfo); + Header header = new BasicHeader("X-Auth-Token", restUtil.getToken(nssmfInfo)); + String nssmfUrl = nssmfInfo.getUrl() + this.nssmfUrl; + return restUtil.send(nssmfUrl, this.httpMethod, content, header); + } + + private void updateRequestDbJobStatus(ResponseDescriptor rspDesc, ResourceOperationStatus status, RestResponse rsp) + throws ApplicationException { + + switch (fromString(rspDesc.getStatus())) { + case STARTED: + updateDbStatus(status, rsp.getStatus(), STARTED, QUERY_JOB_STATUS_SUCCESS); + break; + case PROCESSING: + updateDbStatus(status, rsp.getStatus(), PROCESSING, QUERY_JOB_STATUS_SUCCESS); + break; + case FINISHED: + if (rspDesc.getProgress() == 100) { + updateDbStatus(status, rsp.getStatus(), FINISHED, QUERY_JOB_STATUS_SUCCESS); + } + break; + case ERROR: + updateDbStatus(status, rsp.getStatus(), ERROR, QUERY_JOB_STATUS_FAILED); + throw new ApplicationException(500, QUERY_JOB_STATUS_FAILED); + } + } + + protected void updateDbStatus(ResourceOperationStatus status, int rspStatus, JobStatus jobStatus, + String description) { + status.setErrorCode(valueOf(rspStatus)); + status.setStatus(jobStatus.toString()); + status.setStatusDescription(description); + repository.save(status); + } + + @Override + protected RestResponse doQuerySubnetCapability(String req) throws ApplicationException { + RestResponse response = new RestResponse(); + response.setStatus(200); + response.setResponseContent(null); + return response; + } + + /** + * after request, if response code is 2XX, continue handle, else return + */ + @Override + protected void afterRequest() throws ApplicationException { + if (valueOf(restResponse.getStatus()).startsWith("2")) { + doAfterRequest(); + } + } + + + protected void doAfterRequest() throws ApplicationException { + // + NssiResponse response = unMarshal(restResponse.getResponseContent(), NssiResponse.class); + ResourceOperationStatus status = + new ResourceOperationStatus(serviceInfo.getNsiId(), response.getJobId(), serviceInfo.getServiceUuid()); + status.setResourceInstanceID(response.getNssiId()); + + updateDbStatus(status, restResponse.getStatus(), STARTED, NssmfAdapterUtil.getStatusDesc(actionType)); + } +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/InternalNssmfManager.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/InternalNssmfManager.java new file mode 100644 index 0000000000..348bf12bcb --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/InternalNssmfManager.java @@ -0,0 +1,129 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.manager.impl; + +import org.apache.http.Header; +import org.apache.http.message.BasicHeader; +import org.onap.so.adapters.nssmf.consts.NssmfAdapterConsts; +import org.onap.so.adapters.nssmf.entity.RestResponse; +import org.onap.so.adapters.nssmf.enums.SelectionType; +import org.onap.so.adapters.nssmf.exceptions.ApplicationException; +import org.onap.so.beans.nsmf.*; +import org.onap.so.db.request.beans.ResourceOperationStatus; +import static org.onap.so.adapters.nssmf.enums.JobStatus.PROCESSING; +import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.marshal; + +public abstract class InternalNssmfManager extends BaseNssmfManager { + + @Override + protected String wrapAllocateReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + return doWrapAllocateReqBody(nbiRequest); + } + + protected abstract String doWrapAllocateReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException; + + @Override + protected String wrapReqBody(Object object) throws ApplicationException { + NssmfRequest nssmfRequest = new NssmfRequest(serviceInfo, esrInfo.getNetworkType(), object); + return marshal(nssmfRequest); + } + + + @Override + protected String wrapActDeActReqBody(ActDeActNssi actDeActNssi) throws ApplicationException { + + return wrapReqBody(actDeActNssi); + } + + + @Override + protected String wrapDeAllocateReqBody(DeAllocateNssi deAllocateNssi) throws ApplicationException { + return wrapReqBody(deAllocateNssi); + } + + + @Override + protected RestResponse doQueryJobStatus(ResourceOperationStatus status) throws ApplicationException { + return responseDBStatus(status); + } + + private RestResponse responseDBStatus(ResourceOperationStatus status) throws ApplicationException { + ResponseDescriptor descriptor = new ResponseDescriptor(); + if (status == null) { + descriptor.setProgress(0); + descriptor.setStatus(PROCESSING.name()); + descriptor.setStatusDescription("Initiating Nssi Instance"); + return restUtil.createResponse(200, marshal(descriptor)); + } + descriptor.setStatus(status.getStatus()); + descriptor.setStatusDescription(status.getStatusDescription()); + descriptor.setProgress(Integer.parseInt(status.getProgress())); + descriptor.setNssiId(status.getResourceInstanceID()); + // descriptor.setResponseId(status.getOperationId()); + return restUtil.createResponse(200, marshal(descriptor)); + } + + @Override + protected RestResponse sendRequest(String content) { + return sendInternalRequest(content); + } + + @Override + protected void afterRequest() { + // + } + + @Override + protected void afterQueryJobStatus(ResourceOperationStatus status) { + // internal + } + + // internal + private RestResponse sendInternalRequest(String content) { + Header header = new BasicHeader("X-Auth-Token", adapterConfig.getInfraAuth()); + this.nssmfUrl = adapterConfig.getInfraEndpoint() + this.nssmfUrl; + return restUtil.send(this.nssmfUrl, this.httpMethod, content, header); + } + + @Override + protected String getApiVersion() { + return NssmfAdapterConsts.CURRENT_INTERNAL_NSSMF_API_VERSION; + } + + + @Override + protected SelectionType doQueryNSSISelectionCapability() { + return SelectionType.NSSMF; + } + + @Override + protected String wrapModifyReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + return doWrapModifyReqBody(nbiRequest); + } + + protected abstract String doWrapModifyReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException; + + @Override + protected RestResponse doQuerySubnetCapability(String req) throws ApplicationException { + // handler + return sendRequest(req); + } +} 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 new file mode 100644 index 0000000000..bc7a3d0bb7 --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/external/ExternalAnNssmfManager.java @@ -0,0 +1,117 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.manager.impl.external; + +import org.onap.so.adapters.nssmf.entity.RestResponse; +import org.onap.so.adapters.nssmf.enums.ActionType; +import org.onap.so.adapters.nssmf.enums.JobStatus; +import org.onap.so.adapters.nssmf.enums.SelectionType; +import org.onap.so.adapters.nssmf.exceptions.ApplicationException; +import org.onap.so.adapters.nssmf.manager.impl.ExternalNssmfManager; +import org.onap.so.adapters.nssmf.util.NssmfAdapterUtil; +import org.onap.so.beans.nsmf.DeAllocateNssi; +import org.onap.so.beans.nsmf.NssiResponse; +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<>(); + request.put("attributeListIn", nbiRequest.getAllocateAnNssi().getSliceProfile()); + return marshal(request); + } + + @Override + protected void doAfterRequest() throws ApplicationException { + if (ActionType.ALLOCATE.equals(actionType) || ActionType.DEALLOCATE.equals(actionType)) { + 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(UUID.randomUUID().toString()); + resp.setNssiId(nssiId); + + RestResponse returnRsp = new RestResponse(); + + returnRsp.setStatus(202); + returnRsp.setResponseContent(marshal(resp)); + restResponse = returnRsp; + + ResourceOperationStatus status = + new ResourceOperationStatus(serviceInfo.getNsiId(), nssiId, serviceInfo.getServiceUuid()); + status.setResourceInstanceID(nssiId); + + updateDbStatus(status, restResponse.getStatus(), JobStatus.FINISHED, + NssmfAdapterUtil.getStatusDesc(actionType)); + } + // todo + } + + @Override + protected String doWrapModifyReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + // TODO + return null; + } + + @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); + } + + + @Override + public RestResponse modifyNssi(NssmfAdapterNBIRequest modifyRequest) throws ApplicationException { + // TODO + return null; + } + + @Override + public RestResponse activateNssi(NssmfAdapterNBIRequest nbiRequest, String snssai) throws ApplicationException { + // TODO + return null; + } + + @Override + protected SelectionType doQueryNSSISelectionCapability() { + return SelectionType.NSSMF; + } +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/external/ExternalCnNssmfManager.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/external/ExternalCnNssmfManager.java new file mode 100644 index 0000000000..fb76adcce6 --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/external/ExternalCnNssmfManager.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.manager.impl.external; + +import org.onap.so.adapters.nssmf.enums.SelectionType; +import org.onap.so.adapters.nssmf.exceptions.ApplicationException; +import org.onap.so.adapters.nssmf.manager.impl.ExternalNssmfManager; +import org.onap.so.beans.nsmf.DeAllocateNssi; +import org.onap.so.beans.nsmf.NssmfAdapterNBIRequest; +import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.marshal; + +public class ExternalCnNssmfManager extends ExternalNssmfManager { + + @Override + protected String doWrapExtAllocateReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + return marshal(nbiRequest.getAllocateCnNssi()); + } + + @Override + protected String doWrapModifyReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + return marshal(nbiRequest.getAllocateCnNssi()); + } + + @Override + protected String doWrapDeAllocateReqBody(DeAllocateNssi deAllocateNssi) throws ApplicationException { + return marshal(deAllocateNssi); + } + + @Override + protected SelectionType doQueryNSSISelectionCapability() { + + return SelectionType.NSMF; + } + +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/internal/InternalAnNssmfManager.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/internal/InternalAnNssmfManager.java new file mode 100644 index 0000000000..dc6528381b --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/internal/InternalAnNssmfManager.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.manager.impl.internal; + +import org.onap.so.adapters.nssmf.exceptions.ApplicationException; +import org.onap.so.adapters.nssmf.manager.impl.InternalNssmfManager; +import org.onap.so.beans.nsmf.*; +import java.util.HashMap; +import java.util.Map; +import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.marshal; + + +public class InternalAnNssmfManager extends InternalNssmfManager { + + @Override + protected String doWrapAllocateReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + NssmfRequest request = + new NssmfRequest(serviceInfo, nbiRequest.getEsrInfo().getNetworkType(), nbiRequest.getAllocateAnNssi()); + request.setName(nbiRequest.getAllocateAnNssi().getNssiName()); + return marshal(request); + } + + @Override + protected String doWrapModifyReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + AllocateAnNssi allocateAnNssi = nbiRequest.getAllocateAnNssi(); + AnSliceProfile sliceProfile = allocateAnNssi.getSliceProfile(); + Map<String, Object> additional = new HashMap<>(); + additional.put("modifyAction", "allocate"); + additional.put("snssaiList", sliceProfile.getSNSSAIList()); + additional.put("sliceProfileId", sliceProfile.getSliceProfileId()); + additional.put("nsiInfo", allocateAnNssi.getNsiInfo()); + additional.put("scriptName", allocateAnNssi.getScriptName()); + NssmfRequest request = new NssmfRequest(serviceInfo, esrInfo.getNetworkType(), additional); + return marshal(request); + } +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/internal/InternalCnNssmfManager.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/internal/InternalCnNssmfManager.java new file mode 100644 index 0000000000..4a93b3007c --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/internal/InternalCnNssmfManager.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.manager.impl.internal; + +import org.onap.so.adapters.nssmf.exceptions.ApplicationException; +import org.onap.so.adapters.nssmf.manager.impl.InternalNssmfManager; +import org.onap.so.beans.nsmf.*; +import java.util.HashMap; +import java.util.Map; +import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.marshal; + +public class InternalCnNssmfManager extends InternalNssmfManager { + + @Override + protected String doWrapAllocateReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + + NssmfRequest request = + new NssmfRequest(serviceInfo, nbiRequest.getEsrInfo().getNetworkType(), nbiRequest.getAllocateCnNssi()); + request.setName(nbiRequest.getAllocateCnNssi().getNssiName()); + return marshal(request); + } + + @Override + protected String doWrapModifyReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + AllocateCnNssi allocateCnNssi = nbiRequest.getAllocateCnNssi(); + CnSliceProfile cnSliceProfile = allocateCnNssi.getSliceProfile(); + Map<String, Object> additional = new HashMap<>(); + additional.put("modifyAction", "allocate"); + additional.put("nsiInfo", allocateCnNssi.getNsiInfo()); + additional.put("scriptName", allocateCnNssi.getScriptName()); + additional.put("snssaiList", cnSliceProfile.getSnssaiList()); + additional.put("sliceProfileId", cnSliceProfile.getSliceProfileId()); + + NssmfRequest request = new NssmfRequest(serviceInfo, esrInfo.getNetworkType(), additional); + return marshal(request); + } + +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/internal/InternalTnNssmfManager.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/internal/InternalTnNssmfManager.java new file mode 100644 index 0000000000..8bfbd55387 --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/manager/impl/internal/InternalTnNssmfManager.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.manager.impl.internal; + +import org.onap.so.adapters.nssmf.exceptions.ApplicationException; +import org.onap.so.adapters.nssmf.manager.impl.InternalNssmfManager; +import org.onap.so.beans.nsmf.*; +import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.marshal; + +public class InternalTnNssmfManager extends InternalNssmfManager { + + @Override + protected String doWrapAllocateReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + + return marshal(new NssmfRequest(serviceInfo, nbiRequest.getEsrInfo().getNetworkType(), + nbiRequest.getAllocateTnNssi())); + } + + @Override + protected String doWrapModifyReqBody(NssmfAdapterNBIRequest nbiRequest) throws ApplicationException { + // TODO + return null; + } +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/NssmfAdapterRest.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/NssmfAdapterRest.java index d8e1e36058..4fdcbf110f 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/NssmfAdapterRest.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/NssmfAdapterRest.java @@ -20,6 +20,7 @@ package org.onap.so.adapters.nssmf.rest; +import org.onap.so.adapters.nssmf.entity.RestResponse; import org.onap.so.adapters.nssmf.exceptions.ApplicationException; import org.onap.so.beans.nsmf.JobStatusRequest; import org.onap.so.beans.nsmf.NssiActDeActRequest; @@ -43,6 +44,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.assertObjectNotNull; +@Deprecated @Controller @RequestMapping(value = "/api/rest/provMns/v1", produces = {APPLICATION_JSON}, consumes = {APPLICATION_JSON}) public class NssmfAdapterRest { @@ -52,17 +54,6 @@ public class NssmfAdapterRest { @Autowired private NssmfManager nssmfMgr; - @PostMapping(value = "/NSS/SliceProfiles") - public ResponseEntity allocateNssi(@RequestBody NssiAllocateRequest allocate) { - try { - logger.info("Nssmi allocate request is invoked"); - assertObjectNotNull(allocate); - RestResponse rsp = getNssmfMgr().allocateNssi(allocate); - return buildResponse(rsp); - } catch (ApplicationException e) { - return e.buildErrorResponse(); - } - } @PostMapping(value = "/NSS/nssi") public ResponseEntity createNssi(@RequestBody NssiCreateRequest create) { @@ -76,19 +67,6 @@ public class NssmfAdapterRest { } } - @PostMapping(value = "/NSS/SliceProfiles/{sliceProfileId}") - public ResponseEntity deAllocateNssi(@RequestBody NssiDeAllocateRequest deAllocate, - @PathVariable("sliceProfileId") final String sliceId) { - try { - logger.info("Nssmf deallocate request is invoked"); - assertObjectNotNull(deAllocate); - RestResponse rsp = getNssmfMgr().deAllocateNssi(deAllocate, sliceId); - return buildResponse(rsp); - } catch (ApplicationException e) { - return e.buildErrorResponse(); - } - } - @PostMapping(value = "/NSS/nssi/{nssiId}") public ResponseEntity terminateNssi(@RequestBody NssiTerminateRequest terminate, @PathVariable("nssiId") String nssiId) { @@ -128,44 +106,6 @@ public class NssmfAdapterRest { } } - @PostMapping(value = "/NSS/{snssai}/activation") - public ResponseEntity activateNssi(@RequestBody NssiActDeActRequest activate, - @PathVariable("snssai") String snssai) { - try { - logger.info("Nssmf activate request is invoked"); - assertObjectNotNull(activate); - RestResponse rsp = getNssmfMgr().activateNssi(activate, snssai); - return buildResponse(rsp); - } catch (ApplicationException e) { - return e.buildErrorResponse(); - } - } - - @PostMapping(value = "/NSS/{snssai}/deactivation") - public ResponseEntity deactivateNssi(@RequestBody NssiActDeActRequest deActivate, - @PathVariable("snssai") String snssai) { - try { - logger.info("Nssmf activate request is invoked"); - assertObjectNotNull(deActivate); - RestResponse rsp = getNssmfMgr().deActivateNssi(deActivate, snssai); - return buildResponse(rsp); - } catch (ApplicationException e) { - return e.buildErrorResponse(); - } - } - - @PostMapping(value = "/NSS/jobs/{jobId}") - public ResponseEntity queryJobStatus(@RequestBody JobStatusRequest jobStatusReq, - @PathVariable("jobId") String jobId) { - try { - logger.info("Nssmf query job status request is invoked"); - assertObjectNotNull(jobStatusReq); - RestResponse rsp = getNssmfMgr().queryJobStatus(jobStatusReq, jobId); - return buildResponse(rsp); - } catch (ApplicationException e) { - return e.buildErrorResponse(); - } - } @GetMapping(value = "/vendor/{vendorName}/type/{networkType}/NSS" + "/SliceProfiles/{sliceProfileId}") public ResponseEntity queryNssi(@PathVariable("vendorName") String vendorName, diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/NssmfInfo.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/NssmfInfo.java deleted file mode 100644 index 6306643a97..0000000000 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/NssmfInfo.java +++ /dev/null @@ -1,94 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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.adapters.nssmf.rest; - -public class NssmfInfo { - - private String url; - - private String ipAddress; - - private String port; - - private String insecure; - - private String cacert; - - private String userName; - - private String password; - - public String getInsecure() { - return insecure; - } - - public void setInsecure(String insecure) { - this.insecure = insecure; - } - - public String getCacert() { - return cacert; - } - - public void setCacert(String cacert) { - this.cacert = cacert; - } - - public String getIpAddress() { - return ipAddress; - } - - public void setIpAddress(String ipAddress) { - this.ipAddress = ipAddress; - } - - public String getPort() { - return port; - } - - public void setPort(String port) { - this.port = port; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getUserName() { - return userName; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } -} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/NssmfManager.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/NssmfManager.java index 0e25729610..2d0980f60e 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/NssmfManager.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/NssmfManager.java @@ -20,7 +20,10 @@ package org.onap.so.adapters.nssmf.rest; +import org.onap.so.adapters.nssmf.entity.RestResponse; +import org.onap.so.adapters.nssmf.enums.JobStatus; import org.onap.so.adapters.nssmf.exceptions.ApplicationException; +import org.onap.so.adapters.nssmf.util.RestUtil; import org.onap.so.beans.nsmf.ActDeActNssi; import org.onap.so.beans.nsmf.AllocateAnNssi; import org.onap.so.beans.nsmf.AllocateCnNssi; @@ -52,15 +55,15 @@ import org.springframework.context.annotation.Primary; import org.springframework.data.domain.Example; import org.springframework.stereotype.Component; import static java.lang.String.valueOf; -import static org.onap.so.adapters.nssmf.rest.HttpMethod.DELETE; -import static org.onap.so.adapters.nssmf.rest.HttpMethod.GET; -import static org.onap.so.adapters.nssmf.rest.HttpMethod.POST; -import static org.onap.so.adapters.nssmf.rest.HttpMethod.PUT; -import static org.onap.so.adapters.nssmf.rest.JobStatus.ERROR; -import static org.onap.so.adapters.nssmf.rest.JobStatus.FINISHED; -import static org.onap.so.adapters.nssmf.rest.JobStatus.PROCESSING; -import static org.onap.so.adapters.nssmf.rest.JobStatus.STARTED; -import static org.onap.so.adapters.nssmf.rest.JobStatus.fromString; +import static org.onap.so.adapters.nssmf.enums.HttpMethod.DELETE; +import static org.onap.so.adapters.nssmf.enums.HttpMethod.GET; +import static org.onap.so.adapters.nssmf.enums.HttpMethod.POST; +import static org.onap.so.adapters.nssmf.enums.HttpMethod.PUT; +import static org.onap.so.adapters.nssmf.enums.JobStatus.ERROR; +import static org.onap.so.adapters.nssmf.enums.JobStatus.FINISHED; +import static org.onap.so.adapters.nssmf.enums.JobStatus.PROCESSING; +import static org.onap.so.adapters.nssmf.enums.JobStatus.STARTED; +import static org.onap.so.adapters.nssmf.enums.JobStatus.fromString; import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.StatusDesc.ACTIVATE_NSS_SUCCESS; import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.StatusDesc.ALLOCATE_NSS_SUCCESS; import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.StatusDesc.CREATE_NSS_SUCCESS; @@ -76,6 +79,7 @@ import static org.onap.so.beans.nsmf.ActDeActNssi.DE_ACT_URL; @Component @Primary +@Deprecated public class NssmfManager { private static final Logger logger = LoggerFactory.getLogger(NssmfManager.class); @@ -129,14 +133,15 @@ public class NssmfManager { case TRANSPORT: AllocateTnNssi tn = nssmiAllocate.getAllocateTnNssi(); assertObjectNotNull(tn); - assertObjectNotNull(tn.getNsiInfo()); - assertObjectNotNull(tn.getNsiInfo().getNsiId()); - nsiId = tn.getNsiInfo().getNsiId(); + // assertObjectNotNull(tn.getNsiInfo()); + // assertObjectNotNull(tn.getNsiInfo().getNsiId()); + // nsiId = tn.getNsiInfo().getNsiId(); allocateReq = marshal(tn); - allocateUrl = AllocateTnNssi.URL; + // allocateUrl = AllocateTnNssi.URL; break; } + RestResponse rsp = restUtil.sendRequest(allocateUrl, POST, allocateReq, nssmiAllocate.getEsrInfo()); assertObjectNotNull(rsp); @@ -152,6 +157,8 @@ public class NssmfManager { return rsp; } + + public RestResponse createNssi(NssiCreateRequest nssiCreate) throws ApplicationException { assertObjectNotNull(nssiCreate.getEsrInfo()); @@ -192,6 +199,7 @@ public class NssmfManager { return rsp; } + @Deprecated public RestResponse deAllocateNssi(NssiDeAllocateRequest nssiDeallocate, String sliceId) throws ApplicationException { diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/TrustAllHostNameVerifier.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/TrustAllHostNameVerifier.java index 254186bda8..fc0f3ddde5 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/TrustAllHostNameVerifier.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/TrustAllHostNameVerifier.java @@ -23,6 +23,7 @@ package org.onap.so.adapters.nssmf.rest; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; +@Deprecated public class TrustAllHostNameVerifier implements HostnameVerifier { public boolean verify(String hostname, SSLSession session) { diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/service/NssmfManagerService.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/service/NssmfManagerService.java new file mode 100644 index 0000000000..92fe5576dd --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/service/NssmfManagerService.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.service; + +import org.onap.so.adapters.nssmf.annotation.ServiceLogger; +import org.onap.so.beans.nsmf.*; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +@Service +@ServiceLogger +public interface NssmfManagerService { + ResponseEntity allocateNssi(NssmfAdapterNBIRequest allocateRequest); + + ResponseEntity deAllocateNssi(NssmfAdapterNBIRequest allocateRequest, String sliceProfileId); + + ResponseEntity activateNssi(NssmfAdapterNBIRequest deActRequest, String snssai); + + ResponseEntity deActivateNssi(NssmfAdapterNBIRequest nssiDeActivate, String snssai); + + ResponseEntity queryJobStatus(NssmfAdapterNBIRequest jobReq, String jobId); + + ResponseEntity queryNSSISelectionCapability(NssmfAdapterNBIRequest nbiRequest); + + ResponseEntity querySubnetCapability(NssmfAdapterNBIRequest nbiRequest); + +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/service/impl/NssmfManagerServiceImpl.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/service/impl/NssmfManagerServiceImpl.java new file mode 100644 index 0000000000..5b53856f2f --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/service/impl/NssmfManagerServiceImpl.java @@ -0,0 +1,143 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.service.impl; + +import org.apache.commons.lang3.StringUtils; +import org.onap.so.adapters.nssmf.annotation.ServiceLogger; +import org.onap.so.adapters.nssmf.config.NssmfAdapterConfig; +import org.onap.so.adapters.nssmf.enums.ActionType; +import org.onap.so.adapters.nssmf.exceptions.ApplicationException; +import org.onap.so.adapters.nssmf.manager.NssmfManagerBuilder; +import org.onap.so.adapters.nssmf.entity.RestResponse; +import org.onap.so.adapters.nssmf.manager.NssmfManager; +import org.onap.so.adapters.nssmf.service.NssmfManagerService; +import org.onap.so.adapters.nssmf.util.RestUtil; +import org.onap.so.beans.nsmf.*; +import org.onap.so.db.request.data.repository.ResourceOperationStatusRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + + +@Service +@ServiceLogger +public class NssmfManagerServiceImpl implements NssmfManagerService { + + @Autowired + private RestUtil restUtil; + + @Autowired + private ResourceOperationStatusRepository repository; + + @Autowired + private NssmfAdapterConfig nssmfAdapterConfig; + + @Override + public ResponseEntity allocateNssi(NssmfAdapterNBIRequest request) { + try { + + if (StringUtils.isNotBlank(request.getServiceInfo().getNssiId())) { + return buildResponse(buildNssmfManager(request, ActionType.MODIFY).modifyNssi(request)); + } + + return buildResponse(buildNssmfManager(request, ActionType.ALLOCATE).allocateNssi(request)); + + } catch (ApplicationException e) { + return e.buildErrorResponse(); + } + } + + @Override + public ResponseEntity deAllocateNssi(NssmfAdapterNBIRequest request, String sliceProfileId) { + try { + return buildResponse( + buildNssmfManager(request, ActionType.DEALLOCATE).deAllocateNssi(request, sliceProfileId)); + } catch (ApplicationException e) { + return e.buildErrorResponse(); + } + } + + @Override + public ResponseEntity activateNssi(NssmfAdapterNBIRequest request, String snssai) { + try { + return buildResponse(buildNssmfManager(request, ActionType.ACTIVATE).activateNssi(request, snssai)); + } catch (ApplicationException e) { + return e.buildErrorResponse(); + } + } + + @Override + public ResponseEntity deActivateNssi(NssmfAdapterNBIRequest request, String snssai) { + try { + return buildResponse(buildNssmfManager(request, ActionType.DEACTIVATE).deActivateNssi(request, snssai)); + } catch (ApplicationException e) { + return e.buildErrorResponse(); + } + } + + @Override + public ResponseEntity queryJobStatus(NssmfAdapterNBIRequest jobReq, String jobId) { + try { + return buildResponse(buildNssmfManager(jobReq, ActionType.QUERY_JOB_STATUS).queryJobStatus(jobReq, jobId)); + } catch (ApplicationException e) { + return e.buildErrorResponse(); + } + } + + @Override + public ResponseEntity queryNSSISelectionCapability(NssmfAdapterNBIRequest nbiRequest) { + EsrInfo esrInfo = nbiRequest.getEsrInfo(); + try { + return buildResponse(buildNssmfManager(esrInfo, ActionType.QUERY_NSSI_SELECTION_CAPABILITY, null) + .queryNSSISelectionCapability(nbiRequest)); + } catch (ApplicationException e) { + return e.buildErrorResponse(); + } + } + + @Override + public ResponseEntity querySubnetCapability(NssmfAdapterNBIRequest nbiRequest) { + EsrInfo esrInfo = nbiRequest.getEsrInfo(); + try { + return buildResponse(buildNssmfManager(esrInfo, ActionType.QUERY_SUB_NET_CAPABILITY, null) + .querySubnetCapability(nbiRequest)); + } catch (ApplicationException e) { + return e.buildErrorResponse(); + } + } + + private ResponseEntity buildResponse(RestResponse rsp) { + return ResponseEntity.status(rsp.getStatus()).body(rsp.getResponseContent()); + } + + + private NssmfManager buildNssmfManager(NssmfAdapterNBIRequest request, ActionType actionType) + throws ApplicationException { + return buildNssmfManager(request.getEsrInfo(), actionType, request.getServiceInfo()); + } + + private NssmfManager buildNssmfManager(EsrInfo esrInfo, ActionType actionType, ServiceInfo serviceInfo) + throws ApplicationException { + + return new NssmfManagerBuilder(esrInfo).setActionType(actionType).setRepository(repository) + .setRestUtil(restUtil).setAdapterConfig(nssmfAdapterConfig).setServiceInfo(serviceInfo).build(); + } +} diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/util/NssmfAdapterUtil.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/util/NssmfAdapterUtil.java index 3a7c2f19df..090417ddc2 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/util/NssmfAdapterUtil.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/util/NssmfAdapterUtil.java @@ -22,10 +22,12 @@ package org.onap.so.adapters.nssmf.util; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; +import org.onap.so.adapters.nssmf.enums.ActionType; import org.onap.so.adapters.nssmf.exceptions.ApplicationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.onap.logging.filter.base.ErrorCode; +import org.springframework.stereotype.Component; import static org.onap.so.logger.LoggingAnchor.THREE; import static org.onap.so.logger.MessageEnum.RA_NS_EXC; @@ -45,6 +47,8 @@ public class NssmfAdapterUtil { public static final String ALLOCATE_NSS_SUCCESS = "Allocating nss is " + "successful"; + public static final String MODIFY_NSS_SUCCESS = "Modify nss is " + "successful"; + public static final String CREATE_NSS_SUCCESS = "Creating nss is " + "successful"; public static final String DEALLOCATE_NSS_SUCCESS = "Deallocate nss " + "is successful"; @@ -91,4 +95,29 @@ public class NssmfAdapterUtil { } } + + public static String getStatusDesc(ActionType actionType) { + String desc = ""; + switch (actionType) { + case ALLOCATE: + desc = StatusDesc.ALLOCATE_NSS_SUCCESS; + break; + case DEALLOCATE: + desc = StatusDesc.DEALLOCATE_NSS_SUCCESS; + break; + case ACTIVATE: + desc = StatusDesc.ACTIVATE_NSS_SUCCESS; + break; + case DEACTIVATE: + desc = StatusDesc.DEACTIVATE_NSS_SUCCESS; + break; + case MODIFY: + desc = StatusDesc.MODIFY_NSS_SUCCESS; + break; + default: + break; + } + + return desc; + } } diff --git a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/RestUtil.java b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/util/RestUtil.java index dcc6f5ba72..0c5999b20e 100644 --- a/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/rest/RestUtil.java +++ b/adapters/mso-nssmf-adapter/src/main/java/org/onap/so/adapters/nssmf/util/RestUtil.java @@ -18,11 +18,9 @@ * ============LICENSE_END========================================================= */ -package org.onap.so.adapters.nssmf.rest; +package org.onap.so.adapters.nssmf.util; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; +import javax.net.ssl.*; import javax.ws.rs.core.UriBuilder; import java.net.SocketTimeoutException; import java.net.URI; @@ -30,32 +28,29 @@ import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpPut; -import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.client.methods.*; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicHeader; import org.apache.http.util.EntityUtils; -import org.onap.aai.domain.yang.EsrSystemInfo; -import org.onap.aai.domain.yang.EsrSystemInfoList; -import org.onap.aai.domain.yang.EsrThirdpartySdnc; -import org.onap.aai.domain.yang.EsrThirdpartySdncList; +import org.onap.aai.domain.yang.*; import org.onap.so.adapters.nssmf.exceptions.ApplicationException; import org.onap.so.adapters.nssmf.extclients.aai.AaiServiceProvider; -import org.onap.so.adapters.nssmf.model.TokenRequest; -import org.onap.so.adapters.nssmf.model.TokenResponse; +import org.onap.so.adapters.nssmf.entity.TokenRequest; +import org.onap.so.adapters.nssmf.entity.TokenResponse; +import org.onap.so.adapters.nssmf.enums.HttpMethod; +import org.onap.so.adapters.nssmf.entity.NssmfInfo; +import org.onap.so.adapters.nssmf.entity.RestResponse; import org.onap.so.beans.nsmf.EsrInfo; +import org.onap.so.beans.nsmf.ServiceInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import static org.apache.http.entity.ContentType.APPLICATION_JSON; -import static org.onap.so.adapters.nssmf.rest.HttpMethod.POST; +import static org.onap.so.adapters.nssmf.enums.HttpMethod.POST; import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.BAD_REQUEST; import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.marshal; import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.unMarshal; @@ -77,6 +72,10 @@ public class RestUtil { @Autowired private AaiServiceProvider aaiSvcProv; + public void createServiceInstance(ServiceInstance serviceInstance, ServiceInfo serviceInfo) { + aaiSvcProv.invokeCreateServiceInstance(serviceInstance, serviceInfo.getGlobalSubscriberId(), + serviceInfo.getSubscriptionServiceType(), serviceInfo.getNssiId()); + } public NssmfInfo getNssmfHost(EsrInfo esrInfo) throws ApplicationException { EsrThirdpartySdncList sdncList = aaiSvcProv.invokeGetThirdPartySdncList(); @@ -112,10 +111,9 @@ public class RestUtil { throw new ApplicationException(BAD_REQUEST, "ESR information is improper"); } - public RestResponse sendRequest(String url, HttpMethod methodType, String content, EsrInfo esrInfo) - throws ApplicationException { - NssmfInfo nssmfInfo = getNssmfHost(esrInfo); + public String getToken(NssmfInfo nssmfInfo) throws ApplicationException { + TokenRequest req = new TokenRequest(); req.setGrantType("password"); @@ -128,13 +126,12 @@ public class RestUtil { RestResponse tokenRes = send(nssmfInfo.getUrl() + TOKEN_URL, POST, tokenReq, null); TokenResponse res = unMarshal(tokenRes.getResponseContent(), TokenResponse.class); - String token = res.getAccessToken(); - Header header = new BasicHeader("X-Auth-Token", token); - String nssmfUrl = nssmfInfo.getUrl() + url; - return send(nssmfUrl, methodType, content, header); + + return res.getAccessToken(); } - private RestResponse send(String url, HttpMethod methodType, String content, Header header) { + + public RestResponse send(String url, HttpMethod methodType, String content, Header header) { HttpRequestBase req = null; HttpResponse res = null; @@ -168,8 +165,6 @@ public class RestUtil { } if (null != req) { req.reset(); - } else { - logger.debug("method is NULL:"); } req = null; @@ -201,7 +196,7 @@ public class RestUtil { } } - private RestResponse createResponse(int statusCode, String errMsg) { + public RestResponse createResponse(int statusCode, String errMsg) { RestResponse restResponse = new RestResponse(); restResponse.setStatus(statusCode); restResponse.setResponseContent(errMsg); @@ -210,7 +205,7 @@ public class RestUtil { private HttpRequestBase getHttpReq(String url, HttpMethod method, Header header, RequestConfig config, String content) throws ApplicationException { - HttpRequestBase base = null; + HttpRequestBase base; switch (method) { case POST: HttpPost post = new HttpPost(url); @@ -229,6 +224,7 @@ public class RestUtil { break; case PATCH: + base = new HttpPatch(url); break; case DELETE: @@ -238,6 +234,8 @@ public class RestUtil { } base = delete; break; + default: + throw new ApplicationException(404, "invalid method: " + method); } base.setConfig(config); @@ -247,6 +245,14 @@ public class RestUtil { return base; } + public RestResponse sendRequest(String allocateUrl, HttpMethod post, String allocateReq, EsrInfo esrInfo) + throws ApplicationException { + NssmfInfo nssmfInfo = getNssmfHost(esrInfo); + Header header = new BasicHeader("X-Auth-Token", getToken(nssmfInfo)); + String nssmfUrl = nssmfInfo.getUrl() + allocateUrl; + return send(nssmfUrl, post, allocateReq, header); + } + class HttpDeleteWithBody extends HttpEntityEnclosingRequestBase { public static final String METHOD_NAME = "DELETE"; @@ -289,7 +295,7 @@ public class RestUtil { // HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); SSLConnectionSocketFactory sslsf = - new SSLConnectionSocketFactory(sc, new String[] {"TLSv1"}, null, new TrustAllHostNameVerifier()); + new SSLConnectionSocketFactory(sc, new String[] {"TLSv1"}, null, (s, sslSession) -> true); return HttpClients.custom().setSSLSocketFactory(sslsf).build(); } catch (Exception e) { throw new IllegalArgumentException(e); diff --git a/adapters/mso-nssmf-adapter/src/main/resources/application-test.yaml b/adapters/mso-nssmf-adapter/src/main/resources/application-test.yaml new file mode 100644 index 0000000000..8e10dfb72b --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/main/resources/application-test.yaml @@ -0,0 +1,60 @@ + +aai: + auth: 2A11B07DB6214A839394AA1EC5844695F5114FC407FF5422625FB00175A3DCB8A1FF745F22867EFA72D5369D599BBD88DA8BED4233CF5586 + endpoint: https://aai.onap:30233 +logging: + path: logs + +spring: + datasource: + jdbcUrl: jdbc:mariadb://49.232.146.162:8989/requestdb + username: root + password: 123456 + driver-class-name: org.mariadb.jdbc.Driver + initialization-mode: always + jpa: + generate-ddl: false + show-sql: false + hibernate: + ddl-auto: none + naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy + enable-lazy-load-no-trans: true + database-platform: org.hibernate.dialect.MySQL5InnoDBDialect + security: + usercredentials: + - username: bpel + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPEL-Client + - username: mso_admin + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: ACTUATOR +server: + port: 8080 + tomcat: + max-threads: 50 + +mso: + key: 07a7159d3bf51a0e53be7a8f89699be7 + site-name: localSite + logPath: ./logs/nssmf + adapters: + requestDb: + endpoint: https://so-request-db-adapter.onap:8083 + auth: Basic YnBlbDpwYXNzd29yZDEk + infra: + endpoint: https://so.onap:8080 + auth: Basic SW5mcmFQb3J0YWxDbGllbnQ6cGFzc3dvcmQxJA== + +#Actuator +management: + endpoints: + web: + base-path: /manage + exposure: + include: "*" + metrics: + se-global-registry: false + export: + prometheus: + enabled: true # Whether exporting of metrics to Prometheus is enabled. + step: 1m # Step size (i.e. reporting frequency) to use.
\ No newline at end of file diff --git a/adapters/mso-nssmf-adapter/src/main/resources/application.yaml b/adapters/mso-nssmf-adapter/src/main/resources/application.yaml index 303d63d4a2..8da911d4e0 100644 --- a/adapters/mso-nssmf-adapter/src/main/resources/application.yaml +++ b/adapters/mso-nssmf-adapter/src/main/resources/application.yaml @@ -58,6 +58,9 @@ mso: requestDb: endpoint: https://so-request-db-adapter.{{ include "common.namespace" . }}:8083 auth: Basic YnBlbDpwYXNzd29yZDEk + infra: + endpoint: https://so.{{ include "common.namespace" . }}:8080 + auth: Basic SW5mcmFQb3J0YWxDbGllbnQ6cGFzc3dvcmQxJA== #Actuator management: diff --git a/adapters/mso-nssmf-adapter/src/test/java/org/onap/so/adapters/nssmf/NssmfAdapterRestTest.java b/adapters/mso-nssmf-adapter/src/test/java/org/onap/so/adapters/nssmf/NssmfAdapterRestTest.java index 5bfd39096c..67cd913b3e 100644 --- a/adapters/mso-nssmf-adapter/src/test/java/org/onap/so/adapters/nssmf/NssmfAdapterRestTest.java +++ b/adapters/mso-nssmf-adapter/src/test/java/org/onap/so/adapters/nssmf/NssmfAdapterRestTest.java @@ -24,6 +24,7 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.LinkedList; import java.util.List; +import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; @@ -35,12 +36,12 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -import org.onap.so.adapters.nssmf.model.TokenResponse; -import org.onap.so.adapters.nssmf.rest.HttpMethod; +import org.onap.so.adapters.nssmf.entity.TokenResponse; +import org.onap.so.adapters.nssmf.enums.HttpMethod; import org.onap.so.adapters.nssmf.rest.NssmfAdapterRest; -import org.onap.so.adapters.nssmf.rest.NssmfInfo; +import org.onap.so.adapters.nssmf.entity.NssmfInfo; import org.onap.so.adapters.nssmf.rest.NssmfManager; -import org.onap.so.adapters.nssmf.rest.RestUtil; +import org.onap.so.adapters.nssmf.util.RestUtil; import org.onap.so.beans.nsmf.ActDeActNssi; import org.onap.so.beans.nsmf.AllocateCnNssi; import org.onap.so.beans.nsmf.CnSliceProfile; @@ -53,7 +54,7 @@ import org.onap.so.beans.nsmf.NssiAllocateRequest; import org.onap.so.beans.nsmf.NssiDeAllocateRequest; import org.onap.so.beans.nsmf.NssiResponse; import org.onap.so.beans.nsmf.PerfReq; -import org.onap.so.beans.nsmf.PerfReqEmbbList; +import org.onap.so.beans.nsmf.PerfReqEmbb; import org.onap.so.db.request.data.repository.ResourceOperationStatusRepository; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; @@ -127,13 +128,16 @@ public class NssmfAdapterRestTest { } private void createCommonMock(int statusCode, NssmfInfo nssmf) throws Exception { + when(this.restUtil.send(any(String.class), any(HttpMethod.class), any(String.class), any(Header.class))) + .thenCallRealMethod(); + when(this.restUtil.createResponse(any(Integer.class), any(String.class))).thenCallRealMethod(); when(nssmfRest.getNssmfMgr()).thenReturn(nssmfMgr); - when(nssmfRest.allocateNssi(any(NssiAllocateRequest.class))).thenCallRealMethod(); - when(nssmfRest.deAllocateNssi(any(NssiDeAllocateRequest.class), any(String.class))).thenCallRealMethod(); - when(nssmfRest.activateNssi(any(NssiActDeActRequest.class), any(String.class))).thenCallRealMethod(); - when(nssmfRest.deactivateNssi(any(NssiActDeActRequest.class), any(String.class))).thenCallRealMethod(); - - when(nssmfRest.queryJobStatus(any(JobStatusRequest.class), any(String.class))).thenCallRealMethod(); + // when(nssmfRest.createAllocateNssi(any(NssiAllocateRequest.class))).thenCallRealMethod(); + // when(nssmfRest.deAllocateNssi(any(NssiDeAllocateRequest.class), any(String.class))).thenCallRealMethod(); + // when(nssmfRest.activateNssi(any(NssiActDeActRequest.class), any(String.class))).thenCallRealMethod(); + // when(nssmfRest.deactivateNssi(any(NssiActDeActRequest.class), any(String.class))).thenCallRealMethod(); + // + // when(nssmfRest.queryJobStatus(any(JobStatusRequest.class), any(String.class))).thenCallRealMethod(); when(restUtil.sendRequest(any(String.class), any(HttpMethod.class), any(String.class), any(EsrInfo.class))) .thenCallRealMethod(); when(restUtil.getHttpsClient()).thenReturn(httpClient); @@ -168,113 +172,113 @@ public class NssmfAdapterRestTest { doAnswer(answer).when(httpClient).execute(any(HttpRequestBase.class)); } - @Test - public void testNssiAllocate() throws Exception { - NssmfInfo nssmf = new NssmfInfo(); - nssmf.setUserName("nssmf-user"); - nssmf.setPassword("nssmf-pass"); - nssmf.setPort("8080"); - nssmf.setIpAddress("127.0.0.1"); - - NssiResponse nssiRes = new NssiResponse(); - nssiRes.setJobId("4b45d919816ccaa2b762df5120f72067"); - nssiRes.setNssiId("NSSI-C-001-HDBNJ-NSSMF-01-A-ZX"); - - TokenResponse token = new TokenResponse(); - token.setAccessToken("7512eb3feb5249eca5ddd742fedddd39"); - token.setExpires(1800); - - postStream = new ByteArrayInputStream(marshal(nssiRes).getBytes(UTF_8)); - tokenStream = new ByteArrayInputStream(marshal(token).getBytes(UTF_8)); - - createCommonMock(200, nssmf); - // assertEquals(prettyPrint(allocateNssi()), ALLOCATE); - ResponseEntity res = nssmfRest.allocateNssi(allocateNssi()); - assertNotNull(res); - assertNotNull(res.getBody()); - NssiResponse allRes = unMarshal(res.getBody().toString(), NssiResponse.class); - assertEquals(allRes.getJobId(), "4b45d919816ccaa2b762df5120f72067"); - assertEquals(allRes.getNssiId(), "NSSI-C-001-HDBNJ-NSSMF-01-A-ZX"); - } - - @Test - public void testNssiDeAllocate() throws Exception { - NssmfInfo nssmf = new NssmfInfo(); - nssmf.setUserName("nssmf-user"); - nssmf.setPassword("nssmf-pass"); - nssmf.setPort("8080"); - nssmf.setIpAddress("127.0.0.1"); - - NssiResponse nssiRes = new NssiResponse(); - nssiRes.setJobId("4b45d919816ccaa2b762df5120f72067"); - - TokenResponse token = new TokenResponse(); - token.setAccessToken("7512eb3feb5249eca5ddd742fedddd39"); - token.setExpires(1800); - - postStream = new ByteArrayInputStream(marshal(nssiRes).getBytes(UTF_8)); - tokenStream = new ByteArrayInputStream(marshal(token).getBytes(UTF_8)); - - createCommonMock(200, nssmf); - ResponseEntity res = nssmfRest.deAllocateNssi(deAllocateNssi(), "ab9af40f13f721b5f13539d87484098"); - assertNotNull(res); - assertNotNull(res.getBody()); - NssiResponse allRes = unMarshal(res.getBody().toString(), NssiResponse.class); - assertEquals(allRes.getJobId(), "4b45d919816ccaa2b762df5120f72067"); - } - - @Test - public void testNssiActivate() throws Exception { - NssmfInfo nssmf = new NssmfInfo(); - nssmf.setUserName("nssmf-user"); - nssmf.setPassword("nssmf-pass"); - nssmf.setPort("8080"); - nssmf.setIpAddress("127.0.0.1"); - - NssiResponse nssiRes = new NssiResponse(); - nssiRes.setJobId("4b45d919816ccaa2b762df5120f72067"); - - TokenResponse token = new TokenResponse(); - token.setAccessToken("7512eb3feb5249eca5ddd742fedddd39"); - token.setExpires(1800); - - postStream = new ByteArrayInputStream(marshal(nssiRes).getBytes(UTF_8)); - tokenStream = new ByteArrayInputStream(marshal(token).getBytes(UTF_8)); - - createCommonMock(200, nssmf); - ResponseEntity res = nssmfRest.activateNssi(activateNssi(), "001-100001"); - assertNotNull(res); - assertNotNull(res.getBody()); - NssiResponse allRes = unMarshal(res.getBody().toString(), NssiResponse.class); - assertEquals(allRes.getJobId(), "4b45d919816ccaa2b762df5120f72067"); - } - - @Test - public void testNssiDeActivate() throws Exception { - NssmfInfo nssmf = new NssmfInfo(); - nssmf.setUserName("nssmf-user"); - nssmf.setPassword("nssmf-pass"); - nssmf.setPort("8080"); - nssmf.setIpAddress("127.0.0.1"); - - NssiResponse nssiRes = new NssiResponse(); - nssiRes.setJobId("4b45d919816ccaa2b762df5120f72067"); - - TokenResponse token = new TokenResponse(); - token.setAccessToken("7512eb3feb5249eca5ddd742fedddd39"); - token.setExpires(1800); - - postStream = new ByteArrayInputStream(marshal(nssiRes).getBytes(UTF_8)); - tokenStream = new ByteArrayInputStream(marshal(token).getBytes(UTF_8)); - - createCommonMock(200, nssmf); - ResponseEntity res = nssmfRest.deactivateNssi(deActivateNssi(), "001-100001"); - assertNotNull(res); - assertNotNull(res.getBody()); - NssiResponse allRes = unMarshal(res.getBody().toString(), NssiResponse.class); - assertEquals(allRes.getJobId(), "4b45d919816ccaa2b762df5120f72067"); - } - + // @Test + // public void testNssiAllocate() throws Exception { + // NssmfInfo nssmf = new NssmfInfo(); + // nssmf.setUserName("nssmf-user"); + // nssmf.setPassword("nssmf-pass"); + // nssmf.setPort("8080"); + // nssmf.setIpAddress("127.0.0.1"); + // + // NssiResponse nssiRes = new NssiResponse(); + // nssiRes.setJobId("4b45d919816ccaa2b762df5120f72067"); + // nssiRes.setNssiId("NSSI-C-001-HDBNJ-NSSMF-01-A-ZX"); + // + // TokenResponse token = new TokenResponse(); + // token.setAccessToken("7512eb3feb5249eca5ddd742fedddd39"); + // token.setExpires(1800); + // + // postStream = new ByteArrayInputStream(marshal(nssiRes).getBytes(UTF_8)); + // tokenStream = new ByteArrayInputStream(marshal(token).getBytes(UTF_8)); + // + // createCommonMock(200, nssmf); + // // assertEquals(prettyPrint(createAllocateNssi()), ALLOCATE); + // ResponseEntity res = nssmfRest.createAllocateNssi(createAllocateNssi()); + // assertNotNull(res); + // assertNotNull(res.getBody()); + // NssiResponse allRes = unMarshal(res.getBody().toString(), NssiResponse.class); + // assertEquals(allRes.getJobId(), "4b45d919816ccaa2b762df5120f72067"); + // assertEquals(allRes.getNssiId(), "NSSI-C-001-HDBNJ-NSSMF-01-A-ZX"); + // } + // + // @Test + // public void testNssiDeAllocate() throws Exception { + // NssmfInfo nssmf = new NssmfInfo(); + // nssmf.setUserName("nssmf-user"); + // nssmf.setPassword("nssmf-pass"); + // nssmf.setPort("8080"); + // nssmf.setIpAddress("127.0.0.1"); + // + // NssiResponse nssiRes = new NssiResponse(); + // nssiRes.setJobId("4b45d919816ccaa2b762df5120f72067"); + // + // TokenResponse token = new TokenResponse(); + // token.setAccessToken("7512eb3feb5249eca5ddd742fedddd39"); + // token.setExpires(1800); + // + // postStream = new ByteArrayInputStream(marshal(nssiRes).getBytes(UTF_8)); + // tokenStream = new ByteArrayInputStream(marshal(token).getBytes(UTF_8)); + // + // createCommonMock(200, nssmf); + // ResponseEntity res = nssmfRest.deAllocateNssi(deAllocateNssi(), "ab9af40f13f721b5f13539d87484098"); + // assertNotNull(res); + // assertNotNull(res.getBody()); + // NssiResponse allRes = unMarshal(res.getBody().toString(), NssiResponse.class); + // assertEquals(allRes.getJobId(), "4b45d919816ccaa2b762df5120f72067"); + // } + // + // @Test + // public void testNssiActivate() throws Exception { + // NssmfInfo nssmf = new NssmfInfo(); + // nssmf.setUserName("nssmf-user"); + // nssmf.setPassword("nssmf-pass"); + // nssmf.setPort("8080"); + // nssmf.setIpAddress("127.0.0.1"); + // + // NssiResponse nssiRes = new NssiResponse(); + // nssiRes.setJobId("4b45d919816ccaa2b762df5120f72067"); + // + // TokenResponse token = new TokenResponse(); + // token.setAccessToken("7512eb3feb5249eca5ddd742fedddd39"); + // token.setExpires(1800); + // + // postStream = new ByteArrayInputStream(marshal(nssiRes).getBytes(UTF_8)); + // tokenStream = new ByteArrayInputStream(marshal(token).getBytes(UTF_8)); + // + // createCommonMock(200, nssmf); + // ResponseEntity res = nssmfRest.activateNssi(activateNssi(), "001-100001"); + // assertNotNull(res); + // assertNotNull(res.getBody()); + // NssiResponse allRes = unMarshal(res.getBody().toString(), NssiResponse.class); + // assertEquals(allRes.getJobId(), "4b45d919816ccaa2b762df5120f72067"); + // } + // + // @Test + // public void testNssiDeActivate() throws Exception { + // NssmfInfo nssmf = new NssmfInfo(); + // nssmf.setUserName("nssmf-user"); + // nssmf.setPassword("nssmf-pass"); + // nssmf.setPort("8080"); + // nssmf.setIpAddress("127.0.0.1"); + // + // NssiResponse nssiRes = new NssiResponse(); + // nssiRes.setJobId("4b45d919816ccaa2b762df5120f72067"); + // + // TokenResponse token = new TokenResponse(); + // token.setAccessToken("7512eb3feb5249eca5ddd742fedddd39"); + // token.setExpires(1800); + // + // postStream = new ByteArrayInputStream(marshal(nssiRes).getBytes(UTF_8)); + // tokenStream = new ByteArrayInputStream(marshal(token).getBytes(UTF_8)); + // + // createCommonMock(200, nssmf); + // ResponseEntity res = nssmfRest.deactivateNssi(deActivateNssi(), "001-100001"); + // assertNotNull(res); + // assertNotNull(res.getBody()); + // NssiResponse allRes = unMarshal(res.getBody().toString(), NssiResponse.class); + // assertEquals(allRes.getJobId(), "4b45d919816ccaa2b762df5120f72067"); + // } + // @Test public void testAllocateJsonSerDeSer() throws Exception { assertEquals(marshal(allocateNssi()), ALLOCATE); @@ -285,7 +289,7 @@ public class NssmfAdapterRestTest { assertEquals(all.getAllocateCnNssi().getSliceProfile().getResourceSharingLevel(), NON_SHARED); assertNotNull(all.getAllocateCnNssi().getSliceProfile().getPerfReq()); assertNotNull(all.getAllocateCnNssi().getSliceProfile().getPerfReq().getPerfReqEmbbList()); - PerfReqEmbbList embb = + PerfReqEmbb embb = all.getAllocateCnNssi().getSliceProfile().getPerfReq().getPerfReqEmbbList().iterator().next(); assertNotNull(embb); assertEquals(embb.getActivityFactor(), 50); @@ -298,9 +302,9 @@ public class NssmfAdapterRestTest { List<String> plmn = new LinkedList<>(); plmn.add("460-00"); plmn.add("460-01"); - PerfReqEmbbList embb = new PerfReqEmbbList(); + PerfReqEmbb embb = new PerfReqEmbb(); embb.setActivityFactor(50); - List<PerfReqEmbbList> embbList = new LinkedList<>(); + List<PerfReqEmbb> embbList = new LinkedList<>(); embbList.add(embb); PerfReq perfReq = new PerfReq(); perfReq.setPerfReqEmbbList(embbList); @@ -334,50 +338,51 @@ public class NssmfAdapterRestTest { return allocate; } - public NssiDeAllocateRequest deAllocateNssi() throws Exception { - DeAllocateNssi deAllocateNssi = new DeAllocateNssi(); - deAllocateNssi.setTerminateNssiOption(0); - List<String> snssai = new LinkedList<>(); - snssai.add("001-100001"); - deAllocateNssi.setNsiId("NSI-M-001-HDBNJ-NSMF-01-A-ZX"); - deAllocateNssi.setNssiId("NSSI-C-001-HDBNJ-NSSMF-01-A-ZX"); - deAllocateNssi.setScriptName("CN1"); - deAllocateNssi.setSnssaiList(snssai); - EsrInfo esrInfo = new EsrInfo(); - esrInfo.setVendor("huawei"); - esrInfo.setNetworkType(CORE); - NssiDeAllocateRequest deAllocate = new NssiDeAllocateRequest(); - deAllocate.setDeAllocateNssi(deAllocateNssi); - deAllocate.setEsrInfo(esrInfo); - return deAllocate; - } - - public NssiActDeActRequest activateNssi() throws Exception { - EsrInfo esrInfo = new EsrInfo(); - esrInfo.setVendor("huawei"); - esrInfo.setNetworkType(CORE); - ActDeActNssi act = new ActDeActNssi(); - act.setNsiId("NSI-M-001-HDBNJ-NSMF-01-A-ZX"); - act.setNssiId("NSSI-C-001-HDBNJ-NSSMF-01-A-ZX"); - NssiActDeActRequest actReq = new NssiActDeActRequest(); - actReq.setActDeActNssi(act); - actReq.setEsrInfo(esrInfo); - return actReq; - } - - public NssiActDeActRequest deActivateNssi() throws Exception { - EsrInfo esrInfo = new EsrInfo(); - esrInfo.setVendor("huawei"); - esrInfo.setNetworkType(CORE); - ActDeActNssi deAct = new ActDeActNssi(); - deAct.setNsiId("NSI-M-001-HDBNJ-NSMF-01-A-ZX"); - deAct.setNssiId("NSSI-C-001-HDBNJ-NSSMF-01-A-ZX"); - NssiActDeActRequest deActReq = new NssiActDeActRequest(); - deActReq.setActDeActNssi(deAct); - deActReq.setEsrInfo(esrInfo); - return deActReq; - } - + // + // public NssiDeAllocateRequest deAllocateNssi() throws Exception { + // DeAllocateNssi deAllocateNssi = new DeAllocateNssi(); + // deAllocateNssi.setTerminateNssiOption(0); + // List<String> snssai = new LinkedList<>(); + // snssai.add("001-100001"); + // deAllocateNssi.setNsiId("NSI-M-001-HDBNJ-NSMF-01-A-ZX"); + // deAllocateNssi.setNssiId("NSSI-C-001-HDBNJ-NSSMF-01-A-ZX"); + // deAllocateNssi.setScriptName("CN1"); + // deAllocateNssi.setSnssaiList(snssai); + // EsrInfo esrInfo = new EsrInfo(); + // esrInfo.setVendor("huawei"); + // esrInfo.setNetworkType(CORE); + // NssiDeAllocateRequest deAllocate = new NssiDeAllocateRequest(); + // deAllocate.setDeAllocateNssi(deAllocateNssi); + // deAllocate.setEsrInfo(esrInfo); + // return deAllocate; + // } + // + // public NssiActDeActRequest activateNssi() throws Exception { + // EsrInfo esrInfo = new EsrInfo(); + // esrInfo.setVendor("huawei"); + // esrInfo.setNetworkType(CORE); + // ActDeActNssi act = new ActDeActNssi(); + // act.setNsiId("NSI-M-001-HDBNJ-NSMF-01-A-ZX"); + // act.setNssiId("NSSI-C-001-HDBNJ-NSSMF-01-A-ZX"); + // NssiActDeActRequest actReq = new NssiActDeActRequest(); + // actReq.setActDeActNssi(act); + // actReq.setEsrInfo(esrInfo); + // return actReq; + // } + // + // public NssiActDeActRequest deActivateNssi() throws Exception { + // EsrInfo esrInfo = new EsrInfo(); + // esrInfo.setVendor("huawei"); + // esrInfo.setNetworkType(CORE); + // ActDeActNssi deAct = new ActDeActNssi(); + // deAct.setNsiId("NSI-M-001-HDBNJ-NSMF-01-A-ZX"); + // deAct.setNssiId("NSSI-C-001-HDBNJ-NSSMF-01-A-ZX"); + // NssiActDeActRequest deActReq = new NssiActDeActRequest(); + // deActReq.setActDeActNssi(deAct); + // deActReq.setEsrInfo(esrInfo); + // return deActReq; + // } + // public String queryJobStatusNssi() throws Exception { EsrInfo esrInfo = new EsrInfo(); esrInfo.setVendor("huawei"); diff --git a/adapters/mso-nssmf-adapter/src/test/java/org/onap/so/adapters/nssmf/service/impl/NssmfManagerServiceImplTest.java b/adapters/mso-nssmf-adapter/src/test/java/org/onap/so/adapters/nssmf/service/impl/NssmfManagerServiceImplTest.java new file mode 100644 index 0000000000..4a659e1ca3 --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/test/java/org/onap/so/adapters/nssmf/service/impl/NssmfManagerServiceImplTest.java @@ -0,0 +1,438 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + # Copyright (c) 2020, CMCC Technologies Co., Ltd. + # + # Licensed under the Apache License, Version 2.0 (the "License") + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.nssmf.service.impl; + + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.StatusLine; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpRequestBase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.stubbing.Answer; +import org.onap.so.adapters.nssmf.consts.NssmfAdapterConsts; +import org.onap.so.adapters.nssmf.entity.NssmfInfo; +import org.onap.so.adapters.nssmf.entity.TokenResponse; +import org.onap.so.adapters.nssmf.enums.HttpMethod; +import org.onap.so.adapters.nssmf.util.RestUtil; +import org.onap.so.beans.nsmf.*; +import org.onap.so.db.request.beans.ResourceOperationStatus; +import org.onap.so.db.request.data.repository.ResourceOperationStatusRepository; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.util.*; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.marshal; +import static org.onap.so.adapters.nssmf.util.NssmfAdapterUtil.unMarshal; +import static org.onap.so.beans.nsmf.NetworkType.CORE; +import static org.onap.so.beans.nsmf.ResourceSharingLevel.NON_SHARED; + +@RunWith(SpringRunner.class) +public class NssmfManagerServiceImplTest { + + @Mock + private RestUtil restUtil; + + + private NssmfManagerServiceImpl nssiManagerService; + + @Mock + private HttpResponse tokenResponse; + + @Mock + private HttpEntity tokenEntity; + + @Mock + private HttpResponse commonResponse; + + @Mock + private HttpEntity commonEntity; + + @Mock + private StatusLine statusLine; + + @Mock + private HttpClient httpClient; + + private InputStream postStream; + + private InputStream tokenStream; + + @Mock + private ResourceOperationStatusRepository repository; + + @Before + public void setUp() throws Exception { + initMocks(this); + + nssiManagerService = new NssmfManagerServiceImpl(); + + Field restUtil = nssiManagerService.getClass().getDeclaredField("restUtil"); + restUtil.setAccessible(true); + restUtil.set(nssiManagerService, this.restUtil); + + Field repository = nssiManagerService.getClass().getDeclaredField("repository"); + repository.setAccessible(true); + repository.set(nssiManagerService, this.repository); + // nssiManagerService.setRestUtil(this.restUtil); + + when(this.restUtil.send(any(String.class), any(HttpMethod.class), any(), any(Header.class))) + .thenCallRealMethod(); + when(this.restUtil.createResponse(any(Integer.class), any(String.class))).thenCallRealMethod(); + } + + private void createCommonMock(int statusCode, NssmfInfo nssmf) throws Exception { + when(restUtil.getToken(any(NssmfInfo.class))).thenReturn("7512eb3feb5249eca5ddd742fedddd39"); + when(restUtil.getHttpsClient()).thenReturn(httpClient); + + when(statusLine.getStatusCode()).thenReturn(statusCode); + when(restUtil.getNssmfHost(any(EsrInfo.class))).thenReturn(nssmf); + + when(tokenResponse.getEntity()).thenReturn(tokenEntity); + when(tokenResponse.getStatusLine()).thenReturn(statusLine); + when(tokenEntity.getContent()).thenReturn(tokenStream); + + when(commonResponse.getEntity()).thenReturn(commonEntity); + when(commonResponse.getStatusLine()).thenReturn(statusLine); + when(commonEntity.getContent()).thenReturn(postStream); + + Answer<HttpResponse> answer = invocation -> { + Object[] arguments = invocation.getArguments(); + if (arguments != null && arguments.length == 1 && arguments[0] != null) { + + HttpRequestBase base = (HttpRequestBase) arguments[0]; + if (base.getURI().toString().endsWith("/oauth/token")) { + return tokenResponse; + } else { + return commonResponse; + } + } + return commonResponse; + }; + + doAnswer(answer).when(httpClient).execute(any(HttpRequestBase.class)); + + } + + @Test + public void allocateNssi() throws Exception { + + NssmfInfo nssmf = new NssmfInfo(); + nssmf.setUserName("nssmf-user"); + nssmf.setPassword("nssmf-pass"); + nssmf.setPort("8080"); + nssmf.setIpAddress("127.0.0.1"); + nssmf.setUrl("http://127.0.0.1:8080"); + + NssiResponse nssiRes = new NssiResponse(); + nssiRes.setJobId("4b45d919816ccaa2b762df5120f72067"); + nssiRes.setNssiId("NSSI-C-001-HDBNJ-NSSMF-01-A-ZX"); + + TokenResponse token = new TokenResponse(); + token.setAccessToken("7512eb3feb5249eca5ddd742fedddd39"); + token.setExpires(1800); + + postStream = new ByteArrayInputStream(marshal(nssiRes).getBytes(UTF_8)); + tokenStream = new ByteArrayInputStream(marshal(token).getBytes(UTF_8)); + + createCommonMock(200, nssmf); + + + NssmfAdapterNBIRequest nbiRequest = createAllocateNssi(); + assertNotNull(nbiRequest); + System.out.println(marshal(nbiRequest)); + ResponseEntity res = nssiManagerService.allocateNssi(nbiRequest); + assertNotNull(res); + assertNotNull(res.getBody()); + NssiResponse allRes = unMarshal(res.getBody().toString(), NssiResponse.class); + assertEquals(allRes.getJobId(), "4b45d919816ccaa2b762df5120f72067"); + assertEquals(allRes.getNssiId(), "NSSI-C-001-HDBNJ-NSSMF-01-A-ZX"); + + System.out.println(res); + } + + + + private NssmfAdapterNBIRequest createAllocateNssi() { + CnSliceProfile sP = new CnSliceProfile(); + List<String> sns = new LinkedList<>(); + sns.add("001-100001"); + List<String> plmn = new LinkedList<>(); + plmn.add("460-00"); + plmn.add("460-01"); + PerfReqEmbb embb = new PerfReqEmbb(); + embb.setActivityFactor(50); + List<PerfReqEmbb> embbList = new LinkedList<>(); + embbList.add(embb); + PerfReq perfReq = new PerfReq(); + perfReq.setPerfReqEmbbList(embbList); + List<String> taList = new LinkedList<>(); + taList.add("1"); + taList.add("2"); + taList.add("3"); + sP.setSnssaiList(sns); + sP.setSliceProfileId("ab9af40f13f721b5f13539d87484098"); + sP.setPlmnIdList(plmn); + sP.setPerfReq(perfReq); + sP.setMaxNumberofUEs(200); + sP.setCoverageAreaTAList(taList); + sP.setLatency(6); + sP.setResourceSharingLevel(NON_SHARED); + NsiInfo nsiInfo = new NsiInfo(); + nsiInfo.setNsiId("NSI-M-001-HDBNJ-NSMF-01-A-ZX"); + nsiInfo.setNsiName("eMBB-001"); + AllocateCnNssi cnNssi = new AllocateCnNssi(); + cnNssi.setNssiId("NSST-C-001-HDBNJ-NSSMF-01-A-ZX"); + cnNssi.setNssiName("eMBB-001"); + cnNssi.setScriptName("CN1"); + cnNssi.setSliceProfile(sP); + cnNssi.setNsiInfo(nsiInfo); + + NssmfAdapterNBIRequest nbiRequest = createNbiRequest(); + nbiRequest.setAllocateCnNssi(cnNssi); + return nbiRequest; + } + + @Test + public void deAllocateNssi() throws Exception { + DeAllocateNssi deAllocateNssi = new DeAllocateNssi(); + deAllocateNssi.setTerminateNssiOption(0); + List<String> snssai = new LinkedList<>(); + snssai.add("001-100001"); + deAllocateNssi.setNsiId("NSI-M-001-HDBNJ-NSMF-01-A-ZX"); + deAllocateNssi.setNssiId("NSSI-C-001-HDBNJ-NSSMF-01-A-ZX"); + deAllocateNssi.setScriptName("CN1"); + deAllocateNssi.setSnssaiList(snssai); + + NssmfAdapterNBIRequest nbiRequest = createNbiRequest(); + nbiRequest.setDeAllocateNssi(deAllocateNssi); + + NssmfInfo nssmf = new NssmfInfo(); + nssmf.setUserName("nssmf-user"); + nssmf.setPassword("nssmf-pass"); + nssmf.setPort("8080"); + nssmf.setIpAddress("127.0.0.1"); + + NssiResponse nssiRes = new NssiResponse(); + nssiRes.setJobId("4b45d919816ccaa2b762df5120f72067"); + + TokenResponse token = new TokenResponse(); + token.setAccessToken("7512eb3feb5249eca5ddd742fedddd39"); + token.setExpires(1800); + + postStream = new ByteArrayInputStream(marshal(nssiRes).getBytes(UTF_8)); + tokenStream = new ByteArrayInputStream(marshal(token).getBytes(UTF_8)); + + createCommonMock(202, nssmf); + ResponseEntity res = nssiManagerService.deAllocateNssi(nbiRequest, "ab9af40f13f721b5f13539d87484098"); + assertNotNull(res); + assertNotNull(res.getBody()); + NssiResponse allRes = unMarshal(res.getBody().toString(), NssiResponse.class); + assertEquals(allRes.getJobId(), "4b45d919816ccaa2b762df5120f72067"); + assertNotNull(res); + assertNotNull(res.getBody()); + } + + @Test + public void activateNssi() throws Exception { + NssmfInfo nssmf = new NssmfInfo(); + nssmf.setUserName("nssmf-user"); + nssmf.setPassword("nssmf-pass"); + nssmf.setPort("8080"); + nssmf.setIpAddress("127.0.0.1"); + + NssiResponse nssiRes = new NssiResponse(); + nssiRes.setJobId("4b45d919816ccaa2b762df5120f72067"); + + TokenResponse token = new TokenResponse(); + token.setAccessToken("7512eb3feb5249eca5ddd742fedddd39"); + token.setExpires(1800); + + postStream = new ByteArrayInputStream(marshal(nssiRes).getBytes(UTF_8)); + tokenStream = new ByteArrayInputStream(marshal(token).getBytes(UTF_8)); + + ActDeActNssi act = new ActDeActNssi(); + act.setNsiId("NSI-M-001-HDBNJ-NSMF-01-A-ZX"); + act.setNssiId("NSSI-C-001-HDBNJ-NSSMF-01-A-ZX"); + + NssmfAdapterNBIRequest nbiRequest = createNbiRequest(); + nbiRequest.setActDeActNssi(act); + + createCommonMock(200, nssmf); + ResponseEntity res = nssiManagerService.activateNssi(nbiRequest, "001-100001"); + assertNotNull(res); + assertNotNull(res.getBody()); + NssiResponse allRes = unMarshal(res.getBody().toString(), NssiResponse.class); + assertEquals(allRes.getJobId(), "4b45d919816ccaa2b762df5120f72067"); + } + + @Test + public void deActivateNssi() throws Exception { + NssmfInfo nssmf = new NssmfInfo(); + nssmf.setUserName("nssmf-user"); + nssmf.setPassword("nssmf-pass"); + nssmf.setPort("8080"); + nssmf.setIpAddress("127.0.0.1"); + + NssiResponse nssiRes = new NssiResponse(); + nssiRes.setJobId("4b45d919816ccaa2b762df5120f72067"); + + TokenResponse token = new TokenResponse(); + token.setAccessToken("7512eb3feb5249eca5ddd742fedddd39"); + token.setExpires(1800); + + postStream = new ByteArrayInputStream(marshal(nssiRes).getBytes(UTF_8)); + tokenStream = new ByteArrayInputStream(marshal(token).getBytes(UTF_8)); + + ActDeActNssi act = new ActDeActNssi(); + act.setNsiId("NSI-M-001-HDBNJ-NSMF-01-A-ZX"); + act.setNssiId("NSSI-C-001-HDBNJ-NSSMF-01-A-ZX"); + + NssmfAdapterNBIRequest nbiRequest = createNbiRequest(); + nbiRequest.setActDeActNssi(act); + + createCommonMock(200, nssmf); + ResponseEntity res = nssiManagerService.deActivateNssi(nbiRequest, "001-100001"); + assertNotNull(res); + assertNotNull(res.getBody()); + NssiResponse allRes = unMarshal(res.getBody().toString(), NssiResponse.class); + assertEquals(allRes.getJobId(), "4b45d919816ccaa2b762df5120f72067"); + } + + @Test + public void queryJobStatus() throws Exception { + NssmfInfo nssmf = new NssmfInfo(); + nssmf.setUserName("nssmf-user"); + nssmf.setPassword("nssmf-pass"); + nssmf.setPort("8080"); + nssmf.setIpAddress("127.0.0.1"); + + JobStatusResponse jobStatusResponse = new JobStatusResponse(); + ResponseDescriptor descriptor = new ResponseDescriptor(); + descriptor.setResponseId("7512eb3feb5249eca5ddd742fedddd39"); + descriptor.setProgress(20); + descriptor.setStatusDescription("Initiating VNF Instance"); + descriptor.setStatus("processing"); + jobStatusResponse.setResponseDescriptor(descriptor); + + TokenResponse token = new TokenResponse(); + token.setAccessToken("7512eb3feb5249eca5ddd742fedddd39"); + token.setExpires(1800); + + postStream = new ByteArrayInputStream(marshal(jobStatusResponse).getBytes(UTF_8)); + tokenStream = new ByteArrayInputStream(marshal(token).getBytes(UTF_8)); + + ResourceOperationStatus operationStatus = new ResourceOperationStatus(); + operationStatus.setOperationId("4b45d919816ccaa2b762df5120f72067"); + operationStatus.setResourceTemplateUUID("8ee5926d-720b-4bb2-86f9-d20e921c143b"); + operationStatus.setServiceId("NSI-M-001-HDBNJ-NSMF-01-A-ZX"); + + NssmfAdapterNBIRequest nbiRequest = createNbiRequest(); + nbiRequest.setResponseId("7512eb3feb5249eca5ddd742fedddd39"); + Optional<ResourceOperationStatus> optional = Optional.of(operationStatus); + + doAnswer(invocation -> optional).when(repository).findOne(any()); + + createCommonMock(200, nssmf); + + ResponseEntity res = nssiManagerService.queryJobStatus(nbiRequest, "4b45d919816ccaa2b762df5120f72067"); + assertNotNull(res); + assertNotNull(res.getBody()); + JobStatusResponse allRes = unMarshal(res.getBody().toString(), JobStatusResponse.class); + assertEquals(allRes.getResponseDescriptor().getProgress(), 20); + assertEquals(allRes.getResponseDescriptor().getStatus(), "processing"); + assertEquals(allRes.getResponseDescriptor().getResponseId(), "7512eb3feb5249eca5ddd742fedddd39"); + + System.out.println(res); + + } + + @Test + public void queryNSSISelectionCapability() throws Exception { + + NssmfAdapterNBIRequest nbiRequest = createNbiRequest(); + ResponseEntity res = nssiManagerService.queryNSSISelectionCapability(nbiRequest); + assertNotNull(res); + assertNotNull(res.getBody()); + Map allRes = unMarshal(res.getBody().toString(), Map.class); + assertEquals(allRes.get("selection"), "NSMF"); + + System.out.println(res); + + nbiRequest.getEsrInfo().setVendor(NssmfAdapterConsts.ONAP_INTERNAL_TAG); + res = nssiManagerService.queryNSSISelectionCapability(nbiRequest); + assertNotNull(res); + assertNotNull(res.getBody()); + allRes = unMarshal(res.getBody().toString(), Map.class); + assertEquals(allRes.get("selection"), "NSSMF"); + + System.out.println(res); + + nbiRequest.getEsrInfo().setNetworkType(NetworkType.ACCESS); + res = nssiManagerService.queryNSSISelectionCapability(nbiRequest); + assertNotNull(res); + assertNotNull(res.getBody()); + allRes = unMarshal(res.getBody().toString(), Map.class); + assertEquals(allRes.get("selection"), "NSSMF"); + + System.out.println(res); + } + + private NssmfAdapterNBIRequest createNbiRequest() { + NssmfAdapterNBIRequest nbiRequest = new NssmfAdapterNBIRequest(); + EsrInfo esrInfo = new EsrInfo(); + esrInfo.setVendor("huawei"); + esrInfo.setNetworkType(CORE); + ServiceInfo serviceInfo = new ServiceInfo(); + serviceInfo.setServiceUuid("8ee5926d-720b-4bb2-86f9-d20e921c143b"); + serviceInfo.setServiceInvariantUuid("e75698d9-925a-4cdd-a6c0-edacbe6a0b51"); + serviceInfo.setGlobalSubscriberId("5GCustomer"); + serviceInfo.setServiceType("5G"); + serviceInfo.setNsiId("NSI-M-001-HDBNJ-NSMF-01-A-ZX"); + nbiRequest.setEsrInfo(esrInfo); + nbiRequest.setServiceInfo(serviceInfo); + return nbiRequest; + } + + @Test + public void querySubnetCapability() { + NssmfAdapterNBIRequest nbiRequest = createNbiRequest(); + + String subnetCapabilityQuery = "\"subnetTypes\": [\"TN-FH\",\"TN-MH\",\"TN-BH\"]"; + nbiRequest.setSubnetCapabilityQuery(subnetCapabilityQuery); + ResponseEntity res = nssiManagerService.queryNSSISelectionCapability(nbiRequest); + assertNotNull(res); + assertNotNull(res.getBody()); + } +} diff --git a/adapters/mso-nssmf-adapter/src/test/resources/application-test.yaml b/adapters/mso-nssmf-adapter/src/test/resources/application-test.yaml new file mode 100644 index 0000000000..fa323e887b --- /dev/null +++ b/adapters/mso-nssmf-adapter/src/test/resources/application-test.yaml @@ -0,0 +1,60 @@ + +aai: + auth: 2A11B07DB6214A839394AA1EC5844695F5114FC407FF5422625FB00175A3DCB8A1FF745F22867EFA72D5369D599BBD88DA8BED4233CF5586 + endpoint: https://aai.onap:30233 +logging: + path: logs + +spring: + datasource: + username: root + password: 123456 + driver-class-name: org.mariadb.jdbc.Driver + initialization-mode: always + url: jdbc:mariadb://49.232.146.162:8989/requestdb + jpa: + generate-ddl: false + show-sql: false + hibernate: + ddl-auto: none + naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy + enable-lazy-load-no-trans: true + database-platform: org.hibernate.dialect.MySQL5InnoDBDialect + security: + usercredentials: + - username: bpel + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPEL-Client + - username: mso_admin + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: ACTUATOR +server: + port: 8080 + tomcat: + max-threads: 50 + +mso: + key: 07a7159d3bf51a0e53be7a8f89699be7 + site-name: localSite + logPath: ./logs/nssmf + adapters: + requestDb: + endpoint: https://so-request-db-adapter.{{ include "common.namespace" . }}:8083 + auth: Basic YnBlbDpwYXNzd29yZDEk + infra: + endpoint: https://so.{{ include "common.namespace" . }}:8080 + auth: Basic SW5mcmFQb3J0YWxDbGllbnQ6cGFzc3dvcmQxJA== + +#Actuator +management: + endpoints: + web: + base-path: /manage + exposure: + include: "*" + metrics: + se-global-registry: false + export: + prometheus: + enabled: true # Whether exporting of metrics to Prometheus is enabled. + step: 1m # Step size (i.e. reporting frequency) to use.
\ No newline at end of file diff --git a/adapters/mso-oof-adapter/.gitignore b/adapters/mso-oof-adapter/.gitignore new file mode 100644 index 0000000000..549e00a2a9 --- /dev/null +++ b/adapters/mso-oof-adapter/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/adapters/mso-oof-adapter/pom.xml b/adapters/mso-oof-adapter/pom.xml new file mode 100644 index 0000000000..98150d39e0 --- /dev/null +++ b/adapters/mso-oof-adapter/pom.xml @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onap.so</groupId> + <artifactId>adapters</artifactId> + <version>1.7.1-SNAPSHOT</version> + </parent> + <groupId>org.onap.so.adapters</groupId> + <artifactId>mso-oof-adapter</artifactId> + <name>mso-oof-adapter</name> + <description>mso oof adapter</description> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-dependencies</artifactId> + <version>${springboot.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-webflux</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-spring-boot-starter-jaxrs</artifactId> + <version>${cxf.version}</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-rs-service-description-swagger</artifactId> + <version>${cxf.version}</version> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.junit.vintage</groupId> + <artifactId>junit-vintage-engine</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-api</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.vintage</groupId> + <artifactId>junit-vintage-engine</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <finalName>${project.artifactId}-${project.version}</finalName> + <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <configuration> + <mainClass>org.onap.so.adapters.oof.MsoOofAdapterApplication</mainClass> + </configuration> + <executions> + <execution> + <goals> + <goal>repackage</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + </plugin> + </plugins> + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + <excludes> + <exclude>**/*.p12</exclude> + <exclude>**/*.jks</exclude> + </excludes> + </resource> + <resource> + <directory>src/main/resources</directory> + <filtering>false</filtering> + <includes> + <include>**/*.p12</include> + <include>**/*.jks</include> + </includes> + </resource> + </resources> + </build> +</project> diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoDeploymentAlreadyExists.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/MsoOofAdapterApplication.java index 62112f4feb..78fbe6e271 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoDeploymentAlreadyExists.java +++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/MsoOofAdapterApplication.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP - SO * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2020 Wipro Limited. 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. @@ -18,17 +18,15 @@ * ============LICENSE_END========================================================= */ -package org.onap.so.cloudify.exceptions; +package org.onap.so.adapters.oof; -public class MsoDeploymentAlreadyExists extends MsoCloudifyException { +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; - private static final long serialVersionUID = 1L; +@SpringBootApplication +public class MsoOofAdapterApplication { - // 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); + public static void main(String[] args) { + SpringApplication.run(MsoOofAdapterApplication.class, args); } - } diff --git a/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/OofAdapterClientConfig.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/OofAdapterClientConfig.java new file mode 100644 index 0000000000..5e13c592b7 --- /dev/null +++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/OofAdapterClientConfig.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Wipro Limited. 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.adapters.oof; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import org.apache.http.client.HttpClient; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.HttpClients; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class OofAdapterClientConfig { + + @Bean + public RestTemplate getRestTemplate() { + HttpComponentsClientHttpRequestFactory requestFactory = + new HttpComponentsClientHttpRequestFactory(getHttpsClient()); + requestFactory.setConnectTimeout(60000); + requestFactory.setReadTimeout(60000); + return new RestTemplate(requestFactory); + } + + private HttpClient getHttpsClient() { + TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {} + + public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {} + }}; + + // Install the all-trusting trust manager + try { + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + HostnameVerifier hostnameVerifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sc, + new String[] {"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"}, null, hostnameVerifier); + return HttpClients.custom().setSSLSocketFactory(sslsf).build(); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } +} diff --git a/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/WebSecurityConfig.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/WebSecurityConfig.java new file mode 100644 index 0000000000..9a07b0119f --- /dev/null +++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/WebSecurityConfig.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Wipro Limited. 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.adapters.oof; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@EnableWebSecurity +@Configuration +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf().disable(); + } + +} diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoBlueprintAlreadyExists.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/constants/Constants.java index 95912994bc..5d91bf38f8 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoBlueprintAlreadyExists.java +++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/constants/Constants.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP - SO * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2020 Wipro Limited. 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. @@ -17,18 +17,15 @@ * limitations under the License. * ============LICENSE_END========================================================= */ +package org.onap.so.adapters.oof.constants; -package org.onap.so.cloudify.exceptions; +public class Constants { -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); - } + public static final String OOF_ENDPOINT = "mso.oof.endpoint"; + public static final String OOF_AUTH = "mso.oof.auth"; + public static final String MSO_KEY = "mso.msoKey"; + public static final String CAMUNDA_URL = "mso.camundaURL"; + public static final String CAMUNDA_AUTH = "mso.camundaAuth"; + public static final String WORKFLOW_MESSAGE_ENPOINT = "mso.workflow.message.endpoint"; } diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoCloudifyManagerNotFound.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/exceptions/OofAdapterException.java index bc6fd6204c..ff16d7442c 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloudify/exceptions/MsoCloudifyManagerNotFound.java +++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/exceptions/OofAdapterException.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP - SO * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2020 Wipro Limited. 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. @@ -18,16 +18,22 @@ * ============LICENSE_END========================================================= */ -package org.onap.so.cloudify.exceptions; +package org.onap.so.adapters.oof.exceptions; -public class MsoCloudifyManagerNotFound extends MsoCloudifyException { +public class OofAdapterException extends Exception { 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); + public OofAdapterException(String message) { + super(message); + } + + public OofAdapterException(Throwable e) { + super(e); + } + + public OofAdapterException(String message, Throwable e) { + super(message, e); } } diff --git a/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/model/OofRequest.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/model/OofRequest.java new file mode 100644 index 0000000000..1eb694fd96 --- /dev/null +++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/model/OofRequest.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Wipro Limited. 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.adapters.oof.model; + +/** + * POJO representing generic request payload from BPMN processes + */ +public class OofRequest { + + private String apiPath; + + private Object requestDetails; + + public String getApiPath() { + return apiPath; + } + + public void setApiPath(String apiPath) { + this.apiPath = apiPath; + } + + public Object getRequestDetails() { + return requestDetails; + } + + public void setRequestDetails(Object requestDetails) { + this.requestDetails = requestDetails; + } + + @Override + public String toString() { + return "{\"apiPath:\"\"" + apiPath + "\"\", requestDetails:\"\"" + requestDetails + "}"; + } + +} diff --git a/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/rest/OofCallbackHandler.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/rest/OofCallbackHandler.java new file mode 100644 index 0000000000..f8da6c6d2e --- /dev/null +++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/rest/OofCallbackHandler.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Wipro Limited. 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.adapters.oof.rest; + +import org.onap.so.adapters.oof.exceptions.OofAdapterException; +import org.onap.so.adapters.oof.utils.OofUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +/** + * A generic call back handler to receive async response from OOF + */ +@RestController +@RequestMapping("/so/adapters/oof/callback/") +public class OofCallbackHandler { + + @Autowired + OofUtils utils; + + @Autowired + RestTemplate restTemplate; + + private static final Logger logger = LoggerFactory.getLogger(OofCallbackHandler.class); + + @PostMapping("/{version:[vV][1]}/{messageEventName}/{correlator}") + public ResponseEntity<String> processCallback(@PathVariable("messageEventName") String messageEventName, + @PathVariable("correlator") String correlator, @RequestBody String oofCallbackRequest) + throws OofAdapterException { + logger.debug("Oof Async response received for event : {} , callback request body : {} ", messageEventName, + oofCallbackRequest); + String camundaMsgUrl = utils.getCamundaMsgUrl(messageEventName, correlator); + HttpEntity<String> request = new HttpEntity<String>(oofCallbackRequest, utils.getCamundaHeaders()); + try { + ResponseEntity<String> response = restTemplate.postForEntity(camundaMsgUrl, request, String.class); + logger.debug("Response from BPMN : {} ", response); + return response; + } catch (Exception e) { + logger.warn("Error injecting message event into BPMN {} {} ", e.getCause(), e.getMessage()); + throw new OofAdapterException(e); + } + + } + +} diff --git a/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/rest/OofClient.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/rest/OofClient.java new file mode 100644 index 0000000000..3a91ec495e --- /dev/null +++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/rest/OofClient.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Wipro Limited. 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.adapters.oof.rest; + +import org.onap.so.adapters.oof.exceptions.OofAdapterException; +import org.onap.so.adapters.oof.model.OofRequest; +import org.onap.so.adapters.oof.utils.OofUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +/** + * A generic client class to call OOF with request from BPMN + */ +@RestController +@RequestMapping("/so/adapters/oof/") +public class OofClient { + + @Autowired + RestTemplate restTemplate; + + @Autowired + OofUtils utils; + + private static final Logger logger = LoggerFactory.getLogger(OofClient.class); + + @PostMapping("/{version:[vV][1]}") + public ResponseEntity<String> callOof(@RequestBody OofRequest oofRequest) throws OofAdapterException { + try { + logger.debug("Received Request from BPEL {} ", oofRequest); + String oofUrl = utils.getOofurl(oofRequest.getApiPath()); + HttpEntity<?> request = new HttpEntity<>(oofRequest.getRequestDetails(), utils.getOofHttpHeaders()); + ResponseEntity<String> response = restTemplate.postForEntity(oofUrl, request, String.class); + logger.debug("Response from OOF : {} ", response); + return response; + } catch (Exception e) { + logger.warn("Error while calling OOF {} {} ", e.getCause(), e.getMessage()); + throw new OofAdapterException(e); + } + } + +} diff --git a/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/utils/OofUtils.java b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/utils/OofUtils.java new file mode 100644 index 0000000000..f45baa30fe --- /dev/null +++ b/adapters/mso-oof-adapter/src/main/java/org/onap/so/adapters/oof/utils/OofUtils.java @@ -0,0 +1,110 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Wipro Limited. 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.adapters.oof.utils; + +import java.security.GeneralSecurityException; +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.DatatypeConverter; +import org.onap.so.adapters.oof.constants.Constants; +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.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; + +@Component +public class OofUtils { + private static Logger logger = LoggerFactory.getLogger(OofUtils.class); + + @Autowired + private Environment env; + + /** + * @param messageEventName + * @param correlator + * @return + */ + public String getCamundaMsgUrl(String messageEventName, String correlator) { + System.out.println(env); + String camundaMsgUrl = new StringBuilder(env.getRequiredProperty(Constants.WORKFLOW_MESSAGE_ENPOINT)) + .append("/").append(messageEventName).append("/").append(correlator).toString(); + return camundaMsgUrl; + } + + /** + * @return + */ + public HttpHeaders getCamundaHeaders() { + HttpHeaders headers = new HttpHeaders(); + List<MediaType> acceptableMediaTypes = new ArrayList<>(); + acceptableMediaTypes.add(MediaType.ALL); + headers.setAccept(acceptableMediaTypes); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.add(HttpHeaders.AUTHORIZATION, addAuthorizationHeader(env.getRequiredProperty(Constants.CAMUNDA_AUTH), + env.getRequiredProperty(Constants.MSO_KEY))); + return headers; + } + + /** + * @param auth + * @param msoKey + * @return + */ + protected String addAuthorizationHeader(String auth, String msoKey) { + String basicAuth = null; + try { + String userCredentials = CryptoUtils.decrypt(auth, msoKey); + if (userCredentials != null) { + basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes()); + } + } catch (GeneralSecurityException e) { + logger.error("Security exception", e); + } + return basicAuth; + } + + /** + * @return + * @throws Exception + */ + public HttpHeaders getOofHttpHeaders() throws Exception { + HttpHeaders headers = new HttpHeaders(); + List<MediaType> acceptableMediaTypes = new ArrayList<>(); + acceptableMediaTypes.add(MediaType.APPLICATION_JSON); + headers.setAccept(acceptableMediaTypes); + headers.setContentType(MediaType.APPLICATION_JSON); + return headers; + } + + /** + * @param apiPath + * @return + */ + public String getOofurl(String apiPath) { + return new StringBuilder(env.getRequiredProperty(Constants.OOF_ENDPOINT)).append(apiPath).toString(); + } + + +} diff --git a/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/rest/OofCallbackHandlerTest.java b/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/rest/OofCallbackHandlerTest.java new file mode 100644 index 0000000000..3a2f7f5e11 --- /dev/null +++ b/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/rest/OofCallbackHandlerTest.java @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Wipro Limited. 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.adapters.oof.rest; + +import static org.mockito.Mockito.when; +import java.io.File; +import java.io.IOException; +import org.junit.Before; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.onap.so.adapters.oof.utils.OofUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; +import com.fasterxml.jackson.databind.ObjectMapper; + + +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +class OofCallbackHandlerTest { + + @Autowired + TestRestTemplate restTemplate; + + @MockBean + OofUtils oofutils; + + @MockBean + RestTemplate mockrestTemplate; + + @Before + void prepareMocks() throws Exception { + ResponseEntity<Object> responseEntity = new ResponseEntity<>(HttpStatus.OK); + when(oofutils.getCamundaHeaders()).thenReturn(new HttpHeaders()); + when(oofutils.getCamundaMsgUrl(Mockito.anyString(), Mockito.anyString())).thenReturn("oofurl"); + when(mockrestTemplate.postForEntity(Mockito.anyString(), Mockito.any(), Mockito.any())) + .thenReturn(responseEntity); + } + + @Test + void processCallbackTest() throws Exception { + Object request = prepareOofResponse(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity<Object> entity = new HttpEntity<Object>(request, headers); + ResponseEntity<String> response = restTemplate.postForEntity( + "/so/adapters/oof/callback/v1/NSISelectionResponse/d88da85c-d9e8-4f73-b837-3a72a431622a", entity, + String.class); + Assertions.assertEquals(HttpStatus.OK, response.getStatusCode()); + } + + private Object prepareOofResponse() throws IOException { + File file = new ClassPathResource("testInputs/NsiSelectionResponse.json").getFile(); + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(file, Object.class); + } + +} diff --git a/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/rest/OofClientTest.java b/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/rest/OofClientTest.java new file mode 100644 index 0000000000..ff38a9af63 --- /dev/null +++ b/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/rest/OofClientTest.java @@ -0,0 +1,86 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Wipro Limited. 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.adapters.oof.rest; + +import static org.mockito.Mockito.when; +import java.io.File; +import java.io.IOException; +import org.junit.Before; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.onap.so.adapters.oof.model.OofRequest; +import org.onap.so.adapters.oof.utils.OofUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; +import com.fasterxml.jackson.databind.ObjectMapper; + +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +class OofClientTest { + + @Autowired + TestRestTemplate restTemplate; + + @MockBean + OofUtils oofutils; + + @MockBean + RestTemplate mockrestTemplate; + + @Before + void prepareMocks() throws Exception { + ResponseEntity<Object> responseEntity = new ResponseEntity<>(HttpStatus.OK); + when(oofutils.getOofHttpHeaders()).thenReturn(new HttpHeaders()); + when(oofutils.getOofurl(Mockito.anyString())).thenReturn("oofurl"); + when(mockrestTemplate.postForEntity(Mockito.anyString(), Mockito.any(), Mockito.any())) + .thenReturn(responseEntity); + } + + @Test + void callOofTest() throws Exception { + OofRequest request = prepareOofRequest(); + System.out.println(request); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity<OofRequest> entity = new HttpEntity<OofRequest>(request, headers); + ResponseEntity<String> response = restTemplate.postForEntity("/so/adapters/oof/v1", entity, String.class); + Assertions.assertEquals(HttpStatus.OK, response.getStatusCode()); + } + + private OofRequest prepareOofRequest() throws IOException { + File file = new ClassPathResource("testInputs/NsiSelectionOofRequest.json").getFile(); + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(file, OofRequest.class); + } + + +} diff --git a/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/utils/OofUtilsTest.java b/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/utils/OofUtilsTest.java new file mode 100644 index 0000000000..e68fa10c3e --- /dev/null +++ b/adapters/mso-oof-adapter/src/test/java/org/onap/so/adapters/oof/utils/OofUtilsTest.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Wipro Limited. 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.adapters.oof.utils; + +import static org.mockito.Mockito.when; +import java.security.GeneralSecurityException; +import javax.xml.bind.DatatypeConverter; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.onap.so.utils.CryptoUtils; +import org.springframework.core.env.Environment; +import org.springframework.http.HttpHeaders; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +class OofUtilsTest { + + @InjectMocks + OofUtils oofUtils; + + @Mock + Environment env; + + @Test + void testGetCamundaMsgUrl() { + when(env.getRequiredProperty(Mockito.anyString())).thenReturn("dummyString"); + String camundamsgUrl = oofUtils.getCamundaMsgUrl("samplemessage", "sampleCorrelator"); + Assertions.assertNotNull(camundamsgUrl); + } + + + void testGetCamundaHeaders() throws GeneralSecurityException { + when(env.getRequiredProperty(Mockito.anyString())).thenReturn("dummyString"); + when(CryptoUtils.decrypt(Mockito.anyString(), Mockito.anyString())).thenReturn("decryptedString"); + HttpHeaders headers = oofUtils.getCamundaHeaders(); + Assertions.assertNotNull(headers); + } + + + @Test + void testGetOofHttpHeaders() throws Exception { + when(env.getRequiredProperty(Mockito.anyString())).thenReturn("dummyString"); + HttpHeaders headers = oofUtils.getOofHttpHeaders(); + Assertions.assertNotNull(headers); + } + + @Test + void testGetOofurl() { + when(env.getRequiredProperty(Mockito.anyString())).thenReturn("dummyString"); + String oofurl = oofUtils.getOofurl("/api/v1/"); + Assertions.assertNotNull(oofurl); + } + +} diff --git a/adapters/mso-oof-adapter/src/test/resources/testInputs/NsiSelectionOofRequest.json b/adapters/mso-oof-adapter/src/test/resources/testInputs/NsiSelectionOofRequest.json new file mode 100644 index 0000000000..569aae9f38 --- /dev/null +++ b/adapters/mso-oof-adapter/src/test/resources/testInputs/NsiSelectionOofRequest.json @@ -0,0 +1,84 @@ +{ + "apiPath":"/api/oof/selection/nsi/v1", + "requestDetails":{ + "serviceProfile":{ + "blob":"content" + }, + "requestInfo":{ + "transactionId":"d290f1ee-6c54-4b01-90e6-d701748f0851", + "requestId":"d290f1ee-6c54-4b01-90e6-d701748f0851", + "callbackUrl":"myDomain.com/myCallback", + "callbackHeader":{ + "blob":"content" + }, + "sourceId":"d290f1ee-6c54-4b01-90e6-d701748f0851", + "timeout":5, + "numSolutions":1 + }, + "NSTInfo":{ + "UUID":"3fa85f64-5717-4562-b3fc-2c963f66afa1", + "invariantUUID":"7ua85f64-5717-4562-b3fc-2c963f66afa6", + "name":"embb-nst" + }, + "NSSTInfo":[ + { + "UUID":"3fa85f64-5717-4562-b3fc-2c963f66afa2", + "invariantUUID":"2fa85f64-5717-4562-b3fc-2c963f66afa6", + "name":"embb-an-nf" + }, + { + "UUID":"3fa85f64-5717-4562-b3fc-2c963f66afa3", + "invariantUUID":"4fa85f64-5717-4562-b3fc-2c963f66afa6", + "name":"embb-cn" + }, + { + "UUID":"3fa85f64-5717-4562-b3fc-2c963f66afa4", + "invariantUUID":"5ta85f64-5717-4562-b3fc-2c963f66afa6", + "name":"embb-tn-fh" + }, + { + "UUID":"3fa85f64-5717-4562-b3fc-2c963f66afa5", + "invariantUUID":"6ya85f64-5717-4562-b3fc-2c963f66afa6", + "name":"embb-tn-mh" + }, + { + "UUID":"3fa85f64-5717-4562-b3fc-2c963f66afa7", + "invariantUUID":"7ua85f64-5717-4562-b3fc-2c963f66afa6", + "name":"embb-tn-bh" + } + ], + "preferReuse":false, + "subnetCapabilities":[ + { + "domainType":"AN-NF", + "capabilityDetails":{ + "blob":"content" + } + }, + { + "domainType":"CN", + "capabilityDetails":{ + "blob":"content" + } + }, + { + "domainType":"TN-FH", + "capabilityDetails":{ + "blob":"content" + } + }, + { + "domainType":"TN-MH", + "capabilityDetails":{ + "blob":"content" + } + }, + { + "domainType":"TN-BH", + "capabilityDetails":{ + "blob":"content" + } + } + ] +} +}
\ No newline at end of file diff --git a/adapters/mso-oof-adapter/src/test/resources/testInputs/NsiSelectionResponse.json b/adapters/mso-oof-adapter/src/test/resources/testInputs/NsiSelectionResponse.json new file mode 100644 index 0000000000..4ddca3eaf9 --- /dev/null +++ b/adapters/mso-oof-adapter/src/test/resources/testInputs/NsiSelectionResponse.json @@ -0,0 +1,20 @@ +{ + "transactionId": "s4r0f1ee-6c54-4b01-90e6-d701748f0851", + "requestId": "r500f1ee-6c54-4b01-90e6-d701748f0851", + "requestStatus": "completed", + "solutions": [ + { + "existingNSI": false, + "newNSISolution": { + "sliceProfiles": [ + { + "domainType":"CN" + } + ], + "matchLevel": { + "blob": "content" + } + } + } + ] +} diff --git a/adapters/mso-openstack-adapters/pom.xml b/adapters/mso-openstack-adapters/pom.xml index ad41b0f050..eb6cba5510 100644 --- a/adapters/mso-openstack-adapters/pom.xml +++ b/adapters/mso-openstack-adapters/pom.xml @@ -298,7 +298,7 @@ <dependency> <groupId>commons-validator</groupId> <artifactId>commons-validator</artifactId> - <version>1.4.0</version> + <version>1.4.1</version> </dependency> <!-- added for unit testing --> diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/inventory/delete/DeleteAAIInventory.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/inventory/delete/DeleteAAIInventory.java index 1f0422b0b2..22e6b1fc22 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/inventory/delete/DeleteAAIInventory.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/inventory/delete/DeleteAAIInventory.java @@ -54,9 +54,9 @@ public class DeleteAAIInventory { CloudSite cloudSite = cloudConfig.getCloudSite(cloudInformation.getRegionId()) .orElseThrow(() -> new MsoCloudSiteNotFound(cloudInformation.getRegionId())); CloudIdentity cloudIdentity = cloudSite.getIdentityService(); - HeatBridgeApi heatBridgeClient = - new HeatBridgeImpl(new AAIResourcesClient(), cloudIdentity, cloudInformation.getOwner(), - cloudInformation.getRegionId(), cloudSite.getRegionId(), cloudInformation.getTenantId()); + HeatBridgeApi heatBridgeClient = new HeatBridgeImpl(new AAIResourcesClient(), cloudIdentity, + cloudInformation.getOwner(), cloudInformation.getRegionId(), cloudSite.getRegionId(), + cloudInformation.getTenantId(), cloudInformation.getNodeType()); heatBridgeClient.authenticate(); heatBridgeClient.deleteVfModuleData(cloudInformation.getVnfId(), cloudInformation.getVfModuleId()); diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/inventory/CreateAAIInventory.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/inventory/CreateAAIInventory.java index 12751f8c27..3f79c43bf8 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/inventory/CreateAAIInventory.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/inventory/CreateAAIInventory.java @@ -64,9 +64,9 @@ public class CreateAAIInventory { List<String> oobMgtNetNames = new ArrayList<>(); - HeatBridgeApi heatBridgeClient = - new HeatBridgeImpl(new AAIResourcesClient(), cloudIdentity, cloudInformation.getOwner(), - cloudInformation.getRegionId(), cloudSite.getRegionId(), cloudInformation.getTenantId()); + HeatBridgeApi heatBridgeClient = new HeatBridgeImpl(new AAIResourcesClient(), cloudIdentity, + cloudInformation.getOwner(), cloudInformation.getRegionId(), cloudSite.getRegionId(), + cloudInformation.getTenantId(), cloudInformation.getNodeType()); heatBridgeClient.authenticate(); @@ -119,8 +119,8 @@ public class CreateAAIInventory { "Successfully queried neutron resources and built AAI actions to add l-interfaces to vservers."); // Update AAI - logger.debug("Current Dry Run Value: {}", env.getProperty("heatBridgeDryrun", Boolean.class, true)); - heatBridgeClient.submitToAai(env.getProperty("heatBridgeDryrun", Boolean.class, true)); + logger.debug("Current Dry Run Value: {}", env.getProperty("heatBridgeDryrun", Boolean.class, false)); + heatBridgeClient.submitToAai(env.getProperty("heatBridgeDryrun", Boolean.class, false)); } catch (Exception ex) { logger.debug("Heatbrige failed for stackId: " + cloudInformation.getTemplateInstanceId(), ex); } diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java index a4e6cccc06..bafba3e901 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java @@ -155,7 +155,7 @@ public interface HeatBridgeApi { * @param cloudOwner */ void buildAddVserverLInterfacesToAaiAction(List<Resource> stackResources, List<String> oobMgtNetIds, - String cloudOwner); + String cloudOwner) throws HeatBridgeException; /** * Query and build AAI actions for Openstack Compute resources to AAI's pserver and pinterface objects 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 ef2577d6fe..90a578d3b4 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 @@ -32,6 +32,8 @@ */ package org.onap.so.heatbridge; +import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -49,6 +51,7 @@ import org.apache.commons.validator.routines.InetAddressValidator; import org.onap.aai.domain.yang.Flavor; import org.onap.aai.domain.yang.Image; import org.onap.aai.domain.yang.L3InterfaceIpv4AddressList; +import org.onap.aai.domain.yang.L3InterfaceIpv6AddressList; import org.onap.aai.domain.yang.L3Network; import org.onap.aai.domain.yang.LInterface; import org.onap.aai.domain.yang.PInterface; @@ -59,22 +62,31 @@ import org.onap.aai.domain.yang.SriovPf; import org.onap.aai.domain.yang.SriovPfs; import org.onap.aai.domain.yang.Subnets; import org.onap.aai.domain.yang.SriovVf; -import org.onap.aai.domain.yang.SriovVfs; import org.onap.aai.domain.yang.VfModule; import org.onap.aai.domain.yang.Vlan; -import org.onap.aai.domain.yang.Vlans; import org.onap.aai.domain.yang.Vserver; -import org.onap.aaiclient.client.aai.AAIObjectType; +import org.onap.aaiclient.client.aai.AAIDSLQueryClient; import org.onap.aaiclient.client.aai.AAIResourcesClient; import org.onap.aaiclient.client.aai.AAISingleTransactionClient; import org.onap.aaiclient.client.aai.entities.AAIResultWrapper; import org.onap.aaiclient.client.aai.entities.Relationships; +import org.onap.aaiclient.client.aai.entities.Results; 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.generated.fluentbuilders.AAIFluentTypeBuilder.Types; +import org.onap.aaiclient.client.graphinventory.Format; +import org.onap.aaiclient.client.graphinventory.entities.DSLQuery; +import org.onap.aaiclient.client.graphinventory.entities.DSLQueryBuilder; +import org.onap.aaiclient.client.graphinventory.entities.DSLStartNode; +import org.onap.aaiclient.client.graphinventory.entities.Node; +import org.onap.aaiclient.client.graphinventory.entities.Start; +import org.onap.aaiclient.client.graphinventory.entities.TraversalBuilder; +import org.onap.aaiclient.client.graphinventory.entities.__; import org.onap.aaiclient.client.graphinventory.entities.uri.Depth; import org.onap.aaiclient.client.graphinventory.exceptions.BulkProcessFailed; import org.onap.logging.filter.base.ErrorCode; +import org.onap.so.cloud.resource.beans.NodeType; import org.onap.so.db.catalog.beans.CloudIdentity; import org.onap.so.db.catalog.beans.ServerType; import org.onap.so.heatbridge.constants.HeatBridgeConstants; @@ -96,6 +108,8 @@ import org.openstack4j.model.network.Subnet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.env.Environment; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; @@ -110,21 +124,34 @@ public class HeatBridgeImpl implements HeatBridgeApi { private static final String ERR_MSG_NULL_OS_CLIENT = "Initialization error: Null openstack client. Authenticate with Keystone first."; private static final String OOB_MGT_NETWORK_IDENTIFIER = "Management"; + + protected static final String DIRECT = "direct"; + protected static final String PCI_SLOT = "pci_slot"; + protected static final String OVSNET = "ovsnet"; + protected static final String SRIOV = "SRIOV"; + protected static final String RESOURCE_LINK = "resource-link"; + + protected static final Object PRIVATE_VLANS = "private_vlans"; + protected static final Object PUBLIC_VLANS = "public_vlans"; + + protected ObjectMapper mapper = new ObjectMapper(); + private OpenstackClient osClient; private AAIResourcesClient resourcesClient; + private AAIDSLQueryClient aaiDSLClient; private AAISingleTransactionClient transaction; private String cloudOwner; private String cloudRegionId; private String regionId; private String tenantId; + private NodeType nodeType; private AaiHelper aaiHelper = new AaiHelper(); private CloudIdentity cloudIdentity; private Environment env; - public HeatBridgeImpl(AAIResourcesClient resourcesClient, final CloudIdentity cloudIdentity, @Nonnull final String cloudOwner, @Nonnull final String cloudRegionId, @Nonnull final String regionId, - @Nonnull final String tenantId) { + @Nonnull final String tenantId, @Nonnull final NodeType nodeType) { Objects.requireNonNull(cloudOwner, "Null cloud-owner value!"); Objects.requireNonNull(cloudRegionId, "Null cloud-region identifier!"); Objects.requireNonNull(tenantId, "Null tenant identifier!"); @@ -136,6 +163,7 @@ public class HeatBridgeImpl implements HeatBridgeApi { this.regionId = regionId; this.tenantId = tenantId; this.resourcesClient = resourcesClient; + this.nodeType = nodeType; if (resourcesClient != null) this.transaction = resourcesClient.beginSingleTransaction(); if (SpringContextHelper.getAppContext() != null) @@ -201,6 +229,11 @@ public class HeatBridgeImpl implements HeatBridgeApi { return serverIds.stream().map(serverId -> osClient.getServerById(serverId)).collect(Collectors.toList()); } + + protected Server getOpenstackServerById(String deviceId) { + return osClient.getServerById(deviceId); + } + @Override public List<Network> getAllOpenstackProviderNetworks(final List<Resource> stackResources) { Objects.requireNonNull(osClient, ERR_MSG_NULL_OS_CLIENT); @@ -240,7 +273,8 @@ public class HeatBridgeImpl implements HeatBridgeApi { l3Network.setRelationshipList(relationshipList); transaction.createIfNotExists( - AAIUriFactory.createResourceUri(AAIObjectType.L3_NETWORK, l3Network.getNetworkId()), + AAIUriFactory + .createResourceUri(AAIFluentTypeBuilder.network().l3Network(l3Network.getNetworkId())), Optional.of(l3Network)); } }); @@ -252,8 +286,8 @@ public class HeatBridgeImpl implements HeatBridgeApi { for (org.openstack4j.model.compute.Image image : images) { Image aaiImage = aaiHelper.buildImage(image); try { - AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.IMAGE, cloudOwner, cloudRegionId, - aaiImage.getImageId()); + AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() + .cloudRegion(cloudOwner, cloudRegionId).image(aaiImage.getImageId())); if (!resourcesClient.exists(uri)) { transaction.create(uri, aaiImage); logger.debug("Queuing AAI command to add image: " + aaiImage.getImageId()); @@ -273,8 +307,8 @@ public class HeatBridgeImpl implements HeatBridgeApi { for (org.openstack4j.model.compute.Flavor flavor : flavors) { Flavor aaiFlavor = aaiHelper.buildFlavor(flavor); try { - AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.FLAVOR, cloudOwner, cloudRegionId, - aaiFlavor.getFlavorId()); + AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() + .cloudRegion(cloudOwner, cloudRegionId).flavor(aaiFlavor.getFlavorId())); transaction.createIfNotExists(uri, Optional.of(aaiFlavor)); } catch (WebApplicationException e) { throw new HeatBridgeException( @@ -292,18 +326,24 @@ public class HeatBridgeImpl implements HeatBridgeApi { // Build vserver relationships to: image, flavor, pserver, vf-module vserver.setRelationshipList( aaiHelper.getVserverRelationshipList(cloudOwner, cloudRegionId, genericVnfId, vfModuleId, server)); - transaction.createIfNotExists(AAIUriFactory.createResourceUri(AAIObjectType.VSERVER, cloudOwner, - cloudRegionId, tenantId, vserver.getVserverId()), Optional.of(vserver)); + transaction.createIfNotExists( + AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() + .cloudRegion(cloudOwner, cloudRegionId).tenant(tenantId).vserver(vserver.getVserverId())), + Optional.of(vserver)); }); } @Override public void buildAddVserverLInterfacesToAaiAction(final List<Resource> stackResources, - final List<String> oobMgtNetIds, String cloudOwner) { + final List<String> oobMgtNetIds, String cloudOwner) throws HeatBridgeException { Objects.requireNonNull(osClient, ERR_MSG_NULL_OS_CLIENT); List<String> portIds = extractStackResourceIdsByResourceType(stackResources, HeatBridgeConstants.OS_PORT_RESOURCE_TYPE); + + if (portIds == null) + return; for (String portId : portIds) { + boolean isL2Multicast = false; Port port = osClient.getPortById(portId); Network network = osClient.getNetworkById(port.getNetworkId()); LInterface lIf = new LInterface(); @@ -314,32 +354,54 @@ public class HeatBridgeImpl implements HeatBridgeApi { lIf.setIsPortMirrored(false); lIf.setIsIpUnnumbered(false); lIf.setInMaint(false); - if (oobMgtNetIds != null && oobMgtNetIds.contains(port.getNetworkId())) { - lIf.setInterfaceRole(OOB_MGT_NETWORK_IDENTIFIER); - } else { - lIf.setInterfaceRole(port.getvNicType()); - } - boolean isL2Multicast = false; - if (port.getProfile().get("trusted") != null) { + + if (port.getProfile() != null && port.getProfile().get("trusted") != null) { String trusted = port.getProfile().get("trusted").toString(); if (Boolean.parseBoolean(trusted)) { isL2Multicast = true; } } lIf.setL2Multicasting(isL2Multicast); + lIf.setInterfaceType(getInterfaceType(nodeType, port.getvNicType())); + lIf.setRelationshipList(new RelationshipList()); - transaction.createIfNotExists(AAIUriFactory.createResourceUri(AAIObjectType.L_INTERFACE, cloudOwner, - cloudRegionId, tenantId, port.getDeviceId(), lIf.getInterfaceName()), Optional.of(lIf)); + if (oobMgtNetIds != null && oobMgtNetIds.contains(port.getNetworkId())) { + lIf.setInterfaceRole(OOB_MGT_NETWORK_IDENTIFIER); + } else { + lIf.setInterfaceRole(port.getvNicType()); + } + + // Update l-interface to the vserver + transaction.createIfNotExists( + AAIUriFactory.createResourceUri( + AAIFluentTypeBuilder.cloudInfrastructure().cloudRegion(cloudOwner, cloudRegionId) + .tenant(tenantId).vserver(port.getDeviceId()).lInterface(lIf.getInterfaceName())), + Optional.of(lIf)); updateLInterfaceIps(port, lIf); + if (cloudOwner.equals(env.getProperty("mso.cloudOwner.included", ""))) { - updateLInterfaceVlan(port, lIf); + Server server = getOpenstackServerById(port.getDeviceId()); + updateLInterfaceVlan(port, lIf, server.getHypervisorHostname()); } updateSriovPfToPserver(port, lIf); } } + protected String getInterfaceType(NodeType nodeType, String nicType) { + logger.debug("nicType: " + nicType + "nodeType: " + nodeType); + if (DIRECT.equalsIgnoreCase(nicType)) { + return SRIOV; + } else { + if (nodeType == NodeType.GREENFIELD) { + return NodeType.GREENFIELD.getNetworkTechnologyName(); + } else { + return NodeType.BROWNFIELD.getNetworkTechnologyName(); + } + } + } + @Override public void createPserversAndPinterfacesIfNotPresentInAai(final List<Resource> stackResources) throws HeatBridgeException { @@ -353,8 +415,10 @@ public class HeatBridgeImpl implements HeatBridgeApi { for (String portId : portIds) { Port port = osClient.getPortById(portId); if (port.getvNicType().equalsIgnoreCase(HeatBridgeConstants.OS_SRIOV_PORT_TYPE)) { - createPServerPInterfaceIfNotExists(serverHostnames.get(port.getHostId()).getHostname(), - aaiHelper.buildPInterface(port)); + Pserver foundServer = serverHostnames.get(port.getHostId()); + if (foundServer != null) { + createPServerPInterfaceIfNotExists(foundServer.getHostname(), aaiHelper.buildPInterface(port)); + } } } } @@ -366,6 +430,7 @@ public class HeatBridgeImpl implements HeatBridgeApi { for (Server server : osServers) { Pserver pserver = aaiHelper.buildPserver(server); if (pserver != null) { + logger.debug("Adding Pserver: " + server.getHost()); pserverMap.put(server.getHost(), pserver); } } @@ -389,18 +454,21 @@ public class HeatBridgeImpl implements HeatBridgeApi { private void createPServerIfNotExists(Map<String, Pserver> serverHostnames) { for (Pserver pserver : serverHostnames.values()) { - AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.PSERVER, pserver.getHostname()); + AAIResourceUri uri = AAIUriFactory + .createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure().pserver(pserver.getHostname())); resourcesClient.createIfNotExists(uri, Optional.of(pserver)); } } private void createPServerPInterfaceIfNotExists(String pserverHostname, PInterface pInterface) { - AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.P_INTERFACE, pserverHostname, - pInterface.getInterfaceName()); + AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() + .pserver(pserverHostname).pInterface(pInterface.getInterfaceName())); resourcesClient.createIfNotExists(uri, Optional.of(pInterface)); } - private void updateLInterfaceVlan(final Port port, final LInterface lIf) { + private void updateLInterfaceVlan(final Port port, final LInterface lIf, final String hostName) + throws HeatBridgeException { + // add back all vlan logic Vlan vlan = new Vlan(); Network network = osClient.getNetworkById(port.getNetworkId()); if (network.getNetworkType() != null && network.getNetworkType().equals(NetworkType.VLAN)) { @@ -410,7 +478,6 @@ public class HeatBridgeImpl implements HeatBridgeApi { vlan.setInMaint(false); vlan.setIsIpUnnumbered(false); vlan.setIsPrivate(false); - transaction .createIfNotExists( AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() @@ -419,6 +486,32 @@ public class HeatBridgeImpl implements HeatBridgeApi { Optional.of(vlan)); } + if (nodeType == NodeType.GREENFIELD) { + validatePhysicalNetwork(port, network); + processOVS(lIf, hostName, NodeType.GREENFIELD.getInterfaceName()); + } else { + processOVS(lIf, hostName, NodeType.BROWNFIELD.getInterfaceName()); + } + + List<String> privateVlans = (ArrayList<String>) port.getProfile().get(PRIVATE_VLANS); + List<String> publicVlans = (ArrayList<String>) port.getProfile().get(PUBLIC_VLANS); + List<String> vlans = null; + if (publicVlans != null && !publicVlans.isEmpty()) { + vlans = publicVlans.stream().filter(publicVlan -> !Strings.isNullOrEmpty(publicVlan)) + .collect(Collectors.toList()); + } else { + vlans = new ArrayList<>(); + } + + if (privateVlans != null && !privateVlans.isEmpty()) { + List<String> temp = privateVlans.stream().filter(privateVlan -> !Strings.isNullOrEmpty(privateVlan)) + .collect(Collectors.toList()); + vlans.addAll(temp); + } + vlans.stream().forEach(vlanLocal -> logger.debug("Vlan Id: {}", vlanLocal)); + + processVlanTag(lIf, vlans); + if (port.getvNicType() != null && port.getvNicType().equalsIgnoreCase(HeatBridgeConstants.OS_SRIOV_PORT_TYPE)) { SriovVf sriovVf = new SriovVf(); sriovVf.setPciId(port.getProfile().get(HeatBridgeConstants.OS_PCI_SLOT_KEY).toString()); @@ -436,6 +529,49 @@ public class HeatBridgeImpl implements HeatBridgeApi { } } + protected String createVlanTagUri(String vlanIdOuter) throws HeatBridgeException { + int vlanOuterInt = Integer.parseInt(vlanIdOuter); + DSLQueryBuilder<Start, Node> builder = TraversalBuilder + .fragment(new DSLStartNode(Types.CLOUD_REGION, __.key("cloud-owner", cloudOwner), + __.key("cloud-region-id", cloudRegionId))) + .to(__.node(Types.VLAN_RANGE)) + .to(__.node(Types.VLAN_TAG, __.key("vlan-id-outer", vlanOuterInt)).output()); + String results = getAAIDSLClient().query(Format.PATHED, new DSLQuery(builder.build())); + Optional<String> vlanTagURI = findLinkedURI(results); + if (vlanTagURI.isPresent()) + return vlanTagURI.get(); + else + throw new HeatBridgeException("Cannot find VlanTag Related Link " + vlanIdOuter); + } + + + protected void processVlanTag(LInterface lInterface, List<String> vlanTags) throws HeatBridgeException { + for (String vlanTag : vlanTags) { + Relationship vlanTagRelationship = new Relationship(); + vlanTagRelationship.setRelatedLink(createVlanTagUri(vlanTag)); + lInterface.getRelationshipList().getRelationship().add(vlanTagRelationship); + } + } + + protected void validatePhysicalNetwork(Port neutronPort, Network network) throws HeatBridgeException { + String physicalNetworkType = network.getProviderPhyNet(); + if (!OVSNET.equalsIgnoreCase(physicalNetworkType)) { + String exceptionMessage = String.format( + "The OVS-DPDK port is expected to have a physical network of type ovsnet but was found to have %s instead.", + physicalNetworkType); + throw new HeatBridgeException(exceptionMessage); + } + } + + protected void processOVS(LInterface lInterface, String hostName, String interfaceName) { + Relationship lagRelationship = new Relationship(); + lagRelationship.setRelatedLink(AAIUriFactory + .createResourceUri( + AAIFluentTypeBuilder.cloudInfrastructure().pserver(hostName).lagInterface(interfaceName)) + .build().toString()); + lInterface.getRelationshipList().getRelationship().add(lagRelationship); + } + /** * Needs to be corrected according to the specification that is in draft If pserver/p-interface does not have a * SRIOV-PF object matching the PCI-ID of the Openstack port object, then create it in AAI. Openstack SRIOV Port @@ -461,9 +597,11 @@ public class HeatBridgeImpl implements HeatBridgeApi { lIf.setInterfaceDescription( "Attached to SR-IOV port: " + pserverHostName + "::" + matchingPifName.get()); try { - Optional<PInterface> matchingPIf = resourcesClient.get(PInterface.class, AAIUriFactory - .createResourceUri(AAIObjectType.P_INTERFACE, pserverHostName, matchingPifName.get()) - .depth(Depth.ONE)); + Optional<PInterface> matchingPIf = resourcesClient.get(PInterface.class, + AAIUriFactory + .createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() + .pserver(pserverHostName).pInterface(matchingPifName.get())) + .depth(Depth.ONE)); if (matchingPIf.isPresent()) { SriovPfs pIfSriovPfs = matchingPIf.get().getSriovPfs(); if (pIfSriovPfs == null) { @@ -481,16 +619,18 @@ public class HeatBridgeImpl implements HeatBridgeApi { logger.debug("Queuing AAI command to update sriov-pf object to pserver: " + pserverHostName + "/" + matchingPifName.get()); - AAIResourceUri sriovPfUri = AAIUriFactory.createResourceUri(AAIObjectType.SRIOV_PF, - pserverHostName, matchingPifName.get(), sriovPf.getPfPciId()); + AAIResourceUri sriovPfUri = AAIUriFactory.createResourceUri( + AAIFluentTypeBuilder.cloudInfrastructure().pserver(pserverHostName) + .pInterface(matchingPifName.get()).sriovPf(sriovPf.getPfPciId())); + if (!resourcesClient.exists(sriovPfUri)) { transaction.create(sriovPfUri, sriovPf); - AAIResourceUri sriovVfUri = AAIUriFactory.createResourceUri(AAIObjectType.SRIOV_VF, - cloudOwner, cloudRegionId, tenantId, port.getDeviceId(), lIf.getInterfaceName(), - port.getProfile().get(HeatBridgeConstants.OS_PCI_SLOT_KEY).toString()); - + AAIResourceUri sriovVfUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder + .cloudInfrastructure().cloudRegion(cloudOwner, cloudRegionId).tenant(tenantId) + .vserver(port.getDeviceId()).lInterface(lIf.getInterfaceName()).sriovVf( + port.getProfile().get(HeatBridgeConstants.OS_PCI_SLOT_KEY).toString())); transaction.connect(sriovPfUri, sriovVfUri); } } @@ -505,13 +645,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()); @@ -522,6 +663,21 @@ public class HeatBridgeImpl implements HeatBridgeApi { .cloudRegion(cloudOwner, cloudRegionId).tenant(tenantId).vserver(port.getDeviceId()) .lInterface(lIf.getInterfaceName()).l3InterfaceIpv4AddressList(ipAddress)), Optional.of(lInterfaceIp)); + } else if (InetAddressValidator.getInstance().isValidInet6Address(ipAddress)) { + 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()); + ipv6.setL3InterfaceIpv6PrefixLength(Long.parseLong(cidr.getNetworkPrefixLength().toString())); + + transaction.createIfNotExists( + AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() + .cloudRegion(cloudOwner, cloudRegionId).tenant(tenantId).vserver(port.getDeviceId()) + .lInterface(lIf.getInterfaceName()).l3InterfaceIpv6AddressList(ipAddress)), + Optional.of(ipv6)); } } } @@ -543,17 +699,16 @@ public class HeatBridgeImpl implements HeatBridgeApi { Objects.requireNonNull(vnfId, "Null vnf-id!"); Objects.requireNonNull(vfModuleId, "Null vf-module-id!"); try { - Optional<VfModule> vfModule = resourcesClient - .get(AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId).depth(Depth.ONE), - NotFoundException.class) - .asBean(VfModule.class); + Optional<VfModule> vfModule = resourcesClient.get(AAIUriFactory + .createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId).vfModule(vfModuleId)) + .depth(Depth.ONE), NotFoundException.class).asBean(VfModule.class); AAIResultWrapper resultWrapper = new AAIResultWrapper(vfModule.get()); Optional<Relationships> relationships = resultWrapper.getRelationships(); logger.debug("VfModule contains relationships in AAI: {}", relationships.isPresent()); if (relationships.isPresent()) { - List<AAIResourceUri> l3NetworkUris = relationships.get().getRelatedUris(AAIObjectType.L3_NETWORK); + List<AAIResourceUri> l3NetworkUris = relationships.get().getRelatedUris(Types.L3_NETWORK); logger.debug("L3Network contains {} relationships in AAI", l3NetworkUris.size()); if (!l3NetworkUris.isEmpty()) { @@ -566,13 +721,13 @@ public class HeatBridgeImpl implements HeatBridgeApi { } } - List<AAIResourceUri> vserverUris = relationships.get().getRelatedUris(AAIObjectType.VSERVER); + List<AAIResourceUri> vserverUris = relationships.get().getRelatedUris(Types.VSERVER); logger.debug("VServer contains {} relationships in AAI", vserverUris.size()); createTransactionToDeleteSriovPfFromPserver(vserverUris); if (!vserverUris.isEmpty()) { for (AAIResourceUri vserverUri : vserverUris) { - if (env.getProperty("heatBridgeDryrun", Boolean.class, true)) { + if (env.getProperty("heatBridgeDryrun", Boolean.class, false)) { logger.debug("Would delete Vserver: {}", vserverUri.build().toString()); } else { resourcesClient.delete(vserverUri); @@ -598,7 +753,8 @@ public class HeatBridgeImpl implements HeatBridgeApi { String pserverName = entry.getKey(); List<String> pciIds = entry.getValue(); Optional<Pserver> pserver = resourcesClient.get(Pserver.class, - AAIUriFactory.createResourceUri(AAIObjectType.PSERVER, pserverName).depth(Depth.TWO)); + AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure().pserver(pserverName)) + .depth(Depth.TWO)); if (pserver.isPresent()) { // For each pserver/p-interface match sriov-vfs by pic-id and delete them. pserver.get().getPInterfaces().getPInterface().stream().filter( @@ -607,15 +763,15 @@ public class HeatBridgeImpl implements HeatBridgeApi { if (pciIds.contains(sriovPf.getPfPciId())) { logger.debug("creating transaction to delete SR-IOV PF: " + pIf.getInterfaceName() + " from PServer: " + pserverName); - if (env.getProperty("heatBridgeDryrun", Boolean.class, true)) { + if (env.getProperty("heatBridgeDryrun", Boolean.class, false)) { logger.debug("Would delete Sriov Pf: {}", - AAIUriFactory - .createResourceUri(AAIObjectType.SRIOV_PF, pserverName, - pIf.getInterfaceName(), sriovPf.getPfPciId()) - .build().toString()); + AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() + .pserver(pserverName).pInterface(pIf.getInterfaceName()) + .sriovPf(sriovPf.getPfPciId())).build()); } else { - resourcesClient.delete(AAIUriFactory.createResourceUri(AAIObjectType.SRIOV_PF, - pserverName, pIf.getInterfaceName(), sriovPf.getPfPciId())); + resourcesClient.delete(AAIUriFactory.createResourceUri( + AAIFluentTypeBuilder.cloudInfrastructure().pserver(pserverName) + .pInterface(pIf.getInterfaceName()).sriovPf(sriovPf.getPfPciId()))); } } })); @@ -629,12 +785,11 @@ public class HeatBridgeImpl implements HeatBridgeApi { AAIResultWrapper vserverWrapper = resourcesClient.get(vserverUri.depth(Depth.TWO)); Optional<Relationships> vserverRelationships = vserverWrapper.getRelationships(); if (vserverRelationships.isPresent() - && CollectionUtils.isNotEmpty(vserverRelationships.get().getRelatedLinks(AAIObjectType.PSERVER))) { + && CollectionUtils.isNotEmpty(vserverRelationships.get().getRelatedLinks(Types.PSERVER))) { Vserver vserver = vserverWrapper.asBean(Vserver.class).get(); List<String> pciIds = HeatBridgeUtils.extractPciIdsFromVServer(vserver); if (CollectionUtils.isNotEmpty(pciIds)) { - List<AAIResourceUri> matchingPservers = - vserverRelationships.get().getRelatedUris(AAIObjectType.PSERVER); + List<AAIResourceUri> matchingPservers = vserverRelationships.get().getRelatedUris(Types.PSERVER); if (matchingPservers != null && matchingPservers.size() == 1) { pserverToPciIdMap.put(matchingPservers.get(0).getURIKeys().get("hostname"), pciIds); } @@ -648,4 +803,28 @@ public class HeatBridgeImpl implements HeatBridgeApi { Map<Object, Boolean> map = new ConcurrentHashMap<>(); return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; } + + protected Optional<String> findLinkedURI(String jsonResultsString) { + Results<Map<String, String>> results; + try { + results = mapper.readValue(jsonResultsString, new TypeReference<Results<Map<String, String>>>() {}); + if (results.getResult().size() == 1) { + return Optional.of(results.getResult().get(0).get(RESOURCE_LINK)); + } else if (results.getResult().isEmpty()) { + return Optional.empty(); + } else { + throw new IllegalStateException("more than one result returned"); + } + } catch (IOException e) { + logger.error("Error retrieving URI from Results JSON", e); + return Optional.empty(); + } + } + + protected AAIDSLQueryClient getAAIDSLClient() { + if (aaiDSLClient == null) { + aaiDSLClient = new AAIDSLQueryClient(); + } + return aaiDSLClient; + } } diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/helpers/AaiHelper.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/helpers/AaiHelper.java index 7d4e92d9ad..1fa757f547 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/helpers/AaiHelper.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/helpers/AaiHelper.java @@ -252,6 +252,9 @@ public class AaiHelper { .filter(link -> link.getRel().equals(HeatBridgeConstants.OS_RESOURCES_SELF_LINK_KEY)).findFirst() .ifPresent(link -> aaiImage.setImageSelflink(link.getHref())); } + if (aaiImage.getImageSelflink() == null || aaiImage.getImageSelflink().isEmpty()) { + aaiImage.setImageSelflink("NA"); + } return aaiImage; } 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 8c21e3f7f7..cea436b799 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,15 +68,20 @@ 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; +import org.onap.aaiclient.client.aai.AAIDSLQueryClient; import org.onap.aaiclient.client.aai.AAIObjectType; 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.cloud.resource.beans.NodeType; import org.onap.so.db.catalog.beans.CloudIdentity; import org.onap.so.heatbridge.constants.HeatBridgeConstants; import org.onap.so.heatbridge.helpers.AaiHelper; @@ -93,11 +101,14 @@ 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) +@RunWith(MockitoJUnitRunner.Silent.class) public class HeatBridgeImplTest { private static final String CLOUD_OWNER = "CloudOwner"; @@ -117,33 +128,24 @@ public class HeatBridgeImplTest { private AAISingleTransactionClient transaction; @Mock + private AAIDSLQueryClient mockDSLClient; + + @Mock private Environment env; + @Mock + private Server server; + @InjectMocks - private HeatBridgeImpl heatbridge = - new HeatBridgeImpl(resourcesClient, cloudIdentity, CLOUD_OWNER, REGION_ID, REGION_ID, TENANT_ID); + private HeatBridgeImpl heatbridge = new HeatBridgeImpl(resourcesClient, cloudIdentity, CLOUD_OWNER, REGION_ID, + REGION_ID, TENANT_ID, NodeType.GREENFIELD); @Before public void setUp() throws HeatBridgeException, OpenstackClientException, BulkProcessFailed { when(resourcesClient.beginSingleTransaction()).thenReturn(transaction); } - @Ignore - @Test - public void testQueryNestedHeatStackResources() throws HeatBridgeException { - // Arrange - String heatStackId = "1234567"; - List<Resource> expectedResourceList = (List<Resource>) extractTestStackResources(); - when(osClient.getStackBasedResources(heatStackId, HeatBridgeConstants.OS_DEFAULT_HEAT_NESTING)) - .thenReturn(expectedResourceList); - - // Act - List<Resource> resourceList = heatbridge.queryNestedHeatStackResources(heatStackId); - // Assert - verify(osClient).getStackBasedResources(heatStackId, HeatBridgeConstants.OS_DEFAULT_HEAT_NESTING); - assertEquals(resourceList, expectedResourceList); - } @Test public void testExtractStackResourceIdsByResourceType() throws HeatBridgeException { @@ -160,73 +162,6 @@ public class HeatBridgeImplTest { assertEquals(expectedServerIds, serverIds); } - @Ignore - @Test - public void testGetAllOpenstackServers() { - // Arrange - List<Resource> stackResources = (List<Resource>) extractTestStackResources(); - - Server server1 = mock(Server.class); - Server server2 = mock(Server.class); - List<Server> expectedServers = Arrays.asList(server1, server2); - - when(osClient.getServerById("43c2159b-2c04-46ac-bda5-594110cae2d3")).thenReturn(server1); - when(osClient.getServerById("7cff109a-b2b7-4933-97b4-ec44a8365568")).thenReturn(server2); - - // Act - List<Server> servers = heatbridge.getAllOpenstackServers(stackResources); - - // Assert - assertEquals(expectedServers, servers); - } - - @Ignore - @Test - public void testExtractOpenstackImagesFromServers() { - // Arrange - Server server1 = mock(Server.class); - Server server2 = mock(Server.class); - List<Server> servers = Arrays.asList(server1, server2); - - Image image1 = mock(Image.class); - Image image2 = mock(Image.class); - when(image1.getId()).thenReturn("1"); - when(image2.getId()).thenReturn("1"); - List<Image> expectedDistinctImages = Collections.singletonList(image1); - - when(server1.getImage()).thenReturn(image1); - when(server2.getImage()).thenReturn(image2); - - // Act - List<Image> images = heatbridge.extractOpenstackImagesFromServers(servers); - - // Assert - assertEquals(expectedDistinctImages, images); - } - - @Ignore - @Test - public void testExtractOpenstackFlavorsFromServers() { - // Arrange - Server server1 = mock(Server.class); - Server server2 = mock(Server.class); - List<Server> servers = Arrays.asList(server1, server2); - - Flavor flavor1 = mock(Flavor.class); - Flavor flavor2 = mock(Flavor.class); - when(flavor1.getId()).thenReturn("1"); - when(flavor2.getId()).thenReturn("2"); - List<Flavor> expectedFlavors = Arrays.asList(flavor1, flavor2); - - when(server1.getFlavor()).thenReturn(flavor1); - when(server2.getFlavor()).thenReturn(flavor2); - - // Act - List<Flavor> flavors = heatbridge.extractOpenstackFlavorsFromServers(servers); - - // Assert - assertEquals(expectedFlavors, flavors); - } @Test public void testUpdateVserversToAai() throws HeatBridgeException { @@ -419,14 +354,30 @@ public class HeatBridgeImplTest { when(port.getMacAddress()).thenReturn("78:4f:43:68:e2:78"); when(port.getNetworkId()).thenReturn("890a203a-23gg-56jh-df67-731656a8f13a"); when(port.getDeviceId()).thenReturn("test-device-id"); + + when(osClient.getServerById("test-device-id")).thenReturn(server); + when(server.getHypervisorHostname()).thenReturn("test.server.name"); String pfPciId = "0000:08:00.0"; when(port.getProfile()).thenReturn(ImmutableMap.of(HeatBridgeConstants.OS_PCI_SLOT_KEY, pfPciId, HeatBridgeConstants.OS_PHYSICAL_NETWORK_KEY, "physical_network_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); + Network network = mock(Network.class); when(network.getId()).thenReturn("test-network-id"); when(network.getNetworkType()).thenReturn(NetworkType.VLAN); when(network.getProviderSegID()).thenReturn("2345"); + when(network.getProviderPhyNet()).thenReturn("ovsnet"); when(osClient.getPortById("212a203a-9764-4f42-84ea-731536a8f13a")).thenReturn(port); when(osClient.getPortById("387e3904-8948-43d1-8635-b6c2042b54da")).thenReturn(port); @@ -446,8 +397,9 @@ public class HeatBridgeImplTest { heatbridge.buildAddVserverLInterfacesToAaiAction(stackResources, Arrays.asList("1", "2"), "CloudOwner"); // Assert - verify(transaction, times(15)).createIfNotExists(any(AAIResourceUri.class), any(Optional.class)); + verify(transaction, times(20)).createIfNotExists(any(AAIResourceUri.class), any(Optional.class)); verify(osClient, times(5)).getPortById(anyString()); + verify(osClient, times(5)).getSubnetById("testSubnetId"); verify(osClient, times(10)).getNetworkById(anyString()); } @@ -516,6 +468,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(); diff --git a/adapters/pom.xml b/adapters/pom.xml index 3c71b3c031..49f25b8102 100644 --- a/adapters/pom.xml +++ b/adapters/pom.xml @@ -24,6 +24,7 @@ <module>mso-openstack-adapters</module> <module>etsi-sol003-adapter</module> <module>mso-nssmf-adapter</module> + <module>mso-oof-adapter</module> <module>so-appc-orchestrator</module> </modules> |