diff options
author | Murali-P <murali.p@huawei.com> | 2017-10-16 15:07:16 +0530 |
---|---|---|
committer | Murali-P <murali.p@huawei.com> | 2017-12-04 11:04:54 +0530 |
commit | baebe989f102c10d5077fb24a6948893284a236d (patch) | |
tree | 84566a75879428a950f04a9c369ab1a80afcd8f7 /openecomp-be | |
parent | dcf55799473fe5d585ff1bc8121ab48485baab2b (diff) |
Integrate VNF Repository with SDC
Add Browse VNF packages feature
Change-Id: I0c721829efdac8ad6f72c4ac9d25ec96e091f7ca
Issue-ID: VNFSDK-82
Signed-off-by: Michael Lando <ml636r@att.com>
Signed-off-by: Murali-P <murali.p@huawei.com>
Diffstat (limited to 'openecomp-be')
7 files changed, 418 insertions, 0 deletions
diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/pom.xml b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/pom.xml index 9808d76a9c..ee1b9b3d65 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/pom.xml +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/pom.xml @@ -32,6 +32,11 @@ </dependency> <dependency> <groupId>org.openecomp.sdc.onboarding</groupId> + <artifactId>vnf-repository-rest-services</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdc.onboarding</groupId> <artifactId>validation-rest-services</artifactId> <version>${project.version}</version> </dependency> diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/beans-services.xml b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/beans-services.xml index 126f7814d7..fb2db2b362 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/beans-services.xml +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/beans-services.xml @@ -76,6 +76,7 @@ <ref bean="deploymentFlavors"/> <ref bean="images"/> <ref bean="orchestrationTemplateCandidate"/> + <ref bean="vnfPackageRepository"/> <ref bean="componentDependencyModel"/> <ref bean="activityLog"/> <ref bean="healthCheck"/> diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/pom.xml b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/pom.xml index eb7fe70691..e311a7ca1e 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/pom.xml +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/pom.xml @@ -17,5 +17,6 @@ <modules> <module>/vendor-software-products-rest-services</module> <module>/vendor-software-products-rest-types</module> + <module>/vnf-repository-rest-services</module> </modules> </project> diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vnf-repository-rest-services/pom.xml b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vnf-repository-rest-services/pom.xml new file mode 100644 index 0000000000..47ed01d2d9 --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vnf-repository-rest-services/pom.xml @@ -0,0 +1,104 @@ +<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <artifactId>vnf-repository-rest-services</artifactId> + + <parent> + <groupId>org.openecomp.sdc.onboarding</groupId> + <artifactId>vendor-software-products-rest</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> + + <dependencies> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-core</artifactId> + <version>${spring.framework.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + <version>${spring.framework.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context-support</artifactId> + <version>${spring.framework.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-web</artifactId> + <version>${spring.framework.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-beans</artifactId> + <version>${spring.framework.version}</version> + </dependency> + + <!-- CXF --> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-frontend-jaxrs</artifactId> + <version>${cxf.version}</version> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>${http.client.version}</version> + </dependency> + + + <!-- Java Stuff --> + <dependency> + <groupId>javax.inject</groupId> + <artifactId>javax.inject</artifactId> + <version>${javax.inject.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdc</groupId> + <artifactId>openecomp-sdc-common-rest</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdc</groupId> + <artifactId>common-app-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdc.common</groupId> + <artifactId>openecomp-configuration-management-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdc.common</groupId> + <artifactId>openecomp-configuration-management-core</artifactId> + <version>${project.version}</version> + <scope>runtime</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdc.onboarding</groupId> + <artifactId>vendor-software-products-rest-services</artifactId> + <version>${project.version}</version> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <includes> + <include>test/core/unittest/offline/**</include> + </includes> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vnf-repository-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/VnfPackageRepository.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vnf-repository-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/VnfPackageRepository.java new file mode 100644 index 0000000000..1d922a63e8 --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vnf-repository-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/VnfPackageRepository.java @@ -0,0 +1,71 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openecomp.sdcrests.vsp.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.openecomp.sdcrests.vendorsoftwareproducts.types.UploadFileResponseDto; +import org.springframework.validation.annotation.Validated; + +import javax.validation.constraints.NotNull; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.File; +import static org.openecomp.sdcrests.common.RestConstants.USER_ID_HEADER_PARAM; +import static org.openecomp.sdcrests.common.RestConstants.USER_MISSING_ERROR_MSG; + +@Path("/v1.0/vendor-software-products/{vspId}/versions/{versionId}/vnfrepository") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Api(value = "VNF Repository packages") +@Validated +public interface VnfPackageRepository extends VspEntities { + + @GET + @Path("/vnfpackages") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @ApiOperation(value = "Get VNF packages from VNF Repository", notes = "Call VNF Repostory to get VNF package details", response = File.class) + Response getVnfPackages(@PathParam("vspId") String vspId, + @ApiParam(value = "Version Id") @PathParam("versionId") String versionId, + @NotNull(message = USER_MISSING_ERROR_MSG) @HeaderParam(USER_ID_HEADER_PARAM) String user) throws Exception; + + @GET + @Path("/vnfpackage/{csarId}/download") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @ApiOperation(value = "Download VNF package from VNF Repository", notes = "Download VNF package from VNF repository and send to client", response = File.class) + Response downloadVnfPackage(@PathParam("vspId") String vspId, + @ApiParam(value = "Version Id") @PathParam("versionId") String versionId, + @PathParam("csarId") String csarId, + @NotNull(message = USER_MISSING_ERROR_MSG) @HeaderParam(USER_ID_HEADER_PARAM) String user) throws Exception; + + @POST + @Path("/vnfpackage/{csarId}/import") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Import VNF package from VNF Repository", notes = "Call VNF Repostory to download VNF package, validate it and send the response", response = UploadFileResponseDto.class) + Response importVnfPackage(@PathParam("vspId") String vspId, + @ApiParam(value = "Version Id") @PathParam("versionId") String versionId, + @PathParam("csarId") String csarId, + @NotNull(message = USER_MISSING_ERROR_MSG) @HeaderParam(USER_ID_HEADER_PARAM) String user) throws Exception; + +} diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vnf-repository-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/VnfPackageRepositoryImpl.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vnf-repository-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/VnfPackageRepositoryImpl.java new file mode 100644 index 0000000000..acbfb328f1 --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vnf-repository-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/VnfPackageRepositoryImpl.java @@ -0,0 +1,232 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openecomp.sdcrests.vsp.rest.services; + +import org.apache.http.HttpStatus; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.openecomp.sdc.logging.messages.AuditMessages; +import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManager; +import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManagerFactory; +import org.openecomp.sdc.vendorsoftwareproduct.types.UploadFileResponse; +import org.openecomp.sdc.versioning.types.VersionableEntityAction; +import org.openecomp.sdcrests.vendorsoftwareproducts.types.UploadFileResponseDto; +import org.openecomp.sdcrests.vsp.rest.VnfPackageRepository; +import org.openecomp.sdcrests.vsp.rest.mapping.MapUploadFileResponseToUploadFileResponseDto; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Service; +import org.openecomp.sdc.common.rest.api.IRestClient; +import org.openecomp.sdc.common.rest.api.RestConfigurationInfo; +import org.openecomp.sdc.common.rest.api.RestResponse; +import org.openecomp.sdc.common.rest.impl.RestClientServiceFactory; +import org.openecomp.config.api.Configuration; +import org.openecomp.config.api.ConfigurationManager; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +import javax.inject.Named; +import javax.ws.rs.core.Response; + +import static org.openecomp.core.utilities.file.FileUtils.getFileExtension; +import static org.openecomp.core.utilities.file.FileUtils.getNetworkPackageName; + +/** + * + * The class implements the API interface with VNF Repository (VNFSDK) such as + * i) Get all the VNF Package Meta-data ii) Download the VNF Package iii) Import + * VNF package to SDC catalog (Download & validate) + * + * @version Amsterdam release (ONAP 1.0) + * + */ +@Named +@Service("vnfPackageRepository") +@Scope(value = "prototype") +public class VnfPackageRepositoryImpl implements VnfPackageRepository { + + private static final Logger LOGGER = LoggerFactory.getLogger(VnfPackageRepositoryImpl.class); + private static IRestClient iRestClnt = null; + private static boolean initFlag = false; + + // Default VNF Repository configuration + private static final String CONFIG_NAMESPACE = "vnfsdk"; + + // Default address for VNF repository docker + private static final String DEF_DOCKER_COMPOSE_ADDR = "172.18.0.1"; + private static String ipAddress = DEF_DOCKER_COMPOSE_ADDR; + + // Default Download package URI and Get VNF package meta-data URI - + // configurable + private static String getVnfPkgUri = "/onapapi/vnfsdk-marketplace/v1/PackageResource/csars"; + private static String downldPkgUri = "/onapapi/vnfsdk-marketplace/v1/PackageResource/csars/%s/files"; + + // Default port for VNF Repository + private static String port = "8702"; + + @Override + public Response getVnfPackages(String vspId, String versionId, String user) throws Exception { + + LOGGER.audit(AuditMessages.AUDIT_MSG, "Get VNF Packages from Repository:{}", vspId); + + // Step 1: Create REST client and configuration and prepare URI + init(); + + // Step 2: Build URI based on the IP address and port allocated + RestResponse rsp = iRestClnt.doGET(getVnfPkgUri, null); + if (HttpStatus.SC_OK != rsp.getHttpStatusCode()) { + LOGGER.error("Failed to query VNF package metadata:uri={}, Response={}", getVnfPkgUri, rsp); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } + + // Step 3: Send the response to the client + LOGGER.debug("Response from VNF Repository: {}", rsp.getResponse()); + + return Response.ok(rsp.getResponse()).build(); + } + + @Override + public Response importVnfPackage(String vspId, String versionId, String csarId, String user) throws Exception { + + LOGGER.audit(AuditMessages.AUDIT_MSG, "Import VNF Packages from Repository:{}", csarId); + + // Step 1: Create REST client and configuration and prepare URI + init(); + + // Step 2: Build URI based on the IP address and port allocated + String uri = String.format(downldPkgUri, csarId); + RestResponse rsp = iRestClnt.doGET(getVnfPkgUri, null); + if (HttpStatus.SC_OK != rsp.getHttpStatusCode()) { + LOGGER.error("Failed to download package from VNF Repository:uri={}, Response={}", uri, rsp); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } + LOGGER.debug(AuditMessages.AUDIT_MSG, "Response from VNF Repository for download package is success "); + + // Step 3: Import the file to SDC and validate and send the response + try (InputStream fileStream = new BufferedInputStream( + new ByteArrayInputStream(rsp.getResponse().getBytes(StandardCharsets.ISO_8859_1)))) { + + String filename = "temp_" + csarId + ".csar"; + OrchestrationTemplateCandidateManager candidateManager = OrchestrationTemplateCandidateManagerFactory + .getInstance().createInterface(); + UploadFileResponse uploadFileResponse = candidateManager.upload(vspId, + resolveVspVersion(vspId, null, user, VersionableEntityAction.Write), fileStream, user, + getFileExtension(filename), getNetworkPackageName(filename)); + + UploadFileResponseDto uploadFileResponseDto = new MapUploadFileResponseToUploadFileResponseDto() + .applyMapping(uploadFileResponse, UploadFileResponseDto.class); + + return Response.ok(uploadFileResponseDto).build(); + } catch (IOException e) { + // Exception while uploading file + LOGGER.error("Exception while uploading VNF package received from VNF Repository:", e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } + } + + @Override + public Response downloadVnfPackage(String vspId, String versionId, String csarId, String user) throws Exception { + + LOGGER.audit(AuditMessages.AUDIT_MSG + "Download VNF Packages from Repository:csarId={}", csarId); + + // Step 1: Create REST client and configuration and prepare URI + init(); + + // Step 2: Build URI based on the IP address and port allocated + String uri = String.format(downldPkgUri, csarId); + RestResponse rsp = iRestClnt.doGET(uri, null); + if (HttpStatus.SC_OK != rsp.getHttpStatusCode()) { + LOGGER.error("Failed to download package from VNF Repository:uri={}, Response={}", uri, rsp); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } + + // Step 3:Send response to the client + String filename = "temp_" + csarId + ".csar"; + Response.ResponseBuilder response = Response.ok(rsp.getResponse().getBytes(StandardCharsets.ISO_8859_1)); + response.header("Content-Disposition", "attachment; filename=" + filename); + + LOGGER.debug(AuditMessages.AUDIT_MSG, "Response from VNF Repository for download package is success "); + + return response.build(); + } + + private static void setRestClient() { + + if (null == iRestClnt) { + RestConfigurationInfo restInfo = new RestConfigurationInfo(); + iRestClnt = RestClientServiceFactory.createRestClientService(restInfo); + if (null == iRestClnt) { + return; + } + } + } + + private static void setVnfRepoConfig() { + + try { + // Step 1: Fetch the on-boarding configuration + Configuration config = ConfigurationManager.lookup(); + + String vnfRepoHost = config.getAsString(CONFIG_NAMESPACE, "vnfRepoHost"); + if (null != vnfRepoHost) { + ipAddress = vnfRepoHost; + } + + String vnfRepoPort = config.getAsString(CONFIG_NAMESPACE, "vnfRepoPort"); + if (null != vnfRepoPort) { + port = vnfRepoPort; + } + + String getVnfUri = config.getAsString(CONFIG_NAMESPACE, "getVnfUri"); + if (null != getVnfUri) { + getVnfPkgUri = getVnfUri; + } + + String downloadVnfUri = config.getAsString(CONFIG_NAMESPACE, "downloadVnfUri"); + if (null != downloadVnfUri) { + downldPkgUri = downloadVnfUri; + } + + } catch (Exception e) { + LOGGER.error("Failed to load configuration, Exception caught, using default configuration", e); + } + + getVnfPkgUri = new StringBuilder("http://").append(ipAddress).append(":").append(port).append(getVnfPkgUri) + .toString(); + + downldPkgUri = new StringBuilder("http://").append(ipAddress).append(":").append(port).append(downldPkgUri) + .toString(); + } + + private static synchronized void init() throws Exception { + if (!initFlag) { + // Step 1: Initialize configuration + setVnfRepoConfig(); + + // Step 2: Initialize rest client + setRestClient(); + if (null == iRestClnt) { + LOGGER.error("REST initialization error, Rest client is null"); + throw new Exception("Rest Initializer error, Rest client is null"); + } + + initFlag = true; + } + } +} diff --git a/openecomp-be/configuration/config-vnfsdk.yaml b/openecomp-be/configuration/config-vnfsdk.yaml new file mode 100644 index 0000000000..a59f6711b9 --- /dev/null +++ b/openecomp-be/configuration/config-vnfsdk.yaml @@ -0,0 +1,4 @@ +vnfRepoPort: 8702 +vnfRepoHost: 172.18.0.1 +getVnfUri: /onapapi/vnfsdk-marketplace/v1/PackageResource/csars +downloadVnfUri: /onapapi/vnfsdk-marketplace/v1/PackageResource/csars/%s/files |