2 * Copyright (C) 2019 Bell Canada. All rights reserved.
4 * NOTICE: All the intellectual and technical concepts contained herein are
5 * proprietary to Bell Canada and are protected by trade secret or copyright law.
6 * Unauthorized copying of this file, via any medium is strictly prohibited.
9 package org.onap.ccsdk.cds.cdssdclistener.service;
11 import static java.nio.file.Files.walk;
12 import com.google.protobuf.ByteString;
13 import io.grpc.ManagedChannel;
14 import io.grpc.ManagedChannelBuilder;
16 import java.io.FileOutputStream;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.io.OutputStream;
20 import java.nio.file.Files;
21 import java.nio.file.Path;
22 import java.nio.file.Paths;
23 import java.util.Enumeration;
24 import java.util.List;
25 import java.util.Optional;
26 import java.util.regex.Pattern;
27 import java.util.stream.Collectors;
28 import java.util.stream.Stream;
29 import java.util.zip.ZipEntry;
30 import java.util.zip.ZipFile;
31 import org.apache.commons.io.FileUtils;
32 import org.apache.tomcat.util.http.fileupload.IOUtils;
33 import org.onap.ccsdk.cds.cdssdclistener.client.CdsSdcListenerAuthClientInterceptor;
34 import org.onap.ccsdk.cds.cdssdclistener.handler.BluePrintProcesssorHandler;
35 import org.onap.ccsdk.cds.controllerblueprints.common.api.Status;
36 import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintUploadInput;
37 import org.onap.ccsdk.cds.controllerblueprints.management.api.FileChunk;
38 import org.onap.sdc.api.results.IDistributionClientDownloadResult;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41 import org.springframework.beans.factory.annotation.Autowired;
42 import org.springframework.beans.factory.annotation.Value;
43 import org.springframework.boot.context.properties.ConfigurationProperties;
44 import org.springframework.stereotype.Component;
47 @ConfigurationProperties("listenerservice")
48 public class ListenerServiceImpl implements ListenerService {
51 private BluePrintProcesssorHandler bluePrintProcesssorHandler;
54 private CdsSdcListenerAuthClientInterceptor cdsSdcListenerAuthClientInterceptor;
56 @Value("${listenerservice.config.grpcAddress}")
57 private String grpcAddress;
59 @Value("${listenerservice.config.grpcPort}")
62 private static final String CBA_ZIP_PATH = "Artifacts/Resources/[a-zA-Z0-9-_]+/Deployment/CONTROLLER_BLUEPRINT_ARCHIVE/[a-zA-Z0-9-_]+[.]zip";
63 private static final int SUCCESS_CODE = 200;
64 private static final String CSAR_FILE_EXTENSION = ".csar";
65 private static final Logger LOGGER = LoggerFactory.getLogger(ListenerServiceImpl.class);
68 public void extractBluePrint(String csarArchivePath, String cbaArchivePath) {
69 Path cbaStorageDir = getStorageDirectory(cbaArchivePath);
70 try (ZipFile zipFile = new ZipFile(csarArchivePath)) {
71 Enumeration<? extends ZipEntry> entries = zipFile.entries();
72 while (entries.hasMoreElements()) {
73 ZipEntry entry = entries.nextElement();
74 String fileName = entry.getName();
75 if (Pattern.matches(CBA_ZIP_PATH, fileName)) {
76 final String cbaArchiveName = Paths.get(fileName).getFileName().toString();
77 LOGGER.info("Storing the CBA archive {}", cbaArchiveName);
78 storeBluePrint(zipFile, cbaArchiveName, cbaStorageDir, entry);
81 } catch (Exception e) {
82 LOGGER.error("Failed to extract blueprint", e);
86 private void storeBluePrint(ZipFile zipFile, String fileName, Path cbaArchivePath, ZipEntry entry) {
87 Path targetLocation = cbaArchivePath.resolve(fileName);
88 LOGGER.info("The target location for zip file is {}", targetLocation);
89 File targetZipFile = new File(targetLocation.toString());
92 targetZipFile.createNewFile();
93 } catch (IOException e) {
94 LOGGER.error("Could not able to create file {}", targetZipFile, e);
97 try (InputStream inputStream = zipFile.getInputStream(entry); OutputStream out = new FileOutputStream(
99 IOUtils.copy(inputStream, out);
100 LOGGER.info("Succesfully store the CBA archive {} at this location", targetZipFile);
101 } catch (Exception e) {
102 LOGGER.error("Failed to put zip file into target location {}, {}", targetLocation, e);
107 public void saveBluePrintToCdsDatabase(Path cbaArchivePath) {
108 Optional<List<File>> zipFiles = getFilesFromDisk(cbaArchivePath);
109 zipFiles.ifPresent(this::prepareRequestForCdsBackend);
113 public void extractCsarAndStore(IDistributionClientDownloadResult result, String csarArchivePath) {
115 // Create CSAR storage directory
116 Path csarStorageDir = getStorageDirectory(csarArchivePath);
118 byte[] payload = result.getArtifactPayload();
119 String csarFileName = result.getArtifactFilename() + CSAR_FILE_EXTENSION;
120 Path targetLocation = csarStorageDir.resolve(csarFileName);
122 LOGGER.info("The target location for the CSAR file is {}", targetLocation);
124 File targetCsarFile = new File(targetLocation.toString());
126 try (FileOutputStream outFile = new FileOutputStream(targetCsarFile)) {
127 outFile.write(payload, 0, payload.length);
128 } catch (Exception e) {
129 LOGGER.error("Failed to put CSAR file into target location {}, {}", targetLocation, e);
133 private Path getStorageDirectory(String path) {
134 Path fileStorageLocation = Paths.get(path).toAbsolutePath().normalize();
136 if (!fileStorageLocation.toFile().exists()) {
138 return Files.createDirectories(fileStorageLocation);
139 } catch (IOException e) {
140 LOGGER.error("Fail to create directory", e);
143 return fileStorageLocation;
146 private void prepareRequestForCdsBackend(List<File> files) {
147 final ManagedChannel channel = getManagedChannel();
149 files.forEach(zipFile -> {
151 final BluePrintUploadInput request = generateBluePrintUploadInputBuilder(zipFile);
153 // Send request to CDS Backend.
154 final Status responseStatus = bluePrintProcesssorHandler.sendRequest(request, channel);
156 if (responseStatus.getCode() != SUCCESS_CODE) {
157 LOGGER.error("Failed to store the CBA archive into CDS DB due to {}",
158 responseStatus.getErrorMessage());
160 LOGGER.info(responseStatus.getMessage());
163 } catch (Exception e) {
164 LOGGER.error("Failure due to", e);
166 //Delete the file from the local disk.
167 boolean fileDeleted = zipFile.delete();
170 LOGGER.error("Could not able to delete the zip file {}", zipFile.toString());
176 private ManagedChannel getManagedChannel() {
177 return ManagedChannelBuilder.forAddress(grpcAddress, grpcPort)
179 .intercept(cdsSdcListenerAuthClientInterceptor)
183 private BluePrintUploadInput generateBluePrintUploadInputBuilder(File file) throws IOException {
184 byte[] bytes = FileUtils.readFileToByteArray(file);
185 FileChunk fileChunk = FileChunk.newBuilder().setChunk(ByteString.copyFrom(bytes)).build();
187 return BluePrintUploadInput.newBuilder()
188 .setFileChunk(fileChunk)
193 * Extract files from the given path
195 * @param path where files reside.
196 * @return list of files.
198 public Optional<List<File>> getFilesFromDisk(Path path) {
199 try (Stream<Path> fileTree = walk(path)) {
200 // Get the list of files from the path
201 return Optional.of(fileTree.filter(Files::isRegularFile)
203 .collect(Collectors.toList()));
204 } catch (IOException e) {
205 LOGGER.error("Failed to find the file", e);
208 return Optional.empty();