CDS-SDC Listener application 20/83920/10
authorprathamesh morde <prathamesh.morde@bell.ca>
Tue, 2 Apr 2019 03:19:42 +0000 (23:19 -0400)
committerprathamesh morde <prathamesh.morde@bell.ca>
Thu, 4 Apr 2019 22:51:16 +0000 (18:51 -0400)
Things done
-Implementation of GRPC client to store CBA archive using CDS Backend
-Unit test coverage.
-Tested locally.
-Minor bug fix, performance improvement, more logging and make use of BluePrintProcessorHandler api
in ListenerServiceImpl class.
-Extract csar artifact from IDistributionClientResult and store it into local file(disk).

Change-Id: I08b0de017396bb76d5bc13ddb9e7b430990e8df0
Issue-ID: CCSDK-1184
Signed-off-by: prathamesh morde <prathamesh.morde@bell.ca>
13 files changed:
ms/cds-sdc-listener/application/pom.xml
ms/cds-sdc-listener/application/src/main/java/org/onap/ccsdk/cds/cdssdclistener/CdsSdcListenerNotificationCallback.java
ms/cds-sdc-listener/application/src/main/java/org/onap/ccsdk/cds/cdssdclistener/client/CdsSdcListenerAuthClientInterceptor.java [new file with mode: 0644]
ms/cds-sdc-listener/application/src/main/java/org/onap/ccsdk/cds/cdssdclistener/client/CdsSdcListenerClient.java [moved from ms/cds-sdc-listener/application/src/main/java/org/onap/ccsdk/cds/cdssdclistener/CdsSdcListenerClient.java with 89% similarity]
ms/cds-sdc-listener/application/src/main/java/org/onap/ccsdk/cds/cdssdclistener/dto/CdsSdcListenerDto.java [moved from ms/cds-sdc-listener/application/src/main/java/org/onap/ccsdk/cds/cdssdclistener/CdsSdcListenerDto.java with 86% similarity]
ms/cds-sdc-listener/application/src/main/java/org/onap/ccsdk/cds/cdssdclistener/handler/BluePrintProcesssorHandler.java [new file with mode: 0644]
ms/cds-sdc-listener/application/src/main/java/org/onap/ccsdk/cds/cdssdclistener/service/ListenerService.java
ms/cds-sdc-listener/application/src/main/java/org/onap/ccsdk/cds/cdssdclistener/service/ListenerServiceImpl.java
ms/cds-sdc-listener/application/src/main/resources/application.yml
ms/cds-sdc-listener/application/src/test/java/org/onap/ccsdk/cds/cdssdclistener/CdsSdcListenerClientTest.java
ms/cds-sdc-listener/application/src/test/java/org/onap/ccsdk/cds/cdssdclistener/handler/BluePrintProcessorHandlerTest.java [new file with mode: 0644]
ms/cds-sdc-listener/application/src/test/java/org/onap/ccsdk/cds/cdssdclistener/service/ListenerServiceImplTest.java
ms/cds-sdc-listener/application/src/test/resources/testcba.zip [new file with mode: 0644]

index 899d173..c2ec8b9 100644 (file)
   <artifactId>cds-sdc-listener-application</artifactId>
   <name>CDS-SDC Listener Application </name>
 
+  <properties>
+    <grpc.version>1.17.1</grpc.version>
+    <protobuf.version>3.6.1</protobuf.version>
+  </properties>
+
   <dependencies>
     <!-- Spring boot -->
       <dependency>
       <scope>test</scope>
     </dependency>
 
+    <!-- GRPC Dependencies -->
+    <dependency>
+      <groupId>io.grpc</groupId>
+      <artifactId>grpc-netty</artifactId>
+      <version>${grpc.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>io.grpc</groupId>
+      <artifactId>grpc-protobuf</artifactId>
+      <version>${grpc.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>io.grpc</groupId>
+      <artifactId>grpc-stub</artifactId>
+      <version>${grpc.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.protobuf</groupId>
+      <artifactId>protobuf-java</artifactId>
+      <version>${protobuf.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>io.grpc</groupId>
+      <artifactId>grpc-testing</artifactId>
+      <version>${grpc.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.onap.ccsdk.cds.components</groupId>
+      <artifactId>proto-definition</artifactId>
+      <version>0.4.2-SNAPSHOT</version>
+    </dependency>
+
+    <!-- SDC Distribution client dependency -->
+    <dependency>
+      <groupId>org.onap.sdc.sdc-distribution-client</groupId>
+      <artifactId>sdc-distribution-client</artifactId>
+      <version>1.3.0</version>
+    </dependency>
+
   </dependencies>
 
   <build>
index aaab8d8..e2aae96 100644 (file)
@@ -9,7 +9,13 @@
 package org.onap.ccsdk.cds.cdssdclistener;
 
 import static org.onap.sdc.utils.DistributionActionResultEnum.SUCCESS;
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
+import org.onap.ccsdk.cds.cdssdclistener.dto.CdsSdcListenerDto;
 import org.onap.ccsdk.cds.cdssdclistener.service.ListenerServiceImpl;
 import org.onap.sdc.api.IDistributionClient;
 import org.onap.sdc.api.consumer.INotificationCallback;
@@ -19,9 +25,14 @@ import org.onap.sdc.api.results.IDistributionClientDownloadResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.ComponentScan;
 import org.springframework.stereotype.Component;
 
+@ConfigurationProperties("listenerservice")
 @Component
+@ComponentScan("org.onap.ccsdk.cds.cdssdclistener.dto")
 public class CdsSdcListenerNotificationCallback implements INotificationCallback {
 
     @Autowired
@@ -30,6 +41,9 @@ public class CdsSdcListenerNotificationCallback implements INotificationCallback
     @Autowired
     private ListenerServiceImpl listenerService;
 
+    @Value("${listenerservice.config.archivePath}")
+    private String pathToStoreArchives;
+
     private static final Logger LOGGER = LoggerFactory.getLogger(CdsSdcListenerNotificationCallback.class);
 
     @Override
@@ -45,7 +59,7 @@ public class CdsSdcListenerNotificationCallback implements INotificationCallback
     }
 
     /**
-     * Download the TOSCA CSAR artifact.
+     * Download the TOSCA CSAR artifact and process it.
      *
      * @param info - Artifact information
      * @param distributionClient - SDC distribution client
@@ -53,6 +67,7 @@ public class CdsSdcListenerNotificationCallback implements INotificationCallback
     private void downloadCsarArtifacts(IArtifactInfo info, IDistributionClient distributionClient) {
         final String url = info.getArtifactURL();
         final String id = info.getArtifactUUID();
+
         if (Objects.equals(info.getArtifactType(), CdsSdcListenerConfiguration.TOSCA_CSAR)) {
             LOGGER.info("Trying to download the artifact from : {} and UUID is {} ", url, id);
 
@@ -63,8 +78,30 @@ public class CdsSdcListenerNotificationCallback implements INotificationCallback
                 LOGGER.error("Failed to download the artifact from : {} due to {} ", url,
                     result.getDistributionActionResult());
             } else {
-                // TODO Store the CSAR into CSARArchive path and extract the Blueprint using ListenerServiceImpl.extractBluePrint
+                LOGGER.info("Trying to write CSAR artifact to file  with URL {} and UUID {}", url, id);
+                processCsarArtifact(result);
             }
         }
     }
+
+    public void processCsarArtifact(IDistributionClientDownloadResult result) {
+        Path cbaArchivePath = Paths.get(pathToStoreArchives, "cba-archive");
+        Path csarArchivePath = Paths.get(pathToStoreArchives, "csar-archive");
+
+        // extract and store the CSAR archive into local disk.
+        listenerService.extractCsarAndStore(result, csarArchivePath.toString());
+
+        Optional<List<File>> csarFiles = listenerService.getFilesFromDisk(csarArchivePath);
+
+        if (csarFiles.isPresent()) {
+
+            //Extract CBA archive from CSAR package and and store it into CDS Database.
+            csarFiles.get()
+                .forEach(file -> listenerService.extractBluePrint(file.getAbsolutePath(), cbaArchivePath.toString()));
+
+            listenerService.saveBluePrintToCdsDatabase(cbaArchivePath);
+        } else {
+            LOGGER.error("The CSAR file is not present at this location {}", csarArchivePath);
+        }
+    }
 }
diff --git a/ms/cds-sdc-listener/application/src/main/java/org/onap/ccsdk/cds/cdssdclistener/client/CdsSdcListenerAuthClientInterceptor.java b/ms/cds-sdc-listener/application/src/main/java/org/onap/ccsdk/cds/cdssdclistener/client/CdsSdcListenerAuthClientInterceptor.java
new file mode 100644 (file)
index 0000000..528fbe2
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 Bell Canada. All rights reserved.
+ *
+ * NOTICE:  All the intellectual and technical concepts contained herein are
+ * proprietary to Bell Canada and are protected by trade secret or copyright law.
+ * Unauthorized copying of this file, via any medium is strictly prohibited.
+ */
+
+package org.onap.ccsdk.cds.cdssdclistener.client;
+
+import io.grpc.CallOptions;
+import io.grpc.Channel;
+import io.grpc.ClientCall;
+import io.grpc.ClientInterceptor;
+import io.grpc.ForwardingClientCall;
+import io.grpc.Metadata;
+import io.grpc.Metadata.Key;
+import io.grpc.MethodDescriptor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * To provide authentication with GRPC server.
+ */
+@ConfigurationProperties("listenerservice")
+@Component
+public class CdsSdcListenerAuthClientInterceptor implements ClientInterceptor {
+
+    @Value("${listenerservice.config.authHeader}")
+    private String basicAuth;
+
+    @Override
+    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> methodDescriptor,
+                                                               CallOptions callOptions, Channel channel) {
+        Key<String> authHeader = Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER);
+        return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(
+            channel.newCall(methodDescriptor, callOptions)) {
+            @Override
+            public void start(Listener<RespT> responseListener, Metadata headers) {
+                headers.put(authHeader, basicAuth);
+                super.start(responseListener, headers);
+            }
+        };
+    }
+}
@@ -5,9 +5,12 @@
  * proprietary to Bell Canada and are protected by trade secret or copyright law.
  * Unauthorized copying of this file, via any medium is strictly prohibited.
  */
-package org.onap.ccsdk.cds.cdssdclistener;
+package org.onap.ccsdk.cds.cdssdclistener.client;
 
 import java.util.Optional;
+import org.onap.ccsdk.cds.cdssdclistener.CdsSdcListenerConfiguration;
+import org.onap.ccsdk.cds.cdssdclistener.dto.CdsSdcListenerDto;
+import org.onap.ccsdk.cds.cdssdclistener.CdsSdcListenerNotificationCallback;
 import org.onap.ccsdk.cds.cdssdclistener.exceptions.CdsSdcListenerException;
 import org.onap.sdc.api.IDistributionClient;
 import org.onap.sdc.api.results.IDistributionClientResult;
@@ -17,10 +20,12 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.event.ApplicationReadyEvent;
+import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.event.EventListener;
 import org.springframework.stereotype.Component;
 
 @Component
+@ComponentScan("org.onap.ccsdk.cds.cdssdclistener.dto")
 public class CdsSdcListenerClient {
 
     private static Logger LOG = LoggerFactory.getLogger(CdsSdcListenerClient.class);
@@ -5,10 +5,12 @@
  * proprietary to Bell Canada and are protected by trade secret or copyright law.
  * Unauthorized copying of this file, via any medium is strictly prohibited.
  */
-package org.onap.ccsdk.cds.cdssdclistener;
+package org.onap.ccsdk.cds.cdssdclistener.dto;
 
 import org.onap.sdc.api.IDistributionClient;
+import org.springframework.stereotype.Component;
 
+@Component
 public class CdsSdcListenerDto {
 
     private IDistributionClient distributionClient;
diff --git a/ms/cds-sdc-listener/application/src/main/java/org/onap/ccsdk/cds/cdssdclistener/handler/BluePrintProcesssorHandler.java b/ms/cds-sdc-listener/application/src/main/java/org/onap/ccsdk/cds/cdssdclistener/handler/BluePrintProcesssorHandler.java
new file mode 100644 (file)
index 0000000..6b03b6d
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 Bell Canada. All rights reserved.
+ *
+ * NOTICE:  All the intellectual and technical concepts contained herein are
+ * proprietary to Bell Canada and are protected by trade secret or copyright law.
+ * Unauthorized copying of this file, via any medium is strictly prohibited.
+ */
+
+package org.onap.ccsdk.cds.cdssdclistener.handler;
+
+import io.grpc.ManagedChannel;
+import org.onap.ccsdk.cds.controllerblueprints.common.api.Status;
+import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintManagementOutput;
+import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintManagementServiceGrpc;
+import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintManagementServiceGrpc.BluePrintManagementServiceBlockingStub;
+import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintUploadInput;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@ConfigurationProperties("listenerservice")
+@Component
+public class BluePrintProcesssorHandler implements AutoCloseable {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(BluePrintProcesssorHandler.class);
+
+    private ManagedChannel channel;
+
+    /**
+     * Sending CBA archive to CDS backend to store into its Database.
+     *
+     * @param request BluePrintManagementInput object holds CBA archive, its version and blueprints.
+     * @param managedChannel - ManagedChannel object helps to access the server or application end point.
+     * @return A response object
+     */
+    public Status sendRequest(BluePrintUploadInput request, ManagedChannel managedChannel) {
+        LOGGER.info("Sending request to blueprint processor");
+
+        this.channel = managedChannel;
+
+        final BluePrintManagementServiceBlockingStub syncStub = BluePrintManagementServiceGrpc.newBlockingStub(channel);
+
+        // Send the request to CDS backend.
+        final BluePrintManagementOutput response = syncStub.uploadBlueprint(request);
+
+        return response.getStatus();
+    }
+
+    @Override
+    public void close() {
+        if (channel != null) {
+            channel.shutdown();
+        }
+        LOGGER.info("Stopping GRPC connection to CDS backend");
+    }
+}
index 5dc0c21..1efbe8f 100644 (file)
@@ -8,7 +8,8 @@
 
 package org.onap.ccsdk.cds.cdssdclistener.service;
 
-import java.util.zip.ZipFile;
+import java.nio.file.Path;
+import org.onap.sdc.api.results.IDistributionClientDownloadResult;
 
 public interface ListenerService {
 
@@ -23,7 +24,15 @@ public interface ListenerService {
     /**
      * Store the Zip file into CDS database.
      *
-     * @param file The file to be stored.
+     * @param path path where zip file exists.
      */
-    void saveBluePrintToCdsDatabase(ZipFile file);
+    void saveBluePrintToCdsDatabase(Path path);
+
+    /**
+     * Extract and store CSAR to file.
+     *
+     * @param result - IDistributionClientDownloadResult contains payload.
+     * @param csarArchivePath The destination path where CSAR will be stored.
+     */
+    void extractCsarAndStore(IDistributionClientDownloadResult result, String csarArchivePath);
 }
index 4ff2a6e..3705208 100644 (file)
@@ -8,6 +8,10 @@
 
 package org.onap.ccsdk.cds.cdssdclistener.service;
 
+import static java.nio.file.Files.walk;
+import com.google.protobuf.ByteString;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -17,12 +21,24 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Enumeration;
+import java.util.List;
+import java.util.Optional;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
+import org.apache.commons.io.FileUtils;
 import org.apache.tomcat.util.http.fileupload.IOUtils;
+import org.onap.ccsdk.cds.cdssdclistener.client.CdsSdcListenerAuthClientInterceptor;
+import org.onap.ccsdk.cds.cdssdclistener.handler.BluePrintProcesssorHandler;
+import org.onap.ccsdk.cds.controllerblueprints.common.api.Status;
+import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintUploadInput;
+import org.onap.ccsdk.cds.controllerblueprints.management.api.FileChunk;
+import org.onap.sdc.api.results.IDistributionClientDownloadResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.stereotype.Component;
@@ -31,13 +47,21 @@ import org.springframework.stereotype.Component;
 @ConfigurationProperties("listenerservice")
 public class ListenerServiceImpl implements ListenerService {
 
-    @Value("${listenerservice.config.csarArchive}")
-    private String csarArchivePath;
+    @Autowired
+    private BluePrintProcesssorHandler bluePrintProcesssorHandler;
 
-    @Value("${listenerservice.config.cbaArchive}")
-    private String cbaArchivePath;
+    @Autowired
+    private CdsSdcListenerAuthClientInterceptor cdsSdcListenerAuthClientInterceptor;
+
+    @Value("${listenerservice.config.grpcAddress}")
+    private String grpcAddress;
+
+    @Value("${listenerservice.config.grpcPort}")
+    private int grpcPort;
 
     private static final String CBA_ZIP_PATH = "Artifacts/Resources/[a-zA-Z0-9-_]+/Deployment/CONTROLLER_BLUEPRINT_ARCHIVE/[a-zA-Z0-9-_]+[.]zip";
+    private static final int SUCCESS_CODE = 200;
+    private static final String CSAR_FILE_EXTENSION = ".csar";
     private static final Logger LOGGER = LoggerFactory.getLogger(ListenerServiceImpl.class);
 
     @Override
@@ -50,6 +74,7 @@ public class ListenerServiceImpl implements ListenerService {
                 String fileName = entry.getName();
                 if (Pattern.matches(CBA_ZIP_PATH, fileName)) {
                     final String cbaArchiveName = Paths.get(fileName).getFileName().toString();
+                    LOGGER.info("Storing the CBA archive {}", cbaArchiveName);
                     storeBluePrint(zipFile, cbaArchiveName, cbaStorageDir, entry);
                 }
             }
@@ -59,13 +84,12 @@ public class ListenerServiceImpl implements ListenerService {
     }
 
     private void storeBluePrint(ZipFile zipFile, String fileName, Path cbaArchivePath, ZipEntry entry) {
-        final String changedFileName = fileName + ".zip";
-        Path targetLocation = cbaArchivePath.resolve(changedFileName);
+        Path targetLocation = cbaArchivePath.resolve(fileName);
+        LOGGER.info("The target location for zip file is {}", targetLocation);
         File targetZipFile = new File(targetLocation.toString());
 
         try {
             targetZipFile.createNewFile();
-
         } catch (IOException e) {
             LOGGER.error("Could not able to create file {}", targetZipFile, e);
         }
@@ -73,15 +97,43 @@ public class ListenerServiceImpl implements ListenerService {
         try (InputStream inputStream = zipFile.getInputStream(entry); OutputStream out = new FileOutputStream(
             targetZipFile)) {
             IOUtils.copy(inputStream, out);
+            LOGGER.info("Succesfully store the CBA archive {} at this location", targetZipFile);
+        } catch (Exception e) {
+            LOGGER.error("Failed to put zip file into target location {}, {}", targetLocation, e);
+        }
+    }
+
+    @Override
+    public void saveBluePrintToCdsDatabase(Path cbaArchivePath) {
+        Optional<List<File>> zipFiles = getFilesFromDisk(cbaArchivePath);
+        zipFiles.ifPresent(this::prepareRequestForCdsBackend);
+    }
+
+    @Override
+    public void extractCsarAndStore(IDistributionClientDownloadResult result, String csarArchivePath) {
+
+        // Create CSAR storage directory
+        Path csarStorageDir = getStorageDirectory(csarArchivePath);
+
+        byte[] payload = result.getArtifactPayload();
+        String csarFileName = result.getArtifactFilename() + CSAR_FILE_EXTENSION;
+        Path targetLocation = csarStorageDir.resolve(csarFileName);
+
+        LOGGER.info("The target location for the CSAR file is {}", targetLocation);
+
+        File targetCsarFile = new File(targetLocation.toString());
+
+        try (FileOutputStream outFile = new FileOutputStream(targetCsarFile)) {
+            outFile.write(payload, 0, payload.length);
         } catch (Exception e) {
-            LOGGER.error("Failed to put zip file into target location {}", targetLocation, e);
+            LOGGER.error("Failed to put CSAR file into target location {}, {}", targetLocation, e);
         }
     }
 
     private Path getStorageDirectory(String path) {
         Path fileStorageLocation = Paths.get(path).toAbsolutePath().normalize();
 
-        if (!Files.exists(fileStorageLocation)) {
+        if (!fileStorageLocation.toFile().exists()) {
             try {
                 return Files.createDirectories(fileStorageLocation);
             } catch (IOException e) {
@@ -91,8 +143,68 @@ public class ListenerServiceImpl implements ListenerService {
         return fileStorageLocation;
     }
 
-    @Override
-    public void saveBluePrintToCdsDatabase(ZipFile file) {
-        //TODO
+    private void prepareRequestForCdsBackend(List<File> files) {
+        final ManagedChannel channel = getManagedChannel();
+
+        files.forEach(zipFile -> {
+            try {
+                final BluePrintUploadInput request = generateBluePrintUploadInputBuilder(zipFile);
+
+                // Send request to CDS Backend.
+                final Status responseStatus = bluePrintProcesssorHandler.sendRequest(request, channel);
+
+                if (responseStatus.getCode() != SUCCESS_CODE) {
+                    LOGGER.error("Failed to store the CBA archive into CDS DB due to {}",
+                        responseStatus.getErrorMessage());
+                } else {
+                    LOGGER.info(responseStatus.getMessage());
+                }
+
+            } catch (Exception e) {
+                LOGGER.error("Failure due to", e);
+            } finally {
+                //Delete the file from the local disk.
+                boolean fileDeleted = zipFile.delete();
+
+                if (!fileDeleted) {
+                    LOGGER.error("Could not able to delete the zip file {}", zipFile.toString());
+                }
+            }
+        });
+    }
+
+    private ManagedChannel getManagedChannel() {
+        return ManagedChannelBuilder.forAddress(grpcAddress, grpcPort)
+                                    .usePlaintext()
+                                    .intercept(cdsSdcListenerAuthClientInterceptor)
+                                    .build();
+    }
+
+    private BluePrintUploadInput generateBluePrintUploadInputBuilder(File file) throws IOException {
+        byte[] bytes = FileUtils.readFileToByteArray(file);
+        FileChunk fileChunk = FileChunk.newBuilder().setChunk(ByteString.copyFrom(bytes)).build();
+
+        return BluePrintUploadInput.newBuilder()
+                .setFileChunk(fileChunk)
+                .build();
+    }
+
+    /**
+     * Extract files from the given path
+     *
+     * @param path where files reside.
+     * @return list of files.
+     */
+    public Optional<List<File>> getFilesFromDisk(Path path) {
+        try (Stream<Path> fileTree = walk(path)) {
+            // Get the list of files from the path
+            return Optional.of(fileTree.filter(Files::isRegularFile)
+                                       .map(Path::toFile)
+                                       .collect(Collectors.toList()));
+        } catch (IOException e) {
+            LOGGER.error("Failed to find the file", e);
+        }
+
+        return Optional.empty();
     }
 }
index 88de3b1..657ea9e 100644 (file)
@@ -14,6 +14,8 @@ listenerservice:
       keyStorePath:
       activateServerTLSAuth : false
       isUseHttpsWithDmaap: false
-      csarArchive: /opt/app/onap/cds-sdc-listener/csar-archive
-      cbaArchive: /opt/app/onap/cds/sdc-listener/cba-archive
+      archivePath: opt/app/onap/cds-sdc-listener/
+      grpcAddress: localhost
+      grpcPort: 9111
+      authHeader: Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==
 
index 4d0631f..9486314 100644 (file)
@@ -17,6 +17,8 @@ import mockit.VerificationsInOrder;
 import mockit.integration.junit4.JMockit;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.onap.ccsdk.cds.cdssdclistener.client.CdsSdcListenerClient;
+import org.onap.ccsdk.cds.cdssdclistener.dto.CdsSdcListenerDto;
 import org.onap.ccsdk.cds.cdssdclistener.exceptions.CdsSdcListenerException;
 import org.onap.sdc.api.IDistributionClient;
 import org.onap.sdc.api.results.IDistributionClientResult;
diff --git a/ms/cds-sdc-listener/application/src/test/java/org/onap/ccsdk/cds/cdssdclistener/handler/BluePrintProcessorHandlerTest.java b/ms/cds-sdc-listener/application/src/test/java/org/onap/ccsdk/cds/cdssdclistener/handler/BluePrintProcessorHandlerTest.java
new file mode 100644 (file)
index 0000000..0d38dec
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2019 Bell Canada. All rights reserved.
+ *
+ * NOTICE:  All the intellectual and technical concepts contained herein are
+ * proprietary to Bell Canada and are protected by trade secret or copyright law.
+ * Unauthorized copying of this file, via any medium is strictly prohibited.
+ */
+
+package org.onap.ccsdk.cds.cdssdclistener.handler;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import com.google.protobuf.ByteString;
+import io.grpc.ManagedChannel;
+import io.grpc.inprocess.InProcessChannelBuilder;
+import io.grpc.inprocess.InProcessServerBuilder;
+import io.grpc.stub.StreamObserver;
+import io.grpc.testing.GrpcCleanupRule;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Paths;
+import org.apache.commons.io.FileUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.ccsdk.cds.cdssdclistener.client.CdsSdcListenerAuthClientInterceptor;
+import org.onap.ccsdk.cds.controllerblueprints.common.api.Status;
+import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintManagementOutput;
+import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintManagementServiceGrpc.BluePrintManagementServiceImplBase;
+import org.onap.ccsdk.cds.controllerblueprints.management.api.BluePrintUploadInput;
+import org.onap.ccsdk.cds.controllerblueprints.management.api.FileChunk;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+
+@RunWith(SpringRunner.class)
+@EnableConfigurationProperties({BluePrintProcesssorHandler.class, CdsSdcListenerAuthClientInterceptor.class})
+@SpringBootTest(classes = {BluePrintProcessorHandlerTest.class})
+public class BluePrintProcessorHandlerTest {
+
+    @Autowired
+    private BluePrintProcesssorHandler bluePrintProcesssorHandler;
+
+    @Autowired
+    private CdsSdcListenerAuthClientInterceptor cdsSdcListenerAuthClientInterceptor;
+
+    @Rule
+    public GrpcCleanupRule grpcCleanup = new GrpcCleanupRule();
+
+    private static final String CBA_ARCHIVE = "src/test/resources/testcba.zip";
+    private static final String SUCCESS_MSG = "Successfully uploaded CBA";
+    private static final int SUCCESS_CODE = 200;
+    private ManagedChannel channel;
+
+    @Before
+    public void setUp() throws IOException {
+        final BluePrintManagementServiceImplBase serviceImplBase = new BluePrintManagementServiceImplBase() {
+            @Override
+            public void uploadBlueprint(BluePrintUploadInput request,
+                StreamObserver<BluePrintManagementOutput> responseObserver) {
+                responseObserver.onNext(getBluePrintManagementOutput());
+                responseObserver.onCompleted();
+            }
+        };
+
+        // Generate server name.
+        String serverName = InProcessServerBuilder.generateName();
+
+        // Create a server, add service, start, and register.
+        grpcCleanup.register(
+            InProcessServerBuilder.forName(serverName).addService(serviceImplBase).directExecutor().build().start());
+
+        // Create a client channel.
+        channel = grpcCleanup.register(InProcessChannelBuilder.forName(serverName).directExecutor().build());
+    }
+
+    @Test
+    public void testApplicationEndPointSucess() throws IOException {
+        // Arrange
+        BluePrintUploadInput request = generateRequest();
+
+        // Act
+        Status output = bluePrintProcesssorHandler.sendRequest(request, channel);
+
+        // Verify
+        assertEquals(SUCCESS_CODE, output.getCode());
+        assertTrue(output.getMessage().contains(SUCCESS_MSG));
+    }
+
+    private BluePrintUploadInput generateRequest() throws IOException {
+        File file = Paths.get(CBA_ARCHIVE).toFile();
+        byte[] bytes = FileUtils.readFileToByteArray(file);
+        FileChunk fileChunk = FileChunk.newBuilder().setChunk(ByteString.copyFrom(bytes)).build();
+
+        return BluePrintUploadInput.newBuilder().setFileChunk(fileChunk).build();
+    }
+
+    private BluePrintManagementOutput getBluePrintManagementOutput() {
+        return BluePrintManagementOutput.newBuilder()
+                .setStatus(Status.newBuilder().setMessage(SUCCESS_MSG).setCode(200).build())
+                .build();
+    }
+}
index 05e1ffd..e33fbcd 100644 (file)
@@ -8,23 +8,34 @@
 
 package org.onap.ccsdk.cds.cdssdclistener.service;
 
+import static junit.framework.TestCase.assertTrue;
+import java.io.IOException;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
+import org.onap.ccsdk.cds.cdssdclistener.client.CdsSdcListenerAuthClientInterceptor;
+import org.onap.ccsdk.cds.cdssdclistener.handler.BluePrintProcesssorHandler;
+import org.onap.sdc.impl.mock.DistributionClientDownloadResultStubImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 
 @RunWith(SpringRunner.class)
-@EnableConfigurationProperties(ListenerServiceImpl.class)
+@EnableConfigurationProperties({ListenerServiceImpl.class, CdsSdcListenerAuthClientInterceptor.class,
+    BluePrintProcesssorHandler.class})
 @SpringBootTest(classes = {ListenerServiceImplTest.class})
 public class ListenerServiceImplTest {
 
     private static final String CSAR_SAMPLE = "src/test/resources/service-Testsvc140.csar";
+    private static final String ZIP_FILE = ".zip";
+    private static final String CSAR_FILE = ".csar";
+    private String csarArchivePath;
     private Path tempDirectoryPath;
 
     @Rule
@@ -33,12 +44,40 @@ public class ListenerServiceImplTest {
     @Autowired
     private ListenerServiceImpl listenerService;
 
+    @Before
+    public void setup() {
+        csarArchivePath = folder.getRoot().toString();
+        tempDirectoryPath = Paths.get(csarArchivePath, "cds-sdc-listener-test");
+    }
     @Test
-    public void extractBluePrintSuccessfully() {
+    public void extractBluePrintSuccessfully() throws IOException {
+        // Act
+        listenerService.extractBluePrint(CSAR_SAMPLE, tempDirectoryPath.toString());
+
+        // Verify
+        String result = checkFileExists(tempDirectoryPath);
+        assertTrue(result.contains(ZIP_FILE));
+    }
+
+    @Test
+    public void storeCsarArtifactToFileSuccessfully() throws  IOException {
         // Arrange
-        tempDirectoryPath = Paths.get(folder.getRoot().toString(), "cds-sdc-listener-test");
+        DistributionClientDownloadResultStubImpl resultStub = new DistributionClientDownloadResultStubImpl();
 
         // Act
-        listenerService.extractBluePrint(CSAR_SAMPLE, tempDirectoryPath.toString());
+        listenerService.extractCsarAndStore(resultStub, tempDirectoryPath.toString());
+
+        // Verify
+        String result = checkFileExists(tempDirectoryPath);
+        assertTrue(result.contains(CSAR_FILE));
+    }
+
+    private String checkFileExists(Path path) throws IOException {
+        return Files.walk(path)
+            .filter(Files::isRegularFile)
+            .map(Path::toFile)
+            .findAny()
+            .get()
+            .getName();
     }
 }
diff --git a/ms/cds-sdc-listener/application/src/test/resources/testcba.zip b/ms/cds-sdc-listener/application/src/test/resources/testcba.zip
new file mode 100644 (file)
index 0000000..c886fe6
Binary files /dev/null and b/ms/cds-sdc-listener/application/src/test/resources/testcba.zip differ