2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
19 * Modifications copyright (c) 2019 Nokia
20 * ================================================================================
23 package org.openecomp.sdc.be.components.impl;
25 import fj.data.Either;
26 import io.vavr.Function3;
27 import java.util.Optional;
28 import java.util.function.BiFunction;
29 import java.util.function.BooleanSupplier;
30 import org.apache.commons.collections.CollectionUtils;
31 import org.apache.commons.lang3.StringUtils;
32 import org.apache.commons.lang3.tuple.ImmutablePair;
33 import org.openecomp.sdc.be.catalog.enums.ChangeTypeEnum;
34 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
35 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
36 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
37 import org.openecomp.sdc.be.components.impl.generic.GenericTypeBusinessLogic;
38 import org.openecomp.sdc.be.components.validation.component.ComponentContactIdValidator;
39 import org.openecomp.sdc.be.components.validation.component.ComponentDescriptionValidator;
40 import org.openecomp.sdc.be.components.validation.component.ComponentIconValidator;
41 import org.openecomp.sdc.be.components.validation.component.ComponentNameValidator;
42 import org.openecomp.sdc.be.components.validation.component.ComponentProjectCodeValidator;
43 import org.openecomp.sdc.be.components.validation.component.ComponentTagsValidator;
44 import org.openecomp.sdc.be.components.validation.component.ComponentValidator;
45 import org.openecomp.sdc.be.config.BeEcompErrorManager;
46 import org.openecomp.sdc.be.config.ConfigurationManager;
47 import org.openecomp.sdc.be.dao.api.ActionStatus;
48 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
49 import org.openecomp.sdc.be.dao.utils.MapUtil;
50 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
51 import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition;
52 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
53 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
54 import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum;
55 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
56 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
57 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
58 import org.openecomp.sdc.be.facade.operations.CatalogOperation;
59 import org.openecomp.sdc.be.impl.ComponentsUtils;
60 import org.openecomp.sdc.be.model.ArtifactDefinition;
61 import org.openecomp.sdc.be.model.CapReqDef;
62 import org.openecomp.sdc.be.model.Component;
63 import org.openecomp.sdc.be.model.ComponentInstance;
64 import org.openecomp.sdc.be.model.ComponentInstanceInput;
65 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
66 import org.openecomp.sdc.be.model.ComponentParametersView;
67 import org.openecomp.sdc.be.model.DataTypeDefinition;
68 import org.openecomp.sdc.be.model.GroupDefinition;
69 import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement;
70 import org.openecomp.sdc.be.model.InputDefinition;
71 import org.openecomp.sdc.be.model.LifecycleStateEnum;
72 import org.openecomp.sdc.be.model.Operation;
73 import org.openecomp.sdc.be.model.PropertyDefinition;
74 import org.openecomp.sdc.be.model.Resource;
75 import org.openecomp.sdc.be.model.User;
76 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
77 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
78 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
79 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
80 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
81 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
82 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
83 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
84 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
85 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
86 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
87 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
88 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
89 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
90 import org.openecomp.sdc.be.user.Role;
91 import org.openecomp.sdc.be.utils.CommonBeUtils;
92 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
93 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
94 import org.openecomp.sdc.common.log.wrappers.Logger;
95 import org.openecomp.sdc.common.util.ValidationUtils;
96 import org.openecomp.sdc.exception.ResponseFormat;
97 import org.springframework.beans.factory.annotation.Autowired;
99 import java.util.ArrayList;
100 import java.util.HashMap;
101 import java.util.List;
102 import java.util.Map;
103 import java.util.Map.Entry;
104 import java.util.stream.Collectors;
106 public abstract class ComponentBusinessLogic extends BaseBusinessLogic {
108 protected ArtifactsBusinessLogic artifactsBusinessLogic;
110 protected final GroupBusinessLogic groupBusinessLogic;
112 protected GenericTypeBusinessLogic genericTypeBusinessLogic;
114 protected ComponentDescriptionValidator componentDescriptionValidator;
115 protected ComponentProjectCodeValidator componentProjectCodeValidator;
117 protected CatalogOperation catalogOperations;
118 protected ComponentIconValidator componentIconValidator;
120 protected ComponentValidator componentValidator;
121 protected ComponentTagsValidator componentTagsValidator;
122 protected ComponentNameValidator componentNameValidator;
123 protected ComponentContactIdValidator componentContactIdValidator;
125 public ComponentBusinessLogic(IElementOperation elementDao,
126 IGroupOperation groupOperation,
127 IGroupInstanceOperation groupInstanceOperation,
128 IGroupTypeOperation groupTypeOperation,
129 GroupBusinessLogic groupBusinessLogic,
130 InterfaceOperation interfaceOperation,
131 InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
132 ArtifactsBusinessLogic artifactsBusinessLogic,
133 ArtifactsOperations artifactToscaOperation,
134 ComponentContactIdValidator componentContactIdValidator,
135 ComponentNameValidator componentNameValidator,
136 ComponentTagsValidator componentTagsValidator,
137 ComponentValidator componentValidator,
138 ComponentIconValidator componentIconValidator,
139 ComponentProjectCodeValidator componentProjectCodeValidator,
140 ComponentDescriptionValidator componentDescriptionValidator){
142 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation,
143 interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
144 this.artifactsBusinessLogic = artifactsBusinessLogic;
145 this.groupBusinessLogic = groupBusinessLogic;
146 this.componentContactIdValidator = componentContactIdValidator;
147 this.componentNameValidator = componentNameValidator;
148 this.componentTagsValidator = componentTagsValidator;
149 this.componentValidator = componentValidator;
150 this.componentIconValidator = componentIconValidator;
151 this.componentProjectCodeValidator = componentProjectCodeValidator;
152 this.componentDescriptionValidator = componentDescriptionValidator;
155 public void setComponentDescriptionValidator(ComponentDescriptionValidator componentDescriptionValidator) {
156 this.componentDescriptionValidator = componentDescriptionValidator;
159 public void setComponentProjectCodeValidator(ComponentProjectCodeValidator componentProjectCodeValidator) {
160 this.componentProjectCodeValidator = componentProjectCodeValidator;
163 public void setComponentIconValidator(ComponentIconValidator componentIconValidator) {
164 this.componentIconValidator = componentIconValidator;
167 public void setComponentContactIdValidator(ComponentContactIdValidator componentContactIdValidator) {
168 this.componentContactIdValidator = componentContactIdValidator;
171 public void setComponentTagsValidator(ComponentTagsValidator componentTagsValidator) {
172 this.componentTagsValidator = componentTagsValidator;
175 public void setComponentNameValidator(ComponentNameValidator componentNameValidator) {
176 this.componentNameValidator = componentNameValidator;
181 public void setGenericTypeBusinessLogic(GenericTypeBusinessLogic genericTypeBusinessLogic) {
182 this.genericTypeBusinessLogic = genericTypeBusinessLogic;
185 private static final Logger log = Logger.getLogger(ComponentBusinessLogic.class.getName());
187 private static final String TAG_FIELD_LABEL = "tag";
189 public abstract Either<List<String>, ResponseFormat> deleteMarkedComponents();
191 public abstract ComponentInstanceBusinessLogic getComponentInstanceBL();
193 public abstract Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId);
198 * @param dataParamsToReturn
201 public abstract Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String componentId, List<String> dataParamsToReturn);
203 User validateUser(User user, String ecompErrorContext, Component component, AuditingActionEnum auditAction, boolean inTransaction) {
205 ResponseFormat responseFormat;
207 validateUserNotEmpty(user, ecompErrorContext);
208 validatedUser = validateUserExists(user);
209 } catch(ByActionStatusComponentException e){
210 if(e.getActionStatus() == ActionStatus.MISSING_INFORMATION){
211 user.setUserId("UNKNOWN");
213 responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
214 componentsUtils.auditComponentAdmin(responseFormat, user, component, auditAction, component.getComponentType());
216 } catch(ByResponseFormatComponentException e){
217 responseFormat = e.getResponseFormat();
218 componentsUtils.auditComponentAdmin(responseFormat, user, component, auditAction, component.getComponentType());
221 return validatedUser;
224 protected void validateUserRole(User user, Component component, List<Role> roles, AuditingActionEnum auditAction, String comment) {
225 if (roles != null && roles.isEmpty()) {
226 roles.add(Role.ADMIN);
227 roles.add(Role.DESIGNER);
230 validateUserRole(user, roles);
231 }catch (ByActionStatusComponentException e) {
232 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
233 handleComponentException(component, comment, responseFormat, user, auditAction);
235 }catch (ByResponseFormatComponentException e) {
236 ResponseFormat responseFormat = e.getResponseFormat();
237 handleComponentException(component, comment, responseFormat, user, auditAction);
242 private void handleComponentException(Component component, String comment, ResponseFormat responseFormat,
243 User user, AuditingActionEnum auditAction){
244 String commentStr = null;
245 String distrStatus = null;
246 ComponentTypeEnum componentType = component.getComponentType();
247 if (componentType == ComponentTypeEnum.SERVICE) {
248 distrStatus = ((ServiceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition()).getDistributionStatus();
249 commentStr = comment;
251 componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(componentType.getValue()),
252 ResourceVersionInfo.newBuilder().distributionStatus(distrStatus).build(),
253 ResourceVersionInfo.newBuilder().distributionStatus(distrStatus).build(),
254 commentStr, null, null);
257 public Either<Boolean, ResponseFormat> validateConformanceLevel(String componentUuid, ComponentTypeEnum componentTypeEnum, String userId) {
258 log.trace("validate conformance level");
260 if (componentTypeEnum != ComponentTypeEnum.SERVICE) {
261 log.error("conformance level validation for non service component, id {}", componentUuid);
262 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
263 return Either.right(errorResponse);
266 validateUserExists(userId);
268 Either<ComponentMetadataData, StorageOperationStatus> eitherComponent = toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, null);
269 if (eitherComponent.isRight()) {
270 log.error("can't validate conformance level, component not found, uuid {}", componentUuid);
271 BeEcompErrorManager.getInstance().logBeComponentMissingError("validateConformanceLevel", componentTypeEnum.getValue(), componentUuid);
273 StorageOperationStatus status = eitherComponent.right().value();
274 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(status, componentTypeEnum);
275 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus);
276 return Either.right(responseFormat);
279 String componentConformanceLevel = eitherComponent.left().value().getMetadataDataDefinition().getConformanceLevel();
280 if (StringUtils.isBlank(componentConformanceLevel)) {
281 log.error("component conformance level property is null or empty, uuid {}", componentUuid);
282 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
283 return Either.right(errorResponse);
286 String configConformanceLevel = ConfigurationManager.getConfigurationManager().getConfiguration().getMinToscaConformanceLevel();
287 Boolean result = true;
288 if (CommonBeUtils.conformanceLevelCompare(componentConformanceLevel, configConformanceLevel) < 0) {
289 log.error("invalid asset conformance level, uuid {}, asset conformanceLevel {}, config conformanceLevel {}", componentUuid, componentConformanceLevel, configConformanceLevel);
292 log.trace("conformance level validation finished");
294 return Either.left(result);
298 protected void checkComponentFieldsForOverrideAttempt(Component component) {
299 if (component.getLifecycleState() != null) {
300 log.info("LifecycleState cannot be defined by user. This field will be overridden by the application");
302 if (component.getVersion() != null) {
303 log.info("Version cannot be defined by user. This field will be overridden by the application");
305 if (component.getCreatorUserId() != null || component.getCreatorFullName() != null) {
306 log.info("Creator cannot be defined by user. This field will be overridden by the application");
308 if (component.getLastUpdaterUserId() != null || component.getLastUpdaterFullName() != null) {
309 log.info("Last Updater cannot be defined by user. This field will be overridden by the application");
311 if (component.getCreationDate() != null) {
312 log.info("Creation Date cannot be defined by user. This field will be overridden by the application");
314 if (component.isHighestVersion() != null) {
315 log.info("Is Highest Version cannot be defined by user. This field will be overridden by the application");
317 if (component.getUUID() != null) {
318 log.info("UUID cannot be defined by user. This field will be overridden by the application");
320 if (component.getLastUpdateDate() != null) {
321 log.info("Last Update Date cannot be defined by user. This field will be overridden by the application");
323 if (component.getUniqueId() != null) {
324 log.info("uid cannot be defined by user. This field will be overridden by the application.");
325 component.setUniqueId(null);
327 if (component.getInvariantUUID() != null) {
328 log.info("Invariant UUID cannot be defined by user. This field will be overridden by the application.");
332 public CapReqDef getRequirementsAndCapabilities(String componentId, ComponentTypeEnum componentTypeEnum, String userId) {
334 validateUserExists(userId);
335 ComponentParametersView filter = new ComponentParametersView(true);
336 filter.setIgnoreCapabilities(false);
337 filter.setIgnoreRequirements(false);
338 filter.setIgnoreComponentInstances(false);
341 Component component = validateComponentExists(componentId, componentTypeEnum, filter);
342 return new CapReqDef(component.getRequirements(), component.getCapabilities());
343 }catch (ComponentException e){
344 BeEcompErrorManager.getInstance().logBeComponentMissingError("getRequirementsAndCapabilities", componentTypeEnum.getValue(), componentId);
345 throwComponentException(e.getResponseFormat());
350 public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponents(boolean isAbstractAbstract, ComponentTypeEnum componentTypeEnum, String internalComponentType, List<String> componentUids,
353 validateUserExists(userId);
354 List<Component> result = new ArrayList<>();
355 List<String> componentsUidToFetch = new ArrayList<>();
356 componentsUidToFetch.addAll(componentUids);
357 if (!componentsUidToFetch.isEmpty()) {
358 log.debug("Number of Components to fetch from graph is {}", componentsUidToFetch.size());
359 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade.getLatestVersionNotAbstractComponents(isAbstractAbstract, componentTypeEnum, internalComponentType, componentsUidToFetch);
361 if (nonCheckoutCompResponse.isLeft()) {
362 log.debug("Retrived Resource successfully.");
363 result.addAll(nonCheckoutCompResponse.left().value());
365 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value())));
368 return Either.left(result);
371 janusGraphDao.commit();
375 private Boolean isHighest(HighestFilterEnum highestFilter) {
376 Boolean isHighest = null;
377 switch (highestFilter) {
383 case NON_HIGHEST_ONLY:
392 public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponentsMetadata(boolean isAbstractAbstract, HighestFilterEnum highestFilter, ComponentTypeEnum componentTypeEnum, String internalComponentType, String userId) {
393 ResponseFormat responseFormat = null;
396 validateUserExists(userId);
397 Boolean isHighest = isHighest(highestFilter);
398 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade.getLatestVersionNotAbstractMetadataOnly(isAbstractAbstract, componentTypeEnum, internalComponentType);
400 if (nonCheckoutCompResponse.isLeft()) {
401 log.debug("Retrieved Resource successfully.");
402 return Either.left(nonCheckoutCompResponse.left().value());
404 responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value()));
406 janusGraphDao.commit();
408 return Either.right(responseFormat);
411 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
415 @SuppressWarnings("unchecked")
416 public void setToscaArtifactsPlaceHolders(Component component, User user) {
417 Map<String, ArtifactDefinition> artifactMap = component.getToscaArtifacts();
418 if (artifactMap == null) {
419 artifactMap = new HashMap<>();
421 String componentUniqueId = component.getUniqueId();
422 String componentSystemName = component.getSystemName();
423 String componentType = component.getComponentType().getValue().toLowerCase();
424 Map<String, Object> toscaArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts();
426 if (toscaArtifacts != null) {
427 for (Entry<String, Object> artifactInfoMap : toscaArtifacts.entrySet()) {
428 Map<String, Object> artifactInfo = (Map<String, Object>) artifactInfoMap.getValue();
429 ArtifactDefinition artifactDefinition = artifactsBusinessLogic.createArtifactPlaceHolderInfo(componentUniqueId, artifactInfoMap.getKey(), artifactInfo, user, ArtifactGroupTypeEnum.TOSCA);
430 artifactDefinition.setArtifactName(ValidationUtils.normalizeFileName(componentType + "-" + componentSystemName + artifactInfo.get("artifactName")));
431 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
434 component.setToscaArtifacts(artifactMap);
437 public Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock) {
438 return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true, true);
441 public Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock, boolean retrieveResource) {
442 return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true, retrieveResource);
445 private Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock, boolean fetchTemplatesFromDB, boolean retrieveResource) {
446 if (retrieveResource) {
447 Either<Component, StorageOperationStatus> toscaElement = toscaOperationFacade.getToscaFullElement(component.getUniqueId());
448 if ( toscaElement.isRight() ){
449 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(toscaElement.right().value(), component.getComponentType()));
451 component = toscaElement.left().value();
454 Either<ArtifactDefinition, Operation> generateToscaRes =
455 saveToscaArtifactAndPopulateToscaArtifactsWithResult(component, componentsUtils,
456 ArtifactTypeEnum.TOSCA_TEMPLATE,
457 (comp, toscaArtifact) ->
458 saveToscaArtifactPayload(toscaArtifact, comp, user, isInCertificationRequest, shouldLock,
459 inTransaction, fetchTemplatesFromDB));
461 if (!isAbstractResource(component)) {
462 generateToscaRes = saveToscaArtifactAndPopulateToscaArtifactsWithResult(component, componentsUtils,
463 ArtifactTypeEnum.TOSCA_CSAR,
464 (comp, toscaArtifactArg) -> saveToscaArtifactPayload(toscaArtifactArg, comp, user,
465 isInCertificationRequest, shouldLock, inTransaction, true));
467 return generateToscaRes;
470 private static Either<ArtifactDefinition, Operation> saveToscaArtifactAndPopulateToscaArtifactsWithResult(
472 final ComponentsUtils componentsUtils,
473 final ArtifactTypeEnum artifactEnum,
474 final BiFunction<Component, ArtifactDefinition, Either<ArtifactDefinition, Operation>> saveToscaArtifactPayloadFunction) {
476 ArtifactDefinition artifactDefinition = getToscaArtifactByTypeOrThrowException(component, artifactEnum,
479 Either<ArtifactDefinition, Operation> result =
480 saveToscaArtifactPayloadFunction.apply(component, artifactDefinition);
482 if (result.isLeft()) {
483 ArtifactDefinition def = result.left().value();
484 component.getToscaArtifacts().put(def.getArtifactLabel(), def);
490 private static Optional<ArtifactDefinition> getToscaArtifactByType(
491 final Map<String, ArtifactDefinition> toscaArtifacts,
492 final ArtifactTypeEnum typeEnum) {
493 return toscaArtifacts.values().stream()
494 .filter(p -> p.getArtifactType().equals(typeEnum.getType()))
498 private static ArtifactDefinition getToscaArtifactByTypeOrThrowException(
499 final Component component,
500 final ArtifactTypeEnum typeEnum,
501 final ComponentsUtils componentsUtils) {
503 return Optional.ofNullable(component.getToscaArtifacts())
504 .flatMap(toscaArtifacts -> getToscaArtifactByType(toscaArtifacts, typeEnum))
506 log.debug("Impossible to find a ToscaArtifact with type '{}' for {}", typeEnum.getType(), component);
507 return new ByResponseFormatComponentException(
508 componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, typeEnum.name()));
512 private boolean isAbstractResource(Component component) {
513 return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource)component).isAbstract();
516 private Either<ArtifactDefinition, Operation> saveToscaArtifactPayload(ArtifactDefinition artifactDefinition, org.openecomp.sdc.be.model.Component component, User user, boolean isInCertificationRequest, boolean shouldLock,
517 boolean inTransaction, boolean fetchTemplatesFromDB) {
518 return artifactsBusinessLogic.generateAndSaveToscaArtifact(artifactDefinition, component, user, isInCertificationRequest, shouldLock, inTransaction, fetchTemplatesFromDB);
521 public ImmutablePair<String, byte[]> getToscaModelByComponentUuid(ComponentTypeEnum componentType, String uuid, ResourceCommonInfo resourceCommonInfo) {
523 Either<List<Component>, StorageOperationStatus> latestVersionEither = toscaOperationFacade.getComponentListByUuid(uuid, null);
525 if (latestVersionEither.isRight()) {
526 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(latestVersionEither.right().value(), componentType));
529 List<Component> components = latestVersionEither.left().value();
531 Component component = components.stream().filter(Component::isHighestVersion).findFirst().orElse(null);
532 if(component == null){
533 component = components.stream().filter(c -> c.getLifecycleState() == LifecycleStateEnum.CERTIFIED).findFirst().orElse(null);
536 if(component == null){
537 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, componentType)));
539 resourceCommonInfo.setResourceName(component.getName());
540 // TODO remove after migration - handle artifact not found(no
542 if (null == component.getToscaArtifacts() || component.getToscaArtifacts().isEmpty()) {
543 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ArtifactTypeEnum.TOSCA_CSAR.name()));
545 ArtifactDefinition csarArtifact = component.getToscaArtifacts().values().stream()
546 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType()))
548 return artifactsBusinessLogic.handleDownloadToscaModelRequest(component, csarArtifact);
551 protected StorageOperationStatus markComponentToDelete(Component component) {
553 ComponentTypeEnum componentType = component.getComponentType();
554 String uniqueId = component.getUniqueId();
555 if (Boolean.TRUE.equals(component.getIsDeleted())) {
556 log.info("component {} already marked as deleted. id= {}, type={}", component.getName(), uniqueId, componentType);
557 return StorageOperationStatus.NOT_FOUND;
560 StorageOperationStatus markResourceToDelete = toscaOperationFacade.markComponentToDelete(component);
561 if (StorageOperationStatus.OK != markResourceToDelete) {
562 log.debug("failed to mark component {} of type {} for delete. error = {}", uniqueId, componentType, markResourceToDelete);
563 return markResourceToDelete;
565 log.debug("Component {} of type {} was marked as deleted", uniqueId, componentType);
566 updateCatalog(component, ChangeTypeEnum.DELETE);
567 return StorageOperationStatus.OK;
571 public Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Component currentComponent, Component updatedComponent, AuditingActionEnum auditingAction) {
572 String descriptionUpdated = updatedComponent.getDescription();
573 String descriptionCurrent = currentComponent.getDescription();
574 if (descriptionUpdated != null && !descriptionCurrent.equals(descriptionUpdated)) {
575 componentDescriptionValidator.validateAndCorrectField(user, updatedComponent, auditingAction);
576 currentComponent.setDescription(updatedComponent.getDescription());
578 return Either.left(true);
581 public Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Component currentComponent, Component updatedComponent) {
582 String projectCodeUpdated = updatedComponent.getProjectCode();
583 String projectCodeCurrent = currentComponent.getProjectCode();
584 if (projectCodeUpdated != null && !projectCodeCurrent.equals(projectCodeUpdated)) {
586 componentProjectCodeValidator.validateAndCorrectField(user, updatedComponent, null);
587 } catch (ComponentException exp) {
588 ResponseFormat errorRespons = exp.getResponseFormat();
589 return Either.right(errorRespons);
591 currentComponent.setProjectCode(updatedComponent.getProjectCode());
593 return Either.left(true);
596 public Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Component currentComponent, Component updatedComponent, boolean hasBeenCertified) {
597 String iconUpdated = updatedComponent.getIcon();
598 String iconCurrent = currentComponent.getIcon();
599 if (iconUpdated != null && !iconCurrent.equals(iconUpdated)) {
600 if (!hasBeenCertified) {
601 componentIconValidator.validateAndCorrectField(user, updatedComponent, null);
602 currentComponent.setIcon(updatedComponent.getIcon());
604 log.info("icon {} cannot be updated once the component has been certified once.", iconUpdated);
605 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_PARAMETER_CANNOT_BE_CHANGED, "Icon", currentComponent.getComponentType().name().toLowerCase());
606 return Either.right(errorResponse);
609 return Either.left(true);
612 protected Either<List<String>, ResponseFormat> deleteMarkedComponents(ComponentTypeEnum componentType) {
614 log.trace("start deleteMarkedComponents");
615 Either<List<String>, StorageOperationStatus> deleteMarkedElements = toscaOperationFacade.deleteMarkedElements(componentType);
618 if ( deleteMarkedElements.isRight()){
619 janusGraphDao.rollback();
620 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteMarkedElements.right().value(), componentType));
621 return Either.right(responseFormat);
623 log.trace("end deleteMarkedComponents");
624 janusGraphDao.commit();
625 return Either.left(deleteMarkedElements.left().value());
628 public Either<List<ArtifactDefinition>, StorageOperationStatus> getComponentArtifactsForDelete(String parentId, NodeTypeEnum parentType) {
629 List<ArtifactDefinition> artifacts = new ArrayList<>();
630 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse = artifactToscaOperation.getArtifacts(parentId);
631 if (artifactsResponse.isRight()) {
632 if (artifactsResponse.right().value() != StorageOperationStatus.NOT_FOUND) {
633 log.debug("failed to retrieve artifacts for {} {}", parentType, parentId);
634 return Either.right(artifactsResponse.right().value());
637 artifacts.addAll(artifactsResponse.left().value().values());
639 return Either.left(artifacts);
646 * @param dataParamsToReturn - ui list of params to return
650 public Either<UiComponentDataTransfer, ResponseFormat> getComponentDataFilteredByParams(String componentId, User user, List<String> dataParamsToReturn) {
653 validateUserExists(user);
656 UiComponentDataTransfer result = new UiComponentDataTransfer();
658 if(dataParamsToReturn == null || dataParamsToReturn.isEmpty()) {
662 Either<UiComponentDataTransfer, ResponseFormat> uiDataTransferEither = getUiComponentDataTransferByComponentId(componentId, dataParamsToReturn);
663 if(uiDataTransferEither.isRight()){
664 return Either.right(uiDataTransferEither.right().value());
666 result = uiDataTransferEither.left().value();
669 return Either.left(result);
672 protected <T extends Component> void generateAndAddInputsFromGenericTypeProperties(T component, Resource genericType) {
673 List<InputDefinition> genericAndComponentInputs = new ArrayList<>();
674 List<InputDefinition> genericInputs = genericTypeBusinessLogic.generateInputsFromGenericTypeProperties(genericType);
675 genericAndComponentInputs.addAll(genericInputs);
676 if (null != component.getInputs()){
677 List<InputDefinition> nonGenericInputsFromComponent = getAllNonGenericInputsFromComponent(genericInputs, component.getInputs());
678 genericAndComponentInputs.addAll(nonGenericInputsFromComponent);
680 component.setInputs(genericAndComponentInputs);
683 private List<InputDefinition> getAllNonGenericInputsFromComponent(List<InputDefinition> genericInputs, List<InputDefinition> componentInputs) {
684 if (genericInputs == null) {
685 return componentInputs;
688 Map<String, InputDefinition> inputByNameMap = MapUtil.toMap(genericInputs, InputDefinition::getName);
689 List<InputDefinition> componentNonGenericInputs = new ArrayList<>();
690 componentInputs.stream().forEach(input -> {
691 if (!inputByNameMap.containsKey(input.getName())) {
692 componentNonGenericInputs.add(input);
695 return componentNonGenericInputs;
698 protected <T extends Component> Resource fetchAndSetDerivedFromGenericType(T component){
699 Either<Resource, ResponseFormat> genericTypeEither = this.genericTypeBusinessLogic.fetchDerivedFromGenericType(component);
700 if(genericTypeEither.isRight()){
701 log.debug("Failed to fetch latest generic type for component {} of type", component.getName(), component.assetType());
702 throw new ByActionStatusComponentException(ActionStatus.GENERIC_TYPE_NOT_FOUND, component.assetType());
704 Resource genericTypeResource = genericTypeEither.left().value();
705 component.setDerivedFromGenericInfo(genericTypeResource);
706 return genericTypeResource;
709 public Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstanceProperties(String componentId, Map<FilterKeyEnum, List<String>> filters, String userId) {
710 Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> response = null;
711 Either<Component, StorageOperationStatus> getResourceRes = null;
713 if(!filters.containsKey(FilterKeyEnum.NAME_FRAGMENT) && StringUtils.isEmpty(filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0))){
714 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
716 if (userId != null && response == null) {
717 validateUserExists(userId);
719 if(response == null){
720 getResourceRes = toscaOperationFacade.getToscaElement(componentId);
721 if(getResourceRes.isRight()){
722 response = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getResourceRes.right().value())));
725 if(response == null){
726 response = getFilteredComponentInstancesProperties(getResourceRes.left().value(), filters);
728 } catch(Exception e){
729 log.debug("The exception {} occured during filtered instance properties fetching. the containing component is {}. ", e, componentId);
730 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
732 if (response != null && response.isLeft()){
733 toscaOperationFacade.commit();
735 toscaOperationFacade.rollback();
741 private Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstancesProperties(Component component, Map<FilterKeyEnum, List<String>> filters) {
743 Map<String, List<IComponentInstanceConnectedElement>> filteredProperties = new HashMap<>();
744 Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> result = Either.left(filteredProperties);
745 List<ComponentInstance> filteredInstances = getFilteredInstances(component, filters.get(FilterKeyEnum.RESOURCE_TYPE));
746 String propertyNameFragment= filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0);
747 boolean searchByFragment = propertyNameFragment.length() > 3 ;
748 if(CollectionUtils.isNotEmpty(filteredInstances)){
749 for(ComponentInstance instance : filteredInstances){
750 if(component.getComponentInstancesProperties()!=null &&component.getComponentInstancesProperties().containsKey(instance.getUniqueId())){
751 List<IComponentInstanceConnectedElement> currProperties = getFilteredComponentInstanceProperties(component.getComponentInstancesProperties().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
752 setFilteredProperties(filteredProperties, instance, currProperties);
754 if(component.getComponentInstancesInputs()!=null && component.getComponentInstancesInputs().containsKey(instance.getUniqueId())){
755 List<IComponentInstanceConnectedElement> currInputs = getFilteredComponentInstanceInputs(component.getComponentInstancesInputs().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
756 if(CollectionUtils.isNotEmpty(currInputs)){
757 checkFilteredProperties(filteredProperties, instance, currInputs);
765 private void setFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance, List<IComponentInstanceConnectedElement> currProperties) {
766 if(CollectionUtils.isNotEmpty(currProperties)){
767 filteredProperties.put(instance.getUniqueId(), currProperties);
771 private void checkFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance, List<IComponentInstanceConnectedElement> currInputs) {
772 if(filteredProperties.get(instance.getUniqueId())!=null){
773 filteredProperties.get(instance.getUniqueId()).addAll(currInputs);
775 filteredProperties.put(instance.getUniqueId(), currInputs);
779 private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceInputs(List<ComponentInstanceInput> inputs, String propertyNameFragment, boolean searchByFragment) {
780 return inputs.stream().filter(i -> isMatchingInput(i, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
783 private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceProperties(List<ComponentInstanceProperty> instanceProperties, String propertyNameFragment, boolean searchByFragment) {
784 return instanceProperties.stream().filter(p -> isMatchingProperty(p, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
787 private boolean isMatchingInput(ComponentInstanceInput input, String propertyNameFragment, boolean searchByFragment) {
788 boolean isMatching = false;
789 if(searchByFragment && input.getName().toLowerCase().contains(propertyNameFragment)){
792 if(!searchByFragment && input.getName().equalsIgnoreCase(propertyNameFragment)){
798 private boolean isMatchingProperty(ComponentInstanceProperty property, String propertyNameFragment, boolean searchByFragment) {
799 boolean isMatching = false;
800 if(searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment)){
803 if(!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)){
806 if (!isMatching && !ToscaPropertyType.isPrimitiveType(property.getType())){
807 isMatching = isMatchingComplexPropertyByRecursively(property, propertyNameFragment, searchByFragment);
812 private boolean isMatchingComplexPropertyByRecursively(PropertyDataDefinition property, String propertyNameFragment, boolean searchByFragment) {
814 List<PropertyDefinition> dataTypeProperties;
815 DataTypeDefinition currentProperty;
816 if(searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment.toLowerCase())){
819 if(!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)){
823 propertyType = isEmptyInnerType(property) ? property.getType() : property.getSchema().getProperty().getType();
825 if(ToscaPropertyType.isScalarType(propertyType)){
828 Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameRes = propertyOperation.getDataTypeByName(propertyType);
829 if(getDataTypeByNameRes.isRight()){
832 currentProperty = getDataTypeByNameRes.left().value();
833 dataTypeProperties = currentProperty.getProperties();
835 boolean dataPropertiesNotNull = CollectionUtils.isNotEmpty(dataTypeProperties);
836 BooleanSupplier dataMatchesComplexProperty = () -> isMatchingComplexProperty(propertyNameFragment,
837 searchByFragment, dataTypeProperties);
838 BooleanSupplier parentPropertiesNotNull = () -> CollectionUtils
839 .isNotEmpty(currentProperty.getDerivedFrom().getProperties());
840 BooleanSupplier parentDataMatchesComplexProperty = () -> isMatchingComplexProperty(propertyNameFragment,
841 searchByFragment, currentProperty.getDerivedFrom().getProperties());
843 return ((dataPropertiesNotNull && dataMatchesComplexProperty.getAsBoolean())
844 || (parentPropertiesNotNull.getAsBoolean() && parentDataMatchesComplexProperty.getAsBoolean()));
847 private boolean isMatchingComplexProperty(String propertyNameFragment, boolean searchByFragment, List<PropertyDefinition> dataTypeProperties) {
848 for(PropertyDefinition prop : dataTypeProperties){
849 if(isMatchingComplexPropertyByRecursively(prop, propertyNameFragment, searchByFragment)){
856 private boolean isEmptyInnerType(PropertyDataDefinition property) {
857 return property == null|| property.getSchema() == null || property.getSchema().getProperty() == null || property.getSchema().getProperty().getType() == null;
860 public Either<Boolean, ResponseFormat> shouldUpgradeToLatestGeneric(Component clonedComponent) {
862 if(!clonedComponent.deriveFromGeneric())
863 return Either.left(false);
864 Boolean shouldUpgrade = false;
865 String currentGenericType = clonedComponent.getDerivedFromGenericType();
866 String currentGenericVersion = clonedComponent.getDerivedFromGenericVersion();
867 Resource genericTypeResource = fetchAndSetDerivedFromGenericType(clonedComponent);
868 if(null == currentGenericType || !currentGenericType.equals(genericTypeResource.getToscaResourceName()) || !currentGenericVersion.equals(genericTypeResource.getVersion())){
869 shouldUpgrade = upgradeToLatestGeneric(clonedComponent, genericTypeResource);
871 reverntUpdateOfGenericVersion(clonedComponent, currentGenericType, currentGenericVersion);
874 return Either.left(shouldUpgrade);
877 private void reverntUpdateOfGenericVersion(Component clonedComponent, String currentGenericType, String currentGenericVersion) {
878 clonedComponent.setDerivedFromGenericType(currentGenericType);
879 clonedComponent.setDerivedFromGenericVersion(currentGenericVersion);
882 private <T extends PropertyDataDefinition> Either<Map<String, T>, String> validateNoConflictingProperties(List<T> currentList, List<T> upgradedList) {
883 Map<String, T> currentMap = ToscaDataDefinition.listToMapByName(currentList);
884 Map<String, T> upgradedMap = ToscaDataDefinition.listToMapByName(upgradedList);
885 return ToscaDataDefinition.mergeDataMaps(upgradedMap, currentMap, true);
888 private boolean shouldUpgradeNodeType(Component componentToCheckOut, Resource latestGeneric){
890 List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
891 Either<Map<String, PropertyDefinition>, String> validMerge = validateNoConflictingProperties(genericTypeProps, ((Resource)componentToCheckOut).getProperties());
892 if (validMerge.isRight()) {
893 log.debug("property {} cannot be overriden, check out performed without upgrading to latest generic", validMerge.right().value());
896 List<PropertyDefinition> genericTypeAttributes = latestGeneric.getAttributes();
897 validMerge = validateNoConflictingProperties(genericTypeAttributes, ((Resource)componentToCheckOut).getAttributes());
898 if (validMerge.isRight()) {
899 log.debug("attribute {} cannot be overriden, check out performed without upgrading to latest generic", validMerge.right().value());
905 private boolean upgradeToLatestGeneric(Component componentToCheckOut, Resource latestGeneric) {
907 if (!componentToCheckOut.shouldGenerateInputs()) {
908 //node type - validate properties and attributes
909 return shouldUpgradeNodeType(componentToCheckOut, latestGeneric);
911 List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
912 List<InputDefinition> genericTypeInputs = null == genericTypeProps? null : genericTypeBusinessLogic.convertGenericTypePropertiesToInputsDefintion(genericTypeProps, latestGeneric.getUniqueId());
913 List<InputDefinition> currentList = new ArrayList<>();
914 // nullify existing ownerId from existing list and merge into updated list
915 if (null != componentToCheckOut.getInputs()) {
916 for(InputDefinition input : componentToCheckOut.getInputs()) {
917 InputDefinition copy = new InputDefinition(input);
918 copy.setOwnerId(null);
919 currentList.add(copy);
922 if (null == genericTypeInputs) {
923 componentToCheckOut.setInputs(currentList);
927 Either<Map<String, InputDefinition>, String> eitherMerged = validateNoConflictingProperties(genericTypeInputs, currentList);
928 if (eitherMerged.isRight()) {
929 log.debug("input {} cannot be overriden, check out performed without upgrading to latest generic", eitherMerged.right().value());
932 componentToCheckOut.setInputs(new ArrayList<>(eitherMerged.left().value().values()));
937 private List<ComponentInstance> getFilteredInstances(Component component, List<String> resourceTypes) {
938 List<ComponentInstance> filteredInstances = null;
939 if(CollectionUtils.isEmpty(resourceTypes)){
940 filteredInstances = component.getComponentInstances();
942 else if(CollectionUtils.isNotEmpty(component.getComponentInstances())){
943 filteredInstances = component.getComponentInstances()
944 .stream().filter(i -> isMatchingType(i.getOriginType(), resourceTypes)).collect(Collectors.toList());
946 if(filteredInstances == null){
947 filteredInstances = new ArrayList<>();
949 return filteredInstances;
952 private boolean isMatchingType(OriginTypeEnum originType, List<String> resourceTypes) {
953 boolean isMatchingType = false;
954 for(String resourceType : resourceTypes){
955 if(originType == OriginTypeEnum.findByValue(resourceType.toUpperCase())){
956 isMatchingType = true;
960 return isMatchingType;
963 public Either<Component, ActionStatus> shouldUpgradeToLatestDerived(Component clonedComponent) {
964 //general implementation. Must be error for service, VF . In ResourceBuisnessLogic exist override
965 return Either.right(ActionStatus.GENERAL_ERROR);
968 protected Either<Component, ResponseFormat> updateCatalog(Component component, ChangeTypeEnum changeStatus){
969 log.debug("update Catalog start with Component Type {} And Componet Name {} with change status {}", component.getComponentType().name(), component.getName(), changeStatus.name());
970 ActionStatus status = catalogOperations.updateCatalog(changeStatus,component);
971 if(status != ActionStatus.OK){
972 return Either.right( componentsUtils.getResponseFormat(status));
975 return Either.left(component);
978 public CatalogOperation getCatalogOperations() {
979 return catalogOperations;
983 public void setCatalogOperations(CatalogOperation catalogOperations) {
984 this.catalogOperations = catalogOperations;
987 public List<GroupDefinition> throwComponentException(ResponseFormat responseFormat) {
988 throw new ByResponseFormatComponentException(responseFormat);