cc24873e924dd4ba49c882002ca7e6c7fd9eaeb5
[sdc.git] /
1 /*
2  * Copyright © 2016-2018 European Support Limited
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
17 package org.openecomp.sdc.vendorsoftwareproduct.impl;
18
19 import org.apache.commons.collections4.CollectionUtils;
20 import org.apache.commons.collections4.MapUtils;
21 import org.openecomp.core.enrichment.api.EnrichmentManager;
22 import org.openecomp.core.enrichment.factory.EnrichmentManagerFactory;
23 import org.openecomp.core.model.dao.EnrichedServiceModelDao;
24 import org.openecomp.core.model.dao.ServiceModelDao;
25 import org.openecomp.core.model.types.ServiceElement;
26 import org.openecomp.core.util.UniqueValueUtil;
27 import org.openecomp.core.utilities.file.FileContentHandler;
28 import org.openecomp.core.utilities.json.JsonSchemaDataGenerator;
29 import org.openecomp.core.utilities.json.JsonUtil;
30 import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
31 import org.openecomp.core.validation.api.ValidationManager;
32 import org.openecomp.core.validation.util.MessageContainerUtil;
33 import org.openecomp.sdc.common.errors.CoreException;
34 import org.openecomp.sdc.common.errors.ErrorCode;
35 import org.openecomp.sdc.common.errors.ValidationErrorBuilder;
36 import org.openecomp.sdc.common.utils.CommonUtil;
37 import org.openecomp.sdc.datatypes.error.ErrorLevel;
38 import org.openecomp.sdc.datatypes.error.ErrorMessage;
39 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
40 import org.openecomp.sdc.tosca.services.impl.ToscaFileOutputServiceCsarImpl;
41 import org.openecomp.sdc.validation.util.ValidationManagerUtil;
42 import org.openecomp.sdc.vendorlicense.facade.VendorLicenseFacade;
43 import org.openecomp.sdc.vendorlicense.licenseartifacts.VendorLicenseArtifactsService;
44 import org.openecomp.sdc.vendorsoftwareproduct.CompositionEntityDataManager;
45 import org.openecomp.sdc.vendorsoftwareproduct.CompositionEntityDataManagerFactory;
46 import org.openecomp.sdc.vendorsoftwareproduct.ManualVspToscaManager;
47 import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManager;
48 import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductConstants;
49 import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductManager;
50 import org.openecomp.sdc.vendorsoftwareproduct.dao.ComponentDao;
51 import org.openecomp.sdc.vendorsoftwareproduct.dao.ComponentDependencyModelDao;
52 import org.openecomp.sdc.vendorsoftwareproduct.dao.ComputeDao;
53 import org.openecomp.sdc.vendorsoftwareproduct.dao.DeploymentFlavorDao;
54 import org.openecomp.sdc.vendorsoftwareproduct.dao.ImageDao;
55 import org.openecomp.sdc.vendorsoftwareproduct.dao.NicDao;
56 import org.openecomp.sdc.vendorsoftwareproduct.dao.OrchestrationTemplateDao;
57 import org.openecomp.sdc.vendorsoftwareproduct.dao.PackageInfoDao;
58 import org.openecomp.sdc.vendorsoftwareproduct.dao.VendorSoftwareProductInfoDao;
59 import org.openecomp.sdc.vendorsoftwareproduct.dao.errors.VendorSoftwareProductNotFoundErrorBuilder;
60 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.ComponentDependencyModelEntity;
61 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.ComponentEntity;
62 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.ComputeEntity;
63 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.DeploymentFlavorEntity;
64 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.ImageEntity;
65 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.NicEntity;
66 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.OnboardingMethod;
67 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.OrchestrationTemplateCandidateData;
68 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.OrchestrationTemplateEntity;
69 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.PackageInfo;
70 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspDetails;
71 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspQuestionnaireEntity;
72 import org.openecomp.sdc.vendorsoftwareproduct.errors.ComponentDependencyModelErrorBuilder;
73 import org.openecomp.sdc.vendorsoftwareproduct.errors.ComponentErrorBuilder;
74 import org.openecomp.sdc.vendorsoftwareproduct.errors.DeploymentFlavorErrorBuilder;
75 import org.openecomp.sdc.vendorsoftwareproduct.errors.FileCreationErrorBuilder;
76 import org.openecomp.sdc.vendorsoftwareproduct.errors.InformationArtifactCreationErrorBuilder;
77 import org.openecomp.sdc.vendorsoftwareproduct.errors.NicInternalNetworkErrorBuilder;
78 import org.openecomp.sdc.vendorsoftwareproduct.errors.PackageInvalidErrorBuilder;
79 import org.openecomp.sdc.vendorsoftwareproduct.errors.PackageNotFoundErrorBuilder;
80 import org.openecomp.sdc.vendorsoftwareproduct.errors.TranslationFileCreationErrorBuilder;
81 import org.openecomp.sdc.vendorsoftwareproduct.errors.VendorSoftwareProductInvalidErrorBuilder;
82 import org.openecomp.sdc.vendorsoftwareproduct.informationArtifact.InformationArtifactGenerator;
83 import org.openecomp.sdc.vendorsoftwareproduct.services.schemagenerator.SchemaGenerator;
84 import org.openecomp.sdc.vendorsoftwareproduct.types.QuestionnaireResponse;
85 import org.openecomp.sdc.vendorsoftwareproduct.types.QuestionnaireValidationResult;
86 import org.openecomp.sdc.vendorsoftwareproduct.types.ValidationResponse;
87 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.FilesDataStructure;
88 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.ComponentComputeAssociation;
89 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.CompositionEntityId;
90 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.CompositionEntityType;
91 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.CompositionEntityValidationData;
92 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.DeploymentFlavor;
93 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.NetworkType;
94 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.Nic;
95 import org.openecomp.sdc.vendorsoftwareproduct.types.schemagenerator.ComponentQuestionnaireSchemaInput;
96 import org.openecomp.sdc.vendorsoftwareproduct.types.schemagenerator.SchemaTemplateContext;
97 import org.openecomp.sdc.vendorsoftwareproduct.types.schemagenerator.SchemaTemplateInput;
98 import org.openecomp.sdc.vendorsoftwareproduct.utils.ComponentDependencyTracker;
99 import org.openecomp.sdc.versioning.VersioningManager;
100 import org.openecomp.sdc.versioning.VersioningManagerFactory;
101 import org.openecomp.sdc.versioning.VersioningUtil;
102 import org.openecomp.sdc.versioning.dao.types.Version;
103
104 import java.io.BufferedOutputStream;
105 import java.io.ByteArrayInputStream;
106 import java.io.ByteArrayOutputStream;
107 import java.io.File;
108 import java.io.FileOutputStream;
109 import java.io.IOException;
110 import java.io.OutputStream;
111 import java.nio.ByteBuffer;
112 import java.util.ArrayList;
113 import java.util.Collection;
114 import java.util.Collections;
115 import java.util.HashMap;
116 import java.util.HashSet;
117 import java.util.List;
118 import java.util.Map;
119 import java.util.Objects;
120 import java.util.Optional;
121 import java.util.Set;
122 import java.util.zip.ZipInputStream;
123 import java.util.zip.ZipOutputStream;
124
125 public class VendorSoftwareProductManagerImpl implements VendorSoftwareProductManager {
126
127   private final OrchestrationTemplateDao orchestrationTemplateDao;
128   private final OrchestrationTemplateCandidateManager orchestrationTemplateCandidateManager;
129   private final VendorSoftwareProductInfoDao vspInfoDao;
130   private final VendorLicenseFacade vendorLicenseFacade;
131   private final ServiceModelDao<ToscaServiceModel, ServiceElement> serviceModelDao;
132   private final EnrichedServiceModelDao<ToscaServiceModel, ServiceElement> enrichedServiceModelDao;
133   private final VendorLicenseArtifactsService licenseArtifactsService;
134   private final InformationArtifactGenerator informationArtifactGenerator;
135   private final PackageInfoDao packageInfoDao;
136   private final DeploymentFlavorDao deploymentFlavorDao;
137   private final ComponentDao componentDao;
138   private final ComponentDependencyModelDao componentDependencyModelDao;
139   private final NicDao nicDao;
140   private final ComputeDao computeDao;
141   private final ImageDao imageDao;
142   private final ManualVspToscaManager manualVspToscaManager;
143
144   public VendorSoftwareProductManagerImpl(
145       OrchestrationTemplateDao orchestrationTemplateDataDao,
146       OrchestrationTemplateCandidateManager orchestrationTemplateCandidateManager,
147       VendorSoftwareProductInfoDao vspInfoDao,
148       VendorLicenseFacade vendorLicenseFacade,
149       ServiceModelDao<ToscaServiceModel, ServiceElement> serviceModelDao,
150       EnrichedServiceModelDao<ToscaServiceModel, ServiceElement> enrichedServiceModelDao,
151       VendorLicenseArtifactsService licenseArtifactsService,
152       InformationArtifactGenerator informationArtifactGenerator,
153       PackageInfoDao packageInfoDao,
154       DeploymentFlavorDao deploymentFlavorDao,
155       ComponentDao componentDao,
156       ComponentDependencyModelDao componentDependencyModelDao,
157       NicDao nicDao,
158       ComputeDao computeDao,
159       ImageDao imageDao,
160       ManualVspToscaManager manualVspToscaManager) {
161     this.orchestrationTemplateDao = orchestrationTemplateDataDao;
162     this.orchestrationTemplateCandidateManager = orchestrationTemplateCandidateManager;
163     this.vspInfoDao = vspInfoDao;
164     this.vendorLicenseFacade = vendorLicenseFacade;
165     this.serviceModelDao = serviceModelDao;
166     this.enrichedServiceModelDao = enrichedServiceModelDao;
167     this.licenseArtifactsService = licenseArtifactsService;
168     this.informationArtifactGenerator = informationArtifactGenerator;
169     this.packageInfoDao = packageInfoDao;
170     this.deploymentFlavorDao = deploymentFlavorDao;
171     this.componentDao = componentDao;
172     this.componentDependencyModelDao = componentDependencyModelDao;
173     this.nicDao = nicDao;
174     this.computeDao = computeDao;
175     this.imageDao = imageDao;
176     this.manualVspToscaManager = manualVspToscaManager;
177
178     registerToVersioning();
179   }
180
181   private void registerToVersioning() {
182     serviceModelDao.registerVersioning(
183         VendorSoftwareProductConstants.VENDOR_SOFTWARE_PRODUCT_VERSIONABLE_TYPE);
184     enrichedServiceModelDao.registerVersioning(
185         VendorSoftwareProductConstants.VENDOR_SOFTWARE_PRODUCT_VERSIONABLE_TYPE);
186   }
187
188   @Override
189   public ValidationResponse validate(String vspId, Version version) throws IOException {
190     VspDetails vspDetails = getValidatedVsp(vspId, version);
191     List<ErrorCode> vspErrors = new ArrayList<>(validateVspFields(vspDetails));
192     ValidationResponse validationResponse = new ValidationResponse();
193     if (Objects.nonNull(vspDetails.getOnboardingMethod())
194         && OnboardingMethod.Manual.name().equals(vspDetails.getOnboardingMethod())) {
195       validateManualOnboardingMethod(vspDetails, validationResponse, vspErrors);
196     } else {
197       validateOrchestrationTemplateCandidate(validationResponse, vspErrors, vspId, version);
198       if (!validationResponse.isValid()) {
199         return validationResponse;
200       }
201       if (vspDetails.getVlmVersion() != null || vspDetails.getLicenseAgreement() != null
202           || vspDetails.getFeatureGroups() != null) {
203         vspErrors.addAll(validateMandatoryLicenseFields(vspDetails));
204       }
205       OrchestrationTemplateEntity orchestrationTemplate =
206           orchestrationTemplateDao.get(vspId, version);
207       ToscaServiceModel serviceModel =
208           serviceModelDao.getServiceModel(vspId, vspDetails.getVersion());
209       if (!isOrchestrationTemplateExist(orchestrationTemplate)
210           || !isServiceModelExist(serviceModel)) {
211         vspErrors.add(VendorSoftwareProductInvalidErrorBuilder
212             .vendorSoftwareProductMissingServiceModelErrorBuilder(vspDetails.getId(),
213                 vspDetails.getVersion()));
214       }
215       validationResponse.setUploadDataErrors(validateOrchestrationTemplate(orchestrationTemplate));
216     }
217     Collection<ComponentDependencyModelEntity> componentDependencies =
218         componentDependencyModelDao.list(new ComponentDependencyModelEntity(vspId, version, null));
219
220     QuestionnaireValidationResult questionnaireValidationResult = validateQuestionnaire
221         (vspDetails.getId(), vspDetails.getVersion(), vspDetails.getOnboardingMethod());
222
223     if (Objects.nonNull(questionnaireValidationResult)) {
224       if (validationResponse.getQuestionnaireValidationResult() == null || validationResponse
225           .getQuestionnaireValidationResult().getValidationData() == null) {
226         validationResponse.setQuestionnaireValidationResult(questionnaireValidationResult);
227       } else {
228         validationResponse.getQuestionnaireValidationResult().getValidationData().addAll
229             (questionnaireValidationResult.getValidationData());
230       }
231     }
232
233     if (validateComponentDependencies(componentDependencies)) {
234       vspErrors
235           .add(ComponentDependencyModelErrorBuilder.getcyclicDependencyComponentErrorBuilder());
236     }
237     validationResponse
238         .setVspErrors(vspErrors);
239     validationResponse.setLicensingDataErrors(validateLicensingData(vspDetails));
240     return validationResponse;
241   }
242
243   private void validateOrchestrationTemplateCandidate(ValidationResponse validationResponse,
244                                                       List<ErrorCode> vspErrors, String vspId,
245                                                       Version version) {
246     OrchestrationTemplateCandidateData orchestrationTemplateCandidateData =
247         orchestrationTemplateCandidateManager.getInfo(vspId, version);
248     String validationData = orchestrationTemplateCandidateData.getValidationData();
249     String fileName = orchestrationTemplateCandidateData.getFileName();
250     if (Objects.nonNull(orchestrationTemplateCandidateData.getFileSuffix())) {
251       if (validationData.isEmpty()) {
252         vspErrors.add(VendorSoftwareProductInvalidErrorBuilder
253             .candidateDataNotProcessedOrAbortedErrorBuilder(fileName));
254         validationResponse.setVspErrors(vspErrors);
255       } else {
256         vspErrors.add(VendorSoftwareProductInvalidErrorBuilder.invalidProcessedCandidate(fileName));
257         validationResponse.setVspErrors(vspErrors);
258       }
259     }
260   }
261
262   private void validateManualOnboardingMethod(VspDetails vspDetails,
263                                               ValidationResponse validationResponse,
264                                               List<ErrorCode> vspErrors) {
265     vspErrors.addAll(validateMandatoryLicenseFields(vspDetails));
266
267     Collection<DeploymentFlavorEntity> deploymentFlavors = deploymentFlavorDao
268         .list(new DeploymentFlavorEntity(vspDetails.getId(), vspDetails.getVersion(), null));
269     if (CollectionUtils.isEmpty(deploymentFlavors)) {
270       vspErrors
271           .add(VendorSoftwareProductInvalidErrorBuilder.vspMissingDeploymentFlavorErrorBuilder());
272     }
273     vspErrors.addAll(validateDeploymentFlavors(deploymentFlavors));
274
275     Set<CompositionEntityValidationData> componentValidationResult =
276         componentValidation(vspDetails.getId(), vspDetails.getVersion());
277     if (!CollectionUtils.isEmpty(componentValidationResult)) {
278       if (validationResponse.getQuestionnaireValidationResult() == null
279           || validationResponse.getQuestionnaireValidationResult().getValidationData() == null) {
280         validationResponse.setQuestionnaireValidationResult(
281             new QuestionnaireValidationResult(componentValidationResult));
282       } else {
283         validationResponse.getQuestionnaireValidationResult().getValidationData()
284             .addAll(componentValidationResult);
285       }
286     }
287   }
288
289   @Override
290   public Map<String, List<ErrorMessage>> compile(String vspId, Version version) {
291     ToscaServiceModel serviceModel =
292         OnboardingMethod.Manual.name().equals(getValidatedVsp(vspId, version).getOnboardingMethod())
293             //Generate Tosca service model for Manual Onboarding flow
294             ? manualVspToscaManager
295             .generateToscaModel(manualVspToscaManager.gatherVspInformation(vspId, version))
296             : serviceModelDao.getServiceModel(vspId, version);
297
298       return compile(vspId, version, serviceModel);
299   }
300
301   private boolean validateComponentDependencies(
302       Collection<ComponentDependencyModelEntity> componentDependencies) {
303     ComponentDependencyTracker dependencyTracker = new ComponentDependencyTracker();
304
305     for (ComponentDependencyModelEntity componentDependency : componentDependencies) {
306       dependencyTracker.addDependency(componentDependency.getSourceComponentId(),
307           componentDependency.getTargetComponentId());
308     }
309     return dependencyTracker.isCyclicDependencyPresent();
310   }
311
312   private Collection<ErrorCode> validateDeploymentFlavors(
313       Collection<DeploymentFlavorEntity> deploymentFlavors) {
314
315     Collection<ErrorCode> errorCodeList = new ArrayList<>();
316     if (!CollectionUtils.isEmpty(deploymentFlavors)) {
317       deploymentFlavors.forEach(deploymentFlavor -> {
318         DeploymentFlavorEntity deployment = deploymentFlavorDao.get(deploymentFlavor);
319         DeploymentFlavor deploymentlocalFlavor = deployment.getDeploymentFlavorCompositionData();
320         if (deploymentlocalFlavor != null) {
321           if (deploymentlocalFlavor.getFeatureGroupId() == null) {
322             ErrorCode deploymentFlavorErrorBuilder = DeploymentFlavorErrorBuilder.
323                 getFeatureGroupMandatoryErrorBuilder(deploymentlocalFlavor.getModel());
324             errorCodeList.add(deploymentFlavorErrorBuilder);
325           }
326           validateComponetComputeAssociations(errorCodeList, deploymentFlavor,
327                   deployment, deploymentlocalFlavor);
328         }
329       });
330     }
331     return errorCodeList;
332   }
333
334   private void validateComponetComputeAssociations(Collection<ErrorCode> errorCodeList,
335                                                    DeploymentFlavorEntity deploymentFlavor,
336                                                    DeploymentFlavorEntity deployment,
337                                                    DeploymentFlavor deploymentlocalFlavor) {
338     List<ComponentComputeAssociation> componetComputeAssociations =
339         deploymentlocalFlavor.getComponentComputeAssociations();
340     if (CollectionUtils.isEmpty(componetComputeAssociations)) {
341       CompositionEntityValidationData compositionEntityValidationData = new
342           CompositionEntityValidationData(CompositionEntityType.deployment, deploymentFlavor
343           .getId());
344       compositionEntityValidationData.setEntityName(deployment
345           .getDeploymentFlavorCompositionData().getModel());
346       ErrorCode deploymentFlavorErrorBuilder = DeploymentFlavorErrorBuilder
347           .getInvalidComponentComputeAssociationErrorBuilder(
348               deploymentlocalFlavor.getModel());
349
350       errorCodeList.add(deploymentFlavorErrorBuilder);
351     } else {
352       componetComputeAssociations.forEach(componetComputeAssociation -> {
353         if (componetComputeAssociation == null
354             || !(componetComputeAssociation.getComponentId() != null
355             && componetComputeAssociation.getComputeFlavorId() != null)) {
356           CompositionEntityValidationData compositionEntityValidationData = new
357               CompositionEntityValidationData(CompositionEntityType.deployment,
358               deploymentFlavor.getId());
359           compositionEntityValidationData.setEntityName(deployment
360               .getDeploymentFlavorCompositionData().getModel());
361           ErrorCode deploymentFlavorErrorBuilder = DeploymentFlavorErrorBuilder
362               .getInvalidComponentComputeAssociationErrorBuilder(
363                   deploymentlocalFlavor.getModel());
364
365           errorCodeList.add(deploymentFlavorErrorBuilder);
366         }
367       });
368     }
369   }
370
371   private Set<CompositionEntityValidationData> componentValidation(String vspId, Version version) {
372     Set<CompositionEntityValidationData> validationData = new HashSet<>();
373     Collection<ComponentEntity> components =
374         componentDao.list(new ComponentEntity(vspId, version, null));
375     if (!CollectionUtils.isEmpty(components)) {
376       components.forEach(component -> {
377         validateImage(vspId, version, validationData, component);
378         validateNic(vspId, version, validationData, component);
379
380       });
381     }
382
383     return validationData;
384   }
385
386   private void validateNic(String vspId, Version version,
387                            Set<CompositionEntityValidationData> validationData,
388                            ComponentEntity component) {
389     Collection<NicEntity> nics =
390         nicDao.list(new NicEntity(vspId, version, component.getId(), null));
391     if (CollectionUtils.isNotEmpty(nics)) {
392       nics.forEach(nicEntity -> {
393         NicEntity nic = nicDao.get(new NicEntity(vspId, version, component.getId(),
394             nicEntity.getId()));
395         NetworkType networkType = nic.getNicCompositionData().getNetworkType();
396         String networkId = nic.getNicCompositionData().getNetworkId();
397         if (networkType.equals(NetworkType.Internal) && networkId == null) {
398           CompositionEntityValidationData compositionEntityValidationData = new
399               CompositionEntityValidationData(CompositionEntityType.nic, nic.getId());
400           compositionEntityValidationData.setEntityName(nic.getNicCompositionData().getName());
401           ErrorCode nicInternalNetworkErrorBuilder = NicInternalNetworkErrorBuilder
402               .getNicNullNetworkIdInternalNetworkIdErrorBuilder();
403           List<String> errors = new ArrayList<>();
404           errors.add(nicInternalNetworkErrorBuilder.message());
405           compositionEntityValidationData.setErrors(errors);
406           validationData.add(compositionEntityValidationData);
407         }
408       });
409     }
410   }
411
412   private void validateImage(String vspId, Version version,
413                              Set<CompositionEntityValidationData> validationData,
414                              ComponentEntity component) {
415     Collection<ImageEntity> images =
416         imageDao.list(new ImageEntity(vspId, version, component.getId(), null));
417     if (CollectionUtils.isEmpty(images)) {
418       CompositionEntityValidationData compositionEntityValidationData = new
419           CompositionEntityValidationData(component.getType(), component.getId());
420       compositionEntityValidationData
421           .setEntityName(component.getComponentCompositionData().getDisplayName());
422       ErrorCode vfcMissingImageErrorBuilder =
423           ComponentErrorBuilder.vfcMissingImageErrorBuilder();
424       List<String> errors = new ArrayList<>();
425       errors.add(vfcMissingImageErrorBuilder.message());
426       compositionEntityValidationData.setErrors(errors);
427       validationData.add(compositionEntityValidationData);
428     }
429   }
430
431   private List<ErrorCode> validateVspFields(VspDetails vspDetails) {
432     List<ErrorCode> errors = new ArrayList<>();
433
434     if (vspDetails.getName() == null) {
435       errors.add(createMissingMandatoryFieldError("name"));
436     }
437     if (vspDetails.getDescription() == null) {
438       errors.add(createMissingMandatoryFieldError("description"));
439     }
440     if (vspDetails.getVendorId() == null) {
441       errors.add(createMissingMandatoryFieldError("vendor Id"));
442     }
443     if (vspDetails.getCategory() == null) {
444       errors.add(createMissingMandatoryFieldError("category"));
445     }
446     if (vspDetails.getSubCategory() == null) {
447       errors.add(createMissingMandatoryFieldError("sub category"));
448     }
449     return errors;
450   }
451
452   private List<ErrorCode> validateMandatoryLicenseFields(VspDetails vspDetails) {
453     List<ErrorCode> errors = new ArrayList<>();
454     if (vspDetails.getVlmVersion() == null) {
455       errors.add(createMissingMandatoryFieldError("licensing version"));
456     }
457     if (vspDetails.getLicenseAgreement() == null) {
458       errors.add(createMissingMandatoryFieldError("license agreement"));
459     }
460     if (CollectionUtils.isEmpty(vspDetails.getFeatureGroups())) {
461       errors.add(createMissingMandatoryFieldError("feature groups"));
462     }
463     return errors;
464   }
465
466   private static ErrorCode createMissingMandatoryFieldError(String fieldName) {
467     return new ValidationErrorBuilder("must be supplied", fieldName).build();
468   }
469
470   private Map<String, List<ErrorMessage>> compile(String vendorSoftwareProductId, Version version,
471                                                   ToscaServiceModel serviceModel) {
472     if (!isServiceModelExist(serviceModel)) {
473       return null;
474     }
475
476     enrichedServiceModelDao.deleteAll(vendorSoftwareProductId, version);
477
478     EnrichmentManager<ToscaServiceModel> enrichmentManager =
479         EnrichmentManagerFactory.getInstance().createInterface();
480     enrichmentManager.init(vendorSoftwareProductId, version);
481     enrichmentManager.setModel(serviceModel);
482     Map<String, List<ErrorMessage>> enrichErrors = enrichmentManager.enrich();
483
484     enrichedServiceModelDao
485         .storeServiceModel(vendorSoftwareProductId, version, enrichmentManager.getModel());
486
487     return enrichErrors;
488   }
489
490   private Collection<ErrorCode> validateLicensingData(VspDetails vspDetails) {
491     if (vspDetails.getVendorId() == null || vspDetails.getVlmVersion() == null
492         || vspDetails.getLicenseAgreement() == null
493         || CollectionUtils.isEmpty(vspDetails.getFeatureGroups())) {
494       return Collections.emptyList();
495     }
496     return vendorLicenseFacade
497         .validateLicensingData(vspDetails.getVendorId(), vspDetails.getVlmVersion(),
498             vspDetails.getLicenseAgreement(), vspDetails.getFeatureGroups());
499   }
500
501   @Override
502   public VspDetails createVsp(VspDetails vspDetails) {
503     vspInfoDao.create(vspDetails);
504     vspInfoDao.updateQuestionnaireData(vspDetails.getId(), vspDetails.getVersion(),
505         new JsonSchemaDataGenerator(getVspQuestionnaireSchema(null)).generateData());
506     return vspDetails;
507   }
508
509   @Override
510   public void updateVsp(VspDetails vspDetails) {
511     VspDetails retrieved = vspInfoDao.get(vspDetails);
512     // TODO: 6/21/2017 remove this validation when validation will be added in the REST level
513     if (retrieved == null) {
514       throw new RuntimeException(String.format("Vsp with id %s and version %s does not exist.",
515           vspDetails.getId(), vspDetails.getVersion().getId()));
516     }
517     vspDetails.setOnboardingMethod(retrieved.getOnboardingMethod());
518
519     //If any existing feature group is removed from VSP which is also associated in DF then
520     //update DF to remove feature group associations.
521     updateDeploymentFlavor(vspDetails);
522
523     updateUniqueName(retrieved.getName(), vspDetails.getName());
524     vspInfoDao.update(vspDetails);
525   }
526
527   private void updateDeploymentFlavor(VspDetails vspDetails) {
528     final List<String> featureGroups = vspDetails.getFeatureGroups();
529     if (featureGroups != null) {
530       final Collection<DeploymentFlavorEntity> deploymentFlavorEntities = deploymentFlavorDao
531           .list(new DeploymentFlavorEntity(vspDetails.getId(), vspDetails
532               .getVersion(), null));
533       if (Objects.nonNull(deploymentFlavorEntities)) {
534         for (DeploymentFlavorEntity deploymentFlavorEntity : deploymentFlavorEntities) {
535           updateDeploymentFlavourEntity(featureGroups, deploymentFlavorEntity);
536         }
537       }
538     }
539   }
540
541   private void updateDeploymentFlavourEntity(List<String> featureGroups,
542                                              DeploymentFlavorEntity deploymentFlavorEntity) {
543     final String featureGroupId =
544         deploymentFlavorEntity.getDeploymentFlavorCompositionData().getFeatureGroupId();
545     if (!featureGroups.contains(featureGroupId)) {
546       DeploymentFlavor deploymentFlavorCompositionData =
547           deploymentFlavorEntity.getDeploymentFlavorCompositionData();
548       deploymentFlavorCompositionData.setFeatureGroupId(null);
549       deploymentFlavorEntity.setDeploymentFlavorCompositionData
550           (deploymentFlavorCompositionData);
551       deploymentFlavorDao.update(deploymentFlavorEntity);
552     }
553   }
554
555
556   @Override
557   public VspDetails getVsp(String vspId, Version version) {
558       return getValidatedVsp(vspId, version);
559   }
560
561   private VspDetails getValidatedVsp(String vspId, Version version) {
562     VspDetails vsp = vspInfoDao.get(new VspDetails(vspId, version));
563     if (vsp == null) {
564       throw new CoreException(new VendorSoftwareProductNotFoundErrorBuilder(vspId).build());
565     }
566     return vsp;
567   }
568
569   @Override
570   public void deleteVsp(String vspId) {
571     throw new UnsupportedOperationException(
572         VendorSoftwareProductConstants.UNSUPPORTED_OPERATION_ERROR);
573   }
574
575   @Override
576   public List<PackageInfo> listPackages(String category, String subCategory) {
577     return packageInfoDao.listByCategory(category, subCategory);
578   }
579
580   @Override
581   public File getTranslatedFile(String vspId, Version version) {
582     PackageInfo packageInfo = packageInfoDao.get(new PackageInfo(vspId, version));
583     if (packageInfo == null) {
584       throw new CoreException(new PackageNotFoundErrorBuilder(vspId, version).build());
585     }
586
587     ByteBuffer translatedFileBuffer = packageInfo.getTranslatedFile();
588     if (translatedFileBuffer == null) {
589       throw new CoreException(new PackageInvalidErrorBuilder(vspId, version).build());
590     }
591
592     File translatedFile = new File(VendorSoftwareProductConstants.VSP_PACKAGE_ZIP);
593
594     try (FileOutputStream fos = new FileOutputStream(translatedFile)) {
595       fos.write(translatedFileBuffer.array());
596     } catch (IOException exception) {
597       throw new CoreException(new TranslationFileCreationErrorBuilder(vspId, version).build(),
598           exception);
599     }
600     return translatedFile;
601   }
602
603   @Override
604
605   public byte[] getOrchestrationTemplateFile(String vspId, Version version) {
606     OrchestrationTemplateEntity uploadData = orchestrationTemplateDao.get(vspId, version);
607     ByteBuffer contentData = uploadData.getContentData();
608     if (contentData == null) {
609       return null;
610     }
611
612     ByteArrayOutputStream baos = new ByteArrayOutputStream();
613
614     try (final ZipOutputStream zos = new ZipOutputStream(baos);
615          ZipInputStream ignored = new ZipInputStream(
616              new ByteArrayInputStream(contentData.array()))) {
617       zos.write(contentData.array());
618     } catch (IOException exception) {
619       throw new CoreException(new FileCreationErrorBuilder(vspId).build(), exception);
620     }
621     return baos.toByteArray();
622   }
623
624   @Override
625   public OrchestrationTemplateEntity getOrchestrationTemplateInfo(String vspId, Version version) {
626     return orchestrationTemplateDao.getInfo(vspId, version);
627   }
628
629   @Override
630   public Optional<FilesDataStructure> getOrchestrationTemplateStructure(String vspId,
631                                                                         Version version) {
632     Optional<String> jsonFileDataStructure =
633         orchestrationTemplateDao.getOrchestrationTemplateStructure(vspId, version);
634
635     if (jsonFileDataStructure.isPresent() && JsonUtil.isValidJson(jsonFileDataStructure.get())) {
636       return Optional
637           .of(JsonUtil.json2Object(jsonFileDataStructure.get(), FilesDataStructure.class));
638     } else {
639       return Optional.empty();
640     }
641   }
642
643   @Override
644   public PackageInfo createPackage(String vspId, Version version) {
645     ToscaServiceModel toscaServiceModel = enrichedServiceModelDao.getServiceModel(vspId, version);
646     VspDetails vspDetails = vspInfoDao.get(new VspDetails(vspId, version));
647     Version vlmVersion = vspDetails.getVlmVersion();
648     if (vlmVersion != null) {
649       populateVersionsForVlm(vspDetails.getVendorId(), vlmVersion);
650     }
651     PackageInfo packageInfo = createPackageInfo(vspDetails);
652
653     ToscaFileOutputServiceCsarImpl toscaServiceTemplateServiceCsar =
654         new ToscaFileOutputServiceCsarImpl();
655     FileContentHandler licenseArtifacts = licenseArtifactsService
656         .createLicenseArtifacts(vspDetails.getId(), vspDetails.getVendorId(), vlmVersion,
657             vspDetails.getFeatureGroups());
658     //todo add tosca validation here
659     packageInfo.setTranslatedFile(ByteBuffer.wrap(
660         toscaServiceTemplateServiceCsar.createOutputFile(toscaServiceModel, licenseArtifacts)));
661
662     packageInfoDao.create(packageInfo);
663     return packageInfo;
664   }
665
666   protected void populateVersionsForVlm(String vlmId, Version vlmVersion) {
667     VersioningManager versioningManager = VersioningManagerFactory.getInstance().createInterface();
668     versioningManager.list(vlmId).stream()
669         .filter(version -> version.getId().equalsIgnoreCase(vlmVersion.getId()))
670         .findAny()
671         .ifPresent(version -> {
672           vlmVersion.setMinor(version.getMinor());
673           vlmVersion.setMajor(version.getMajor());
674         });
675   }
676
677   private PackageInfo createPackageInfo(VspDetails vspDetails) {
678     PackageInfo packageInfo = new PackageInfo(vspDetails.getId(), vspDetails.getVersion());
679     packageInfo.setVspName(vspDetails.getName());
680     packageInfo.setVspDescription(vspDetails.getDescription());
681     packageInfo.setCategory(vspDetails.getCategory());
682     packageInfo.setSubCategory(vspDetails.getSubCategory());
683     packageInfo.setVendorName(vspDetails.getVendorName());
684     packageInfo.setPackageType(VendorSoftwareProductConstants.CSAR);
685     packageInfo.setVendorRelease("1.0"); //todo TBD
686     return packageInfo;
687   }
688
689   @Override
690
691   public QuestionnaireResponse getVspQuestionnaire(String vspId, Version version) {
692     VspQuestionnaireEntity retrieved = vspInfoDao.getQuestionnaire(vspId, version);
693     VersioningUtil.validateEntityExistence(retrieved, new VspQuestionnaireEntity(vspId, version),
694         VspDetails.ENTITY_TYPE);
695
696     String questionnaireData = retrieved.getQuestionnaireData();
697
698     QuestionnaireResponse questionnaireResponse = new QuestionnaireResponse();
699     questionnaireResponse.setData(questionnaireData);
700     questionnaireResponse.setSchema(getVspQuestionnaireSchema(null));
701     return questionnaireResponse;
702   }
703
704   @Override
705   public void updateVspQuestionnaire(String vspId, Version version, String questionnaireData) {
706     vspInfoDao.updateQuestionnaireData(vspId, version, questionnaireData);
707   }
708
709
710   private Map<String, List<ErrorMessage>> validateOrchestrationTemplate(
711       OrchestrationTemplateEntity orchestrationTemplate) throws IOException {
712
713     if (!isOrchestrationTemplateExist(orchestrationTemplate)) {
714       return null;
715     }
716     Map<String, List<ErrorMessage>> validationErrors = new HashMap<>();
717
718     FileContentHandler fileContentMap = CommonUtil.validateAndUploadFileContent(
719         OnboardingTypesEnum.getOnboardingTypesEnum(orchestrationTemplate.getFileSuffix()),
720         orchestrationTemplate.getContentData().array());
721
722     if (CommonUtil.isFileOriginFromZip(orchestrationTemplate.getFileSuffix())) {
723       ValidationManager validationManager =
724           ValidationManagerUtil.initValidationManager(fileContentMap);
725       validationErrors.putAll(validationManager.validate());
726     }
727
728     return
729         MapUtils.isEmpty(MessageContainerUtil.getMessageByLevel(ErrorLevel.ERROR, validationErrors))
730             ? null : validationErrors;
731   }
732
733   private QuestionnaireValidationResult validateQuestionnaire(String vspId, Version version,
734                                                               String onboardingMethod) {
735     // The apis of CompositionEntityDataManager used here are stateful!
736     // so, it must be re-created from scratch when it is used!
737     CompositionEntityDataManager compositionEntityDataManager =
738         CompositionEntityDataManagerFactory.getInstance().createInterface();
739     compositionEntityDataManager
740         .addEntity(vspInfoDao.getQuestionnaire(vspId, version), null);
741
742     Collection<NicEntity> nics = nicDao.listByVsp(vspId, version);
743
744     Map<String, List<String>> nicNamesByComponent = new HashMap<>();
745     for (NicEntity nicEntity : nics) {
746       compositionEntityDataManager.addEntity(nicEntity, null);
747
748       Nic nic = nicEntity.getNicCompositionData();
749       if (nic != null && nic.getName() != null) {
750         List<String> nicNames =
751             nicNamesByComponent.computeIfAbsent(nicEntity.getComponentId(), k -> new ArrayList<>());
752         nicNames.add(nic.getName());
753       }
754     }
755
756     Collection<ComponentEntity> components =
757         componentDao.listCompositionAndQuestionnaire(vspId, version);
758     components.forEach(component -> compositionEntityDataManager.addEntity(component,
759         new ComponentQuestionnaireSchemaInput(nicNamesByComponent.get(component.getId()),
760             JsonUtil.json2Object(component.getQuestionnaireData(), Map.class))));
761
762     Collection<ComputeEntity> computes = computeDao.listByVsp(vspId, version);
763     computes.forEach(compute -> compositionEntityDataManager.addEntity(compute, null));
764
765     if (OnboardingMethod.Manual.name().equals(onboardingMethod)) {
766       Collection<ImageEntity> images = imageDao.listByVsp(vspId, version);
767       images.forEach(image -> compositionEntityDataManager.addEntity(image, null));
768     }
769
770     Map<CompositionEntityId, Collection<String>> errorsByEntityId =
771         compositionEntityDataManager.validateEntitiesQuestionnaire();
772     if (MapUtils.isNotEmpty(errorsByEntityId)) {
773       compositionEntityDataManager.buildTrees();
774       compositionEntityDataManager.addErrorsToTrees(errorsByEntityId);
775       return new QuestionnaireValidationResult(
776           compositionEntityDataManager.getAllErrorsByVsp(vspId));
777     }
778     return null;
779   }
780
781   @Override
782   public File getInformationArtifact(String vspId, Version version) {
783     VspDetails vspDetails = vspInfoDao.get(new VspDetails(vspId, version));
784
785     if (vspDetails == null) {
786       return null;
787     }
788
789     String vspName = vspDetails.getName();
790     ByteBuffer infoArtifactAsByteBuffer;
791     File infoArtifactFile;
792     try {
793       infoArtifactAsByteBuffer = ByteBuffer.wrap(informationArtifactGenerator.generate(vspId,
794           version).getBytes());
795
796       infoArtifactFile =
797           new File(
798               String.format(VendorSoftwareProductConstants.INFORMATION_ARTIFACT_NAME, vspName));
799       try (OutputStream out = new BufferedOutputStream(new FileOutputStream(infoArtifactFile))) {
800         out.write(infoArtifactAsByteBuffer.array());
801       }
802
803     } catch (IOException ex) {
804       throw new CoreException(new InformationArtifactCreationErrorBuilder(vspId).build(), ex);
805     }
806     return infoArtifactFile;
807   }
808
809   String getVspQuestionnaireSchema(SchemaTemplateInput schemaInput) {
810     return SchemaGenerator
811         .generate(SchemaTemplateContext.questionnaire, CompositionEntityType.vsp, schemaInput);
812   }
813
814   void updateUniqueName(String oldVspName, String newVspName) {
815     UniqueValueUtil.updateUniqueValue(
816         VendorSoftwareProductConstants.UniqueValues.VENDOR_SOFTWARE_PRODUCT_NAME,
817         oldVspName, newVspName);
818   }
819
820   @Override
821   public Collection<ComputeEntity> getComputeByVsp(String vspId, Version version) {
822     return computeDao.listByVsp(vspId, version);
823   }
824
825   private boolean isOrchestrationTemplateExist(OrchestrationTemplateEntity orchestrationTemplate) {
826     return orchestrationTemplate != null
827         && orchestrationTemplate.getContentData() != null
828         && orchestrationTemplate.getFileSuffix() != null
829         && orchestrationTemplate.getFileName() != null;
830   }
831
832   private boolean isServiceModelExist(ToscaServiceModel serviceModel) {
833     return serviceModel != null && serviceModel.getEntryDefinitionServiceTemplate() != null;
834   }
835
836 }