2 * Copyright 2017 Huawei Technologies Co., Ltd.
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.vnfsdk.marketplace.wrapper;
19 import java.io.BufferedInputStream;
21 import java.io.FileInputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.concurrent.Callable;
27 import java.util.concurrent.ExecutorService;
28 import java.util.concurrent.Executors;
30 import javax.ws.rs.core.HttpHeaders;
31 import javax.ws.rs.core.MediaType;
32 import javax.ws.rs.core.Response;
33 import javax.ws.rs.core.Response.Status;
35 import org.apache.commons.io.IOUtils;
36 import org.apache.commons.lang3.StringUtils;
37 import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
38 import org.onap.validation.csar.CsarValidator;
39 import org.onap.vnfsdk.marketplace.common.CommonConstant;
40 import org.onap.vnfsdk.marketplace.common.FileUtil;
41 import org.onap.vnfsdk.marketplace.common.RestUtil;
42 import org.onap.vnfsdk.marketplace.common.ToolUtil;
43 import org.onap.vnfsdk.marketplace.db.entity.PackageData;
44 import org.onap.vnfsdk.marketplace.db.exception.MarketplaceResourceException;
45 import org.onap.vnfsdk.marketplace.db.resource.PackageManager;
46 import org.onap.vnfsdk.marketplace.db.util.MarketplaceDbUtil;
47 import org.onap.vnfsdk.marketplace.entity.request.PackageBasicInfo;
48 import org.onap.vnfsdk.marketplace.entity.response.PackageMeta;
49 import org.onap.vnfsdk.marketplace.entity.response.UploadPackageResponse;
50 import org.onap.vnfsdk.marketplace.filemanage.FileManagerFactory;
51 import org.onap.vnfsdk.marketplace.onboarding.entity.OnBoardingOperResult;
52 import org.onap.vnfsdk.marketplace.onboarding.entity.OnBoardingResult;
53 import org.onap.vnfsdk.marketplace.onboarding.entity.OnBoardingSteps;
54 import org.onap.vnfsdk.marketplace.onboarding.entity.OnBoradingRequest;
55 import org.onap.vnfsdk.marketplace.onboarding.hooks.functiontest.FunctionTestExceutor;
56 import org.onap.vnfsdk.marketplace.onboarding.hooks.functiontest.FunctionTestHook;
57 import org.onap.vnfsdk.marketplace.onboarding.hooks.validatelifecycle.ValidateLifecycleTestResponse;
58 import org.onap.vnfsdk.marketplace.onboarding.onboardmanager.OnBoardingHandler;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
62 public class PackageWrapper {
64 private static PackageWrapper packageWrapper;
66 private static final Logger LOG = LoggerFactory.getLogger(PackageWrapper.class);
69 * get PackageWrapper instance.
71 * @return package wrapper instance
73 public static PackageWrapper getInstance() {
74 if(packageWrapper == null) {
75 packageWrapper = new PackageWrapper();
77 return packageWrapper;
80 public Response updateValidateStatus(InputStream inputStream) throws IOException {
81 String reqParam = IOUtils.toString(inputStream);
82 LOG.info("updateValidateStatus request param:" + reqParam);
83 if(StringUtils.isBlank(reqParam)) {
84 LOG.error("The updateValidateStatus request params can't be null");
85 return Response.status(Status.EXPECTATION_FAILED).build();
88 ValidateLifecycleTestResponse lyfValidateResp = null; //TBD - Use Gson - jackson has security issue/
89 //JsonUtil.fromJson(reqParam, ValidateLifecycleTestResponse.class);
90 if(!checkOperationSucess(lyfValidateResp)) {
91 return Response.status(Status.EXPECTATION_FAILED).build();
94 String funcTestResponse = FunctionTestExceutor.executeFunctionTest(reqParam);
95 if(null == funcTestResponse) {
96 return Response.status(Status.EXPECTATION_FAILED).build();
99 if(!funcTestResponse.contains(CommonConstant.SUCCESS_STR)) {
100 return Response.status(Status.EXPECTATION_FAILED).build();
103 return Response.ok().build();
106 private boolean checkOperationSucess(ValidateLifecycleTestResponse lyfValidateResp) {
107 boolean bOperStatus = false;
108 if(null == lyfValidateResp) {
109 LOG.error("ValidateLifecycleTestResponse is NUll !!!");
112 if(lyfValidateResp.getLifecycle_status().equalsIgnoreCase(CommonConstant.SUCCESS_STR)
113 && lyfValidateResp.getValidate_status().equalsIgnoreCase(CommonConstant.SUCCESS_STR)) {
114 LOG.error("Lifecycle/Validation Response failed :" + lyfValidateResp.getLifecycle_status() + File.separator
115 + lyfValidateResp.getValidate_status());
122 * query package list by condition.
124 * @param name package name
125 * @param provider package provider
126 * @param version package version
127 * @param deletionPending package deletionPending
128 * @param type package type
131 public Response queryPackageListByCond(String name, String provider, String version, String deletionPending,
133 List<PackageData> dbresult = new ArrayList<>();
134 List<PackageMeta> result = new ArrayList<>();
135 LOG.info("query package info.name:" + name + " provider:" + provider + " version" + version + " deletionPending"
136 + deletionPending + " type:" + type);
138 dbresult = PackageManager.getInstance().queryPackage(name, provider, version, deletionPending, type);
139 result = PackageWrapperUtil.packageDataList2PackageMetaList(dbresult);
140 return Response.ok(ToolUtil.objectToString(result)).build();
141 } catch(MarketplaceResourceException e1) {
142 LOG.error("query package by csarId from db error ! ", e1);
143 return RestUtil.getRestException(e1.getMessage());
148 * query package by id.
150 * @param csarId package id
153 public Response queryPackageById(String csarId) {
154 PackageData dbResult = PackageWrapperUtil.getPackageInfoById(csarId);
155 PackageMeta result = PackageWrapperUtil.packageData2PackageMeta(dbResult);
156 return Response.ok(ToolUtil.objectToString(result)).build();
162 * @param uploadedInputStream inputStream
163 * @param fileDetail package detail
164 * @param head http header
166 * @throws Exception e
168 public Response uploadPackage(InputStream uploadedInputStream, FormDataContentDisposition fileDetail,
169 String details, HttpHeaders head) throws MarketplaceResourceException {
170 LOG.info("Upload/Reupload request Received !!!!");
172 String packageId = MarketplaceDbUtil.generateId();
173 return handlePackageUpload(packageId, uploadedInputStream, fileDetail, details, head);
174 } catch(IOException e) {
175 LOG.error("can't get package id", e);
177 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
180 private UploadPackageResponse manageUpload(String packageId, String fileName, String fileLocation, String details,
181 String contentRange) throws IOException, MarketplaceResourceException {
182 String localDirName = ToolUtil.getTempDir(CommonConstant.CATALOG_CSAR_DIR_NAME, fileName);
183 PackageBasicInfo basicInfo = PackageWrapperUtil.getPacageBasicInfo(fileLocation);
184 UploadPackageResponse result = new UploadPackageResponse();
185 Boolean isEnd = PackageWrapperUtil.isUploadEnd(contentRange);
187 PackageMeta packageMeta =
188 PackageWrapperUtil.getPackageMeta(packageId, fileName, fileLocation, basicInfo, details);
190 String path = basicInfo.getType().toString() + File.separator + basicInfo.getProvider() + File.separator
191 + packageMeta.getCsarId() + File.separator + fileName.replace(".csar", "") + File.separator
192 + basicInfo.getVersion();
194 String dowloadUri = File.separator + path + File.separator;
195 packageMeta.setDownloadUri(dowloadUri);
197 LOG.info("dest path is : " + path);
198 LOG.info("packageMeta = " + ToolUtil.objectToString(packageMeta));
200 PackageData packageData = PackageWrapperUtil.getPackageData(packageMeta);
202 List<PackageData> lstPkgData = PackageManager.getInstance().queryPackage(packageMeta.getName(), "", "", "", "");
203 if (!lstPkgData.isEmpty())
205 LOG.error ("Package name is not unique");
209 String destPath = File.separator + path + File.separator + File.separator;
210 boolean uploadResult = FileManagerFactory.createFileManager().upload(localDirName, destPath);
212 OnBoradingRequest oOnboradingRequest = new OnBoradingRequest();
213 oOnboradingRequest.setCsarId(packageId);
214 oOnboradingRequest.setPackageName(fileName);
215 oOnboradingRequest.setPackagePath(localDirName);
217 packageData.setCsarId(packageId);
218 packageData.setDownloadCount(-1);
219 PackageData packateDbData = PackageManager.getInstance().addPackage(packageData);
221 LOG.info("Store package data to database succed ! packateDbData = "
222 + ToolUtil.objectToString(packateDbData));
223 LOG.info("upload package file end, fileName:" + fileName);
225 result.setCsarId(packateDbData.getCsarId());
227 addOnBoardingRequest(oOnboradingRequest);
229 LOG.info("OnboradingRequest Data : " + ToolUtil.objectToString(oOnboradingRequest));
231 } catch(NullPointerException e) {
232 LOG.error("Package basicInfo is incorrect ! basicIonfo = " + ToolUtil.objectToString(basicInfo), e);
240 * Interface for Uploading package
243 * @param uploadedInputStream
248 * @throws IOException
249 * @throws MarketplaceResourceException
251 private Response handlePackageUpload(String packageId, InputStream uploadedInputStream,
252 FormDataContentDisposition fileDetail, String details, HttpHeaders head)
253 throws IOException, MarketplaceResourceException {
254 boolean bResult = handleDataValidate(packageId, uploadedInputStream, fileDetail);
256 LOG.error("Validation of Input received for Package Upload failed !!!");
257 return Response.status(Status.EXPECTATION_FAILED).build();
260 String fileName = "temp_" + packageId + ".csar";
261 if(null != fileDetail) {
262 LOG.info("the fileDetail = " + ToolUtil.objectToString(fileDetail));
264 fileName = ToolUtil.processFileName(fileDetail.getFileName());
267 String localDirName = ToolUtil.getTempDir(CommonConstant.CATALOG_CSAR_DIR_NAME, fileName);
269 String contentRange = null;
271 contentRange = head.getHeaderString(CommonConstant.HTTP_HEADER_CONTENT_RANGE);
273 LOG.info("store package chunk file, fileName:" + fileName + ",contentRange:" + contentRange);
274 if(ToolUtil.isEmptyString(contentRange)) {
275 int fileSize = uploadedInputStream.available();
276 contentRange = "0-" + fileSize + "/" + fileSize;
279 String fileLocation = ToolUtil.storeChunkFileInLocal(localDirName, fileName, uploadedInputStream);
280 LOG.info("the fileLocation when upload package is :" + fileLocation);
282 uploadedInputStream.close();
285 CsarValidator cv = new CsarValidator(packageId, fileLocation);
287 if(!cv.validateCsar()) {
288 LOG.error("Could not validate failed");
289 return Response.status(Status.EXPECTATION_FAILED).build();
291 } catch(Exception e) {
292 LOG.error("CSAR validation panicked", e);
293 return Response.status(Status.EXPECTATION_FAILED).build();
296 UploadPackageResponse result = manageUpload(packageId, fileName, fileLocation, details, contentRange);
298 return Response.ok(ToolUtil.objectToString(result), MediaType.APPLICATION_JSON).build();
300 return Response.serverError().build();
305 * Execute OnBarding request
307 * @param oOnboradingRequest
309 private void addOnBoardingRequest(final OnBoradingRequest oOnboradingRequest) {
310 ExecutorService es = Executors.newFixedThreadPool(CommonConstant.ONBOARDING_THREAD_COUNT);
311 Callable<Integer> callableInteger = () -> {
312 new OnBoardingHandler().handleOnBoardingReq(oOnboradingRequest);
313 return CommonConstant.SUCESS;
315 es.submit(callableInteger);
319 * delete package by package id.
321 * @param csarId package id
324 public Response delPackage(String csarId) {
325 LOG.info("delete package info.csarId:" + csarId);
326 if(ToolUtil.isEmptyString(csarId)) {
327 LOG.error("delete package fail, csarid is null");
328 return Response.serverError().build();
330 deletePackageDataById(csarId);
331 return Response.ok().build();
335 * Delete Package by CSAR ID
339 private void deletePackageDataById(String csarId) {
340 String packagePath = PackageWrapperUtil.getPackagePath(csarId);
341 if(packagePath == null) {
342 LOG.error("package path is null! ");
346 FileManagerFactory.createFileManager().delete(packagePath);
347 // Delete Results Data
348 FileManagerFactory.createFileManager().delete(File.separator + csarId);
350 // delete package data from database
352 PackageManager.getInstance().deletePackage(csarId);
353 } catch(MarketplaceResourceException e1) {
354 LOG.error("delete package by csarId from db error ! " + e1.getMessage(), e1);
359 * download package by package id.
361 * @param csarId package id
364 public Response downloadCsarPackagesById(String csarId) {
365 PackageData packageData = PackageWrapperUtil.getPackageInfoById(csarId);
367 String packageName = packageData.getName();
368 String path = org.onap.vnfsdk.marketplace.filemanage.http.ToolUtil.getHttpServerAbsolutePath()
369 + File.separatorChar + packageData.getType() + File.separatorChar + packageData.getProvider()
370 + File.separatorChar + packageData.getCsarId() + File.separator + packageName + File.separatorChar
371 + packageData.getVersion() + File.separator + packageName + ".csar";
373 LOG.info("downloadCsarPackagesById path is : " + path);
375 File csarFile = new File(path);
376 if(!csarFile.exists()) {
377 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
380 LOG.info("downloadCsarPackagesById ABS path is : " + csarFile.getAbsolutePath());
383 InputStream fis = new BufferedInputStream(new FileInputStream(csarFile.getAbsolutePath()));
384 return Response.ok(fis).header("Content-Disposition", "attachment; filename=\"" + csarFile.getName() + "\"")
386 } catch(Exception e1) {
387 LOG.error("download vnf package fail.", e1);
388 return RestUtil.getRestException(e1.getMessage());
393 * get package file uri.
395 * @param csarId package id
396 * @param relativePath file relative path
399 public Response getCsarFileUri(String csarId) {
400 return downloadCsarPackagesById(csarId);
404 * Interface to Update Download count for CSAR ID
409 public Response updateDwonloadCount(String csarId) {
410 return handleDownladCountUpdate(csarId) ? Response.ok().build()
411 : Response.status(Status.EXPECTATION_FAILED).build();
415 * Handle downlowa count update
420 private boolean handleDownladCountUpdate(String csarId) {
421 boolean bupdateSucess = false;
423 PackageManager.getInstance().updateDownloadCount(csarId);
424 bupdateSucess = true;
425 } catch(Exception exp) {
426 LOG.error("Updating Donwload count failed for Package with ID !!! : " + exp.getMessage(), exp);
428 return bupdateSucess;
432 * Interface to Re upload Package
435 * @param uploadedInputStream
442 public Response reUploadPackage(String csarId, InputStream uploadedInputStream,
443 FormDataContentDisposition fileDetail, String details, HttpHeaders head)
444 throws MarketplaceResourceException {
445 LOG.info("Reupload request Received !!!!");
447 // STEP 1: Validate Input Data
448 // ----------------------------
449 boolean bResult = handleDataValidate(csarId, uploadedInputStream, fileDetail);
451 LOG.error("Validation of Input received for Package Upload failed during Reload!!!");
452 return Response.status(Status.EXPECTATION_FAILED).build();
456 // STEP 2: Delete All Package Data based on package id
457 // ----------------------------------------------------
458 deletePackageDataById(csarId);
460 // STEP 3: upload package with same package id
461 // -------------------------------------------
462 return handlePackageUpload(csarId, uploadedInputStream, fileDetail, details, head);
463 } catch(IOException e) {
464 LOG.error("delete package failed", e);
466 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
470 * Interface to get OnBoarding Result by Operation Type
477 public Response getOnBoardingResult(String csarId, String operTypeId, String operId) {
478 LOG.info("getOnBoardingResult request : csarId:" + csarId + " operTypeId:" + operTypeId + " operId:" + operId);
480 PackageData packageData = PackageWrapperUtil.getPackageInfoById(csarId);
481 if(null == packageData) {
482 return Response.status(Response.Status.PRECONDITION_FAILED).build();
485 handleDelayExec(operId);
487 OnBoardingResult oOnBoardingResult = FunctionTestHook.getOnBoardingResult(packageData);
488 if(null == oOnBoardingResult) {
489 return Response.status(Response.Status.PRECONDITION_FAILED).build();
491 filterOnBoardingResultByOperId(oOnBoardingResult, operId);
493 String strResult = ToolUtil.objectToString(oOnBoardingResult);
494 LOG.info("getOnBoardingResult response : " + strResult);
495 return Response.ok(strResult, "application/json").build();
496 } catch(NullPointerException e) {
497 LOG.error("Null param in getOnBoardingResult", e);
498 return Response.status(Response.Status.BAD_REQUEST).build();
502 private void filterOnBoardingResultByOperId(OnBoardingResult oOnBoardingResult, String operId) {
503 if(0 == operId.compareToIgnoreCase("all")) {
506 if(0 == operId.compareToIgnoreCase("download")) {
507 List<OnBoardingOperResult> operResultListTemp = new ArrayList<>();
508 OnBoardingOperResult operResultListTmp = new OnBoardingOperResult();
509 operResultListTmp.setOperId("download");
510 operResultListTmp.setStatus(0);
511 operResultListTemp.add(operResultListTmp);
512 oOnBoardingResult.setOperResult(operResultListTemp);
515 List<OnBoardingOperResult> operResultListOut = new ArrayList<>();
516 List<OnBoardingOperResult> operResultList = oOnBoardingResult.getOperResult();
517 for(OnBoardingOperResult operResult : operResultList) {
518 if(0 == operResult.getOperId().compareToIgnoreCase(operId)) {
519 operResultListOut.add(operResult);
522 oOnBoardingResult.setOperResult(operResultListOut);
526 * Interface to get OnBoarding Status by Operation ID
532 public Response getOperResultByOperTypeId(String csarId, String operTypeId) {
533 LOG.error("getOnBoardingResult request : csarId:" + csarId + " operTypeId:" + operTypeId);
534 if(null == csarId || null == operTypeId || csarId.isEmpty() || operTypeId.isEmpty()) {
535 return Response.status(Status.BAD_REQUEST).build();
538 PackageData packageData = PackageWrapperUtil.getPackageInfoById(csarId);
539 if(null == packageData) {
540 LOG.error("Failed to find package for PackageID:" + csarId);
541 return Response.status(Status.PRECONDITION_FAILED).build();
544 // Get result key to fetch Function Test Results
545 // ---------------------------------------------
546 String strResult = FunctionTestHook.getFuncTestResults(packageData);
547 if(null == strResult) {
548 LOG.error("NULL reponse for getOperResultByOperTypeId response :" + strResult);
549 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
551 LOG.info("getOperResultByOperTypeId response :" + strResult);
552 return Response.ok(strResult, MediaType.APPLICATION_JSON).build();
555 private boolean handleDataValidate(String packageId, InputStream uploadedInputStream,
556 FormDataContentDisposition fileDetail) {
557 boolean bvalidateOk = false;
558 if((null != uploadedInputStream) && (fileDetail != null) && !ToolUtil.isEmptyString(packageId)) {
565 * Interface to get OnBoarding Steps
569 public Response getOnBoardingSteps() {
570 LOG.info("Get OnBoarding Steps request Received !!!");
572 String filePath = org.onap.vnfsdk.marketplace.filemanage.http.ToolUtil.getAppDeployPath() + File.separator
573 + "generalconfig/OnBoardingSteps.json";
574 LOG.info("Onboarding Steps Json file Path :" + filePath);
576 OnBoardingSteps oOnBoardingSteps =
577 (OnBoardingSteps)FileUtil.readJsonDatafFromFile(filePath, OnBoardingSteps.class);
578 if(null == oOnBoardingSteps) {
579 return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
581 String strResult = ToolUtil.objectToString(oOnBoardingSteps);
582 LOG.info("getOnBoardingSteps response :" + strResult);
583 return Response.ok(strResult, MediaType.APPLICATION_JSON).build();
586 private void handleDelayExec(String operId) {
587 if(0 == operId.compareToIgnoreCase(CommonConstant.functionTest.FUNCTEST_EXEC)) {
590 } catch(InterruptedException e) {
591 LOG.info("handleDelayExex response : ", e);
592 Thread.currentThread().interrupt();