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