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.
 
  16 package org.onap.vnfsdk.marketplace.wrapper;
 
  18 import java.io.BufferedInputStream;
 
  20 import java.io.FileInputStream;
 
  21 import java.io.IOException;
 
  22 import java.io.InputStream;
 
  23 import java.util.ArrayList;
 
  24 import java.util.List;
 
  25 import java.util.concurrent.Callable;
 
  26 import java.util.concurrent.ExecutorService;
 
  27 import java.util.concurrent.Executors;
 
  29 import javax.ws.rs.core.HttpHeaders;
 
  30 import javax.ws.rs.core.MediaType;
 
  31 import javax.ws.rs.core.Response;
 
  32 import javax.ws.rs.core.Response.Status;
 
  34 import org.apache.commons.io.IOUtils;
 
  35 import org.apache.commons.lang3.StringUtils;
 
  36 import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
 
  37 import org.onap.vnfsdk.marketplace.common.CommonConstant;
 
  38 import org.onap.vnfsdk.marketplace.common.FileUtil;
 
  39 import org.onap.vnfsdk.marketplace.common.JsonUtil;
 
  40 import org.onap.vnfsdk.marketplace.common.RestUtil;
 
  41 import org.onap.vnfsdk.marketplace.common.ToolUtil;
 
  42 import org.onap.vnfsdk.marketplace.db.entity.PackageData;
 
  43 import org.onap.vnfsdk.marketplace.db.exception.MarketplaceResourceException;
 
  44 import org.onap.vnfsdk.marketplace.db.resource.PackageManager;
 
  45 import org.onap.vnfsdk.marketplace.db.util.MarketplaceDbUtil;
 
  46 import org.onap.vnfsdk.marketplace.entity.request.PackageBasicInfo;
 
  47 import org.onap.vnfsdk.marketplace.entity.response.PackageMeta;
 
  48 import org.onap.vnfsdk.marketplace.entity.response.UploadPackageResponse;
 
  49 import org.onap.vnfsdk.marketplace.filemanage.FileManagerFactory;
 
  50 import org.onap.vnfsdk.marketplace.onboarding.entity.OnBoardingOperResult;
 
  51 import org.onap.vnfsdk.marketplace.onboarding.entity.OnBoardingResult;
 
  52 import org.onap.vnfsdk.marketplace.onboarding.entity.OnBoardingSteps;
 
  53 import org.onap.vnfsdk.marketplace.onboarding.entity.OnBoradingRequest;
 
  54 import org.onap.vnfsdk.marketplace.onboarding.hooks.functiontest.FunctionTestExceutor;
 
  55 import org.onap.vnfsdk.marketplace.onboarding.hooks.functiontest.FunctionTestHook;
 
  56 import org.onap.vnfsdk.marketplace.onboarding.hooks.validatelifecycle.ValidateLifecycleTestResponse;
 
  57 import org.onap.vnfsdk.marketplace.onboarding.onboardmanager.OnBoardingHandler;
 
  58 import org.slf4j.Logger;
 
  59 import org.slf4j.LoggerFactory;
 
  61 import org.onap.validation.csar.CsarValidator;
 
  63 import net.sf.json.JSONObject;
 
  65 public class PackageWrapper {
 
  66     private static PackageWrapper packageWrapper;
 
  67     private static final Logger LOG = LoggerFactory.getLogger(PackageWrapper.class);
 
  70      * 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
 
  82         String reqParam = IOUtils.toString(inputStream);
 
  83         LOG.info("updateValidateStatus request param:"+reqParam);
 
  84         if(StringUtils.isBlank(reqParam)) {
 
  85             LOG.error("The updateValidateStatus request params can't be null");
 
  86             return Response.status(Status.EXPECTATION_FAILED).build();
 
  89         ValidateLifecycleTestResponse lyfValidateResp = JsonUtil.fromJson(reqParam, ValidateLifecycleTestResponse.class);
 
  90         if(!checkOperationSucess(lyfValidateResp))
 
  92             return Response.status(Status.EXPECTATION_FAILED).build();
 
  95         String funcTestResponse = FunctionTestExceutor.executeFunctionTest(reqParam);
 
  96         if(null == funcTestResponse)
 
  98             return Response.status(Status.EXPECTATION_FAILED).build();
 
 101         JSONObject funcTestRspObject = JSONObject.fromObject(funcTestResponse);
 
 102         if(!funcTestRspObject.get("status").equals(CommonConstant.SUCCESS_STR))
 
 104             return Response.status(Status.EXPECTATION_FAILED).build();
 
 107         JSONObject result = new JSONObject();
 
 108         result.put("msg","SUCCESS");
 
 109         return Response.ok(ToolUtil.objectToString(result), MediaType.APPLICATION_JSON).build();
 
 112     private boolean checkOperationSucess(ValidateLifecycleTestResponse lyfValidateResp)
 
 114         boolean bOperStatus = false;
 
 115         if(null == lyfValidateResp)
 
 117             LOG.error("ValidateLifecycleTestResponse  is NUll !!!");
 
 120         if(lyfValidateResp.getLifecycle_status().equalsIgnoreCase(CommonConstant.SUCCESS_STR)
 
 121                 && lyfValidateResp.getValidate_status().equalsIgnoreCase(CommonConstant.SUCCESS_STR))
 
 123             LOG.error("Lifecycle/Validation Response failed :" + lyfValidateResp.getLifecycle_status() + File.separator + lyfValidateResp.getValidate_status());
 
 130      * query package list by condition.
 
 131      * @param name package name
 
 132      * @param provider package provider
 
 133      * @param version package version
 
 134      * @param deletionPending package deletionPending
 
 135      * @param type package type
 
 138     public Response queryPackageListByCond(String name, String provider, String version,
 
 139             String deletionPending, String type) {
 
 140         List<PackageData> dbresult = new ArrayList<>();
 
 141         List<PackageMeta> result = new ArrayList<>();
 
 142         LOG.info("query package info.name:" + name + " provider:" + provider + " version" + version
 
 143                 + " deletionPending" + deletionPending + " type:" + type);
 
 146                     PackageManager.getInstance().queryPackage(name, provider, version, deletionPending, type);
 
 147             result = PackageWrapperUtil.packageDataList2PackageMetaList(dbresult);
 
 148             return Response.ok(ToolUtil.objectToString(result)).build();
 
 149         } catch (MarketplaceResourceException e1) {
 
 150             LOG.error("query package by csarId from db error ! ", e1);
 
 151             return RestUtil.getRestException(e1.getMessage());
 
 156      * query package by id.
 
 157      * @param csarId package id
 
 160     public Response queryPackageById(String csarId) {
 
 161         PackageData dbResult = PackageWrapperUtil.getPackageInfoById(csarId);
 
 162         PackageMeta result = PackageWrapperUtil.packageData2PackageMeta(dbResult);
 
 163         return Response.ok(ToolUtil.objectToString(result)).build();
 
 168      * @param uploadedInputStream inputStream
 
 169      * @param fileDetail package detail
 
 170      * @param head http header
 
 172      * @throws Exception e
 
 174     public Response uploadPackage(InputStream uploadedInputStream,
 
 175             FormDataContentDisposition fileDetail, String details, HttpHeaders head) throws MarketplaceResourceException
 
 177         LOG.info("Upload/Reupload request Received !!!!");
 
 179             String packageId = MarketplaceDbUtil.generateId();
 
 180             return handlePackageUpload(packageId,uploadedInputStream, fileDetail, details, head);
 
 181         } catch (IOException e) {
 
 182             LOG.error("can't get package id", e);
 
 184         return Response.status(Status.INTERNAL_SERVER_ERROR).build();
 
 188      * Interface for Uploading package
 
 190      * @param uploadedInputStream
 
 195      * @throws IOException
 
 196      * @throws MarketplaceResourceException
 
 198     private Response handlePackageUpload(String packageId,InputStream uploadedInputStream, FormDataContentDisposition fileDetail,
 
 199             String details, HttpHeaders head) throws IOException, MarketplaceResourceException
 
 201         boolean bResult = handleDataValidate(packageId,uploadedInputStream,fileDetail);
 
 204             LOG.error("Validation of Input received for Package Upload failed !!!");
 
 205             return Response.status(Status.EXPECTATION_FAILED).build();
 
 208         String fileName = "temp_"+ packageId + ".csar";
 
 209         if (null != fileDetail)
 
 211             LOG.info("the fileDetail = " + ToolUtil.objectToString(fileDetail));
 
 213             fileName = ToolUtil.processFileName(fileDetail.getFileName());
 
 216         String localDirName = ToolUtil.getTempDir(CommonConstant.CATALOG_CSAR_DIR_NAME, fileName);
 
 218         String contentRange = null;
 
 221             contentRange = head.getHeaderString(CommonConstant.HTTP_HEADER_CONTENT_RANGE);
 
 223         LOG.info("store package chunk file, fileName:" + fileName + ",contentRange:" + contentRange);
 
 224         if (ToolUtil.isEmptyString(contentRange))
 
 226             int fileSize = uploadedInputStream.available();
 
 227             contentRange = "0-" + fileSize + "/" + fileSize;
 
 230         String fileLocation = ToolUtil.storeChunkFileInLocal(localDirName, fileName, uploadedInputStream);
 
 231         LOG.info("the fileLocation when upload package is :" + fileLocation);
 
 233         uploadedInputStream.close();
 
 236                 CsarValidator cv = new CsarValidator(packageId, fileLocation);
 
 238                 if (!cv.validateCsar()) {
 
 239                         LOG.error("Could not validate failed");
 
 240                         return Response.status(Status.EXPECTATION_FAILED).build();
 
 244         } catch (Exception e) {
 
 245                 LOG.error("CSAR validation panicked", e);
 
 246                 return Response.status(Status.EXPECTATION_FAILED).build();
 
 250         PackageBasicInfo basicInfo = PackageWrapperUtil.getPacageBasicInfo(fileLocation);
 
 251         UploadPackageResponse result = new UploadPackageResponse();
 
 252         Boolean isEnd = PackageWrapperUtil.isUploadEnd(contentRange);
 
 255             PackageMeta packageMeta = PackageWrapperUtil.getPackageMeta(packageId,fileName, fileLocation, basicInfo, details);
 
 257                 String path =  basicInfo.getType().toString() + File.separator + basicInfo.getProvider() + File.separator +  packageMeta.getCsarId() + File.separator + fileName.replace(".csar", "") + File.separator + basicInfo.getVersion();
 
 259                 String dowloadUri = File.separator + path + File.separator;
 
 260                 packageMeta.setDownloadUri(dowloadUri);
 
 262                 LOG.info("dest path is : " + path);
 
 263                 LOG.info("packageMeta = " + ToolUtil.objectToString(packageMeta));
 
 265                 PackageData packageData = PackageWrapperUtil.getPackageData(packageMeta);
 
 267                 String destPath = File.separator + path + File.separator + File.separator;
 
 268                 boolean uploadResult = FileManagerFactory.createFileManager().upload(localDirName, destPath);
 
 271                     OnBoradingRequest oOnboradingRequest = new OnBoradingRequest();
 
 272                     oOnboradingRequest.setCsarId(packageId);
 
 273                     oOnboradingRequest.setPackageName(fileName);
 
 274                     oOnboradingRequest.setPackagePath(localDirName);
 
 276                     packageData.setCsarId(packageId);
 
 277                     packageData.setDownloadCount(-1);
 
 278                     PackageData packateDbData = PackageManager.getInstance().addPackage(packageData);
 
 280                     LOG.info("Store package data to database succed ! packateDbData = "  + ToolUtil.objectToString(packateDbData));
 
 281                     LOG.info("upload package file end, fileName:" + fileName);
 
 283                     result.setCsarId(packateDbData.getCsarId());
 
 285                     addOnBoardingRequest(oOnboradingRequest);
 
 287                     LOG.info("OnboradingRequest Data : "  + ToolUtil.objectToString(oOnboradingRequest));
 
 289             } catch (NullPointerException e) {
 
 290                 LOG.error("Package basicInfo is incorrect ! basicIonfo = " + ToolUtil.objectToString(basicInfo), e);
 
 291                 return Response.serverError().build();
 
 294         return Response.ok(ToolUtil.objectToString(result), MediaType.APPLICATION_JSON).build();
 
 298      * Execute OnBarding request
 
 299      * @param oOnboradingRequest
 
 301     private void addOnBoardingRequest(final OnBoradingRequest oOnboradingRequest)
 
 303         ExecutorService es = Executors.newFixedThreadPool(CommonConstant.ONBOARDING_THREAD_COUNT);
 
 304         Callable<Integer> callableInteger = () -> {
 
 305             new OnBoardingHandler().handleOnBoardingReq(oOnboradingRequest);
 
 306             return CommonConstant.SUCESS;
 
 308         es.submit(callableInteger);
 
 312      * delete package by package id.
 
 313      * @param csarId package id
 
 316     public Response delPackage(String csarId) {
 
 317         LOG.info("delete package  info.csarId:" + csarId);
 
 318         if (ToolUtil.isEmptyString(csarId)) {
 
 319             LOG.error("delete package  fail, csarid is null");
 
 320             return Response.serverError().build();
 
 322         deletePackageDataById(csarId);
 
 323         return Response.ok().build();
 
 327      * Delete Package by CSAR ID
 
 330     private void  deletePackageDataById(String csarId) {
 
 331         String packagePath = PackageWrapperUtil.getPackagePath(csarId);
 
 332         if (packagePath == null) {
 
 333             LOG.error("package path is null! ");
 
 337         FileManagerFactory.createFileManager().delete(packagePath);
 
 338         //Delete Results Data
 
 339         FileManagerFactory.createFileManager().delete(File.separator + csarId);
 
 342         //delete package data from database
 
 344             PackageManager.getInstance().deletePackage(csarId);
 
 345         } catch (MarketplaceResourceException e1) {
 
 346             LOG.error("delete package  by csarId from db error ! " + e1.getMessage(), e1);
 
 351      * download package by package id.
 
 352      * @param csarId package id
 
 355     public Response downloadCsarPackagesById(String csarId) {
 
 356         PackageData packageData = PackageWrapperUtil.getPackageInfoById(csarId);
 
 358         String packageName = packageData.getName();
 
 359         String path = org.onap.vnfsdk.marketplace.filemanage.http.ToolUtil.getHttpServerAbsolutePath() +File.separatorChar+packageData.getType()+File.separatorChar+
 
 360                 packageData.getProvider()+File.separatorChar+ packageData.getCsarId() +File.separator +packageName+File.separatorChar+packageData.getVersion()
 
 361                 +File.separator + packageName + ".csar";
 
 363         LOG.info("downloadCsarPackagesById path is :  " + path);
 
 365         File csarFile = new File(path);
 
 366         if (!csarFile.exists()) {
 
 367             return Response.status(Status.INTERNAL_SERVER_ERROR).build();
 
 370         LOG.info("downloadCsarPackagesById ABS path is :  " + csarFile.getAbsolutePath());
 
 374             InputStream fis = new BufferedInputStream(new FileInputStream(csarFile.getAbsolutePath()));
 
 375             return Response.ok(fis)
 
 376                     .header("Content-Disposition", "attachment; filename=\"" + csarFile.getName() + "\"")
 
 381             LOG.error("download vnf package fail.", e1);
 
 382             return RestUtil.getRestException(e1.getMessage());
 
 387      * get package file uri.
 
 388      * @param csarId package id
 
 389      * @param relativePath file relative path
 
 392     public Response getCsarFileUri(String csarId) {
 
 393         return downloadCsarPackagesById(csarId);
 
 397      * Interface to Update Download count for CSAR ID
 
 401     public Response updateDwonloadCount(String csarId) {
 
 402         return handleDownladCountUpdate(csarId) ?
 
 403                 Response.ok().build() :
 
 404                     Response.status(Status.EXPECTATION_FAILED).build();
 
 408      * Handle downlowa count update
 
 412     private boolean handleDownladCountUpdate(String csarId) {
 
 413         boolean bupdateSucess = false;
 
 416             PackageManager.getInstance().updateDwonloadCount(csarId);
 
 417             bupdateSucess = true;
 
 419         catch (Exception exp)
 
 421             LOG.error("Updating Donwload count failed for Package with ID !!! : " + exp.getMessage(), exp);
 
 423         return bupdateSucess;
 
 427      * Interface to Re upload Package
 
 429      * @param uploadedInputStream
 
 436     public Response reUploadPackage(String csarId,
 
 437             InputStream uploadedInputStream,
 
 438             FormDataContentDisposition fileDetail,
 
 440             HttpHeaders head) throws MarketplaceResourceException
 
 442         LOG.info("Reupload request Received !!!!");
 
 444             //STEP 1: Validate Input Data
 
 445             //----------------------------
 
 446         boolean bResult = handleDataValidate(csarId,uploadedInputStream,fileDetail);
 
 449             LOG.error("Validation of Input received for Package Upload failed during Reload!!!");
 
 450             return Response.status(Status.EXPECTATION_FAILED).build();
 
 454             //STEP 2: Delete All Package Data based on package id
 
 455             //----------------------------------------------------
 
 456             deletePackageDataById(csarId);
 
 458             //STEP 3: upload package with same package id
 
 459             //-------------------------------------------
 
 460             return handlePackageUpload(csarId,uploadedInputStream, fileDetail, details, head);
 
 461         } catch (IOException e) {
 
 462             LOG.error("delete package failed", e);
 
 464         return Response.status(Status.INTERNAL_SERVER_ERROR).build();
 
 468      * Interface to get OnBoarding Result by Operation Type
 
 474     public Response getOnBoardingResult(String csarId, String operTypeId, String operId)
 
 476         LOG.info("getOnBoardingResult request : csarId:" + csarId + " operTypeId:" + operTypeId + " operId:" + operId);
 
 478             PackageData packageData = PackageWrapperUtil.getPackageInfoById(csarId);
 
 479             if (null == packageData) {
 
 480                 return Response.status(Response.Status.PRECONDITION_FAILED).build();
 
 483             handleDelayExec(operId);
 
 485             OnBoardingResult oOnBoardingResult = FunctionTestHook.getOnBoardingResult(packageData);
 
 486             if (null == oOnBoardingResult) {
 
 487                 return Response.status(Response.Status.PRECONDITION_FAILED).build();
 
 489             filterOnBoardingResultByOperId(oOnBoardingResult, operId);
 
 491             String strResult = ToolUtil.objectToString(oOnBoardingResult);
 
 492             LOG.info("getOnBoardingResult response : " + strResult);
 
 493             return Response.ok(strResult, "application/json").build();
 
 494         } catch (NullPointerException e) {
 
 495             LOG.error("Null param in getOnBoardingResult", e);
 
 496             return Response.status(Response.Status.BAD_REQUEST).build();
 
 501     private void filterOnBoardingResultByOperId(OnBoardingResult oOnBoardingResult, String operId)
 
 503         if (0 == operId.compareToIgnoreCase("all")) {
 
 506         if (0 == operId.compareToIgnoreCase("download"))
 
 508             List<OnBoardingOperResult> operResultListTemp = new ArrayList<>();
 
 509             OnBoardingOperResult operResultListTmp = new OnBoardingOperResult();
 
 510             operResultListTmp.setOperId("download");
 
 511             operResultListTmp.setStatus(0);
 
 512             operResultListTemp.add(operResultListTmp);
 
 513             oOnBoardingResult.setOperResult(operResultListTemp);
 
 516         List<OnBoardingOperResult> operResultListOut = new ArrayList<>();
 
 517         List<OnBoardingOperResult> operResultList = oOnBoardingResult.getOperResult();
 
 518         for (OnBoardingOperResult operResult : operResultList) {
 
 519             if (0 == operResult.getOperId().compareToIgnoreCase(operId)) {
 
 520                 operResultListOut.add(operResult);
 
 523         oOnBoardingResult.setOperResult(operResultListOut);
 
 527      * Interface to get OnBoarding Status by Operation ID
 
 532     public Response getOperResultByOperTypeId(String csarId, String operTypeId)
 
 534         LOG.error("getOnBoardingResult request : csarId:"+ csarId + " operTypeId:"+operTypeId);
 
 535         if(null == csarId || null == operTypeId || csarId.isEmpty()  || operTypeId.isEmpty())
 
 537             return Response.status(Status.BAD_REQUEST).build();
 
 540         PackageData packageData = PackageWrapperUtil.getPackageInfoById(csarId);
 
 541         if(null == packageData)
 
 543             LOG.error("Failed to find package for PackageID:"+ csarId);
 
 544             return Response.status(Status.PRECONDITION_FAILED).build();
 
 547         //Get result key to fetch Function Test Results
 
 548         //---------------------------------------------
 
 549         String strResult = FunctionTestHook.getFuncTestResults(packageData);
 
 550         if(null == strResult)
 
 552             LOG.error("NULL reponse for getOperResultByOperTypeId response :"+ strResult);
 
 553             return Response.status(Status.INTERNAL_SERVER_ERROR).build();
 
 555         LOG.info("getOperResultByOperTypeId response :"+ strResult);
 
 556         return Response.ok(strResult, MediaType.APPLICATION_JSON).build();
 
 559     private boolean handleDataValidate(String packageId,InputStream uploadedInputStream, FormDataContentDisposition fileDetail)
 
 561         boolean bvalidateOk = false;
 
 562         if ((null != uploadedInputStream) && (fileDetail != null) && !ToolUtil.isEmptyString(packageId))
 
 570      * Interface to get OnBoarding Steps
 
 573     public Response getOnBoardingSteps()
 
 575         LOG.info("Get OnBoarding Steps request Received !!!");
 
 577         String filePath = org.onap.vnfsdk.marketplace.filemanage.http.ToolUtil.getAppDeployPath() + File.separator +"generalconfig/OnBoardingSteps.json";
 
 578         LOG.info("Onboarding Steps Json file Path  :" + filePath);
 
 580         OnBoardingSteps oOnBoardingSteps = (OnBoardingSteps)FileUtil.readJsonDatafFromFile(filePath, OnBoardingSteps.class);
 
 581         if (null == oOnBoardingSteps) {
 
 582             return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
 
 584         String strResult = ToolUtil.objectToString(oOnBoardingSteps);
 
 585         LOG.info("getOnBoardingSteps response :" + strResult);
 
 586         return Response.ok(strResult, MediaType.APPLICATION_JSON).build();
 
 589     private void handleDelayExec(String operId)
 
 591         if (0 == operId.compareToIgnoreCase(CommonConstant.functionTest.FUNCTEST_EXEC))
 
 597             catch (InterruptedException e)
 
 599                 LOG.info("handleDelayExex response : ", e);
 
 600                 Thread.currentThread().interrupt();