2 * Copyright © 2016-2018 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.openecomp.sdc.vendorsoftwareproduct.impl;
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;
104 import java.io.BufferedOutputStream;
105 import java.io.ByteArrayInputStream;
106 import java.io.ByteArrayOutputStream;
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;
125 public class VendorSoftwareProductManagerImpl implements VendorSoftwareProductManager {
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;
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,
158 ComputeDao computeDao,
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;
178 registerToVersioning();
181 private void registerToVersioning() {
182 serviceModelDao.registerVersioning(
183 VendorSoftwareProductConstants.VENDOR_SOFTWARE_PRODUCT_VERSIONABLE_TYPE);
184 enrichedServiceModelDao.registerVersioning(
185 VendorSoftwareProductConstants.VENDOR_SOFTWARE_PRODUCT_VERSIONABLE_TYPE);
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);
197 validateOrchestrationTemplateCandidate(validationResponse, vspErrors, vspId, version);
198 if (!validationResponse.isValid()) {
199 return validationResponse;
201 if (vspDetails.getVlmVersion() != null || vspDetails.getLicenseAgreement() != null
202 || vspDetails.getFeatureGroups() != null) {
203 vspErrors.addAll(validateMandatoryLicenseFields(vspDetails));
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()));
215 validationResponse.setUploadDataErrors(validateOrchestrationTemplate(orchestrationTemplate));
218 QuestionnaireValidationResult questionnaireValidationResult = validateQuestionnaire
219 (vspDetails.getId(), vspDetails.getVersion(), vspDetails.getOnboardingMethod());
221 if (Objects.nonNull(questionnaireValidationResult)) {
222 if (validationResponse.getQuestionnaireValidationResult() == null || validationResponse
223 .getQuestionnaireValidationResult().getValidationData() == null) {
224 validationResponse.setQuestionnaireValidationResult(questionnaireValidationResult);
226 validationResponse.getQuestionnaireValidationResult().getValidationData().addAll
227 (questionnaireValidationResult.getValidationData());
231 Collection<ComponentDependencyModelEntity> componentDependencies =
232 componentDependencyModelDao.list(new ComponentDependencyModelEntity(vspId, version, null));
234 if (validateComponentDependencies(componentDependencies)) {
236 .add(ComponentDependencyModelErrorBuilder.getcyclicDependencyComponentErrorBuilder());
239 .setVspErrors(vspErrors);
240 validationResponse.setLicensingDataErrors(validateLicensingData(vspDetails));
241 return validationResponse;
244 private void validateOrchestrationTemplateCandidate(ValidationResponse validationResponse,
245 List<ErrorCode> vspErrors, String vspId,
247 OrchestrationTemplateCandidateData orchestrationTemplateCandidateData =
248 orchestrationTemplateCandidateManager.getInfo(vspId, version);
249 String validationData = orchestrationTemplateCandidateData.getValidationData();
250 String fileName = orchestrationTemplateCandidateData.getFileName();
251 if (Objects.nonNull(orchestrationTemplateCandidateData.getFileSuffix())) {
252 if (validationData.isEmpty()) {
253 vspErrors.add(VendorSoftwareProductInvalidErrorBuilder
254 .candidateDataNotProcessedOrAbortedErrorBuilder(fileName));
256 vspErrors.add(VendorSoftwareProductInvalidErrorBuilder.invalidProcessedCandidate(fileName));
258 validationResponse.setVspErrors(vspErrors);
262 private void validateManualOnboardingMethod(VspDetails vspDetails,
263 ValidationResponse validationResponse,
264 List<ErrorCode> vspErrors) {
265 vspErrors.addAll(validateMandatoryLicenseFields(vspDetails));
267 Collection<DeploymentFlavorEntity> deploymentFlavors = deploymentFlavorDao
268 .list(new DeploymentFlavorEntity(vspDetails.getId(), vspDetails.getVersion(), null));
269 if (CollectionUtils.isEmpty(deploymentFlavors)) {
271 .add(VendorSoftwareProductInvalidErrorBuilder.vspMissingDeploymentFlavorErrorBuilder());
273 vspErrors.addAll(validateDeploymentFlavors(deploymentFlavors));
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));
283 validationResponse.getQuestionnaireValidationResult().getValidationData()
284 .addAll(componentValidationResult);
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);
298 return compile(vspId, version, serviceModel);
301 private boolean validateComponentDependencies(
302 Collection<ComponentDependencyModelEntity> componentDependencies) {
303 ComponentDependencyTracker dependencyTracker = new ComponentDependencyTracker();
305 for (ComponentDependencyModelEntity componentDependency : componentDependencies) {
306 dependencyTracker.addDependency(componentDependency.getSourceComponentId(),
307 componentDependency.getTargetComponentId());
309 return dependencyTracker.isCyclicDependencyPresent();
312 private Collection<ErrorCode> validateDeploymentFlavors(
313 Collection<DeploymentFlavorEntity> deploymentFlavors) {
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);
326 validateComponetComputeAssociations(errorCodeList, deploymentFlavor,
327 deployment, deploymentlocalFlavor);
331 return errorCodeList;
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
344 compositionEntityValidationData.setEntityName(deployment
345 .getDeploymentFlavorCompositionData().getModel());
346 ErrorCode deploymentFlavorErrorBuilder = DeploymentFlavorErrorBuilder
347 .getInvalidComponentComputeAssociationErrorBuilder(
348 deploymentlocalFlavor.getModel());
350 errorCodeList.add(deploymentFlavorErrorBuilder);
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());
365 errorCodeList.add(deploymentFlavorErrorBuilder);
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);
383 return validationData;
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(),
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);
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);
431 private List<ErrorCode> validateVspFields(VspDetails vspDetails) {
432 List<ErrorCode> errors = new ArrayList<>();
434 if (vspDetails.getName() == null) {
435 errors.add(createMissingMandatoryFieldError("name"));
437 if (vspDetails.getDescription() == null) {
438 errors.add(createMissingMandatoryFieldError("description"));
440 if (vspDetails.getVendorId() == null) {
441 errors.add(createMissingMandatoryFieldError("vendor Id"));
443 if (vspDetails.getCategory() == null) {
444 errors.add(createMissingMandatoryFieldError("category"));
446 if (vspDetails.getSubCategory() == null) {
447 errors.add(createMissingMandatoryFieldError("sub category"));
452 private List<ErrorCode> validateMandatoryLicenseFields(VspDetails vspDetails) {
453 List<ErrorCode> errors = new ArrayList<>();
454 if (vspDetails.getVlmVersion() == null) {
455 errors.add(createMissingMandatoryFieldError("licensing version"));
457 if (vspDetails.getLicenseAgreement() == null) {
458 errors.add(createMissingMandatoryFieldError("license agreement"));
460 if (CollectionUtils.isEmpty(vspDetails.getFeatureGroups())) {
461 errors.add(createMissingMandatoryFieldError("feature groups"));
466 private static ErrorCode createMissingMandatoryFieldError(String fieldName) {
467 return new ValidationErrorBuilder("must be supplied", fieldName).build();
470 private Map<String, List<ErrorMessage>> compile(String vendorSoftwareProductId, Version version,
471 ToscaServiceModel serviceModel) {
472 if (!isServiceModelExist(serviceModel)) {
476 enrichedServiceModelDao.deleteAll(vendorSoftwareProductId, version);
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();
484 enrichedServiceModelDao
485 .storeServiceModel(vendorSoftwareProductId, version, enrichmentManager.getModel());
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();
496 return vendorLicenseFacade
497 .validateLicensingData(vspDetails.getVendorId(), vspDetails.getVlmVersion(),
498 vspDetails.getLicenseAgreement(), vspDetails.getFeatureGroups());
502 public VspDetails createVsp(VspDetails vspDetails) {
503 vspInfoDao.create(vspDetails);
504 vspInfoDao.updateQuestionnaireData(vspDetails.getId(), vspDetails.getVersion(),
505 new JsonSchemaDataGenerator(getVspQuestionnaireSchema(null)).generateData());
510 public void updateVsp(VspDetails vspDetails) {
511 VspDetails retrieved = vspInfoDao.get(vspDetails);
512 if (retrieved == null) {
513 throw new CoreException((new ErrorCode.ErrorCodeBuilder()
514 .withMessage(String.format("Vsp with id %s and version %s does not exist.",
515 vspDetails.getId(), vspDetails.getVersion().getId()))).build());
517 vspDetails.setOnboardingMethod(retrieved.getOnboardingMethod());
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);
523 updateUniqueName(retrieved.getName(), vspDetails.getName());
524 vspInfoDao.update(vspDetails);
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);
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);
557 public VspDetails getVsp(String vspId, Version version) {
558 return getValidatedVsp(vspId, version);
561 private VspDetails getValidatedVsp(String vspId, Version version) {
562 VspDetails vsp = vspInfoDao.get(new VspDetails(vspId, version));
564 throw new CoreException(new VendorSoftwareProductNotFoundErrorBuilder(vspId).build());
570 public void deleteVsp(String vspId) {
571 throw new UnsupportedOperationException(
572 VendorSoftwareProductConstants.UNSUPPORTED_OPERATION_ERROR);
576 public List<PackageInfo> listPackages(String category, String subCategory) {
577 return packageInfoDao.listByCategory(category, subCategory);
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());
587 ByteBuffer translatedFileBuffer = packageInfo.getTranslatedFile();
588 if (translatedFileBuffer == null) {
589 throw new CoreException(new PackageInvalidErrorBuilder(vspId, version).build());
592 File translatedFile = new File(VendorSoftwareProductConstants.VSP_PACKAGE_ZIP);
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(),
600 return translatedFile;
605 public byte[] getOrchestrationTemplateFile(String vspId, Version version) {
606 OrchestrationTemplateEntity uploadData = orchestrationTemplateDao.get(vspId, version);
607 ByteBuffer contentData = uploadData.getContentData();
608 if (contentData == null) {
612 ByteArrayOutputStream baos = new ByteArrayOutputStream();
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);
621 return baos.toByteArray();
625 public OrchestrationTemplateEntity getOrchestrationTemplateInfo(String vspId, Version version) {
626 return orchestrationTemplateDao.getInfo(vspId, version);
630 public Optional<FilesDataStructure> getOrchestrationTemplateStructure(String vspId,
632 Optional<String> jsonFileDataStructure =
633 orchestrationTemplateDao.getOrchestrationTemplateStructure(vspId, version);
635 if (jsonFileDataStructure.isPresent() && JsonUtil.isValidJson(jsonFileDataStructure.get())) {
637 .of(JsonUtil.json2Object(jsonFileDataStructure.get(), FilesDataStructure.class));
639 return Optional.empty();
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);
651 PackageInfo packageInfo = createPackageInfo(vspDetails);
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)));
662 packageInfoDao.create(packageInfo);
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()))
671 .ifPresent(version -> {
672 vlmVersion.setMinor(version.getMinor());
673 vlmVersion.setMajor(version.getMajor());
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
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);
696 String questionnaireData = retrieved.getQuestionnaireData();
698 QuestionnaireResponse questionnaireResponse = new QuestionnaireResponse();
699 questionnaireResponse.setData(questionnaireData);
700 questionnaireResponse.setSchema(getVspQuestionnaireSchema(null));
701 return questionnaireResponse;
705 public void updateVspQuestionnaire(String vspId, Version version, String questionnaireData) {
706 vspInfoDao.updateQuestionnaireData(vspId, version, questionnaireData);
710 private Map<String, List<ErrorMessage>> validateOrchestrationTemplate(
711 OrchestrationTemplateEntity orchestrationTemplate) throws IOException {
713 if (!isOrchestrationTemplateExist(orchestrationTemplate)) {
716 Map<String, List<ErrorMessage>> validationErrors = new HashMap<>();
718 FileContentHandler fileContentMap = CommonUtil.validateAndUploadFileContent(
719 OnboardingTypesEnum.getOnboardingTypesEnum(orchestrationTemplate.getFileSuffix()),
720 orchestrationTemplate.getContentData().array());
722 if (CommonUtil.isFileOriginFromZip(orchestrationTemplate.getFileSuffix())) {
723 ValidationManager validationManager =
724 ValidationManagerUtil.initValidationManager(fileContentMap);
725 validationErrors.putAll(validationManager.validate());
729 MapUtils.isEmpty(MessageContainerUtil.getMessageByLevel(ErrorLevel.ERROR, validationErrors))
730 ? null : validationErrors;
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);
742 Collection<NicEntity> nics = nicDao.listByVsp(vspId, version);
744 Map<String, List<String>> nicNamesByComponent = new HashMap<>();
745 for (NicEntity nicEntity : nics) {
746 compositionEntityDataManager.addEntity(nicEntity, null);
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());
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))));
762 Collection<ComputeEntity> computes = computeDao.listByVsp(vspId, version);
763 computes.forEach(compute -> compositionEntityDataManager.addEntity(compute, null));
765 if (OnboardingMethod.Manual.name().equals(onboardingMethod)) {
766 Collection<ImageEntity> images = imageDao.listByVsp(vspId, version);
767 images.forEach(image -> compositionEntityDataManager.addEntity(image, null));
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));
782 public File getInformationArtifact(String vspId, Version version) {
783 VspDetails vspDetails = vspInfoDao.get(new VspDetails(vspId, version));
785 if (vspDetails == null) {
789 String vspName = vspDetails.getName();
790 ByteBuffer infoArtifactAsByteBuffer;
791 File infoArtifactFile;
793 infoArtifactAsByteBuffer = ByteBuffer.wrap(informationArtifactGenerator.generate(vspId,
794 version).getBytes());
798 String.format(VendorSoftwareProductConstants.INFORMATION_ARTIFACT_NAME, vspName));
799 try (OutputStream out = new BufferedOutputStream(new FileOutputStream(infoArtifactFile))) {
800 out.write(infoArtifactAsByteBuffer.array());
803 } catch (IOException ex) {
804 throw new CoreException(new InformationArtifactCreationErrorBuilder(vspId).build(), ex);
806 return infoArtifactFile;
809 String getVspQuestionnaireSchema(SchemaTemplateInput schemaInput) {
810 return SchemaGenerator
811 .generate(SchemaTemplateContext.questionnaire, CompositionEntityType.vsp, schemaInput);
814 void updateUniqueName(String oldVspName, String newVspName) {
815 UniqueValueUtil.updateUniqueValue(
816 VendorSoftwareProductConstants.UniqueValues.VENDOR_SOFTWARE_PRODUCT_NAME,
817 oldVspName, newVspName);
821 public Collection<ComputeEntity> getComputeByVsp(String vspId, Version version) {
822 return computeDao.listByVsp(vspId, version);
825 private boolean isOrchestrationTemplateExist(OrchestrationTemplateEntity orchestrationTemplate) {
826 return orchestrationTemplate != null
827 && orchestrationTemplate.getContentData() != null
828 && orchestrationTemplate.getFileSuffix() != null
829 && orchestrationTemplate.getFileName() != null;
832 private boolean isServiceModelExist(ToscaServiceModel serviceModel) {
833 return serviceModel != null && serviceModel.getEntryDefinitionServiceTemplate() != null;