From d4438bed17447b76d341d5c06421b51931b8c5b0 Mon Sep 17 00:00:00 2001 From: Murali-P Date: Tue, 14 Feb 2017 10:31:14 +0530 Subject: Interface implementation Resolved:VNFSDK-21 Function test base code Change-Id: I635e434e5c8ffd21fe98f230f0ea9046345d5be5 Signed-off-by: Murali-P --- .../java/org/openo/vnfsdk/functest/FileUtil.java | 231 +++++++++++++++++++++ .../org/openo/vnfsdk/functest/TaskExecution.java | 103 +++++++++ .../vnfsdk/functest/resource/CommonManager.java | 91 +++++++- .../VnfFuncTestResponseHandler.java | 81 ++++++++ .../vnfsdk/functest/util/RestResponseUtil.java | 2 +- .../openo/vnfsdk/functest/util/ZipCompressor.java | 125 +++++++++++ 6 files changed, 630 insertions(+), 3 deletions(-) create mode 100644 vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/FileUtil.java create mode 100644 vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/TaskExecution.java create mode 100644 vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/responsehandler/VnfFuncTestResponseHandler.java create mode 100644 vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/util/ZipCompressor.java (limited to 'vnf-sdk-function-test/src/main') diff --git a/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/FileUtil.java b/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/FileUtil.java new file mode 100644 index 0000000..6d20215 --- /dev/null +++ b/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/FileUtil.java @@ -0,0 +1,231 @@ +/* + * 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.openo.vnfsdk.functest; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class FileUtil { + + public static final Logger LOG = LoggerFactory.getLogger(FileUtil.class); + + private static final int BUFFER_SIZE = 2 * 1024 * 1024; + + private static final int TRY_COUNT = 3; + + private FileUtil() { + + } + + /** + * create dir. + * + * @param dir dir to create + * @return boolean + */ + public static boolean createDirectory(String dir) { + File folder = new File(dir); + int tryCount = 0; + while(tryCount < TRY_COUNT) { + tryCount++; + if(!folder.exists() && !folder.mkdirs()) { + continue; + } else { + return true; + } + } + + return folder.exists(); + } + + /** + * delete file. + * + * @param file the file to delete + * @return boolean + */ + public static boolean deleteFile(File file) { + String hintInfo = file.isDirectory() ? "dir " : "file "; + boolean isFileDeleted = file.delete(); + boolean isFileExist = file.exists(); + if(!isFileExist) { + if(isFileDeleted) { + LOG.info("delete " + hintInfo + file.getAbsolutePath()); + } else { + isFileDeleted = true; + LOG.info("file not exist. no need delete " + hintInfo + file.getAbsolutePath()); + } + } else { + LOG.info("fail to delete " + hintInfo + file.getAbsolutePath()); + } + return isFileDeleted; + } + + /** + * unzip zip file. + * + * @param zipFileName file name to zip + * @param extPlace extPlace + * @return unzip file name + * @throws IOException e1 + */ + public static ArrayList unzip(String zipFileName, String extPlace) throws IOException { + ZipFile zipFile = null; + ArrayList unzipFileNams = new ArrayList(); + + try { + zipFile = new ZipFile(zipFileName); + Enumeration fileEn = zipFile.entries(); + byte[] buffer = new byte[BUFFER_SIZE]; + + while(fileEn.hasMoreElements()) { + InputStream input = null; + BufferedOutputStream bos = null; + try { + ZipEntry entry = (ZipEntry)fileEn.nextElement(); + if(entry.isDirectory()) { + continue; + } + + input = zipFile.getInputStream(entry); + File file = new File(extPlace, entry.getName()); + if(!file.getParentFile().exists()) { + createDirectory(file.getParentFile().getAbsolutePath()); + } + + bos = new BufferedOutputStream(new FileOutputStream(file)); + while(true) { + int length = input.read(buffer); + if(length == -1) { + break; + } + bos.write(buffer, 0, length); + } + unzipFileNams.add(file.getAbsolutePath()); + } finally { + closeOutputStream(bos); + closeInputStream(input); + } + } + } finally { + closeZipFile(zipFile); + } + return unzipFileNams; + } + + public static String[] getDirectory(String directory) { + File file = new File(directory); + String[] directories = file.list(new FilenameFilter() { + + @Override + public boolean accept(File current, String name) { + return new File(current, name).isDirectory(); + } + }); + + return directories; + } + + /** + * close InputStream. + * + * @param inputStream the inputstream to close + */ + private static void closeInputStream(InputStream inputStream) { + try { + if(inputStream != null) { + inputStream.close(); + } + } catch(Exception e1) { + LOG.info("close InputStream error!"); + } + } + + /** + * close OutputStream. + * + * @param outputStream the output stream to close + */ + private static void closeOutputStream(OutputStream outputStream) { + try { + if(outputStream != null) { + outputStream.close(); + } + } catch(Exception e1) { + LOG.info("close OutputStream error!"); + } + } + + /** + * close zipFile. + * + * @param zipFile the zipFile to close + */ + private static void closeZipFile(ZipFile zipFile) { + try { + if(zipFile != null) { + zipFile.close(); + zipFile = null; + } + } catch(IOException e1) { + LOG.info("close ZipFile error!"); + } + } + + public static Boolean checkFileExist(String filePath) { + File file = new File(filePath); + return file.exists(); + } + + public static Boolean deleteFile(String filePath) { + File file = new File(filePath); + if(file.exists()) { + return file.delete(); + } + return true; + } + + public static byte[] convertZipFiletoByteArray(String filename) { + File file = new File(filename); + if(!file.exists()) { + return null; + } + + byte[] byteArrayFile = new byte[(int)file.length()]; + try { + FileInputStream fileInputStream = new FileInputStream(filename); + fileInputStream.read(byteArrayFile); + fileInputStream.close(); + } catch(Exception e) { + e.printStackTrace(); + } + return byteArrayFile; + } +} diff --git a/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/TaskExecution.java b/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/TaskExecution.java new file mode 100644 index 0000000..c95acdf --- /dev/null +++ b/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/TaskExecution.java @@ -0,0 +1,103 @@ +/* + * 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.openo.vnfsdk.functest; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; + +import org.apache.commons.lang3.SystemUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class TaskExecution { + + private static final Logger LOGGER = LoggerFactory.getLogger(TaskExecution.class); + + public void executeScript(String dirPath, UUID uniqueKey) { + + String nl = File.separator; + String curDir = System.getProperty("user.dir"); + String confDir = curDir + nl + "conf" + nl + "robot" + nl; + + // Read the MetaData from the VNF package + ObjectMapper mapper = new ObjectMapper(); + + Map mapValues = null; + try { + mapValues = mapper.readValue(new FileInputStream(confDir + "robotMetaData.json"), Map.class); + } catch(IOException e) { + + LOGGER.error("Reading Json Meta data file failed or file do not exist" + e.getMessage()); + return; + } + + // Form the variables for the upload, transfer and execute command + String scriptDirName = new File(dirPath).getName(); + mapValues.put("SCRIPT_DIR", dirPath); + + String remoteScriptDir = mapValues.get("DIR_REMOTE") + scriptDirName; + String remoteScriptResult = remoteScriptDir + "/" + "output "; + mapValues.put("DIR_REMOTE_RESULT", remoteScriptResult); + + String dirResult = mapValues.get("DIR_RESULT") + uniqueKey; + mapValues.put("DIR_RESULT", dirResult); + + String remoteScriptFile = remoteScriptDir + "/" + mapValues.get("MAIN_SCRIPT"); + String remoteArgs = "--argumentfile " + remoteScriptDir + "/" + "config.args "; + String remoteCommand = "robot " + "-d " + remoteScriptResult + remoteArgs + remoteScriptFile; + mapValues.put("REMOTE_COMMAND", "\"" + remoteCommand + "\""); + + String robotvariables = ""; + for(Entry values : mapValues.entrySet()) { + + robotvariables = robotvariables + " -v " + values.getKey() + ":" + values.getValue() + " "; + } + + // Execute the command + String argumentFilePath = confDir + "config.args "; + String robotScript = confDir + "RemoteConnection.robot"; + + String shellcommand = "cmd.exe /c "; + if(SystemUtils.IS_OS_LINUX) { + shellcommand = "bash "; + } + + Process process = null; + InputStream inputStream = null; + int ch; + try { + String command = + shellcommand + "robot --argumentfile " + argumentFilePath + robotvariables + " " + robotScript; + process = Runtime.getRuntime().exec(command); + inputStream = process.getInputStream(); + while((ch = inputStream.read()) != -1) { + LOGGER.info("" + ch); + } + + } catch(Exception e) { + LOGGER.error("TaskExecution ... executeScript() ... [Exception] ..." + e.getMessage()); + } + } + +} diff --git a/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/resource/CommonManager.java b/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/resource/CommonManager.java index 5c80314..81fa12e 100644 --- a/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/resource/CommonManager.java +++ b/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/resource/CommonManager.java @@ -16,6 +16,18 @@ package org.openo.vnfsdk.functest.resource; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.StringTokenizer; +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -25,6 +37,10 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.eclipse.jetty.http.HttpStatus; +import org.openo.vnfsdk.functest.FileUtil; +import org.openo.vnfsdk.functest.TaskExecution; +import org.openo.vnfsdk.functest.responsehandler.VnfFuncTestResponseHandler; +import org.openo.vnfsdk.functest.util.RestResponseUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,8 +67,49 @@ public class CommonManager { @ApiResponse(code = HttpStatus.UNSUPPORTED_MEDIA_TYPE_415, message = "Unprocessable MicroServiceInfo Entity ", response = String.class), @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500, message = "internal server error", response = String.class)}) @Timed - public Response executeFuncTest() { + public Response executeFuncTest(InputStream csarInputStream) { LOGGER.info("execute function test"); + + try { + + // Convert the stream to script folder + String nl = File.separator; + String filePath = storeChunkFileInLocal("temp", "TempFile.rar", csarInputStream); + + // Unzip the folder + String tempDir = System.getProperty("user.dir") + nl + "temp"; + FileUtil.unzip(filePath, tempDir); + LOGGER.info("File path=" + filePath); + + String directories[] = FileUtil.getDirectory(tempDir); + if(null != directories) { + filePath = tempDir + File.separator + directories[0]; + } + + // Upload the script and execute the script and run command + final UUID uniqueKey = UUID.randomUUID(); + + final String finalPath = filePath; + ExecutorService es = Executors.newFixedThreadPool(3); + final Future future = es.submit(new Callable() { + + public Integer call() throws Exception { + + new TaskExecution().executeScript(finalPath, uniqueKey); + return 0; + } + }); + + // Send REST response + Response response = RestResponseUtil.getSuccessResponse(uniqueKey); + + return response; + + } catch(IOException e) { + + e.printStackTrace(); + } + return null; } @@ -67,8 +124,38 @@ public class CommonManager { @Timed public Response queryResultByFuncTest(@ApiParam(value = "functestId") @PathParam("functestId") String instanceId) { LOGGER.info("query functest result by id." + instanceId); - return null; + // Query VNF Function test result by function test ID + return VnfFuncTestResponseHandler.getInstance().getResponseByFuncTestId(instanceId); + } + public String storeChunkFileInLocal(String dirName, String fileName, InputStream uploadedInputStream) + throws IOException { + File tmpDir = new File(dirName); + System.out.println("tmpdir = " + dirName); + if(!tmpDir.exists()) { + tmpDir.mkdirs(); + } + StringTokenizer st = new StringTokenizer(fileName, "/"); + String actualFile = null; + while(st.hasMoreTokens()) { + actualFile = st.nextToken(); + } + File file = new File(tmpDir + File.separator + actualFile); + OutputStream os = null; + try { + int read = 0; + byte[] bytes = new byte[1024]; + os = new FileOutputStream(file, true); + while((read = uploadedInputStream.read(bytes)) != -1) { + os.write(bytes, 0, read); + } + os.flush(); + return file.getAbsolutePath(); + } finally { + if(os != null) { + os.close(); + } + } } } diff --git a/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/responsehandler/VnfFuncTestResponseHandler.java b/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/responsehandler/VnfFuncTestResponseHandler.java new file mode 100644 index 0000000..b165234 --- /dev/null +++ b/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/responsehandler/VnfFuncTestResponseHandler.java @@ -0,0 +1,81 @@ +/* + * 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.openo.vnfsdk.functest.responsehandler; + +import javax.ws.rs.core.Response; + +import org.openo.vnfsdk.functest.FileUtil; +import org.openo.vnfsdk.functest.util.RestResponseUtil; +import org.openo.vnfsdk.functest.util.ZipCompressor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VnfFuncTestResponseHandler { + + private static boolean deleteFileEnabled = false; + + private static String resultPath = "D:\\Pitchi_docs\\remote\\"; + + private static VnfFuncTestResponseHandler vnfFuncRspHandler; + + private static final Logger logger = LoggerFactory.getLogger(VnfFuncTestResponseHandler.class); + + private VnfFuncTestResponseHandler() { + } + + public static VnfFuncTestResponseHandler getInstance() { + if(vnfFuncRspHandler == null) { + vnfFuncRspHandler = new VnfFuncTestResponseHandler(); + } + return vnfFuncRspHandler; + } + + public Response getResponseByFuncTestId(String funcTestId) { + // Check whether file Exists for the Request received !!! + // ----------------------------------------------------- + String fileName = generateFilePath(funcTestId); + if(!FileUtil.checkFileExist(fileName)) { + logger.warn("Resquested function Test result not avaliable/In-Progress !!!"); + return RestResponseUtil.getErrorResponse(21); + } + + String zipFileName = resultPath + funcTestId + ".zip"; + new ZipCompressor(zipFileName).compress(fileName); + + // Convert Zip-file byteCode and to response !!! + // ----------------------------------------------------- + byte[] byteArrayFile = FileUtil.convertZipFiletoByteArray(zipFileName); + + // Delete the zip file present if Success !!! + // ---------------------------------------------- + if(deleteFileEnabled) { + FileUtil.deleteFile(zipFileName); + } + + if(null != byteArrayFile) { + logger.warn("Resquested function Test result Sucess !!!"); + return RestResponseUtil.getSuccessResponse(byteArrayFile); + } else { + logger.warn("Resquested function Test result Faiuled !!!"); + return RestResponseUtil.getErrorResponse(21); + } + } + + private String generateFilePath(String funcTestId) { + return resultPath + "/" + funcTestId; + } +} diff --git a/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/util/RestResponseUtil.java b/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/util/RestResponseUtil.java index 4130952..6b40ed2 100644 --- a/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/util/RestResponseUtil.java +++ b/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/util/RestResponseUtil.java @@ -23,7 +23,7 @@ public class RestResponseUtil { public static Response getSuccessResponse(Object obj) { if(obj != null) { - return Response.ok(obj).build(); + return Response.ok(GsonUtil.objectToString(obj)).build(); } else { return Response.ok().build(); } diff --git a/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/util/ZipCompressor.java b/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/util/ZipCompressor.java new file mode 100644 index 0000000..7ca6bcb --- /dev/null +++ b/vnf-sdk-function-test/src/main/java/org/openo/vnfsdk/functest/util/ZipCompressor.java @@ -0,0 +1,125 @@ +/* + * 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.openo.vnfsdk.functest.util; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.zip.CRC32; +import java.util.zip.CheckedOutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ZipCompressor { + + public static final Logger LOG = LoggerFactory.getLogger(ZipCompressor.class); + + static final int BUFFER = 8192; + + private File zipFile; + + public ZipCompressor(String pathName) { + zipFile = new File(pathName); + } + + /** + * compress file according several path. + * + * @param pathName file path name + */ + public void compress(String... pathName) { + ZipOutputStream out = null; + try { + FileOutputStream fileOutputStream = new FileOutputStream(zipFile); + CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream, new CRC32()); + out = new ZipOutputStream(cos); + String basedir = ""; + for(int i = 0; i < pathName.length; i++) { + compress(new File(pathName[i]), out, basedir); + } + out.close(); + } catch(Exception e1) { + throw new RuntimeException(e1); + } + } + + /** + * compress file according file path. + * + * @param srcPathName file path name + */ + public void compress(String srcPathName) { + File file = new File(srcPathName); + if(!file.exists()) { + throw new RuntimeException(srcPathName + "not exist!"); + } + try { + FileOutputStream fileOutputStream = new FileOutputStream(zipFile); + CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream, new CRC32()); + ZipOutputStream out = new ZipOutputStream(cos); + String basedir = ""; + compress(file, out, basedir); + out.close(); + } catch(Exception e1) { + throw new RuntimeException(e1); + } + } + + private void compress(File file, ZipOutputStream out, String basedir) { + if(file.isDirectory()) { + System.out.println("compress: " + basedir + file.getName()); + this.compressDirectory(file, out, basedir); + } else { + System.out.println("compress: " + basedir + file.getName()); + this.compressFile(file, out, basedir); + } + } + + private void compressDirectory(File dir, ZipOutputStream out, String basedir) { + if(!dir.exists()) { + return; + } + + File[] files = dir.listFiles(); + for(int i = 0; i < files.length; i++) { + compress(files[i], out, basedir + dir.getName() + "/"); + } + } + + private void compressFile(File file, ZipOutputStream out, String basedir) { + if(!file.exists()) { + return; + } + try { + byte data[] = new byte[BUFFER]; + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); + ZipEntry entry = new ZipEntry(basedir + file.getName()); + out.putNextEntry(entry); + int count; + while((count = bis.read(data, 0, BUFFER)) != -1) { + out.write(data, 0, count); + } + bis.close(); + } catch(Exception e1) { + throw new RuntimeException(e1); + } + } +} -- cgit 1.2.3-korg