b3773c5f29d8c4dc9aefa1dc9f3cb49a7d32a877
[vnfsdk/refrepo.git] /
1 /**
2  * Copyright 2017 Huawei Technologies Co., Ltd.
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package org.onap.vnfsdk.marketplace.wrapper;
17
18 import java.io.BufferedInputStream;
19 import java.io.File;
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;
28
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;
33
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;
60
61 import net.sf.json.JSONObject;
62
63 public class PackageWrapper {
64     private static PackageWrapper packageWrapper;
65     private static final Logger LOG = LoggerFactory.getLogger(PackageWrapper.class);
66
67     /**
68      * get PackageWrapper instance.
69      * @return package wrapper instance
70      */
71     public static PackageWrapper getInstance() {
72         if (packageWrapper == null) {
73             packageWrapper = new PackageWrapper();
74         }
75         return packageWrapper;
76     }
77
78     public Response updateValidateStatus(InputStream inputStream) throws IOException
79     {
80         String reqParam = IOUtils.toString(inputStream);
81         LOG.info("updateValidateStatus request param:"+reqParam);
82         if(StringUtils.isBlank(reqParam)) {
83             LOG.error("The updateValidateStatus request params can't be null");
84             return Response.status(Status.EXPECTATION_FAILED).build();
85         }
86
87         ValidateLifecycleTestResponse lyfValidateResp = JsonUtil.fromJson(reqParam, ValidateLifecycleTestResponse.class);
88         if(!checkOperationSucess(lyfValidateResp))
89         {
90             return Response.status(Status.EXPECTATION_FAILED).build();
91         }
92
93         String funcTestResponse = FunctionTestExceutor.executeFunctionTest(reqParam);
94         if(null == funcTestResponse)
95         {
96             return Response.status(Status.EXPECTATION_FAILED).build();
97         }
98
99         JSONObject funcTestRspObject = JSONObject.fromObject(funcTestResponse);
100         if(!funcTestRspObject.get("status").equals(CommonConstant.SUCCESS_STR))
101         {
102             return Response.status(Status.EXPECTATION_FAILED).build();
103         }
104
105         JSONObject result = new JSONObject();
106         result.put("msg","SUCCESS");
107         return Response.ok(ToolUtil.objectToString(result), MediaType.APPLICATION_JSON).build();
108     }
109
110     private boolean checkOperationSucess(ValidateLifecycleTestResponse lyfValidateResp)
111     {
112         boolean bOperStatus = false;
113         if(null == lyfValidateResp)
114         {
115             LOG.error("ValidateLifecycleTestResponse  is NUll !!!");
116             return bOperStatus;
117         }
118         if(lyfValidateResp.getLifecycle_status().equalsIgnoreCase(CommonConstant.SUCCESS_STR)
119                 && lyfValidateResp.getValidate_status().equalsIgnoreCase(CommonConstant.SUCCESS_STR))
120         {
121             LOG.error("Lifecycle/Validation Response failed :" + lyfValidateResp.getLifecycle_status() + File.separator + lyfValidateResp.getValidate_status());
122             bOperStatus =  true;
123         }
124         return bOperStatus;
125     }
126
127     /**
128      * query package list by condition.
129      * @param name package name
130      * @param provider package provider
131      * @param version package version
132      * @param deletionPending package deletionPending
133      * @param type package type
134      * @return Response
135      */
136     public Response queryPackageListByCond(String name, String provider, String version,
137             String deletionPending, String type) {
138         List<PackageData> dbresult = new ArrayList<>();
139         List<PackageMeta> result = new ArrayList<>();
140         LOG.info("query package info.name:" + name + " provider:" + provider + " version" + version
141                 + " deletionPending" + deletionPending + " type:" + type);
142         try {
143             dbresult =
144                     PackageManager.getInstance().queryPackage(name, provider, version, deletionPending, type);
145             result = PackageWrapperUtil.packageDataList2PackageMetaList(dbresult);
146             return Response.ok(ToolUtil.objectToString(result)).build();
147         } catch (MarketplaceResourceException e1) {
148             LOG.error("query package by csarId from db error ! ", e1);
149             return RestUtil.getRestException(e1.getMessage());
150         }
151     }
152
153     /**
154      * query package by id.
155      * @param csarId package id
156      * @return Response
157      */
158     public Response queryPackageById(String csarId) {
159         PackageData dbResult = PackageWrapperUtil.getPackageInfoById(csarId);
160         PackageMeta result = PackageWrapperUtil.packageData2PackageMeta(dbResult);
161         return Response.ok(ToolUtil.objectToString(result)).build();
162     }
163
164     /**
165      * upload package.
166      * @param uploadedInputStream inputStream
167      * @param fileDetail package detail
168      * @param head http header
169      * @return Response
170      * @throws Exception e
171      */
172     public Response uploadPackage(InputStream uploadedInputStream,
173             FormDataContentDisposition fileDetail, String details, HttpHeaders head) throws MarketplaceResourceException
174     {
175         LOG.info("Upload/Reupload request Received !!!!");
176         try {
177             String packageId = MarketplaceDbUtil.generateId();
178             return handlePackageUpload(packageId,uploadedInputStream, fileDetail, details, head);
179         } catch (IOException e) {
180             LOG.error("can't get package id", e);
181         }
182         return Response.status(Status.INTERNAL_SERVER_ERROR).build();
183     }
184
185     /**
186      * Interface for Uploading package
187      * @param packageId
188      * @param uploadedInputStream
189      * @param fileDetail
190      * @param details
191      * @param head
192      * @return
193      * @throws IOException
194      * @throws MarketplaceResourceException
195      */
196     private Response handlePackageUpload(String packageId,InputStream uploadedInputStream, FormDataContentDisposition fileDetail,
197             String details, HttpHeaders head) throws IOException, MarketplaceResourceException
198     {
199         boolean bResult = handleDataValidate(packageId,uploadedInputStream,fileDetail);
200         if(!bResult)
201         {
202             LOG.error("Validation of Input received for Package Upload failed !!!");
203             return Response.status(Status.EXPECTATION_FAILED).build();
204         }
205
206         String fileName = "temp_"+ packageId + ".csar";
207         if (null != fileDetail)
208         {
209             LOG.info("the fileDetail = " + ToolUtil.objectToString(fileDetail));
210
211             fileName = ToolUtil.processFileName(fileDetail.getFileName());
212         }
213
214         String localDirName = ToolUtil.getTempDir(CommonConstant.CATALOG_CSAR_DIR_NAME, fileName);
215
216         String contentRange = null;
217         if (head != null)
218         {
219             contentRange = head.getHeaderString(CommonConstant.HTTP_HEADER_CONTENT_RANGE);
220         }
221         LOG.info("store package chunk file, fileName:" + fileName + ",contentRange:" + contentRange);
222         if (ToolUtil.isEmptyString(contentRange))
223         {
224             int fileSize = uploadedInputStream.available();
225             contentRange = "0-" + fileSize + "/" + fileSize;
226         }
227
228         String fileLocation = ToolUtil.storeChunkFileInLocal(localDirName, fileName, uploadedInputStream);
229         LOG.info("the fileLocation when upload package is :" + fileLocation);
230
231         uploadedInputStream.close();
232
233         PackageBasicInfo basicInfo = PackageWrapperUtil.getPacageBasicInfo(fileLocation);
234         UploadPackageResponse result = new UploadPackageResponse();
235         Boolean isEnd = PackageWrapperUtil.isUploadEnd(contentRange);
236         if (isEnd)
237         {
238             PackageMeta packageMeta = PackageWrapperUtil.getPackageMeta(packageId,fileName, fileLocation, basicInfo, details);
239             try {
240                 String path =  basicInfo.getType().toString() + File.separator + basicInfo.getProvider() + File.separator +  packageMeta.getCsarId() + File.separator + fileName.replace(".csar", "") + File.separator + basicInfo.getVersion();
241
242                 String dowloadUri = File.separator + path + File.separator;
243                 packageMeta.setDownloadUri(dowloadUri);
244
245                 LOG.info("dest path is : " + path);
246                 LOG.info("packageMeta = " + ToolUtil.objectToString(packageMeta));
247
248                 PackageData packageData = PackageWrapperUtil.getPackageData(packageMeta);
249
250                 String destPath = File.separator + path + File.separator + File.separator;
251                 boolean uploadResult = FileManagerFactory.createFileManager().upload(localDirName, destPath);
252                 if (uploadResult)
253                 {
254                     OnBoradingRequest oOnboradingRequest = new OnBoradingRequest();
255                     oOnboradingRequest.setCsarId(packageId);
256                     oOnboradingRequest.setPackageName(fileName);
257                     oOnboradingRequest.setPackagePath(localDirName);
258
259                     packageData.setCsarId(packageId);
260                     packageData.setDownloadCount(-1);
261                     PackageData packateDbData = PackageManager.getInstance().addPackage(packageData);
262
263                     LOG.info("Store package data to database succed ! packateDbData = "  + ToolUtil.objectToString(packateDbData));
264                     LOG.info("upload package file end, fileName:" + fileName);
265
266                     result.setCsarId(packateDbData.getCsarId());
267
268                     addOnBoardingRequest(oOnboradingRequest);
269
270                     LOG.info("OnboradingRequest Data : "  + ToolUtil.objectToString(oOnboradingRequest));
271                 }
272             } catch (NullPointerException e) {
273                 LOG.error("Package basicInfo is incorrect ! basicIonfo = " + ToolUtil.objectToString(basicInfo), e);
274                 return Response.serverError().build();
275             }
276         }
277         return Response.ok(ToolUtil.objectToString(result), MediaType.APPLICATION_JSON).build();
278     }
279
280     /**
281      * Execute OnBarding request
282      * @param oOnboradingRequest
283      */
284     private void addOnBoardingRequest(final OnBoradingRequest oOnboradingRequest)
285     {
286         ExecutorService es = Executors.newFixedThreadPool(CommonConstant.ONBOARDING_THREAD_COUNT);
287         Callable<Integer> callableInteger = () -> {
288             new OnBoardingHandler().handleOnBoardingReq(oOnboradingRequest);
289             return CommonConstant.SUCESS;
290         };
291         es.submit(callableInteger);
292     }
293
294     /**
295      * delete package by package id.
296      * @param csarId package id
297      * @return Response
298      */
299     public Response delPackage(String csarId) {
300         LOG.info("delete package  info.csarId:" + csarId);
301         if (ToolUtil.isEmptyString(csarId)) {
302             LOG.error("delete package  fail, csarid is null");
303             return Response.serverError().build();
304         }
305         deletePackageDataById(csarId);
306         return Response.ok().build();
307     }
308
309     /**
310      * Delete Package by CSAR ID
311      * @param csarId
312      */
313     private void  deletePackageDataById(String csarId) {
314         String packagePath = PackageWrapperUtil.getPackagePath(csarId);
315         if (packagePath == null) {
316             LOG.error("package path is null! ");
317         }
318
319         //Delete Package
320         FileManagerFactory.createFileManager().delete(packagePath);
321         //Delete Results Data
322         FileManagerFactory.createFileManager().delete(File.separator + csarId);
323
324
325         //delete package data from database
326         try {
327             PackageManager.getInstance().deletePackage(csarId);
328         } catch (MarketplaceResourceException e1) {
329             LOG.error("delete package  by csarId from db error ! " + e1.getMessage(), e1);
330         }
331     }
332
333     /**
334      * download package by package id.
335      * @param csarId package id
336      * @return Response
337      */
338     public Response downloadCsarPackagesById(String csarId) {
339         PackageData packageData = PackageWrapperUtil.getPackageInfoById(csarId);
340
341         String packageName = packageData.getName();
342         String path = org.onap.vnfsdk.marketplace.filemanage.http.ToolUtil.getHttpServerAbsolutePath() +File.separatorChar+packageData.getType()+File.separatorChar+
343                 packageData.getProvider()+File.separatorChar+ packageData.getCsarId() +File.separator +packageName+File.separatorChar+packageData.getVersion()
344                 +File.separator + packageName + ".csar";
345
346         LOG.info("downloadCsarPackagesById path is :  " + path);
347
348         File csarFile = new File(path);
349         if (!csarFile.exists()) {
350             return Response.status(Status.INTERNAL_SERVER_ERROR).build();
351         }
352
353         LOG.info("downloadCsarPackagesById ABS path is :  " + csarFile.getAbsolutePath());
354
355         try
356         {
357             InputStream fis = new BufferedInputStream(new FileInputStream(csarFile.getAbsolutePath()));
358             return Response.ok(fis)
359                     .header("Content-Disposition", "attachment; filename=\"" + csarFile.getName() + "\"")
360                     .build();
361         }
362         catch (Exception e1)
363         {
364             LOG.error("download vnf package fail.", e1);
365             return RestUtil.getRestException(e1.getMessage());
366         }
367     }
368
369     /**
370      * get package file uri.
371      * @param csarId package id
372      * @param relativePath file relative path
373      * @return Response
374      */
375     public Response getCsarFileUri(String csarId) {
376         return downloadCsarPackagesById(csarId);
377     }
378
379     /**
380      * Interface to Update Download count for CSAR ID
381      * @param csarId
382      * @return
383      */
384     public Response updateDwonloadCount(String csarId) {
385         return handleDownladCountUpdate(csarId) ?
386                 Response.ok().build() :
387                     Response.status(Status.EXPECTATION_FAILED).build();
388     }
389
390     /**
391      * Handle downlowa count update
392      * @param csarId
393      * @return
394      */
395     private boolean handleDownladCountUpdate(String csarId) {
396         boolean bupdateSucess = false;
397         try
398         {
399             PackageManager.getInstance().updateDwonloadCount(csarId);
400             bupdateSucess = true;
401         }
402         catch (Exception exp)
403         {
404             LOG.error("Updating Donwload count failed for Package with ID !!! : " + exp.getMessage(), exp);
405         }
406         return bupdateSucess;
407     }
408
409     /**
410      * Interface to Re upload Package
411      * @param csarId
412      * @param uploadedInputStream
413      * @param fileDetail
414      * @param details
415      * @param head
416      * @return
417      * @throws Exception
418      */
419     public Response reUploadPackage(String csarId,
420             InputStream uploadedInputStream,
421             FormDataContentDisposition fileDetail,
422             String details,
423             HttpHeaders head) throws MarketplaceResourceException
424     {
425         LOG.info("Reupload request Received !!!!");
426
427             //STEP 1: Validate Input Data
428             //----------------------------
429         boolean bResult = handleDataValidate(csarId,uploadedInputStream,fileDetail);
430         if(!bResult)
431         {
432             LOG.error("Validation of Input received for Package Upload failed during Reload!!!");
433             return Response.status(Status.EXPECTATION_FAILED).build();
434         }
435
436         try {
437             //STEP 2: Delete All Package Data based on package id
438             //----------------------------------------------------
439             deletePackageDataById(csarId);
440
441             //STEP 3: upload package with same package id
442             //-------------------------------------------
443             return handlePackageUpload(csarId,uploadedInputStream, fileDetail, details, head);
444         } catch (IOException e) {
445             LOG.error("delete package failed", e);
446         }
447         return Response.status(Status.INTERNAL_SERVER_ERROR).build();
448     }
449
450     /**
451      * Interface to get OnBoarding Result by Operation Type
452      * @param csarId
453      * @param operTypeId
454      * @param operId
455      * @return
456      */
457     public Response getOnBoardingResult(String csarId, String operTypeId, String operId)
458     {
459         LOG.info("getOnBoardingResult request : csarId:" + csarId + " operTypeId:" + operTypeId + " operId:" + operId);
460         try {
461             PackageData packageData = PackageWrapperUtil.getPackageInfoById(csarId);
462             if (null == packageData) {
463                 return Response.status(Response.Status.PRECONDITION_FAILED).build();
464             }
465
466             handleDelayExec(operId);
467
468             OnBoardingResult oOnBoardingResult = FunctionTestHook.getOnBoardingResult(packageData);
469             if (null == oOnBoardingResult) {
470                 return Response.status(Response.Status.PRECONDITION_FAILED).build();
471             }
472             filterOnBoardingResultByOperId(oOnBoardingResult, operId);
473
474             String strResult = ToolUtil.objectToString(oOnBoardingResult);
475             LOG.info("getOnBoardingResult response : " + strResult);
476             return Response.ok(strResult, "application/json").build();
477         } catch (NullPointerException e) {
478             LOG.error("Null param in getOnBoardingResult", e);
479             return Response.status(Response.Status.BAD_REQUEST).build();
480         }
481     }
482
483
484     private void filterOnBoardingResultByOperId(OnBoardingResult oOnBoardingResult, String operId)
485     {
486         if (0 == operId.compareToIgnoreCase("all")) {
487             return;
488         }
489         if (0 == operId.compareToIgnoreCase("download"))
490         {
491             List<OnBoardingOperResult> operResultListTemp = new ArrayList<>();
492             OnBoardingOperResult operResultListTmp = new OnBoardingOperResult();
493             operResultListTmp.setOperId("download");
494             operResultListTmp.setStatus(0);
495             operResultListTemp.add(operResultListTmp);
496             oOnBoardingResult.setOperResult(operResultListTemp);
497             return;
498         }
499         List<OnBoardingOperResult> operResultListOut = new ArrayList<>();
500         List<OnBoardingOperResult> operResultList = oOnBoardingResult.getOperResult();
501         for (OnBoardingOperResult operResult : operResultList) {
502             if (0 == operResult.getOperId().compareToIgnoreCase(operId)) {
503                 operResultListOut.add(operResult);
504             }
505         }
506         oOnBoardingResult.setOperResult(operResultListOut);
507     }
508
509     /**
510      * Interface to get OnBoarding Status by Operation ID
511      * @param csarId
512      * @param operTypeId
513      * @return
514      */
515     public Response getOperResultByOperTypeId(String csarId, String operTypeId)
516     {
517         LOG.error("getOnBoardingResult request : csarId:"+ csarId + " operTypeId:"+operTypeId);
518         if(null == csarId || null == operTypeId || csarId.isEmpty()  || operTypeId.isEmpty())
519         {
520             return Response.status(Status.BAD_REQUEST).build();
521         }
522
523         PackageData packageData = PackageWrapperUtil.getPackageInfoById(csarId);
524         if(null == packageData)
525         {
526             LOG.error("Failed to find package for PackageID:"+ csarId);
527             return Response.status(Status.PRECONDITION_FAILED).build();
528         }
529
530         //Get result key to fetch Function Test Results
531         //---------------------------------------------
532         String strResult = FunctionTestHook.getFuncTestResults(packageData);
533         if(null == strResult)
534         {
535             LOG.error("NULL reponse for getOperResultByOperTypeId response :"+ strResult);
536             return Response.status(Status.INTERNAL_SERVER_ERROR).build();
537         }
538         LOG.info("getOperResultByOperTypeId response :"+ strResult);
539         return Response.ok(strResult, MediaType.APPLICATION_JSON).build();
540     }
541
542     private boolean handleDataValidate(String packageId,InputStream uploadedInputStream, FormDataContentDisposition fileDetail)
543     {
544         boolean bvalidateOk = false;
545         if ((null != uploadedInputStream) && (fileDetail != null) && !ToolUtil.isEmptyString(packageId))
546         {
547             bvalidateOk = true;
548         }
549         return bvalidateOk;
550     }
551
552     /**
553      * Interface to get OnBoarding Steps
554      * @return
555      */
556     public Response getOnBoardingSteps()
557     {
558         LOG.info("Get OnBoarding Steps request Received !!!");
559
560         String filePath = org.onap.vnfsdk.marketplace.filemanage.http.ToolUtil.getAppDeployPath() + File.separator +"generalconfig/OnBoardingSteps.json";
561         LOG.info("Onboarding Steps Json file Path  :" + filePath);
562
563         OnBoardingSteps oOnBoardingSteps = (OnBoardingSteps)FileUtil.readJsonDatafFromFile(filePath, OnBoardingSteps.class);
564         if (null == oOnBoardingSteps) {
565             return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
566         }
567         String strResult = ToolUtil.objectToString(oOnBoardingSteps);
568         LOG.info("getOnBoardingSteps response :" + strResult);
569         return Response.ok(strResult, MediaType.APPLICATION_JSON).build();
570     }
571
572     private void handleDelayExec(String operId)
573     {
574         if (0 == operId.compareToIgnoreCase(CommonConstant.functionTest.FUNCTEST_EXEC))
575         {
576             try
577             {
578                 Thread.sleep(8000);
579             }
580             catch (InterruptedException e)
581             {
582                 LOG.info("handleDelayExex response : ", e);
583                 Thread.currentThread().interrupt();
584             }
585         }
586     }
587 }
588