c38bf8a0ec77b40da216102d2a890dcb9c99a8a1
[sdc.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdcrests.vsp.rest.services;
22
23 import org.openecomp.sdc.common.errors.CoreException;
24 import org.openecomp.sdc.common.errors.ErrorCode;
25 import org.openecomp.sdc.datatypes.error.ErrorLevel;
26 import org.openecomp.sdc.datatypes.error.ErrorMessage;
27 import org.openecomp.sdc.logging.api.Logger;
28 import org.openecomp.sdc.logging.api.LoggerFactory;
29 import org.openecomp.sdc.logging.context.MdcUtil;
30 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
31 import org.openecomp.sdc.logging.messages.AuditMessages;
32 import org.openecomp.sdc.logging.types.LoggerConstants;
33 import org.openecomp.sdc.logging.types.LoggerErrorCode;
34 import org.openecomp.sdc.logging.types.LoggerServiceName;
35 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
36 import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductManager;
37 import org.openecomp.sdc.vendorsoftwareproduct.VspManagerFactory;
38 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.ComputeEntity;
39 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.PackageInfo;
40 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspDetails;
41 import org.openecomp.sdc.vendorsoftwareproduct.errors.OnboardingMethodErrorBuilder;
42 import org.openecomp.sdc.vendorsoftwareproduct.types.QuestionnaireResponse;
43 import org.openecomp.sdc.vendorsoftwareproduct.types.ValidationResponse;
44 import org.openecomp.sdc.vendorsoftwareproduct.types.VersionedVendorSoftwareProductInfo;
45 import org.openecomp.sdc.versioning.dao.types.Version;
46 import org.openecomp.sdc.versioning.dao.types.VersionStatus;
47 import org.openecomp.sdc.versioning.types.VersionInfo;
48 import org.openecomp.sdc.versioning.types.VersionableEntityAction;
49 import org.openecomp.sdcrests.vendorsoftwareproducts.types.*;
50 import org.openecomp.sdcrests.vsp.rest.VendorSoftwareProducts;
51 import org.openecomp.sdcrests.vsp.rest.mapping.*;
52 import org.openecomp.sdcrests.wrappers.GenericCollectionWrapper;
53 import org.openecomp.sdcrests.wrappers.StringWrapperResponse;
54 import org.slf4j.MDC;
55 import org.springframework.context.annotation.Scope;
56 import org.springframework.stereotype.Service;
57
58 import javax.inject.Named;
59 import javax.ws.rs.core.Response;
60 import java.io.File;
61 import java.io.IOException;
62 import java.util.Collection;
63 import java.util.List;
64 import java.util.Objects;
65 import java.util.stream.Collectors;
66
67 import static org.openecomp.sdc.logging.messages.AuditMessages.SUBMIT_VSP_ERROR;
68
69
70 @Named
71 @Service("vendorSoftwareProducts")
72 @Scope(value = "prototype")
73 public class VendorSoftwareProductsImpl implements VendorSoftwareProducts {
74
75   private final VendorSoftwareProductManager vendorSoftwareProductManager =
76       VspManagerFactory.getInstance().createInterface();
77
78   private static final Logger logger =
79       LoggerFactory.getLogger(VendorSoftwareProductsImpl.class);
80
81   @Override
82   public Response createVsp(VspDescriptionDto vspDescriptionDto, String user) {
83     MdcUtil.initMdc(LoggerServiceName.Create_VSP.toString());
84     logger.audit(AuditMessages.AUDIT_MSG + AuditMessages.CREATE_VSP
85         + vspDescriptionDto.getName());
86
87     OnboardingMethod onboardingMethod;
88
89     try {
90       onboardingMethod = OnboardingMethod.valueOf(vspDescriptionDto.getOnboardingMethod());
91     } catch (IllegalArgumentException e) {
92       return handleUnknownOnboardingMethod();
93     }
94
95     switch (onboardingMethod) {
96       case NetworkPackage:
97       case Manual:
98         VspDetails vspDetails = new MapVspDescriptionDtoToVspDetails().
99             applyMapping(vspDescriptionDto, VspDetails.class);
100
101         vspDetails = vendorSoftwareProductManager.createVsp(vspDetails, user);
102
103         MapVspDetailsToVspCreationDto mapping = new MapVspDetailsToVspCreationDto();
104         VspCreationDto vspCreationDto = mapping.applyMapping(vspDetails, VspCreationDto.class);
105         return Response.ok(vspCreationDto).build();
106       default:
107         return handleUnknownOnboardingMethod();
108     }
109   }
110
111   private Response handleUnknownOnboardingMethod() {
112     ErrorCode onboardingMethodUpdateErrorCode = OnboardingMethodErrorBuilder
113         .getInvalidOnboardingMethodErrorBuilder();
114     MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_API,
115         LoggerTragetServiceName.ADD_VSP, ErrorLevel.ERROR.name(),
116         LoggerErrorCode.DATA_ERROR.getErrorCode(), onboardingMethodUpdateErrorCode.message());
117     throw new CoreException(onboardingMethodUpdateErrorCode);
118   }
119
120   @Override
121   public Response listVsps(String versionFilter, String user) {
122     MdcUtil.initMdc(LoggerServiceName.List_VSP.toString());
123     List<VersionedVendorSoftwareProductInfo> vspList =
124         vendorSoftwareProductManager.listVsps(versionFilter, user);
125
126     GenericCollectionWrapper<VspDetailsDto> results = new GenericCollectionWrapper<>();
127     if (!vspList.isEmpty()) {
128       MapVersionedVendorSoftwareProductInfoToVspDetailsDto mapper =
129           new MapVersionedVendorSoftwareProductInfoToVspDetailsDto();
130       for (VersionedVendorSoftwareProductInfo versionedVsp : vspList) {
131         results.add(mapper.applyMapping(versionedVsp, VspDetailsDto.class));
132       }
133     }
134
135     return Response.ok(results).build();
136   }
137
138   @Override
139   public Response getVsp(String vspId, String versionId, String user) {
140     MdcUtil.initMdc(LoggerServiceName.Get_VSP.toString());
141
142
143     VspDetails vspDetails =
144         vendorSoftwareProductManager
145             .getVsp(vspId, resolveVspVersion(vspId, versionId, user, VersionableEntityAction.Read),
146                 user);
147
148     VersionInfo versionInfo = getVersionInfo(vspId, VersionableEntityAction.Read, user);
149
150
151     if (vspDetails.getOldVersion() != null && !"".equals(vspDetails.getOldVersion())) {
152       if (Version.valueOf(versionId).equals(versionInfo.getActiveVersion())) {
153         try {
154           Version healedVersion = vendorSoftwareProductManager.callAutoHeal(vspId, versionInfo,
155               vspDetails, user);
156           vspDetails =
157               vendorSoftwareProductManager
158                   .getVsp(vspId, resolveVspVersion(vspId, healedVersion.toString(), user,
159                       VersionableEntityAction.Read), user);
160           versionInfo = getVersionInfo(vspId, VersionableEntityAction.Read, user);
161         } catch (Exception e) {
162           logger.error(e.getMessage(), e);
163         }
164       }
165     }
166
167     VspDetailsDto vspDetailsDto = vspDetails == null
168         ? null
169         : new MapVersionedVendorSoftwareProductInfoToVspDetailsDto()
170             .applyMapping(new VersionedVendorSoftwareProductInfo(vspDetails, versionInfo),
171                 VspDetailsDto.class);
172
173     return Response.ok(vspDetailsDto).build();
174   }
175
176   @Override
177   public Response updateVsp(String vspId, String versionId, VspDescriptionDto vspDescriptionDto,
178                             String user) {
179     MdcUtil.initMdc(LoggerServiceName.Update_VSP.toString());
180     VspDetails vspDetails =
181         new MapVspDescriptionDtoToVspDetails().applyMapping(vspDescriptionDto, VspDetails.class);
182     vspDetails.setId(vspId);
183     vspDetails.setVersion(resolveVspVersion(vspId, null, user, VersionableEntityAction.Write));
184
185     vendorSoftwareProductManager.updateVsp(vspDetails, user);
186
187     return Response.ok().build();
188   }
189
190   @Override
191   public Response deleteVsp(String vspId, String user) {
192     MdcUtil.initMdc(LoggerServiceName.Delete_VSP.toString());
193     vendorSoftwareProductManager.deleteVsp(vspId, user);
194
195     return Response.ok().build();
196   }
197
198   @Override
199   public Response actOnVendorSoftwareProduct(String vspId, String versionId,
200                                              VersionSoftwareProductActionRequestDto request,
201                                              String user) throws IOException {
202
203     switch (request.getAction()) {
204       case Checkout:
205         MDC.put(LoggerConstants.SERVICE_NAME, LoggerServiceName.Checkout_VSP.toString());
206         vendorSoftwareProductManager.checkout(vspId, user);
207         logger.audit(AuditMessages.AUDIT_MSG + AuditMessages.CHECK_OUT_VSP + vspId);
208         break;
209       case Undo_Checkout:
210         MDC.put(LoggerConstants.SERVICE_NAME, LoggerServiceName.Undo_Checkout_VSP.toString());
211         vendorSoftwareProductManager.undoCheckout(vspId, user);
212         break;
213       case Checkin:
214         MDC.put(LoggerConstants.SERVICE_NAME, LoggerServiceName.Checkin_VSP.toString());
215         vendorSoftwareProductManager.checkin(vspId, user);
216         logger.audit(AuditMessages.AUDIT_MSG + AuditMessages.CHECK_IN_VSP + vspId);
217         break;
218       case Submit:
219         MDC.put(LoggerConstants.SERVICE_NAME, LoggerServiceName.Submit_VSP.toString());
220         ValidationResponse validationResponse = vendorSoftwareProductManager.submit(vspId, user);
221         if (!validationResponse.isValid()) {
222           logger.audit(AuditMessages.AUDIT_MSG + AuditMessages.SUBMIT_VSP_FAIL + vspId);
223           if (validationResponse.getVspErrors() != null) {
224             validationResponse.getVspErrors().forEach(errorCode -> logger.audit(AuditMessages
225                 .AUDIT_MSG + String.format(SUBMIT_VSP_ERROR, errorCode.message(), vspId)));
226           }
227           if (validationResponse.getUploadDataErrors() != null) {
228             validationResponse.getUploadDataErrors().values().forEach(errorMessages
229                 -> printAuditForErrors(errorMessages, vspId, SUBMIT_VSP_ERROR));
230           }
231
232           return Response.status(Response.Status.EXPECTATION_FAILED).entity(
233               new MapValidationResponseToDto()
234                   .applyMapping(validationResponse, ValidationResponseDto.class)).build();
235         }
236         logger.audit(AuditMessages.AUDIT_MSG + AuditMessages.SUBMIT_VSP + vspId);
237         break;
238       case Create_Package:
239         MDC.put(LoggerConstants.SERVICE_NAME, LoggerServiceName.Create_Package.toString());
240
241         PackageInfo packageInfo = vendorSoftwareProductManager.createPackage(vspId,
242             resolveVspVersion(vspId, null, user, VersionableEntityAction.Read), user);
243         return Response.ok(packageInfo == null
244             ? null
245             : new MapPackageInfoToPackageInfoDto().applyMapping(packageInfo, PackageInfoDto.class))
246             .build();
247       default:
248     }
249
250     return Response.ok().build();
251   }
252
253   @Override
254   public Response getValidationVsp(String user)
255       throws Exception {
256     String validationVspId = vendorSoftwareProductManager.fetchValidationVsp(user);
257     StringWrapperResponse response = new StringWrapperResponse(validationVspId);
258     return Response.ok(response).build();
259   }
260
261
262   @Override
263   public Response getOrchestrationTemplate(String vspId, String versionId, String user) {
264     MdcUtil.initMdc(LoggerServiceName.Get_Uploaded_File.toString());
265     byte[] orchestrationTemplateFile =
266         vendorSoftwareProductManager
267             .getOrchestrationTemplateFile(vspId,
268                 resolveVspVersion(vspId, versionId, user, VersionableEntityAction.Read), user);
269
270     if (orchestrationTemplateFile == null) {
271       return Response.status(Response.Status.NOT_FOUND).build();
272     }
273     Response.ResponseBuilder response = Response.ok(orchestrationTemplateFile);
274     response.header("Content-Disposition", "attachment; filename=LatestHeatPackage.zip");
275     return response.build();
276   }
277
278   @Override
279   public Response listPackages(String category, String subCategory, String user) {
280     MdcUtil.initMdc(LoggerServiceName.List_Packages.toString());
281     List<PackageInfo> packageInfoList =
282         vendorSoftwareProductManager.listPackages(category, subCategory);
283
284     GenericCollectionWrapper<PackageInfoDto> results = new GenericCollectionWrapper<>();
285     MapPackageInfoToPackageInfoDto mapper = new MapPackageInfoToPackageInfoDto();
286
287     if (packageInfoList != null) {
288       for (PackageInfo packageInfo : packageInfoList) {
289         results.add(mapper.applyMapping(packageInfo, PackageInfoDto.class));
290       }
291     }
292     return Response.ok(results).build();
293   }
294
295   @Override
296   public Response getTranslatedFile(String vspId, String versionId, String user) {
297     MdcUtil.initMdc(LoggerServiceName.Get_Translated_File.toString());
298
299     Version version = Version.valueOf(versionId);
300     Version resolvedVersion = version == null
301         ? getVersionInfo(vspId, VersionableEntityAction.Read, user).getLatestFinalVersion()
302         : version;
303
304     File zipFile = vendorSoftwareProductManager.getTranslatedFile(vspId, resolvedVersion, user);
305
306     Response.ResponseBuilder response = Response.ok(zipFile);
307     if (zipFile == null) {
308       logger.audit(AuditMessages.AUDIT_MSG + AuditMessages.IMPORT_FAIL + vspId);
309       return Response.status(Response.Status.NOT_FOUND).build();
310     }
311     response.header("Content-Disposition", "attachment; filename=" + zipFile.getName());
312
313     logger.audit(AuditMessages.AUDIT_MSG + AuditMessages.IMPORT_SUCCESS + vspId);
314     return response.build();
315   }
316
317   @Override
318   public Response getQuestionnaire(String vspId, String versionId, String user) {
319     MdcUtil.initMdc(LoggerServiceName.Get_Questionnaire_VSP.toString());
320     QuestionnaireResponse questionnaireResponse =
321         vendorSoftwareProductManager.getVspQuestionnaire(vspId,
322             resolveVspVersion(vspId, versionId, user, VersionableEntityAction.Read), user);
323
324     if (questionnaireResponse.getErrorMessage() != null) {
325       return Response.status(Response.Status.EXPECTATION_FAILED).entity(
326           new MapQuestionnaireResponseToQuestionnaireResponseDto()
327               .applyMapping(questionnaireResponse, QuestionnaireResponseDto.class)).build();
328     }
329
330     QuestionnaireResponseDto result = new MapQuestionnaireResponseToQuestionnaireResponseDto()
331         .applyMapping(questionnaireResponse, QuestionnaireResponseDto.class);
332     return Response.ok(result).build();
333   }
334
335   @Override
336   public Response updateQuestionnaire(String questionnaireData, String vspId, String
337       versionId, String user) {
338     MdcUtil.initMdc(LoggerServiceName.Update_Questionnaire_VSP.toString());
339     vendorSoftwareProductManager.updateVspQuestionnaire(vspId,
340         resolveVspVersion(vspId, null, user, VersionableEntityAction.Write),
341         questionnaireData, user);
342     return Response.ok().build();
343   }
344
345   @Override
346   public Response heal(String vspId, String versionId, String user) {
347     vendorSoftwareProductManager.heal(vspId, Version.valueOf(versionId), user);
348
349     return Response.ok().build();
350   }
351
352   @Override
353   public Response getVspInformationArtifact(String vspId, String versionId, String user) {
354     MdcUtil.initMdc(LoggerServiceName.Get_Information_Artifact.toString());
355     File textInformationArtifact =
356         vendorSoftwareProductManager.getInformationArtifact(vspId,
357             resolveVspVersion(vspId, versionId, user, VersionableEntityAction.Read), user);
358
359     Response.ResponseBuilder response = Response.ok(textInformationArtifact);
360     if (textInformationArtifact == null) {
361       return Response.status(Response.Status.NOT_FOUND).build();
362     }
363     response
364         .header("Content-Disposition", "attachment; filename=" + textInformationArtifact.getName());
365     return response.build();
366   }
367
368   public Response listCompute(String vspId, String version, String user) {
369
370     Collection<ComputeEntity> computes = vendorSoftwareProductManager.getComputeByVsp(vspId,
371         resolveVspVersion(vspId, version, user, VersionableEntityAction.Read), user);
372
373     MapComputeEntityToVspComputeDto mapper = new MapComputeEntityToVspComputeDto();
374     GenericCollectionWrapper<VspComputeDto> results = new GenericCollectionWrapper<>();
375     for (ComputeEntity compute : computes) {
376       results.add(mapper.applyMapping(compute, VspComputeDto.class));
377     }
378
379     return Response.ok(results).build();
380   }
381
382   @Override
383   public Response reSubmitAll(String user) throws IOException {
384
385     MDC.put(LoggerConstants.SERVICE_NAME, LoggerServiceName.Re_Submit_ALL_Final_VSPs.toString());
386     logger.audit(AuditMessages.AUDIT_MSG + AuditMessages.RESUBMIT_ALL_FINAL_VSPS);
387
388     List<VersionedVendorSoftwareProductInfo> latestFinalVsps = Objects
389         .requireNonNull(vendorSoftwareProductManager.listVsps(VersionStatus.Final.name(), user));
390
391     List<VersionedVendorSoftwareProductInfo> nonLockedLatestFinalVsps = latestFinalVsps.stream()
392         .filter(vsp ->
393             !isVspLocked(vsp.getVspDetails().getId(), vsp.getVspDetails().getName(), user))
394         .collect(Collectors.toList());
395
396     logger.info("Removed {} VSPs out of {} from processing due to status LOCKED.\n" +
397             "Total number of VSPs: {}. Performing healing and resubmit for all non-Manual VSPs " +
398             "in submitted status.\n No need to pre-set oldVersion field",
399         latestFinalVsps.size() - nonLockedLatestFinalVsps.size(), latestFinalVsps.size(),
400         nonLockedLatestFinalVsps.size());
401
402     int healingCounter = 0;
403     int failedCounter = 0;
404     for (int counter = 0; counter < nonLockedLatestFinalVsps.size(); counter++) {
405       VersionedVendorSoftwareProductInfo versionVspInfo = nonLockedLatestFinalVsps.get(counter);
406       try {
407         final VspDetails vspDetails = versionVspInfo.getVspDetails();
408         if (!OnboardingMethod.Manual.name().equals(vspDetails.getOnboardingMethod())) {
409           logger.info("Starting on healing and resubmit for VSP [{}], #{} out of total {}",
410               vspDetails.getName(), counter + 1, nonLockedLatestFinalVsps.size());
411           reSubmit(vspDetails, user);
412           healingCounter++;
413         }
414       } catch (Exception e) {
415         failedCounter++;
416       }
417     }
418
419     logger.info("Total VSPs processed {}. Completed running healing and resubmit for {} VSPs out" +
420             " of total # of {} submitted VSPs.  Failures count during resubmitAll: {}",
421         nonLockedLatestFinalVsps.size(), healingCounter, latestFinalVsps.size(), failedCounter);
422
423     return Response.ok().build();
424   }
425
426   private boolean isVspLocked(String vspId, String vspName, String user) {
427     final VersionInfo versionInfo = getVersionInfo(vspId, VersionableEntityAction.Read, user);
428
429     if (versionInfo.getStatus().equals(VersionStatus.Locked)) {
430       logger.info("VSP name [{}]/id [{}] status is LOCKED", vspName, vspId);
431       return true;
432     }
433     logger.info("VSP Name {}, VSP id [{}], Active Version {} , Status {}, Latest Final Version {}",
434         vspName, vspId, versionInfo.getActiveVersion().toString(), versionInfo.getStatus(),
435         versionInfo.getLatestFinalVersion().toString());
436     return false;
437   }
438
439
440   private void reSubmit(VspDetails vspDetails, String user) throws Exception {
441     final Version versionBefore = vspDetails.getVersion();
442     vspDetails.setOldVersion("true");
443
444     Version finalVersion;
445     try {
446       finalVersion =
447           vendorSoftwareProductManager
448               .healAndAdvanceFinalVersion(vspDetails.getId(), vspDetails, user);
449     } catch (Exception e) {
450       logger.error("Failed during resubmit, VSP [{}] , version before:{}, version after:{}, " +
451               "status after:{}, with exception:{}",
452           vspDetails.getName(), versionBefore.toString(), vspDetails.getVersion().toString(),
453           vspDetails
454               .getVersion().getStatus().name(), e.getMessage());
455       throw e;
456     }
457
458     logger.info("Completed healing and resubmit for VSP [{}], version before:{}, version after:" +
459         " {}", vspDetails.getName(), versionBefore.toString(), finalVersion);
460   }
461
462   private static void printAuditForErrors(List<ErrorMessage> errorList, String vspId,
463                                           String auditType) {
464     errorList.forEach(errorMessage -> {
465       if (errorMessage.getLevel().equals(ErrorLevel.ERROR)) {
466         logger.audit(AuditMessages.AUDIT_MSG + String.format(auditType, errorMessage.getMessage(),
467             vspId));
468       }
469     });
470   }
471 }