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 com.sun.org.apache.xpath.internal.operations.Bool;
26 import fj.data.Either;
27 import java.util.function.BooleanSupplier;
28 import java.util.function.Supplier;
29 import org.apache.commons.collections.CollectionUtils;
30 import org.apache.commons.lang3.StringUtils;
31 import org.apache.commons.lang3.tuple.ImmutablePair;
32 import org.openecomp.sdc.be.catalog.enums.ChangeTypeEnum;
33 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
34 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
35 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
36 import org.openecomp.sdc.be.components.impl.generic.GenericTypeBusinessLogic;
37 import org.openecomp.sdc.be.components.validation.component.ComponentContactIdValidator;
38 import org.openecomp.sdc.be.components.validation.component.ComponentDescriptionValidator;
39 import org.openecomp.sdc.be.components.validation.component.ComponentIconValidator;
40 import org.openecomp.sdc.be.components.validation.component.ComponentNameValidator;
41 import org.openecomp.sdc.be.components.validation.component.ComponentProjectCodeValidator;
42 import org.openecomp.sdc.be.components.validation.component.ComponentTagsValidator;
43 import org.openecomp.sdc.be.components.validation.component.ComponentValidator;
44 import org.openecomp.sdc.be.config.BeEcompErrorManager;
45 import org.openecomp.sdc.be.config.ConfigurationManager;
46 import org.openecomp.sdc.be.dao.api.ActionStatus;
47 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
48 import org.openecomp.sdc.be.dao.utils.MapUtil;
49 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
50 import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition;
51 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
52 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
53 import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum;
54 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
55 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
56 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
57 import org.openecomp.sdc.be.facade.operations.CatalogOperation;
58 import org.openecomp.sdc.be.model.ArtifactDefinition;
59 import org.openecomp.sdc.be.model.CapReqDef;
60 import org.openecomp.sdc.be.model.Component;
61 import org.openecomp.sdc.be.model.ComponentInstance;
62 import org.openecomp.sdc.be.model.ComponentInstanceInput;
63 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
64 import org.openecomp.sdc.be.model.ComponentParametersView;
65 import org.openecomp.sdc.be.model.DataTypeDefinition;
66 import org.openecomp.sdc.be.model.GroupDefinition;
67 import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement;
68 import org.openecomp.sdc.be.model.InputDefinition;
69 import org.openecomp.sdc.be.model.LifecycleStateEnum;
70 import org.openecomp.sdc.be.model.Operation;
71 import org.openecomp.sdc.be.model.PropertyDefinition;
72 import org.openecomp.sdc.be.model.Resource;
73 import org.openecomp.sdc.be.model.User;
74 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
75 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
76 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
77 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
78 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
79 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
80 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
81 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
82 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
83 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
84 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
85 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
86 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
87 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
88 import org.openecomp.sdc.be.user.Role;
89 import org.openecomp.sdc.be.utils.CommonBeUtils;
90 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
91 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
92 import org.openecomp.sdc.common.log.wrappers.Logger;
93 import org.openecomp.sdc.common.util.ValidationUtils;
94 import org.openecomp.sdc.exception.ResponseFormat;
95 import org.springframework.beans.factory.annotation.Autowired;
97 import java.util.ArrayList;
98 import java.util.HashMap;
99 import java.util.List;
100 import java.util.Map;
101 import java.util.Map.Entry;
102 import java.util.stream.Collectors;
104 public abstract class ComponentBusinessLogic extends BaseBusinessLogic {
106 protected ArtifactsBusinessLogic artifactsBusinessLogic;
108 protected final GroupBusinessLogic groupBusinessLogic;
110 protected GenericTypeBusinessLogic genericTypeBusinessLogic;
112 protected ComponentDescriptionValidator componentDescriptionValidator;
113 protected ComponentProjectCodeValidator componentProjectCodeValidator;
115 protected CatalogOperation catalogOperations;
116 protected ComponentIconValidator componentIconValidator;
118 protected ComponentValidator componentValidator;
119 protected ComponentTagsValidator componentTagsValidator;
120 protected ComponentNameValidator componentNameValidator;
121 protected ComponentContactIdValidator componentContactIdValidator;
123 public ComponentBusinessLogic(IElementOperation elementDao,
124 IGroupOperation groupOperation,
125 IGroupInstanceOperation groupInstanceOperation,
126 IGroupTypeOperation groupTypeOperation,
127 GroupBusinessLogic groupBusinessLogic,
128 InterfaceOperation interfaceOperation,
129 InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
130 ArtifactsBusinessLogic artifactsBusinessLogic,
131 ArtifactsOperations artifactToscaOperation,
132 ComponentContactIdValidator componentContactIdValidator,
133 ComponentNameValidator componentNameValidator,
134 ComponentTagsValidator componentTagsValidator,
135 ComponentValidator componentValidator,
136 ComponentIconValidator componentIconValidator,
137 ComponentProjectCodeValidator componentProjectCodeValidator,
138 ComponentDescriptionValidator componentDescriptionValidator){
140 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation,
141 interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
142 this.artifactsBusinessLogic = artifactsBusinessLogic;
143 this.groupBusinessLogic = groupBusinessLogic;
144 this.componentContactIdValidator = componentContactIdValidator;
145 this.componentNameValidator = componentNameValidator;
146 this.componentTagsValidator = componentTagsValidator;
147 this.componentValidator = componentValidator;
148 this.componentIconValidator = componentIconValidator;
149 this.componentProjectCodeValidator = componentProjectCodeValidator;
150 this.componentDescriptionValidator = componentDescriptionValidator;
153 public void setComponentDescriptionValidator(ComponentDescriptionValidator componentDescriptionValidator) {
154 this.componentDescriptionValidator = componentDescriptionValidator;
157 public void setComponentProjectCodeValidator(ComponentProjectCodeValidator componentProjectCodeValidator) {
158 this.componentProjectCodeValidator = componentProjectCodeValidator;
161 public void setComponentIconValidator(ComponentIconValidator componentIconValidator) {
162 this.componentIconValidator = componentIconValidator;
165 public void setComponentContactIdValidator(ComponentContactIdValidator componentContactIdValidator) {
166 this.componentContactIdValidator = componentContactIdValidator;
169 public void setComponentTagsValidator(ComponentTagsValidator componentTagsValidator) {
170 this.componentTagsValidator = componentTagsValidator;
173 public void setComponentNameValidator(ComponentNameValidator componentNameValidator) {
174 this.componentNameValidator = componentNameValidator;
179 public void setGenericTypeBusinessLogic(GenericTypeBusinessLogic genericTypeBusinessLogic) {
180 this.genericTypeBusinessLogic = genericTypeBusinessLogic;
183 private static final Logger log = Logger.getLogger(ComponentBusinessLogic.class.getName());
185 private static final String TAG_FIELD_LABEL = "tag";
187 public abstract Either<List<String>, ResponseFormat> deleteMarkedComponents();
189 public abstract ComponentInstanceBusinessLogic getComponentInstanceBL();
191 public abstract Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId);
196 * @param dataParamsToReturn
199 public abstract Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String componentId, List<String> dataParamsToReturn);
201 User validateUser(User user, String ecompErrorContext, Component component, AuditingActionEnum auditAction, boolean inTransaction) {
203 ResponseFormat responseFormat;
205 validateUserNotEmpty(user, ecompErrorContext);
206 validatedUser = validateUserExists(user);
207 } catch(ByActionStatusComponentException e){
208 if(e.getActionStatus() == ActionStatus.MISSING_INFORMATION){
209 user.setUserId("UNKNOWN");
211 responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
212 componentsUtils.auditComponentAdmin(responseFormat, user, component, auditAction, component.getComponentType());
214 } catch(ByResponseFormatComponentException e){
215 responseFormat = e.getResponseFormat();
216 componentsUtils.auditComponentAdmin(responseFormat, user, component, auditAction, component.getComponentType());
219 return validatedUser;
222 protected void validateUserRole(User user, Component component, List<Role> roles, AuditingActionEnum auditAction, String comment) {
223 if (roles != null && roles.isEmpty()) {
224 roles.add(Role.ADMIN);
225 roles.add(Role.DESIGNER);
228 validateUserRole(user, roles);
229 }catch (ByActionStatusComponentException e) {
230 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
231 handleComponentException(component, comment, responseFormat, user, auditAction);
233 }catch (ByResponseFormatComponentException e) {
234 ResponseFormat responseFormat = e.getResponseFormat();
235 handleComponentException(component, comment, responseFormat, user, auditAction);
240 private void handleComponentException(Component component, String comment, ResponseFormat responseFormat,
241 User user, AuditingActionEnum auditAction){
242 String commentStr = null;
243 String distrStatus = null;
244 ComponentTypeEnum componentType = component.getComponentType();
245 if (componentType == ComponentTypeEnum.SERVICE) {
246 distrStatus = ((ServiceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition()).getDistributionStatus();
247 commentStr = comment;
249 componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(componentType.getValue()),
250 ResourceVersionInfo.newBuilder().distributionStatus(distrStatus).build(),
251 ResourceVersionInfo.newBuilder().distributionStatus(distrStatus).build(),
252 commentStr, null, null);
255 public Either<Boolean, ResponseFormat> validateConformanceLevel(String componentUuid, ComponentTypeEnum componentTypeEnum, String userId) {
256 log.trace("validate conformance level");
258 if (componentTypeEnum != ComponentTypeEnum.SERVICE) {
259 log.error("conformance level validation for non service component, id {}", componentUuid);
260 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
261 return Either.right(errorResponse);
264 validateUserExists(userId);
266 Either<ComponentMetadataData, StorageOperationStatus> eitherComponent = toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, null);
267 if (eitherComponent.isRight()) {
268 log.error("can't validate conformance level, component not found, uuid {}", componentUuid);
269 BeEcompErrorManager.getInstance().logBeComponentMissingError("validateConformanceLevel", componentTypeEnum.getValue(), componentUuid);
271 StorageOperationStatus status = eitherComponent.right().value();
272 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(status, componentTypeEnum);
273 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus);
274 return Either.right(responseFormat);
277 String componentConformanceLevel = eitherComponent.left().value().getMetadataDataDefinition().getConformanceLevel();
278 if (StringUtils.isBlank(componentConformanceLevel)) {
279 log.error("component conformance level property is null or empty, uuid {}", componentUuid);
280 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
281 return Either.right(errorResponse);
284 String configConformanceLevel = ConfigurationManager.getConfigurationManager().getConfiguration().getMinToscaConformanceLevel();
285 Boolean result = true;
286 if (CommonBeUtils.conformanceLevelCompare(componentConformanceLevel, configConformanceLevel) < 0) {
287 log.error("invalid asset conformance level, uuid {}, asset conformanceLevel {}, config conformanceLevel {}", componentUuid, componentConformanceLevel, configConformanceLevel);
290 log.trace("conformance level validation finished");
292 return Either.left(result);
296 protected void checkComponentFieldsForOverrideAttempt(Component component) {
297 if (component.getLifecycleState() != null) {
298 log.info("LifecycleState cannot be defined by user. This field will be overridden by the application");
300 if (component.getVersion() != null) {
301 log.info("Version cannot be defined by user. This field will be overridden by the application");
303 if (component.getCreatorUserId() != null || component.getCreatorFullName() != null) {
304 log.info("Creator cannot be defined by user. This field will be overridden by the application");
306 if (component.getLastUpdaterUserId() != null || component.getLastUpdaterFullName() != null) {
307 log.info("Last Updater cannot be defined by user. This field will be overridden by the application");
309 if (component.getCreationDate() != null) {
310 log.info("Creation Date cannot be defined by user. This field will be overridden by the application");
312 if (component.isHighestVersion() != null) {
313 log.info("Is Highest Version cannot be defined by user. This field will be overridden by the application");
315 if (component.getUUID() != null) {
316 log.info("UUID cannot be defined by user. This field will be overridden by the application");
318 if (component.getLastUpdateDate() != null) {
319 log.info("Last Update Date cannot be defined by user. This field will be overridden by the application");
321 if (component.getUniqueId() != null) {
322 log.info("uid cannot be defined by user. This field will be overridden by the application.");
323 component.setUniqueId(null);
325 if (component.getInvariantUUID() != null) {
326 log.info("Invariant UUID cannot be defined by user. This field will be overridden by the application.");
330 public CapReqDef getRequirementsAndCapabilities(String componentId, ComponentTypeEnum componentTypeEnum, String userId) {
332 validateUserExists(userId);
333 ComponentParametersView filter = new ComponentParametersView(true);
334 filter.setIgnoreCapabilities(false);
335 filter.setIgnoreRequirements(false);
336 filter.setIgnoreComponentInstances(false);
339 Component component = validateComponentExists(componentId, componentTypeEnum, filter);
340 return new CapReqDef(component.getRequirements(), component.getCapabilities());
341 }catch (ComponentException e){
342 BeEcompErrorManager.getInstance().logBeComponentMissingError("getRequirementsAndCapabilities", componentTypeEnum.getValue(), componentId);
343 throwComponentException(e.getResponseFormat());
348 public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponents(boolean isAbstractAbstract, ComponentTypeEnum componentTypeEnum, String internalComponentType, List<String> componentUids,
351 validateUserExists(userId);
352 List<Component> result = new ArrayList<>();
353 List<String> componentsUidToFetch = new ArrayList<>();
354 componentsUidToFetch.addAll(componentUids);
355 if (!componentsUidToFetch.isEmpty()) {
356 log.debug("Number of Components to fetch from graph is {}", componentsUidToFetch.size());
357 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade.getLatestVersionNotAbstractComponents(isAbstractAbstract, componentTypeEnum, internalComponentType, componentsUidToFetch);
359 if (nonCheckoutCompResponse.isLeft()) {
360 log.debug("Retrived Resource successfully.");
361 result.addAll(nonCheckoutCompResponse.left().value());
363 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value())));
366 return Either.left(result);
369 janusGraphDao.commit();
373 private Boolean isHighest(HighestFilterEnum highestFilter) {
374 Boolean isHighest = null;
375 switch (highestFilter) {
381 case NON_HIGHEST_ONLY:
390 public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponentsMetadata(boolean isAbstractAbstract, HighestFilterEnum highestFilter, ComponentTypeEnum componentTypeEnum, String internalComponentType, String userId) {
391 ResponseFormat responseFormat = null;
394 validateUserExists(userId);
395 Boolean isHighest = isHighest(highestFilter);
396 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade.getLatestVersionNotAbstractMetadataOnly(isAbstractAbstract, componentTypeEnum, internalComponentType);
398 if (nonCheckoutCompResponse.isLeft()) {
399 log.debug("Retrieved Resource successfully.");
400 return Either.left(nonCheckoutCompResponse.left().value());
402 responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value()));
404 janusGraphDao.commit();
406 return Either.right(responseFormat);
409 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
413 @SuppressWarnings("unchecked")
414 public void setToscaArtifactsPlaceHolders(Component component, User user) {
415 Map<String, ArtifactDefinition> artifactMap = component.getToscaArtifacts();
416 if (artifactMap == null) {
417 artifactMap = new HashMap<>();
419 String componentUniqueId = component.getUniqueId();
420 String componentSystemName = component.getSystemName();
421 String componentType = component.getComponentType().getValue().toLowerCase();
422 Map<String, Object> toscaArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts();
424 if (toscaArtifacts != null) {
425 for (Entry<String, Object> artifactInfoMap : toscaArtifacts.entrySet()) {
426 Map<String, Object> artifactInfo = (Map<String, Object>) artifactInfoMap.getValue();
427 ArtifactDefinition artifactDefinition = artifactsBusinessLogic.createArtifactPlaceHolderInfo(componentUniqueId, artifactInfoMap.getKey(), artifactInfo, user, ArtifactGroupTypeEnum.TOSCA);
428 artifactDefinition.setArtifactName(ValidationUtils.normalizeFileName(componentType + "-" + componentSystemName + artifactInfo.get("artifactName")));
429 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
432 component.setToscaArtifacts(artifactMap);
435 public Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock) {
436 return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true, true);
439 public Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock, boolean retrieveResource) {
440 return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true, retrieveResource);
443 private Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock, boolean fetchTemplatesFromDB, boolean retrieveResource) {
444 if (retrieveResource) {
445 Either<Component, StorageOperationStatus> toscaElement = toscaOperationFacade.getToscaFullElement(component.getUniqueId());
446 if ( toscaElement.isRight() ){
447 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(toscaElement.right().value(), component.getComponentType()));
449 component = toscaElement.left().value();
452 Either<ArtifactDefinition, Operation> generateToscaRes = null;
453 if (component.getToscaArtifacts() != null && !component.getToscaArtifacts().isEmpty()) {
454 ArtifactDefinition toscaArtifact = component.getToscaArtifacts().values().stream()
455 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_TEMPLATE.getType()))
457 generateToscaRes = saveToscaArtifactPayload(toscaArtifact, component, user, isInCertificationRequest, shouldLock, inTransaction, fetchTemplatesFromDB);
458 toscaArtifact = generateToscaRes.left().value();
459 component.getToscaArtifacts().put(toscaArtifact.getArtifactLabel(), toscaArtifact);
460 if(!isAbstractResource(component)){
461 toscaArtifact = component.getToscaArtifacts().values().stream()
462 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType()))
464 generateToscaRes = saveToscaArtifactPayload(toscaArtifact, component, user, isInCertificationRequest, shouldLock, inTransaction, true);
465 if (generateToscaRes.isRight()) {
466 return generateToscaRes;
468 toscaArtifact = generateToscaRes.left().value();
469 component.getToscaArtifacts().put(toscaArtifact.getArtifactLabel(), toscaArtifact);
472 return generateToscaRes;
475 private boolean isAbstractResource(Component component) {
476 return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource)component).isAbstract();
479 private Either<ArtifactDefinition, Operation> saveToscaArtifactPayload(ArtifactDefinition artifactDefinition, org.openecomp.sdc.be.model.Component component, User user, boolean isInCertificationRequest, boolean shouldLock,
480 boolean inTransaction, boolean fetchTemplatesFromDB) {
481 return artifactsBusinessLogic.generateAndSaveToscaArtifact(artifactDefinition, component, user, isInCertificationRequest, shouldLock, inTransaction, fetchTemplatesFromDB);
484 public ImmutablePair<String, byte[]> getToscaModelByComponentUuid(ComponentTypeEnum componentType, String uuid, ResourceCommonInfo resourceCommonInfo) {
486 Either<List<Component>, StorageOperationStatus> latestVersionEither = toscaOperationFacade.getComponentListByUuid(uuid, null);
488 if (latestVersionEither.isRight()) {
489 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(latestVersionEither.right().value(), componentType));
492 List<Component> components = latestVersionEither.left().value();
494 Component component = components.stream().filter(Component::isHighestVersion).findFirst().orElse(null);
495 if(component == null){
496 component = components.stream().filter(c -> c.getLifecycleState() == LifecycleStateEnum.CERTIFIED).findFirst().orElse(null);
499 if(component == null){
500 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, componentType)));
502 resourceCommonInfo.setResourceName(component.getName());
503 // TODO remove after migration - handle artifact not found(no
505 if (null == component.getToscaArtifacts() || component.getToscaArtifacts().isEmpty()) {
506 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ArtifactTypeEnum.TOSCA_CSAR.name()));
508 ArtifactDefinition csarArtifact = component.getToscaArtifacts().values().stream()
509 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType()))
511 return artifactsBusinessLogic.handleDownloadToscaModelRequest(component, csarArtifact);
514 protected StorageOperationStatus markComponentToDelete(Component component) {
516 ComponentTypeEnum componentType = component.getComponentType();
517 String uniqueId = component.getUniqueId();
518 if (Boolean.TRUE.equals(component.getIsDeleted())) {
519 log.info("component {} already marked as deleted. id= {}, type={}", component.getName(), uniqueId, componentType);
520 return StorageOperationStatus.NOT_FOUND;
523 StorageOperationStatus markResourceToDelete = toscaOperationFacade.markComponentToDelete(component);
524 if (StorageOperationStatus.OK != markResourceToDelete) {
525 log.debug("failed to mark component {} of type {} for delete. error = {}", uniqueId, componentType, markResourceToDelete);
526 return markResourceToDelete;
528 log.debug("Component {} of type {} was marked as deleted", uniqueId, componentType);
529 updateCatalog(component, ChangeTypeEnum.DELETE);
530 return StorageOperationStatus.OK;
534 public Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Component currentComponent, Component updatedComponent, AuditingActionEnum auditingAction) {
535 String descriptionUpdated = updatedComponent.getDescription();
536 String descriptionCurrent = currentComponent.getDescription();
537 if (descriptionUpdated != null && !descriptionCurrent.equals(descriptionUpdated)) {
538 componentDescriptionValidator.validateAndCorrectField(user, updatedComponent, auditingAction);
539 currentComponent.setDescription(updatedComponent.getDescription());
541 return Either.left(true);
544 public Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Component currentComponent, Component updatedComponent) {
545 String projectCodeUpdated = updatedComponent.getProjectCode();
546 String projectCodeCurrent = currentComponent.getProjectCode();
547 if (projectCodeUpdated != null && !projectCodeCurrent.equals(projectCodeUpdated)) {
549 componentProjectCodeValidator.validateAndCorrectField(user, updatedComponent, null);
550 } catch (ComponentException exp) {
551 ResponseFormat errorRespons = exp.getResponseFormat();
552 return Either.right(errorRespons);
554 currentComponent.setProjectCode(updatedComponent.getProjectCode());
556 return Either.left(true);
559 public Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Component currentComponent, Component updatedComponent, boolean hasBeenCertified) {
560 String iconUpdated = updatedComponent.getIcon();
561 String iconCurrent = currentComponent.getIcon();
562 if (iconUpdated != null && !iconCurrent.equals(iconUpdated)) {
563 if (!hasBeenCertified) {
564 componentIconValidator.validateAndCorrectField(user, updatedComponent, null);
565 currentComponent.setIcon(updatedComponent.getIcon());
567 log.info("icon {} cannot be updated once the component has been certified once.", iconUpdated);
568 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_PARAMETER_CANNOT_BE_CHANGED, "Icon", currentComponent.getComponentType().name().toLowerCase());
569 return Either.right(errorResponse);
572 return Either.left(true);
575 protected Either<List<String>, ResponseFormat> deleteMarkedComponents(ComponentTypeEnum componentType) {
577 log.trace("start deleteMarkedComponents");
578 Either<List<String>, StorageOperationStatus> deleteMarkedElements = toscaOperationFacade.deleteMarkedElements(componentType);
581 if ( deleteMarkedElements.isRight()){
582 janusGraphDao.rollback();
583 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteMarkedElements.right().value(), componentType));
584 return Either.right(responseFormat);
586 log.trace("end deleteMarkedComponents");
587 janusGraphDao.commit();
588 return Either.left(deleteMarkedElements.left().value());
591 public Either<List<ArtifactDefinition>, StorageOperationStatus> getComponentArtifactsForDelete(String parentId, NodeTypeEnum parentType) {
592 List<ArtifactDefinition> artifacts = new ArrayList<>();
593 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse = artifactToscaOperation.getArtifacts(parentId);
594 if (artifactsResponse.isRight()) {
595 if (artifactsResponse.right().value() != StorageOperationStatus.NOT_FOUND) {
596 log.debug("failed to retrieve artifacts for {} {}", parentType, parentId);
597 return Either.right(artifactsResponse.right().value());
600 artifacts.addAll(artifactsResponse.left().value().values());
602 return Either.left(artifacts);
609 * @param dataParamsToReturn - ui list of params to return
613 public Either<UiComponentDataTransfer, ResponseFormat> getComponentDataFilteredByParams(String componentId, User user, List<String> dataParamsToReturn) {
616 validateUserExists(user);
619 UiComponentDataTransfer result = new UiComponentDataTransfer();
621 if(dataParamsToReturn == null || dataParamsToReturn.isEmpty()) {
625 Either<UiComponentDataTransfer, ResponseFormat> uiDataTransferEither = getUiComponentDataTransferByComponentId(componentId, dataParamsToReturn);
626 if(uiDataTransferEither.isRight()){
627 return Either.right(uiDataTransferEither.right().value());
629 result = uiDataTransferEither.left().value();
632 return Either.left(result);
635 protected <T extends Component> void generateAndAddInputsFromGenericTypeProperties(T component, Resource genericType) {
636 List<InputDefinition> genericAndComponentInputs = new ArrayList<>();
637 List<InputDefinition> genericInputs = genericTypeBusinessLogic.generateInputsFromGenericTypeProperties(genericType);
638 genericAndComponentInputs.addAll(genericInputs);
639 if (null != component.getInputs()){
640 List<InputDefinition> nonGenericInputsFromComponent = getAllNonGenericInputsFromComponent(genericInputs, component.getInputs());
641 genericAndComponentInputs.addAll(nonGenericInputsFromComponent);
643 component.setInputs(genericAndComponentInputs);
646 private List<InputDefinition> getAllNonGenericInputsFromComponent(List<InputDefinition> genericInputs, List<InputDefinition> componentInputs) {
647 if (genericInputs == null) {
648 return componentInputs;
651 Map<String, InputDefinition> inputByNameMap = MapUtil.toMap(genericInputs, InputDefinition::getName);
652 List<InputDefinition> componentNonGenericInputs = new ArrayList<>();
653 componentInputs.stream().forEach(input -> {
654 if (!inputByNameMap.containsKey(input.getName())) {
655 componentNonGenericInputs.add(input);
658 return componentNonGenericInputs;
661 protected <T extends Component> Resource fetchAndSetDerivedFromGenericType(T component){
662 Either<Resource, ResponseFormat> genericTypeEither = this.genericTypeBusinessLogic.fetchDerivedFromGenericType(component);
663 if(genericTypeEither.isRight()){
664 log.debug("Failed to fetch latest generic type for component {} of type", component.getName(), component.assetType());
665 throw new ByActionStatusComponentException(ActionStatus.GENERIC_TYPE_NOT_FOUND, component.assetType());
667 Resource genericTypeResource = genericTypeEither.left().value();
668 component.setDerivedFromGenericInfo(genericTypeResource);
669 return genericTypeResource;
672 public Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstanceProperties(String componentId, Map<FilterKeyEnum, List<String>> filters, String userId) {
673 Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> response = null;
674 Either<Component, StorageOperationStatus> getResourceRes = null;
676 if(!filters.containsKey(FilterKeyEnum.NAME_FRAGMENT) && StringUtils.isEmpty(filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0))){
677 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
679 if (userId != null && response == null) {
680 validateUserExists(userId);
682 if(response == null){
683 getResourceRes = toscaOperationFacade.getToscaElement(componentId);
684 if(getResourceRes.isRight()){
685 response = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getResourceRes.right().value())));
688 if(response == null){
689 response = getFilteredComponentInstancesProperties(getResourceRes.left().value(), filters);
691 } catch(Exception e){
692 log.debug("The exception {} occured during filtered instance properties fetching. the containing component is {}. ", e, componentId);
693 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
695 if (response != null && response.isLeft()){
696 toscaOperationFacade.commit();
698 toscaOperationFacade.rollback();
704 private Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstancesProperties(Component component, Map<FilterKeyEnum, List<String>> filters) {
706 Map<String, List<IComponentInstanceConnectedElement>> filteredProperties = new HashMap<>();
707 Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> result = Either.left(filteredProperties);
708 List<ComponentInstance> filteredInstances = getFilteredInstances(component, filters.get(FilterKeyEnum.RESOURCE_TYPE));
709 String propertyNameFragment= filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0);
710 boolean searchByFragment = propertyNameFragment.length() > 3 ;
711 if(CollectionUtils.isNotEmpty(filteredInstances)){
712 for(ComponentInstance instance : filteredInstances){
713 if(component.getComponentInstancesProperties()!=null &&component.getComponentInstancesProperties().containsKey(instance.getUniqueId())){
714 List<IComponentInstanceConnectedElement> currProperties = getFilteredComponentInstanceProperties(component.getComponentInstancesProperties().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
715 setFilteredProperties(filteredProperties, instance, currProperties);
717 if(component.getComponentInstancesInputs()!=null && component.getComponentInstancesInputs().containsKey(instance.getUniqueId())){
718 List<IComponentInstanceConnectedElement> currInputs = getFilteredComponentInstanceInputs(component.getComponentInstancesInputs().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
719 if(CollectionUtils.isNotEmpty(currInputs)){
720 checkFilteredProperties(filteredProperties, instance, currInputs);
728 private void setFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance, List<IComponentInstanceConnectedElement> currProperties) {
729 if(CollectionUtils.isNotEmpty(currProperties)){
730 filteredProperties.put(instance.getUniqueId(), currProperties);
734 private void checkFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance, List<IComponentInstanceConnectedElement> currInputs) {
735 if(filteredProperties.get(instance.getUniqueId())!=null){
736 filteredProperties.get(instance.getUniqueId()).addAll(currInputs);
738 filteredProperties.put(instance.getUniqueId(), currInputs);
742 private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceInputs(List<ComponentInstanceInput> inputs, String propertyNameFragment, boolean searchByFragment) {
743 return inputs.stream().filter(i -> isMatchingInput(i, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
746 private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceProperties(List<ComponentInstanceProperty> instanceProperties, String propertyNameFragment, boolean searchByFragment) {
747 return instanceProperties.stream().filter(p -> isMatchingProperty(p, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
750 private boolean isMatchingInput(ComponentInstanceInput input, String propertyNameFragment, boolean searchByFragment) {
751 boolean isMatching = false;
752 if(searchByFragment && input.getName().toLowerCase().contains(propertyNameFragment)){
755 if(!searchByFragment && input.getName().equalsIgnoreCase(propertyNameFragment)){
761 private boolean isMatchingProperty(ComponentInstanceProperty property, String propertyNameFragment, boolean searchByFragment) {
762 boolean isMatching = false;
763 if(searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment)){
766 if(!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)){
769 if (!isMatching && !ToscaPropertyType.isPrimitiveType(property.getType())){
770 isMatching = isMatchingComplexPropertyByRecursively(property, propertyNameFragment, searchByFragment);
775 private boolean isMatchingComplexPropertyByRecursively(PropertyDataDefinition property, String propertyNameFragment, boolean searchByFragment) {
777 List<PropertyDefinition> dataTypeProperties;
778 DataTypeDefinition currentProperty;
779 if(searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment.toLowerCase())){
782 if(!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)){
786 propertyType = isEmptyInnerType(property) ? property.getType() : property.getSchema().getProperty().getType();
788 if(ToscaPropertyType.isScalarType(propertyType)){
791 Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameRes = propertyOperation.getDataTypeByName(propertyType);
792 if(getDataTypeByNameRes.isRight()){
795 currentProperty = getDataTypeByNameRes.left().value();
796 dataTypeProperties = currentProperty.getProperties();
798 boolean dataPropertiesNotNull = CollectionUtils.isNotEmpty(dataTypeProperties);
799 BooleanSupplier dataMatchesComplexProperty = () -> isMatchingComplexProperty(propertyNameFragment,
800 searchByFragment, dataTypeProperties);
801 BooleanSupplier parentPropertiesNotNull = () -> CollectionUtils
802 .isNotEmpty(currentProperty.getDerivedFrom().getProperties());
803 BooleanSupplier parentDataMatchesComplexProperty = () -> isMatchingComplexProperty(propertyNameFragment,
804 searchByFragment, currentProperty.getDerivedFrom().getProperties());
806 return ((dataPropertiesNotNull && dataMatchesComplexProperty.getAsBoolean())
807 || (parentPropertiesNotNull.getAsBoolean() && parentDataMatchesComplexProperty.getAsBoolean()));
810 private boolean isMatchingComplexProperty(String propertyNameFragment, boolean searchByFragment, List<PropertyDefinition> dataTypeProperties) {
811 for(PropertyDefinition prop : dataTypeProperties){
812 if(isMatchingComplexPropertyByRecursively(prop, propertyNameFragment, searchByFragment)){
819 private boolean isEmptyInnerType(PropertyDataDefinition property) {
820 return property == null|| property.getSchema() == null || property.getSchema().getProperty() == null || property.getSchema().getProperty().getType() == null;
823 public Either<Boolean, ResponseFormat> shouldUpgradeToLatestGeneric(Component clonedComponent) {
825 if(!clonedComponent.deriveFromGeneric())
826 return Either.left(false);
827 Boolean shouldUpgrade = false;
828 String currentGenericType = clonedComponent.getDerivedFromGenericType();
829 String currentGenericVersion = clonedComponent.getDerivedFromGenericVersion();
830 Resource genericTypeResource = fetchAndSetDerivedFromGenericType(clonedComponent);
831 if(null == currentGenericType || !currentGenericType.equals(genericTypeResource.getToscaResourceName()) || !currentGenericVersion.equals(genericTypeResource.getVersion())){
832 shouldUpgrade = upgradeToLatestGeneric(clonedComponent, genericTypeResource);
834 reverntUpdateOfGenericVersion(clonedComponent, currentGenericType, currentGenericVersion);
837 return Either.left(shouldUpgrade);
840 private void reverntUpdateOfGenericVersion(Component clonedComponent, String currentGenericType, String currentGenericVersion) {
841 clonedComponent.setDerivedFromGenericType(currentGenericType);
842 clonedComponent.setDerivedFromGenericVersion(currentGenericVersion);
845 private <T extends PropertyDataDefinition> Either<Map<String, T>, String> validateNoConflictingProperties(List<T> currentList, List<T> upgradedList) {
846 Map<String, T> currentMap = ToscaDataDefinition.listToMapByName(currentList);
847 Map<String, T> upgradedMap = ToscaDataDefinition.listToMapByName(upgradedList);
848 return ToscaDataDefinition.mergeDataMaps(upgradedMap, currentMap, true);
851 private boolean shouldUpgradeNodeType(Component componentToCheckOut, Resource latestGeneric){
853 List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
854 Either<Map<String, PropertyDefinition>, String> validMerge = validateNoConflictingProperties(genericTypeProps, ((Resource)componentToCheckOut).getProperties());
855 if (validMerge.isRight()) {
856 log.debug("property {} cannot be overriden, check out performed without upgrading to latest generic", validMerge.right().value());
859 List<PropertyDefinition> genericTypeAttributes = latestGeneric.getAttributes();
860 validMerge = validateNoConflictingProperties(genericTypeAttributes, ((Resource)componentToCheckOut).getAttributes());
861 if (validMerge.isRight()) {
862 log.debug("attribute {} cannot be overriden, check out performed without upgrading to latest generic", validMerge.right().value());
868 private boolean upgradeToLatestGeneric(Component componentToCheckOut, Resource latestGeneric) {
870 if (!componentToCheckOut.shouldGenerateInputs()) {
871 //node type - validate properties and attributes
872 return shouldUpgradeNodeType(componentToCheckOut, latestGeneric);
874 List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
875 List<InputDefinition> genericTypeInputs = null == genericTypeProps? null : genericTypeBusinessLogic.convertGenericTypePropertiesToInputsDefintion(genericTypeProps, latestGeneric.getUniqueId());
876 List<InputDefinition> currentList = new ArrayList<>();
877 // nullify existing ownerId from existing list and merge into updated list
878 if (null != componentToCheckOut.getInputs()) {
879 for(InputDefinition input : componentToCheckOut.getInputs()) {
880 InputDefinition copy = new InputDefinition(input);
881 copy.setOwnerId(null);
882 currentList.add(copy);
885 if (null == genericTypeInputs) {
886 componentToCheckOut.setInputs(currentList);
890 Either<Map<String, InputDefinition>, String> eitherMerged = validateNoConflictingProperties(genericTypeInputs, currentList);
891 if (eitherMerged.isRight()) {
892 log.debug("input {} cannot be overriden, check out performed without upgrading to latest generic", eitherMerged.right().value());
895 componentToCheckOut.setInputs(new ArrayList<>(eitherMerged.left().value().values()));
900 private List<ComponentInstance> getFilteredInstances(Component component, List<String> resourceTypes) {
901 List<ComponentInstance> filteredInstances = null;
902 if(CollectionUtils.isEmpty(resourceTypes)){
903 filteredInstances = component.getComponentInstances();
905 else if(CollectionUtils.isNotEmpty(component.getComponentInstances())){
906 filteredInstances = component.getComponentInstances()
907 .stream().filter(i -> isMatchingType(i.getOriginType(), resourceTypes)).collect(Collectors.toList());
909 if(filteredInstances == null){
910 filteredInstances = new ArrayList<>();
912 return filteredInstances;
915 private boolean isMatchingType(OriginTypeEnum originType, List<String> resourceTypes) {
916 boolean isMatchingType = false;
917 for(String resourceType : resourceTypes){
918 if(originType == OriginTypeEnum.findByValue(resourceType.toUpperCase())){
919 isMatchingType = true;
923 return isMatchingType;
926 public Either<Component, ActionStatus> shouldUpgradeToLatestDerived(Component clonedComponent) {
927 //general implementation. Must be error for service, VF . In ResourceBuisnessLogic exist override
928 return Either.right(ActionStatus.GENERAL_ERROR);
931 protected Either<Component, ResponseFormat> updateCatalog(Component component, ChangeTypeEnum changeStatus){
932 log.debug("update Catalog start with Component Type {} And Componet Name {} with change status {}", component.getComponentType().name(), component.getName(), changeStatus.name());
933 ActionStatus status = catalogOperations.updateCatalog(changeStatus,component);
934 if(status != ActionStatus.OK){
935 return Either.right( componentsUtils.getResponseFormat(status));
938 return Either.left(component);
941 public CatalogOperation getCatalogOperations() {
942 return catalogOperations;
946 public void setCatalogOperations(CatalogOperation catalogOperations) {
947 this.catalogOperations = catalogOperations;
950 public List<GroupDefinition> throwComponentException(ResponseFormat responseFormat) {
951 throw new ByResponseFormatComponentException(responseFormat);