2 * Copyright © 2017-2019 AT&T, Bell Canada
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.onap.ccsdk.cds.sdclistener.service;
19 import static java.nio.file.Files.walk;
20 import static org.onap.sdc.utils.DistributionStatusEnum.COMPONENT_DONE_ERROR;
21 import static org.onap.sdc.utils.DistributionStatusEnum.COMPONENT_DONE_OK;
22 import com.google.protobuf.ByteString;
23 import io.grpc.ManagedChannel;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.OutputStream;
29 import java.nio.file.Files;
30 import java.nio.file.Path;
31 import java.nio.file.Paths;
32 import java.util.Enumeration;
33 import java.util.List;
34 import java.util.Optional;
35 import java.util.regex.Pattern;
36 import java.util.zip.ZipEntry;
37 import java.util.zip.ZipFile;
38 import org.apache.commons.io.FileUtils;
39 import org.apache.tomcat.util.http.fileupload.IOUtils;
40 import org.onap.ccsdk.cds.sdclistener.client.SdcListenerAuthClientInterceptor;
41 import org.onap.ccsdk.cds.sdclistener.dto.SdcListenerDto;
42 import org.onap.ccsdk.cds.sdclistener.handler.BluePrintProcesssorHandler;
43 import org.onap.ccsdk.cds.sdclistener.status.SdcListenerStatus;
44 import org.onap.ccsdk.cds.sdclistener.util.FileUtil;
45 import org.onap.ccsdk.cds.controllerblueprints.common.api.Status;
46 import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintUploadInput;
47 import org.onap.ccsdk.cds.controllerblueprints.management.api.FileChunk;
48 import org.onap.sdc.api.results.IDistributionClientDownloadResult;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51 import org.springframework.beans.factory.annotation.Autowired;
52 import org.springframework.beans.factory.annotation.Value;
53 import org.springframework.boot.context.properties.ConfigurationProperties;
54 import org.springframework.stereotype.Component;
57 @ConfigurationProperties("listenerservice")
58 public class ListenerServiceImpl implements ListenerService {
61 private BluePrintProcesssorHandler bluePrintProcesssorHandler;
64 private SdcListenerAuthClientInterceptor sdcListenerAuthClientInterceptor;
67 private SdcListenerStatus listenerStatus;
70 private SdcListenerDto sdcListenerDto;
72 @Value("${listenerservice.config.grpcAddress}")
73 private String grpcAddress;
75 @Value("${listenerservice.config.grpcPort}")
78 private static final String CBA_ZIP_PATH = "Artifacts/Resources/[a-zA-Z0-9-_]+/Deployment/CONTROLLER_BLUEPRINT_ARCHIVE/[a-zA-Z0-9-_]+[.]zip";
79 private static final int SUCCESS_CODE = 200;
80 private static final Logger LOGGER = LoggerFactory.getLogger(ListenerServiceImpl.class);
83 public void extractBluePrint(String csarArchivePath, String cbaArchivePath) {
84 Path cbaStorageDir = getStorageDirectory(cbaArchivePath);
85 try (ZipFile zipFile = new ZipFile(csarArchivePath)) {
86 Enumeration<? extends ZipEntry> entries = zipFile.entries();
87 while (entries.hasMoreElements()) {
88 ZipEntry entry = entries.nextElement();
89 String fileName = entry.getName();
90 if (Pattern.matches(CBA_ZIP_PATH, fileName)) {
91 final String cbaArchiveName = Paths.get(fileName).getFileName().toString();
92 LOGGER.info("Storing the CBA archive {}", cbaArchiveName);
93 storeBluePrint(zipFile, cbaArchiveName, cbaStorageDir, entry);
97 } catch (Exception e) {
98 LOGGER.error("Failed to extract blueprint {}", e);
102 private void storeBluePrint(ZipFile zipFile, String fileName, Path cbaArchivePath, ZipEntry entry) {
103 Path targetLocation = cbaArchivePath.resolve(fileName);
104 LOGGER.info("The target location for zip file is {}", targetLocation);
105 File targetZipFile = new File(targetLocation.toString());
108 targetZipFile.createNewFile();
109 } catch (IOException e) {
110 LOGGER.error("Could not able to create file {}", targetZipFile, e);
113 try (InputStream inputStream = zipFile.getInputStream(entry); OutputStream out = new FileOutputStream(
115 IOUtils.copy(inputStream, out);
116 LOGGER.info("Successfully store the CBA archive {} at this location", targetZipFile);
117 } catch (Exception e) {
118 LOGGER.error("Failed to put zip file into target location {}, {}", targetLocation, e);
123 public void saveBluePrintToCdsDatabase(Path cbaArchivePath, ManagedChannel channel) {
124 Optional<List<File>> zipFiles = FileUtil.getFilesFromDisk(cbaArchivePath);
125 zipFiles.ifPresent(files -> prepareRequestForCdsBackend(files, channel, cbaArchivePath.toString()));
129 public void extractCsarAndStore(IDistributionClientDownloadResult result, String csarArchivePath) {
131 // Create CSAR storage directory
132 Path csarStorageDir = getStorageDirectory(csarArchivePath);
133 byte[] payload = result.getArtifactPayload();
134 String csarFileName = result.getArtifactFilename();
135 Path targetLocation = csarStorageDir.resolve(csarFileName);
137 LOGGER.info("The target location for the CSAR file is {}", targetLocation);
139 File targetCsarFile = new File(targetLocation.toString());
141 try (FileOutputStream outFile = new FileOutputStream(targetCsarFile)) {
142 outFile.write(payload, 0, payload.length);
143 } catch (Exception e) {
144 LOGGER.error("Failed to put CSAR file into target location {}, {}", targetLocation, e);
148 private Path getStorageDirectory(String path) {
149 Path fileStorageLocation = Paths.get(path).toAbsolutePath().normalize();
151 if (!fileStorageLocation.toFile().exists()) {
153 return Files.createDirectories(fileStorageLocation);
154 } catch (IOException e) {
155 LOGGER.error("Fail to create directory {}, {}", e, fileStorageLocation);
158 return fileStorageLocation;
161 private void prepareRequestForCdsBackend(List<File> files, ManagedChannel managedChannel, String path) {
162 final String distributionId = sdcListenerDto.getDistributionId();
164 files.forEach(zipFile -> {
166 final BluePrintUploadInput request = generateBluePrintUploadInputBuilder(zipFile);
168 // Send request to CDS Backend.
169 final Status responseStatus = bluePrintProcesssorHandler.sendRequest(request, managedChannel);
171 if (responseStatus.getCode() != SUCCESS_CODE) {
172 final String errorMessage = String.format("Failed to store the CBA archive into CDS DB due to %s",
173 responseStatus.getErrorMessage());
174 listenerStatus.sendResponseStatusBackToSDC(distributionId,
175 COMPONENT_DONE_ERROR, errorMessage);
176 LOGGER.error(errorMessage);
179 LOGGER.info(responseStatus.getMessage());
180 listenerStatus.sendResponseStatusBackToSDC(distributionId,
181 COMPONENT_DONE_OK, null);
184 } catch (Exception e) {
185 final String errorMessage = String.format("Failure due to %s", e.getMessage());
186 listenerStatus.sendResponseStatusBackToSDC(distributionId, COMPONENT_DONE_ERROR, errorMessage);
187 LOGGER.error("Failure due to {}", e);
189 FileUtil.deleteFile(zipFile, path);
194 private BluePrintUploadInput generateBluePrintUploadInputBuilder(File file) throws IOException {
195 byte[] bytes = FileUtils.readFileToByteArray(file);
196 FileChunk fileChunk = FileChunk.newBuilder().setChunk(ByteString.copyFrom(bytes)).build();
198 return BluePrintUploadInput.newBuilder()
199 .setFileChunk(fileChunk)