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 org.apache.commons.collections.CollectionUtils;
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.commons.lang3.tuple.ImmutablePair;
29 import org.openecomp.sdc.be.catalog.enums.ChangeTypeEnum;
30 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
31 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
32 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
33 import org.openecomp.sdc.be.components.impl.generic.GenericTypeBusinessLogic;
34 import org.openecomp.sdc.be.components.validation.component.ComponentContactIdValidator;
35 import org.openecomp.sdc.be.components.validation.component.ComponentDescriptionValidator;
36 import org.openecomp.sdc.be.components.validation.component.ComponentIconValidator;
37 import org.openecomp.sdc.be.components.validation.component.ComponentNameValidator;
38 import org.openecomp.sdc.be.components.validation.component.ComponentProjectCodeValidator;
39 import org.openecomp.sdc.be.components.validation.component.ComponentTagsValidator;
40 import org.openecomp.sdc.be.components.validation.component.ComponentValidator;
41 import org.openecomp.sdc.be.config.BeEcompErrorManager;
42 import org.openecomp.sdc.be.config.ConfigurationManager;
43 import org.openecomp.sdc.be.dao.api.ActionStatus;
44 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
45 import org.openecomp.sdc.be.dao.utils.MapUtil;
46 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
47 import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition;
48 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
49 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
50 import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum;
51 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
52 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
53 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
54 import org.openecomp.sdc.be.facade.operations.CatalogOperation;
55 import org.openecomp.sdc.be.model.ArtifactDefinition;
56 import org.openecomp.sdc.be.model.CapReqDef;
57 import org.openecomp.sdc.be.model.Component;
58 import org.openecomp.sdc.be.model.ComponentInstance;
59 import org.openecomp.sdc.be.model.ComponentInstanceInput;
60 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
61 import org.openecomp.sdc.be.model.ComponentParametersView;
62 import org.openecomp.sdc.be.model.DataTypeDefinition;
63 import org.openecomp.sdc.be.model.GroupDefinition;
64 import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement;
65 import org.openecomp.sdc.be.model.InputDefinition;
66 import org.openecomp.sdc.be.model.LifecycleStateEnum;
67 import org.openecomp.sdc.be.model.Operation;
68 import org.openecomp.sdc.be.model.PropertyDefinition;
69 import org.openecomp.sdc.be.model.Resource;
70 import org.openecomp.sdc.be.model.User;
71 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
72 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
73 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
74 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
75 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
76 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
77 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
78 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
79 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
80 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
81 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
82 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
83 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
84 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
85 import org.openecomp.sdc.be.user.Role;
86 import org.openecomp.sdc.be.utils.CommonBeUtils;
87 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
88 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
89 import org.openecomp.sdc.common.log.wrappers.Logger;
90 import org.openecomp.sdc.common.util.ValidationUtils;
91 import org.openecomp.sdc.exception.ResponseFormat;
92 import org.springframework.beans.factory.annotation.Autowired;
94 import java.util.ArrayList;
95 import java.util.HashMap;
96 import java.util.List;
98 import java.util.Map.Entry;
99 import java.util.stream.Collectors;
101 public abstract class ComponentBusinessLogic extends BaseBusinessLogic {
103 protected ArtifactsBusinessLogic artifactsBusinessLogic;
105 protected final GroupBusinessLogic groupBusinessLogic;
107 protected GenericTypeBusinessLogic genericTypeBusinessLogic;
109 protected ComponentDescriptionValidator componentDescriptionValidator;
110 protected ComponentProjectCodeValidator componentProjectCodeValidator;
112 protected CatalogOperation catalogOperations;
113 protected ComponentIconValidator componentIconValidator;
115 protected ComponentValidator componentValidator;
116 protected ComponentTagsValidator componentTagsValidator;
117 protected ComponentNameValidator componentNameValidator;
118 protected ComponentContactIdValidator componentContactIdValidator;
120 public ComponentBusinessLogic(IElementOperation elementDao,
121 IGroupOperation groupOperation,
122 IGroupInstanceOperation groupInstanceOperation,
123 IGroupTypeOperation groupTypeOperation,
124 GroupBusinessLogic groupBusinessLogic,
125 InterfaceOperation interfaceOperation,
126 InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
127 ArtifactsBusinessLogic artifactsBusinessLogic,
128 ArtifactsOperations artifactToscaOperation,
129 ComponentContactIdValidator componentContactIdValidator,
130 ComponentNameValidator componentNameValidator,
131 ComponentTagsValidator componentTagsValidator,
132 ComponentValidator componentValidator,
133 ComponentIconValidator componentIconValidator,
134 ComponentProjectCodeValidator componentProjectCodeValidator,
135 ComponentDescriptionValidator componentDescriptionValidator){
137 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation,
138 interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
139 this.artifactsBusinessLogic = artifactsBusinessLogic;
140 this.groupBusinessLogic = groupBusinessLogic;
141 this.componentContactIdValidator = componentContactIdValidator;
142 this.componentNameValidator = componentNameValidator;
143 this.componentTagsValidator = componentTagsValidator;
144 this.componentValidator = componentValidator;
145 this.componentIconValidator = componentIconValidator;
146 this.componentProjectCodeValidator = componentProjectCodeValidator;
147 this.componentDescriptionValidator = componentDescriptionValidator;
150 public void setComponentDescriptionValidator(ComponentDescriptionValidator componentDescriptionValidator) {
151 this.componentDescriptionValidator = componentDescriptionValidator;
154 public void setComponentProjectCodeValidator(ComponentProjectCodeValidator componentProjectCodeValidator) {
155 this.componentProjectCodeValidator = componentProjectCodeValidator;
158 public void setComponentIconValidator(ComponentIconValidator componentIconValidator) {
159 this.componentIconValidator = componentIconValidator;
162 public void setComponentContactIdValidator(ComponentContactIdValidator componentContactIdValidator) {
163 this.componentContactIdValidator = componentContactIdValidator;
166 public void setComponentTagsValidator(ComponentTagsValidator componentTagsValidator) {
167 this.componentTagsValidator = componentTagsValidator;
170 public void setComponentNameValidator(ComponentNameValidator componentNameValidator) {
171 this.componentNameValidator = componentNameValidator;
176 public void setGenericTypeBusinessLogic(GenericTypeBusinessLogic genericTypeBusinessLogic) {
177 this.genericTypeBusinessLogic = genericTypeBusinessLogic;
180 private static final Logger log = Logger.getLogger(ComponentBusinessLogic.class.getName());
182 private static final String TAG_FIELD_LABEL = "tag";
184 public abstract Either<List<String>, ResponseFormat> deleteMarkedComponents();
186 public abstract ComponentInstanceBusinessLogic getComponentInstanceBL();
188 public abstract Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId);
193 * @param dataParamsToReturn
196 public abstract Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String componentId, List<String> dataParamsToReturn);
198 User validateUser(User user, String ecompErrorContext, Component component, AuditingActionEnum auditAction, boolean inTransaction) {
200 ResponseFormat responseFormat;
202 validateUserNotEmpty(user, ecompErrorContext);
203 validatedUser = validateUserExists(user);
204 } catch(ByActionStatusComponentException e){
205 if(e.getActionStatus() == ActionStatus.MISSING_INFORMATION){
206 user.setUserId("UNKNOWN");
208 responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
209 componentsUtils.auditComponentAdmin(responseFormat, user, component, auditAction, component.getComponentType());
211 } catch(ByResponseFormatComponentException e){
212 responseFormat = e.getResponseFormat();
213 componentsUtils.auditComponentAdmin(responseFormat, user, component, auditAction, component.getComponentType());
216 return validatedUser;
219 protected void validateUserRole(User user, Component component, List<Role> roles, AuditingActionEnum auditAction, String comment) {
220 if (roles != null && roles.isEmpty()) {
221 roles.add(Role.ADMIN);
222 roles.add(Role.DESIGNER);
225 validateUserRole(user, roles);
226 }catch (ByActionStatusComponentException e) {
227 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
228 handleComponentException(component, comment, responseFormat, user, auditAction);
230 }catch (ByResponseFormatComponentException e) {
231 ResponseFormat responseFormat = e.getResponseFormat();
232 handleComponentException(component, comment, responseFormat, user, auditAction);
237 private void handleComponentException(Component component, String comment, ResponseFormat responseFormat,
238 User user, AuditingActionEnum auditAction){
239 String commentStr = null;
240 String distrStatus = null;
241 ComponentTypeEnum componentType = component.getComponentType();
242 if (componentType == ComponentTypeEnum.SERVICE) {
243 distrStatus = ((ServiceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition()).getDistributionStatus();
244 commentStr = comment;
246 componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(componentType.getValue()),
247 ResourceVersionInfo.newBuilder().distributionStatus(distrStatus).build(),
248 ResourceVersionInfo.newBuilder().distributionStatus(distrStatus).build(),
249 commentStr, null, null);
252 public Either<Boolean, ResponseFormat> validateConformanceLevel(String componentUuid, ComponentTypeEnum componentTypeEnum, String userId) {
253 log.trace("validate conformance level");
255 if (componentTypeEnum != ComponentTypeEnum.SERVICE) {
256 log.error("conformance level validation for non service component, id {}", componentUuid);
257 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
258 return Either.right(errorResponse);
261 validateUserExists(userId);
263 Either<ComponentMetadataData, StorageOperationStatus> eitherComponent = toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, null);
264 if (eitherComponent.isRight()) {
265 log.error("can't validate conformance level, component not found, uuid {}", componentUuid);
266 BeEcompErrorManager.getInstance().logBeComponentMissingError("validateConformanceLevel", componentTypeEnum.getValue(), componentUuid);
268 StorageOperationStatus status = eitherComponent.right().value();
269 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(status, componentTypeEnum);
270 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus);
271 return Either.right(responseFormat);
274 String componentConformanceLevel = eitherComponent.left().value().getMetadataDataDefinition().getConformanceLevel();
275 if (StringUtils.isBlank(componentConformanceLevel)) {
276 log.error("component conformance level property is null or empty, uuid {}", componentUuid);
277 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
278 return Either.right(errorResponse);
281 String configConformanceLevel = ConfigurationManager.getConfigurationManager().getConfiguration().getMinToscaConformanceLevel();
282 Boolean result = true;
283 if (CommonBeUtils.conformanceLevelCompare(componentConformanceLevel, configConformanceLevel) < 0) {
284 log.error("invalid asset conformance level, uuid {}, asset conformanceLevel {}, config conformanceLevel {}", componentUuid, componentConformanceLevel, configConformanceLevel);
287 log.trace("conformance level validation finished");
289 return Either.left(result);
293 protected void checkComponentFieldsForOverrideAttempt(Component component) {
294 if (component.getLifecycleState() != null) {
295 log.info("LifecycleState cannot be defined by user. This field will be overridden by the application");
297 if (component.getVersion() != null) {
298 log.info("Version cannot be defined by user. This field will be overridden by the application");
300 if (component.getCreatorUserId() != null || component.getCreatorFullName() != null) {
301 log.info("Creator cannot be defined by user. This field will be overridden by the application");
303 if (component.getLastUpdaterUserId() != null || component.getLastUpdaterFullName() != null) {
304 log.info("Last Updater cannot be defined by user. This field will be overridden by the application");
306 if (component.getCreationDate() != null) {
307 log.info("Creation Date cannot be defined by user. This field will be overridden by the application");
309 if (component.isHighestVersion() != null) {
310 log.info("Is Highest Version cannot be defined by user. This field will be overridden by the application");
312 if (component.getUUID() != null) {
313 log.info("UUID cannot be defined by user. This field will be overridden by the application");
315 if (component.getLastUpdateDate() != null) {
316 log.info("Last Update Date cannot be defined by user. This field will be overridden by the application");
318 if (component.getUniqueId() != null) {
319 log.info("uid cannot be defined by user. This field will be overridden by the application.");
320 component.setUniqueId(null);
322 if (component.getInvariantUUID() != null) {
323 log.info("Invariant UUID cannot be defined by user. This field will be overridden by the application.");
327 public CapReqDef getRequirementsAndCapabilities(String componentId, ComponentTypeEnum componentTypeEnum, String userId) {
329 validateUserExists(userId);
330 ComponentParametersView filter = new ComponentParametersView(true);
331 filter.setIgnoreCapabilities(false);
332 filter.setIgnoreRequirements(false);
333 filter.setIgnoreComponentInstances(false);
336 Component component = validateComponentExists(componentId, componentTypeEnum, filter);
337 return new CapReqDef(component.getRequirements(), component.getCapabilities());
338 }catch (ComponentException e){
339 BeEcompErrorManager.getInstance().logBeComponentMissingError("getRequirementsAndCapabilities", componentTypeEnum.getValue(), componentId);
340 throwComponentException(e.getResponseFormat());
345 public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponents(boolean isAbstractAbstract, ComponentTypeEnum componentTypeEnum, String internalComponentType, List<String> componentUids,
348 validateUserExists(userId);
349 List<Component> result = new ArrayList<>();
350 List<String> componentsUidToFetch = new ArrayList<>();
351 componentsUidToFetch.addAll(componentUids);
352 if (!componentsUidToFetch.isEmpty()) {
353 log.debug("Number of Components to fetch from graph is {}", componentsUidToFetch.size());
354 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade.getLatestVersionNotAbstractComponents(isAbstractAbstract, componentTypeEnum, internalComponentType, componentsUidToFetch);
356 if (nonCheckoutCompResponse.isLeft()) {
357 log.debug("Retrived Resource successfully.");
358 result.addAll(nonCheckoutCompResponse.left().value());
360 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value())));
363 return Either.left(result);
366 janusGraphDao.commit();
370 private Boolean isHighest(HighestFilterEnum highestFilter) {
371 Boolean isHighest = null;
372 switch (highestFilter) {
378 case NON_HIGHEST_ONLY:
387 public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponentsMetadata(boolean isAbstractAbstract, HighestFilterEnum highestFilter, ComponentTypeEnum componentTypeEnum, String internalComponentType, String userId) {
388 ResponseFormat responseFormat = null;
391 validateUserExists(userId);
392 Boolean isHighest = isHighest(highestFilter);
393 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade.getLatestVersionNotAbstractMetadataOnly(isAbstractAbstract, componentTypeEnum, internalComponentType);
395 if (nonCheckoutCompResponse.isLeft()) {
396 log.debug("Retrieved Resource successfully.");
397 return Either.left(nonCheckoutCompResponse.left().value());
399 responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value()));
401 janusGraphDao.commit();
403 return Either.right(responseFormat);
406 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
410 @SuppressWarnings("unchecked")
411 public void setToscaArtifactsPlaceHolders(Component component, User user) {
412 Map<String, ArtifactDefinition> artifactMap = component.getToscaArtifacts();
413 if (artifactMap == null) {
414 artifactMap = new HashMap<>();
416 String componentUniqueId = component.getUniqueId();
417 String componentSystemName = component.getSystemName();
418 String componentType = component.getComponentType().getValue().toLowerCase();
419 Map<String, Object> toscaArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts();
421 if (toscaArtifacts != null) {
422 for (Entry<String, Object> artifactInfoMap : toscaArtifacts.entrySet()) {
423 Map<String, Object> artifactInfo = (Map<String, Object>) artifactInfoMap.getValue();
424 ArtifactDefinition artifactDefinition = artifactsBusinessLogic.createArtifactPlaceHolderInfo(componentUniqueId, artifactInfoMap.getKey(), artifactInfo, user, ArtifactGroupTypeEnum.TOSCA);
425 artifactDefinition.setArtifactName(ValidationUtils.normalizeFileName(componentType + "-" + componentSystemName + artifactInfo.get("artifactName")));
426 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
429 component.setToscaArtifacts(artifactMap);
432 public Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock) {
433 return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true, true);
436 public Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock, boolean retrieveResource) {
437 return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true, retrieveResource);
440 private Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock, boolean fetchTemplatesFromDB, boolean retrieveResource) {
441 if (retrieveResource) {
442 Either<Component, StorageOperationStatus> toscaElement = toscaOperationFacade.getToscaFullElement(component.getUniqueId());
443 if ( toscaElement.isRight() ){
444 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(toscaElement.right().value(), component.getComponentType()));
446 component = toscaElement.left().value();
449 Either<ArtifactDefinition, Operation> generateToscaRes = null;
450 if (component.getToscaArtifacts() != null && !component.getToscaArtifacts().isEmpty()) {
451 ArtifactDefinition toscaArtifact = component.getToscaArtifacts().values().stream()
452 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_TEMPLATE.getType()))
454 generateToscaRes = saveToscaArtifactPayload(toscaArtifact, component, user, isInCertificationRequest, shouldLock, inTransaction, fetchTemplatesFromDB);
455 toscaArtifact = generateToscaRes.left().value();
456 component.getToscaArtifacts().put(toscaArtifact.getArtifactLabel(), toscaArtifact);
457 if(!isAbstractResource(component)){
458 toscaArtifact = component.getToscaArtifacts().values().stream()
459 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType()))
461 generateToscaRes = saveToscaArtifactPayload(toscaArtifact, component, user, isInCertificationRequest, shouldLock, inTransaction, true);
462 if (generateToscaRes.isRight()) {
463 return generateToscaRes;
465 toscaArtifact = generateToscaRes.left().value();
466 component.getToscaArtifacts().put(toscaArtifact.getArtifactLabel(), toscaArtifact);
469 return generateToscaRes;
472 private boolean isAbstractResource(Component component) {
473 return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource)component).isAbstract();
476 private Either<ArtifactDefinition, Operation> saveToscaArtifactPayload(ArtifactDefinition artifactDefinition, org.openecomp.sdc.be.model.Component component, User user, boolean isInCertificationRequest, boolean shouldLock,
477 boolean inTransaction, boolean fetchTemplatesFromDB) {
478 return artifactsBusinessLogic.generateAndSaveToscaArtifact(artifactDefinition, component, user, isInCertificationRequest, shouldLock, inTransaction, fetchTemplatesFromDB);
481 public ImmutablePair<String, byte[]> getToscaModelByComponentUuid(ComponentTypeEnum componentType, String uuid, ResourceCommonInfo resourceCommonInfo) {
483 Either<List<Component>, StorageOperationStatus> latestVersionEither = toscaOperationFacade.getComponentListByUuid(uuid, null);
485 if (latestVersionEither.isRight()) {
486 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(latestVersionEither.right().value(), componentType));
489 List<Component> components = latestVersionEither.left().value();
491 Component component = components.stream().filter(Component::isHighestVersion).findFirst().orElse(null);
492 if(component == null){
493 component = components.stream().filter(c -> c.getLifecycleState() == LifecycleStateEnum.CERTIFIED).findFirst().orElse(null);
496 if(component == null){
497 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, componentType)));
499 resourceCommonInfo.setResourceName(component.getName());
500 // TODO remove after migration - handle artifact not found(no
502 if (null == component.getToscaArtifacts() || component.getToscaArtifacts().isEmpty()) {
503 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ArtifactTypeEnum.TOSCA_CSAR.name()));
505 ArtifactDefinition csarArtifact = component.getToscaArtifacts().values().stream()
506 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType()))
508 return artifactsBusinessLogic.handleDownloadToscaModelRequest(component, csarArtifact);
511 protected StorageOperationStatus markComponentToDelete(Component component) {
513 ComponentTypeEnum componentType = component.getComponentType();
514 String uniqueId = component.getUniqueId();
515 if (Boolean.TRUE.equals(component.getIsDeleted())) {
516 log.info("component {} already marked as deleted. id= {}, type={}", component.getName(), uniqueId, componentType);
517 return StorageOperationStatus.NOT_FOUND;
520 StorageOperationStatus markResourceToDelete = toscaOperationFacade.markComponentToDelete(component);
521 if (StorageOperationStatus.OK != markResourceToDelete) {
522 log.debug("failed to mark component {} of type {} for delete. error = {}", uniqueId, componentType, markResourceToDelete);
523 return markResourceToDelete;
525 log.debug("Component {} of type {} was marked as deleted", uniqueId, componentType);
526 updateCatalog(component, ChangeTypeEnum.DELETE);
527 return StorageOperationStatus.OK;
531 public Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Component currentComponent, Component updatedComponent, AuditingActionEnum auditingAction) {
532 String descriptionUpdated = updatedComponent.getDescription();
533 String descriptionCurrent = currentComponent.getDescription();
534 if (descriptionUpdated != null && !descriptionCurrent.equals(descriptionUpdated)) {
535 componentDescriptionValidator.validateAndCorrectField(user, updatedComponent, auditingAction);
536 currentComponent.setDescription(updatedComponent.getDescription());
538 return Either.left(true);
541 public Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Component currentComponent, Component updatedComponent) {
542 String projectCodeUpdated = updatedComponent.getProjectCode();
543 String projectCodeCurrent = currentComponent.getProjectCode();
544 if (projectCodeUpdated != null && !projectCodeCurrent.equals(projectCodeUpdated)) {
546 componentProjectCodeValidator.validateAndCorrectField(user, updatedComponent, null);
547 } catch (ComponentException exp) {
548 ResponseFormat errorRespons = exp.getResponseFormat();
549 return Either.right(errorRespons);
551 currentComponent.setProjectCode(updatedComponent.getProjectCode());
553 return Either.left(true);
556 public Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Component currentComponent, Component updatedComponent, boolean hasBeenCertified) {
557 String iconUpdated = updatedComponent.getIcon();
558 String iconCurrent = currentComponent.getIcon();
559 if (iconUpdated != null && !iconCurrent.equals(iconUpdated)) {
560 if (!hasBeenCertified) {
561 componentIconValidator.validateAndCorrectField(user, updatedComponent, null);
562 currentComponent.setIcon(updatedComponent.getIcon());
564 log.info("icon {} cannot be updated once the component has been certified once.", iconUpdated);
565 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_PARAMETER_CANNOT_BE_CHANGED, "Icon", currentComponent.getComponentType().name().toLowerCase());
566 return Either.right(errorResponse);
569 return Either.left(true);
572 protected Either<List<String>, ResponseFormat> deleteMarkedComponents(ComponentTypeEnum componentType) {
574 log.trace("start deleteMarkedComponents");
575 Either<List<String>, StorageOperationStatus> deleteMarkedElements = toscaOperationFacade.deleteMarkedElements(componentType);
578 if ( deleteMarkedElements.isRight()){
579 janusGraphDao.rollback();
580 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteMarkedElements.right().value(), componentType));
581 return Either.right(responseFormat);
583 log.trace("end deleteMarkedComponents");
584 janusGraphDao.commit();
585 return Either.left(deleteMarkedElements.left().value());
588 public Either<List<ArtifactDefinition>, StorageOperationStatus> getComponentArtifactsForDelete(String parentId, NodeTypeEnum parentType) {
589 List<ArtifactDefinition> artifacts = new ArrayList<>();
590 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse = artifactToscaOperation.getArtifacts(parentId);
591 if (artifactsResponse.isRight()) {
592 if (artifactsResponse.right().value() != StorageOperationStatus.NOT_FOUND) {
593 log.debug("failed to retrieve artifacts for {} {}", parentType, parentId);
594 return Either.right(artifactsResponse.right().value());
597 artifacts.addAll(artifactsResponse.left().value().values());
599 return Either.left(artifacts);
606 * @param dataParamsToReturn - ui list of params to return
610 public Either<UiComponentDataTransfer, ResponseFormat> getComponentDataFilteredByParams(String componentId, User user, List<String> dataParamsToReturn) {
613 validateUserExists(user);
616 UiComponentDataTransfer result = new UiComponentDataTransfer();
618 if(dataParamsToReturn == null || dataParamsToReturn.isEmpty()) {
622 Either<UiComponentDataTransfer, ResponseFormat> uiDataTransferEither = getUiComponentDataTransferByComponentId(componentId, dataParamsToReturn);
623 if(uiDataTransferEither.isRight()){
624 return Either.right(uiDataTransferEither.right().value());
626 result = uiDataTransferEither.left().value();
629 return Either.left(result);
632 protected <T extends Component> void generateAndAddInputsFromGenericTypeProperties(T component, Resource genericType) {
633 List<InputDefinition> genericAndComponentInputs = new ArrayList<>();
634 List<InputDefinition> genericInputs = genericTypeBusinessLogic.generateInputsFromGenericTypeProperties(genericType);
635 genericAndComponentInputs.addAll(genericInputs);
636 if (null != component.getInputs()){
637 List<InputDefinition> nonGenericInputsFromComponent = getAllNonGenericInputsFromComponent(genericInputs, component.getInputs());
638 genericAndComponentInputs.addAll(nonGenericInputsFromComponent);
640 component.setInputs(genericAndComponentInputs);
643 private List<InputDefinition> getAllNonGenericInputsFromComponent(List<InputDefinition> genericInputs, List<InputDefinition> componentInputs) {
644 if (genericInputs == null) {
645 return componentInputs;
648 Map<String, InputDefinition> inputByNameMap = MapUtil.toMap(genericInputs, InputDefinition::getName);
649 List<InputDefinition> componentNonGenericInputs = new ArrayList<>();
650 componentInputs.stream().forEach(input -> {
651 if (!inputByNameMap.containsKey(input.getName())) {
652 componentNonGenericInputs.add(input);
655 return componentNonGenericInputs;
658 protected <T extends Component> Resource fetchAndSetDerivedFromGenericType(T component){
659 Either<Resource, ResponseFormat> genericTypeEither = this.genericTypeBusinessLogic.fetchDerivedFromGenericType(component);
660 if(genericTypeEither.isRight()){
661 log.debug("Failed to fetch latest generic type for component {} of type", component.getName(), component.assetType());
662 throw new ByActionStatusComponentException(ActionStatus.GENERIC_TYPE_NOT_FOUND, component.assetType());
664 Resource genericTypeResource = genericTypeEither.left().value();
665 component.setDerivedFromGenericInfo(genericTypeResource);
666 return genericTypeResource;
669 public Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstanceProperties(String componentId, Map<FilterKeyEnum, List<String>> filters, String userId) {
670 Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> response = null;
671 Either<Component, StorageOperationStatus> getResourceRes = null;
673 if(!filters.containsKey(FilterKeyEnum.NAME_FRAGMENT) && StringUtils.isEmpty(filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0))){
674 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
676 if (userId != null && response == null) {
677 validateUserExists(userId);
679 if(response == null){
680 getResourceRes = toscaOperationFacade.getToscaElement(componentId);
681 if(getResourceRes.isRight()){
682 response = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getResourceRes.right().value())));
685 if(response == null){
686 response = getFilteredComponentInstancesProperties(getResourceRes.left().value(), filters);
688 } catch(Exception e){
689 log.debug("The exception {} occured during filtered instance properties fetching. the containing component is {}. ", e, componentId);
690 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
692 if (response.isLeft()){
693 toscaOperationFacade.commit();
695 toscaOperationFacade.rollback();
701 private Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstancesProperties(Component component, Map<FilterKeyEnum, List<String>> filters) {
703 Map<String, List<IComponentInstanceConnectedElement>> filteredProperties = new HashMap<>();
704 Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> result = Either.left(filteredProperties);
705 List<ComponentInstance> filteredInstances = getFilteredInstances(component, filters.get(FilterKeyEnum.RESOURCE_TYPE));
706 String propertyNameFragment= filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0);
707 boolean searchByFragment = propertyNameFragment.length() > 3 ;
708 if(CollectionUtils.isNotEmpty(filteredInstances)){
709 for(ComponentInstance instance : filteredInstances){
710 if(component.getComponentInstancesProperties()!=null &&component.getComponentInstancesProperties().containsKey(instance.getUniqueId())){
711 List<IComponentInstanceConnectedElement> currProperties = getFilteredComponentInstanceProperties(component.getComponentInstancesProperties().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
712 setFilteredProperties(filteredProperties, instance, currProperties);
714 if(component.getComponentInstancesInputs()!=null && component.getComponentInstancesInputs().containsKey(instance.getUniqueId())){
715 List<IComponentInstanceConnectedElement> currInputs = getFilteredComponentInstanceInputs(component.getComponentInstancesInputs().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
716 if(CollectionUtils.isNotEmpty(currInputs)){
717 checkFilteredProperties(filteredProperties, instance, currInputs);
725 private void setFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance, List<IComponentInstanceConnectedElement> currProperties) {
726 if(CollectionUtils.isNotEmpty(currProperties)){
727 filteredProperties.put(instance.getUniqueId(), currProperties);
731 private void checkFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance, List<IComponentInstanceConnectedElement> currInputs) {
732 if(filteredProperties.get(instance.getUniqueId())!=null){
733 filteredProperties.get(instance.getUniqueId()).addAll(currInputs);
735 filteredProperties.put(instance.getUniqueId(), currInputs);
739 private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceInputs(List<ComponentInstanceInput> inputs, String propertyNameFragment, boolean searchByFragment) {
740 return inputs.stream().filter(i -> isMatchingInput(i, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
743 private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceProperties(List<ComponentInstanceProperty> instanceProperties, String propertyNameFragment, boolean searchByFragment) {
744 return instanceProperties.stream().filter(p -> isMatchingProperty(p, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
747 private boolean isMatchingInput(ComponentInstanceInput input, String propertyNameFragment, boolean searchByFragment) {
748 boolean isMatching = false;
749 if(searchByFragment && input.getName().toLowerCase().contains(propertyNameFragment)){
752 if(!searchByFragment && input.getName().equalsIgnoreCase(propertyNameFragment)){
758 private boolean isMatchingProperty(ComponentInstanceProperty property, String propertyNameFragment, boolean searchByFragment) {
759 boolean isMatching = false;
760 if(searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment)){
763 if(!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)){
766 if (!isMatching && !ToscaPropertyType.isPrimitiveType(property.getType())){
767 isMatching = isMatchingComplexPropertyByRecursively(property, propertyNameFragment, searchByFragment);
772 private boolean isMatchingComplexPropertyByRecursively(PropertyDataDefinition property, String propertyNameFragment, boolean searchByFragment) {
774 List<PropertyDefinition> dataTypeProperties;
775 DataTypeDefinition currentProperty;
776 if(searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment.toLowerCase())){
779 if(!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)){
783 propertyType = isEmptyInnerType(property) ? property.getType() : property.getSchema().getProperty().getType();
785 if(ToscaPropertyType.isScalarType(propertyType)){
788 Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameRes = propertyOperation.getDataTypeByName(propertyType);
789 if(getDataTypeByNameRes.isRight()){
792 currentProperty = getDataTypeByNameRes.left().value();
793 dataTypeProperties = currentProperty.getProperties();
795 if(CollectionUtils.isNotEmpty(dataTypeProperties)){
796 if (isMatchingComplexProperty(propertyNameFragment, searchByFragment, dataTypeProperties)){
800 dataTypeProperties = currentProperty.getDerivedFrom().getProperties();
801 if(CollectionUtils.isNotEmpty(dataTypeProperties)){
802 if (isMatchingComplexProperty(propertyNameFragment, searchByFragment, dataTypeProperties)){
809 private boolean isMatchingComplexProperty(String propertyNameFragment, boolean searchByFragment, List<PropertyDefinition> dataTypeProperties) {
810 for(PropertyDefinition prop : dataTypeProperties){
811 if(isMatchingComplexPropertyByRecursively(prop, propertyNameFragment, searchByFragment)){
818 private boolean isEmptyInnerType(PropertyDataDefinition property) {
819 return property == null|| property.getSchema() == null || property.getSchema().getProperty() == null || property.getSchema().getProperty().getType() == null;
822 public Either<Boolean, ResponseFormat> shouldUpgradeToLatestGeneric(Component clonedComponent) {
824 if(!clonedComponent.deriveFromGeneric())
825 return Either.left(false);
826 Boolean shouldUpgrade = false;
827 String currentGenericType = clonedComponent.getDerivedFromGenericType();
828 String currentGenericVersion = clonedComponent.getDerivedFromGenericVersion();
829 Resource genericTypeResource = fetchAndSetDerivedFromGenericType(clonedComponent);
830 if(null == currentGenericType || !currentGenericType.equals(genericTypeResource.getToscaResourceName()) || !currentGenericVersion.equals(genericTypeResource.getVersion())){
831 shouldUpgrade = upgradeToLatestGeneric(clonedComponent, genericTypeResource);
833 reverntUpdateOfGenericVersion(clonedComponent, currentGenericType, currentGenericVersion);
836 return Either.left(shouldUpgrade);
839 private void reverntUpdateOfGenericVersion(Component clonedComponent, String currentGenericType, String currentGenericVersion) {
840 clonedComponent.setDerivedFromGenericType(currentGenericType);
841 clonedComponent.setDerivedFromGenericVersion(currentGenericVersion);
844 private <T extends PropertyDataDefinition> Either<Map<String, T>, String> validateNoConflictingProperties(List<T> currentList, List<T> upgradedList) {
845 Map<String, T> currentMap = ToscaDataDefinition.listToMapByName(currentList);
846 Map<String, T> upgradedMap = ToscaDataDefinition.listToMapByName(upgradedList);
847 return ToscaDataDefinition.mergeDataMaps(upgradedMap, currentMap, true);
850 private boolean shouldUpgradeNodeType(Component componentToCheckOut, Resource latestGeneric){
852 List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
853 Either<Map<String, PropertyDefinition>, String> validMerge = validateNoConflictingProperties(genericTypeProps, ((Resource)componentToCheckOut).getProperties());
854 if (validMerge.isRight()) {
855 log.debug("property {} cannot be overriden, check out performed without upgrading to latest generic", validMerge.right().value());
858 List<PropertyDefinition> genericTypeAttributes = latestGeneric.getAttributes();
859 validMerge = validateNoConflictingProperties(genericTypeAttributes, ((Resource)componentToCheckOut).getAttributes());
860 if (validMerge.isRight()) {
861 log.debug("attribute {} cannot be overriden, check out performed without upgrading to latest generic", validMerge.right().value());
867 private boolean upgradeToLatestGeneric(Component componentToCheckOut, Resource latestGeneric) {
869 if (!componentToCheckOut.shouldGenerateInputs()) {
870 //node type - validate properties and attributes
871 return shouldUpgradeNodeType(componentToCheckOut, latestGeneric);
873 List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
874 List<InputDefinition> genericTypeInputs = null == genericTypeProps? null : genericTypeBusinessLogic.convertGenericTypePropertiesToInputsDefintion(genericTypeProps, latestGeneric.getUniqueId());
875 List<InputDefinition> currentList = new ArrayList<>();
876 // nullify existing ownerId from existing list and merge into updated list
877 if (null != componentToCheckOut.getInputs()) {
878 for(InputDefinition input : componentToCheckOut.getInputs()) {
879 InputDefinition copy = new InputDefinition(input);
880 copy.setOwnerId(null);
881 currentList.add(copy);
884 if (null == genericTypeInputs) {
885 componentToCheckOut.setInputs(currentList);
889 Either<Map<String, InputDefinition>, String> eitherMerged = validateNoConflictingProperties(genericTypeInputs, currentList);
890 if (eitherMerged.isRight()) {
891 log.debug("input {} cannot be overriden, check out performed without upgrading to latest generic", eitherMerged.right().value());
894 componentToCheckOut.setInputs(new ArrayList<>(eitherMerged.left().value().values()));
899 private List<ComponentInstance> getFilteredInstances(Component component, List<String> resourceTypes) {
900 List<ComponentInstance> filteredInstances = null;
901 if(CollectionUtils.isEmpty(resourceTypes)){
902 filteredInstances = component.getComponentInstances();
904 else if(CollectionUtils.isNotEmpty(component.getComponentInstances())){
905 filteredInstances = component.getComponentInstances()
906 .stream().filter(i -> isMatchingType(i.getOriginType(), resourceTypes)).collect(Collectors.toList());
908 if(filteredInstances == null){
909 filteredInstances = new ArrayList<>();
911 return filteredInstances;
914 private boolean isMatchingType(OriginTypeEnum originType, List<String> resourceTypes) {
915 boolean isMatchingType = false;
916 for(String resourceType : resourceTypes){
917 if(originType == OriginTypeEnum.findByValue(resourceType.toUpperCase())){
918 isMatchingType = true;
922 return isMatchingType;
925 public Either<Component, ActionStatus> shouldUpgradeToLatestDerived(Component clonedComponent) {
926 //general implementation. Must be error for service, VF . In ResourceBuisnessLogic exist override
927 return Either.right(ActionStatus.GENERAL_ERROR);
930 protected Either<Component, ResponseFormat> updateCatalog(Component component, ChangeTypeEnum changeStatus){
931 log.debug("update Catalog start with Component Type {} And Componet Name {} with change status {}", component.getComponentType().name(), component.getName(), changeStatus.name());
932 ActionStatus status = catalogOperations.updateCatalog(changeStatus,component);
933 if(status != ActionStatus.OK){
934 return Either.right( componentsUtils.getResponseFormat(status));
937 return Either.left(component);
940 public CatalogOperation getCatalogOperations() {
941 return catalogOperations;
945 public void setCatalogOperations(CatalogOperation catalogOperations) {
946 this.catalogOperations = catalogOperations;
949 public List<GroupDefinition> throwComponentException(ResponseFormat responseFormat) {
950 throw new ByResponseFormatComponentException(responseFormat);