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.AttributeDataDefinition;
53 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
54 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
55 import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum;
56 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
57 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
58 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
59 import org.openecomp.sdc.be.facade.operations.CatalogOperation;
60 import org.openecomp.sdc.be.impl.ComponentsUtils;
61 import org.openecomp.sdc.be.model.ArtifactDefinition;
62 import org.openecomp.sdc.be.model.AttributeDefinition;
63 import org.openecomp.sdc.be.model.CapReqDef;
64 import org.openecomp.sdc.be.model.Component;
65 import org.openecomp.sdc.be.model.ComponentInstance;
66 import org.openecomp.sdc.be.model.ComponentInstanceInput;
67 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
68 import org.openecomp.sdc.be.model.ComponentParametersView;
69 import org.openecomp.sdc.be.model.DataTypeDefinition;
70 import org.openecomp.sdc.be.model.GroupDefinition;
71 import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement;
72 import org.openecomp.sdc.be.model.InputDefinition;
73 import org.openecomp.sdc.be.model.LifecycleStateEnum;
74 import org.openecomp.sdc.be.model.Operation;
75 import org.openecomp.sdc.be.model.PropertyDefinition;
76 import org.openecomp.sdc.be.model.Resource;
77 import org.openecomp.sdc.be.model.User;
78 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
79 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
80 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
81 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
82 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
83 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
84 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
85 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
86 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
87 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
88 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
89 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
90 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
91 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
92 import org.openecomp.sdc.be.user.Role;
93 import org.openecomp.sdc.be.utils.CommonBeUtils;
94 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
95 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
96 import org.openecomp.sdc.common.log.wrappers.Logger;
97 import org.openecomp.sdc.common.util.ValidationUtils;
98 import org.openecomp.sdc.exception.ResponseFormat;
99 import org.springframework.beans.factory.annotation.Autowired;
101 import java.util.ArrayList;
102 import java.util.HashMap;
103 import java.util.List;
104 import java.util.Map;
105 import java.util.Map.Entry;
106 import java.util.stream.Collectors;
108 public abstract class ComponentBusinessLogic extends BaseBusinessLogic {
110 protected ArtifactsBusinessLogic artifactsBusinessLogic;
112 protected final GroupBusinessLogic groupBusinessLogic;
114 protected GenericTypeBusinessLogic genericTypeBusinessLogic;
116 protected ComponentDescriptionValidator componentDescriptionValidator;
117 protected ComponentProjectCodeValidator componentProjectCodeValidator;
119 protected CatalogOperation catalogOperations;
120 protected ComponentIconValidator componentIconValidator;
122 protected ComponentValidator componentValidator;
123 protected ComponentTagsValidator componentTagsValidator;
124 protected ComponentNameValidator componentNameValidator;
125 protected ComponentContactIdValidator componentContactIdValidator;
127 public ComponentBusinessLogic(IElementOperation elementDao,
128 IGroupOperation groupOperation,
129 IGroupInstanceOperation groupInstanceOperation,
130 IGroupTypeOperation groupTypeOperation,
131 GroupBusinessLogic groupBusinessLogic,
132 InterfaceOperation interfaceOperation,
133 InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
134 ArtifactsBusinessLogic artifactsBusinessLogic,
135 ArtifactsOperations artifactToscaOperation,
136 ComponentContactIdValidator componentContactIdValidator,
137 ComponentNameValidator componentNameValidator,
138 ComponentTagsValidator componentTagsValidator,
139 ComponentValidator componentValidator,
140 ComponentIconValidator componentIconValidator,
141 ComponentProjectCodeValidator componentProjectCodeValidator,
142 ComponentDescriptionValidator componentDescriptionValidator){
144 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation,
145 interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
146 this.artifactsBusinessLogic = artifactsBusinessLogic;
147 this.groupBusinessLogic = groupBusinessLogic;
148 this.componentContactIdValidator = componentContactIdValidator;
149 this.componentNameValidator = componentNameValidator;
150 this.componentTagsValidator = componentTagsValidator;
151 this.componentValidator = componentValidator;
152 this.componentIconValidator = componentIconValidator;
153 this.componentProjectCodeValidator = componentProjectCodeValidator;
154 this.componentDescriptionValidator = componentDescriptionValidator;
157 public void setComponentDescriptionValidator(ComponentDescriptionValidator componentDescriptionValidator) {
158 this.componentDescriptionValidator = componentDescriptionValidator;
161 public void setComponentProjectCodeValidator(ComponentProjectCodeValidator componentProjectCodeValidator) {
162 this.componentProjectCodeValidator = componentProjectCodeValidator;
165 public void setComponentIconValidator(ComponentIconValidator componentIconValidator) {
166 this.componentIconValidator = componentIconValidator;
169 public void setComponentContactIdValidator(ComponentContactIdValidator componentContactIdValidator) {
170 this.componentContactIdValidator = componentContactIdValidator;
173 public void setComponentTagsValidator(ComponentTagsValidator componentTagsValidator) {
174 this.componentTagsValidator = componentTagsValidator;
177 public void setComponentNameValidator(ComponentNameValidator componentNameValidator) {
178 this.componentNameValidator = componentNameValidator;
183 public void setGenericTypeBusinessLogic(GenericTypeBusinessLogic genericTypeBusinessLogic) {
184 this.genericTypeBusinessLogic = genericTypeBusinessLogic;
187 private static final Logger log = Logger.getLogger(ComponentBusinessLogic.class.getName());
189 private static final String TAG_FIELD_LABEL = "tag";
191 public abstract Either<List<String>, ResponseFormat> deleteMarkedComponents();
193 public abstract ComponentInstanceBusinessLogic getComponentInstanceBL();
195 public abstract Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId);
200 * @param dataParamsToReturn
203 public abstract Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String componentId, List<String> dataParamsToReturn);
205 User validateUser(User user, String ecompErrorContext, Component component, AuditingActionEnum auditAction, boolean inTransaction) {
207 ResponseFormat responseFormat;
209 validateUserNotEmpty(user, ecompErrorContext);
210 validatedUser = validateUserExists(user);
211 } catch(ByActionStatusComponentException e){
212 if(e.getActionStatus() == ActionStatus.MISSING_INFORMATION){
213 user.setUserId("UNKNOWN");
215 responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
216 componentsUtils.auditComponentAdmin(responseFormat, user, component, auditAction, component.getComponentType());
218 } catch(ByResponseFormatComponentException e){
219 responseFormat = e.getResponseFormat();
220 componentsUtils.auditComponentAdmin(responseFormat, user, component, auditAction, component.getComponentType());
223 return validatedUser;
226 protected void validateUserRole(User user, Component component, List<Role> roles, AuditingActionEnum auditAction, String comment) {
227 if (roles != null && roles.isEmpty()) {
228 roles.add(Role.ADMIN);
229 roles.add(Role.DESIGNER);
232 validateUserRole(user, roles);
233 }catch (ByActionStatusComponentException e) {
234 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
235 handleComponentException(component, comment, responseFormat, user, auditAction);
237 }catch (ByResponseFormatComponentException e) {
238 ResponseFormat responseFormat = e.getResponseFormat();
239 handleComponentException(component, comment, responseFormat, user, auditAction);
244 private void handleComponentException(Component component, String comment, ResponseFormat responseFormat,
245 User user, AuditingActionEnum auditAction){
246 String commentStr = null;
247 String distrStatus = null;
248 ComponentTypeEnum componentType = component.getComponentType();
249 if (componentType == ComponentTypeEnum.SERVICE) {
250 distrStatus = ((ServiceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition()).getDistributionStatus();
251 commentStr = comment;
253 componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(componentType.getValue()),
254 ResourceVersionInfo.newBuilder().distributionStatus(distrStatus).build(),
255 ResourceVersionInfo.newBuilder().distributionStatus(distrStatus).build(),
256 commentStr, null, null);
259 public Either<Boolean, ResponseFormat> validateConformanceLevel(String componentUuid, ComponentTypeEnum componentTypeEnum, String userId) {
260 log.trace("validate conformance level");
262 if (componentTypeEnum != ComponentTypeEnum.SERVICE) {
263 log.error("conformance level validation for non service component, id {}", componentUuid);
264 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
265 return Either.right(errorResponse);
268 validateUserExists(userId);
270 Either<ComponentMetadataData, StorageOperationStatus> eitherComponent = toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, null);
271 if (eitherComponent.isRight()) {
272 log.error("can't validate conformance level, component not found, uuid {}", componentUuid);
273 BeEcompErrorManager.getInstance().logBeComponentMissingError("validateConformanceLevel", componentTypeEnum.getValue(), componentUuid);
275 StorageOperationStatus status = eitherComponent.right().value();
276 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(status, componentTypeEnum);
277 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus);
278 return Either.right(responseFormat);
281 String componentConformanceLevel = eitherComponent.left().value().getMetadataDataDefinition().getConformanceLevel();
282 if (StringUtils.isBlank(componentConformanceLevel)) {
283 log.error("component conformance level property is null or empty, uuid {}", componentUuid);
284 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
285 return Either.right(errorResponse);
288 String configConformanceLevel = ConfigurationManager.getConfigurationManager().getConfiguration().getMinToscaConformanceLevel();
289 Boolean result = true;
290 if (CommonBeUtils.conformanceLevelCompare(componentConformanceLevel, configConformanceLevel) < 0) {
291 log.error("invalid asset conformance level, uuid {}, asset conformanceLevel {}, config conformanceLevel {}", componentUuid, componentConformanceLevel, configConformanceLevel);
294 log.trace("conformance level validation finished");
296 return Either.left(result);
300 protected void checkComponentFieldsForOverrideAttempt(Component component) {
301 if (component.getLifecycleState() != null) {
302 log.info("LifecycleState cannot be defined by user. This field will be overridden by the application");
304 if (component.getVersion() != null) {
305 log.info("Version cannot be defined by user. This field will be overridden by the application");
307 if (component.getCreatorUserId() != null || component.getCreatorFullName() != null) {
308 log.info("Creator cannot be defined by user. This field will be overridden by the application");
310 if (component.getLastUpdaterUserId() != null || component.getLastUpdaterFullName() != null) {
311 log.info("Last Updater cannot be defined by user. This field will be overridden by the application");
313 if (component.getCreationDate() != null) {
314 log.info("Creation Date cannot be defined by user. This field will be overridden by the application");
316 if (component.isHighestVersion() != null) {
317 log.info("Is Highest Version cannot be defined by user. This field will be overridden by the application");
319 if (component.getUUID() != null) {
320 log.info("UUID cannot be defined by user. This field will be overridden by the application");
322 if (component.getLastUpdateDate() != null) {
323 log.info("Last Update Date cannot be defined by user. This field will be overridden by the application");
325 if (component.getUniqueId() != null) {
326 log.info("uid cannot be defined by user. This field will be overridden by the application.");
327 component.setUniqueId(null);
329 if (component.getInvariantUUID() != null) {
330 log.info("Invariant UUID cannot be defined by user. This field will be overridden by the application.");
334 public CapReqDef getRequirementsAndCapabilities(String componentId, ComponentTypeEnum componentTypeEnum, String userId) {
336 validateUserExists(userId);
337 ComponentParametersView filter = new ComponentParametersView(true);
338 filter.setIgnoreCapabilities(false);
339 filter.setIgnoreRequirements(false);
340 filter.setIgnoreComponentInstances(false);
343 Component component = validateComponentExists(componentId, componentTypeEnum, filter);
344 return new CapReqDef(component.getRequirements(), component.getCapabilities());
345 }catch (ComponentException e){
346 BeEcompErrorManager.getInstance().logBeComponentMissingError("getRequirementsAndCapabilities", componentTypeEnum.getValue(), componentId);
347 throwComponentException(e.getResponseFormat());
352 public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponents(boolean isAbstractAbstract, ComponentTypeEnum componentTypeEnum, String internalComponentType, List<String> componentUids,
355 validateUserExists(userId);
356 List<Component> result = new ArrayList<>();
357 List<String> componentsUidToFetch = new ArrayList<>();
358 componentsUidToFetch.addAll(componentUids);
359 if (!componentsUidToFetch.isEmpty()) {
360 log.debug("Number of Components to fetch from graph is {}", componentsUidToFetch.size());
361 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade.getLatestVersionNotAbstractComponents(isAbstractAbstract, componentTypeEnum, internalComponentType, componentsUidToFetch);
363 if (nonCheckoutCompResponse.isLeft()) {
364 log.debug("Retrived Resource successfully.");
365 result.addAll(nonCheckoutCompResponse.left().value());
367 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value())));
370 return Either.left(result);
373 janusGraphDao.commit();
377 private Boolean isHighest(HighestFilterEnum highestFilter) {
378 Boolean isHighest = null;
379 switch (highestFilter) {
385 case NON_HIGHEST_ONLY:
394 public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponentsMetadata(boolean isAbstractAbstract, HighestFilterEnum highestFilter, ComponentTypeEnum componentTypeEnum, String internalComponentType, String userId) {
395 ResponseFormat responseFormat = null;
398 validateUserExists(userId);
399 Boolean isHighest = isHighest(highestFilter);
400 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade.getLatestVersionNotAbstractMetadataOnly(isAbstractAbstract, componentTypeEnum, internalComponentType);
402 if (nonCheckoutCompResponse.isLeft()) {
403 log.debug("Retrieved Resource successfully.");
404 return Either.left(nonCheckoutCompResponse.left().value());
406 responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value()));
408 janusGraphDao.commit();
410 return Either.right(responseFormat);
413 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
417 @SuppressWarnings("unchecked")
418 public void setToscaArtifactsPlaceHolders(Component component, User user) {
419 Map<String, ArtifactDefinition> artifactMap = component.getToscaArtifacts();
420 if (artifactMap == null) {
421 artifactMap = new HashMap<>();
423 String componentUniqueId = component.getUniqueId();
424 String componentSystemName = component.getSystemName();
425 String componentType = component.getComponentType().getValue().toLowerCase();
426 Map<String, Object> toscaArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts();
428 if (toscaArtifacts != null) {
429 for (Entry<String, Object> artifactInfoMap : toscaArtifacts.entrySet()) {
430 Map<String, Object> artifactInfo = (Map<String, Object>) artifactInfoMap.getValue();
431 ArtifactDefinition artifactDefinition = artifactsBusinessLogic.createArtifactPlaceHolderInfo(componentUniqueId, artifactInfoMap.getKey(), artifactInfo, user, ArtifactGroupTypeEnum.TOSCA);
432 artifactDefinition.setArtifactName(ValidationUtils.normalizeFileName(componentType + "-" + componentSystemName + artifactInfo.get("artifactName")));
433 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
436 component.setToscaArtifacts(artifactMap);
439 public Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock) {
440 return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true, true);
443 public Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock, boolean retrieveResource) {
444 return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true, retrieveResource);
447 private Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock, boolean fetchTemplatesFromDB, boolean retrieveResource) {
448 if (retrieveResource) {
449 Either<Component, StorageOperationStatus> toscaElement = toscaOperationFacade.getToscaFullElement(component.getUniqueId());
450 if ( toscaElement.isRight() ){
451 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(toscaElement.right().value(), component.getComponentType()));
453 component = toscaElement.left().value();
456 Either<ArtifactDefinition, Operation> generateToscaRes =
457 saveToscaArtifactAndPopulateToscaArtifactsWithResult(component, componentsUtils,
458 ArtifactTypeEnum.TOSCA_TEMPLATE,
459 (comp, toscaArtifact) ->
460 saveToscaArtifactPayload(toscaArtifact, comp, user, isInCertificationRequest, shouldLock,
461 inTransaction, fetchTemplatesFromDB));
463 if (!isAbstractResource(component)) {
464 generateToscaRes = saveToscaArtifactAndPopulateToscaArtifactsWithResult(component, componentsUtils,
465 ArtifactTypeEnum.TOSCA_CSAR,
466 (comp, toscaArtifactArg) -> saveToscaArtifactPayload(toscaArtifactArg, comp, user,
467 isInCertificationRequest, shouldLock, inTransaction, true));
469 return generateToscaRes;
472 private static Either<ArtifactDefinition, Operation> saveToscaArtifactAndPopulateToscaArtifactsWithResult(
474 final ComponentsUtils componentsUtils,
475 final ArtifactTypeEnum artifactEnum,
476 final BiFunction<Component, ArtifactDefinition, Either<ArtifactDefinition, Operation>> saveToscaArtifactPayloadFunction) {
478 ArtifactDefinition artifactDefinition = getToscaArtifactByTypeOrThrowException(component, artifactEnum,
481 Either<ArtifactDefinition, Operation> result =
482 saveToscaArtifactPayloadFunction.apply(component, artifactDefinition);
484 if (result.isLeft()) {
485 ArtifactDefinition def = result.left().value();
486 component.getToscaArtifacts().put(def.getArtifactLabel(), def);
492 private static Optional<ArtifactDefinition> getToscaArtifactByType(
493 final Map<String, ArtifactDefinition> toscaArtifacts,
494 final ArtifactTypeEnum typeEnum) {
495 return toscaArtifacts.values().stream()
496 .filter(p -> p.getArtifactType().equals(typeEnum.getType()))
500 private static ArtifactDefinition getToscaArtifactByTypeOrThrowException(
501 final Component component,
502 final ArtifactTypeEnum typeEnum,
503 final ComponentsUtils componentsUtils) {
505 return Optional.ofNullable(component.getToscaArtifacts())
506 .flatMap(toscaArtifacts -> getToscaArtifactByType(toscaArtifacts, typeEnum))
508 log.debug("Impossible to find a ToscaArtifact with type '{}' for {}", typeEnum.getType(), component);
509 return new ByResponseFormatComponentException(
510 componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, typeEnum.name()));
514 private boolean isAbstractResource(Component component) {
515 return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource)component).isAbstract();
518 private Either<ArtifactDefinition, Operation> saveToscaArtifactPayload(ArtifactDefinition artifactDefinition, org.openecomp.sdc.be.model.Component component, User user, boolean isInCertificationRequest, boolean shouldLock,
519 boolean inTransaction, boolean fetchTemplatesFromDB) {
520 return artifactsBusinessLogic.generateAndSaveToscaArtifact(artifactDefinition, component, user, isInCertificationRequest, shouldLock, inTransaction, fetchTemplatesFromDB);
523 public ImmutablePair<String, byte[]> getToscaModelByComponentUuid(ComponentTypeEnum componentType, String uuid, ResourceCommonInfo resourceCommonInfo) {
525 Either<List<Component>, StorageOperationStatus> latestVersionEither = toscaOperationFacade.getComponentListByUuid(uuid, null);
527 if (latestVersionEither.isRight()) {
528 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(latestVersionEither.right().value(), componentType));
531 List<Component> components = latestVersionEither.left().value();
533 Component component = components.stream().filter(Component::isHighestVersion).findFirst().orElse(null);
534 if(component == null){
535 component = components.stream().filter(c -> c.getLifecycleState() == LifecycleStateEnum.CERTIFIED).findFirst().orElse(null);
538 if(component == null){
539 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, componentType)));
541 resourceCommonInfo.setResourceName(component.getName());
542 // TODO remove after migration - handle artifact not found(no
544 if (null == component.getToscaArtifacts() || component.getToscaArtifacts().isEmpty()) {
545 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ArtifactTypeEnum.TOSCA_CSAR.name()));
547 ArtifactDefinition csarArtifact = component.getToscaArtifacts().values().stream()
548 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType()))
550 return artifactsBusinessLogic.handleDownloadToscaModelRequest(component, csarArtifact);
553 protected StorageOperationStatus markComponentToDelete(Component component) {
555 ComponentTypeEnum componentType = component.getComponentType();
556 String uniqueId = component.getUniqueId();
557 if (Boolean.TRUE.equals(component.getIsDeleted())) {
558 log.info("component {} already marked as deleted. id= {}, type={}", component.getName(), uniqueId, componentType);
559 return StorageOperationStatus.NOT_FOUND;
562 StorageOperationStatus markResourceToDelete = toscaOperationFacade.markComponentToDelete(component);
563 if (StorageOperationStatus.OK != markResourceToDelete) {
564 log.debug("failed to mark component {} of type {} for delete. error = {}", uniqueId, componentType, markResourceToDelete);
565 return markResourceToDelete;
567 log.debug("Component {} of type {} was marked as deleted", uniqueId, componentType);
568 updateCatalog(component, ChangeTypeEnum.DELETE);
569 return StorageOperationStatus.OK;
573 public Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Component currentComponent, Component updatedComponent, AuditingActionEnum auditingAction) {
574 String descriptionUpdated = updatedComponent.getDescription();
575 String descriptionCurrent = currentComponent.getDescription();
576 if (descriptionUpdated != null && !descriptionCurrent.equals(descriptionUpdated)) {
577 componentDescriptionValidator.validateAndCorrectField(user, updatedComponent, auditingAction);
578 currentComponent.setDescription(updatedComponent.getDescription());
580 return Either.left(true);
583 public Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Component currentComponent, Component updatedComponent) {
584 String projectCodeUpdated = updatedComponent.getProjectCode();
585 String projectCodeCurrent = currentComponent.getProjectCode();
586 if (projectCodeUpdated != null && !projectCodeCurrent.equals(projectCodeUpdated)) {
588 componentProjectCodeValidator.validateAndCorrectField(user, updatedComponent, null);
589 } catch (ComponentException exp) {
590 ResponseFormat errorRespons = exp.getResponseFormat();
591 return Either.right(errorRespons);
593 currentComponent.setProjectCode(updatedComponent.getProjectCode());
595 return Either.left(true);
598 public Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Component currentComponent, Component updatedComponent, boolean hasBeenCertified) {
599 String iconUpdated = updatedComponent.getIcon();
600 String iconCurrent = currentComponent.getIcon();
601 if (iconUpdated != null && !iconCurrent.equals(iconUpdated)) {
602 if (!hasBeenCertified) {
603 componentIconValidator.validateAndCorrectField(user, updatedComponent, null);
604 currentComponent.setIcon(updatedComponent.getIcon());
606 log.info("icon {} cannot be updated once the component has been certified once.", iconUpdated);
607 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_PARAMETER_CANNOT_BE_CHANGED, "Icon", currentComponent.getComponentType().name().toLowerCase());
608 return Either.right(errorResponse);
611 return Either.left(true);
614 protected Either<List<String>, ResponseFormat> deleteMarkedComponents(ComponentTypeEnum componentType) {
616 log.trace("start deleteMarkedComponents");
617 Either<List<String>, StorageOperationStatus> deleteMarkedElements = toscaOperationFacade.deleteMarkedElements(componentType);
620 if ( deleteMarkedElements.isRight()){
621 janusGraphDao.rollback();
622 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteMarkedElements.right().value(), componentType));
623 return Either.right(responseFormat);
625 log.trace("end deleteMarkedComponents");
626 janusGraphDao.commit();
627 return Either.left(deleteMarkedElements.left().value());
630 public Either<List<ArtifactDefinition>, StorageOperationStatus> getComponentArtifactsForDelete(String parentId, NodeTypeEnum parentType) {
631 List<ArtifactDefinition> artifacts = new ArrayList<>();
632 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse = artifactToscaOperation.getArtifacts(parentId);
633 if (artifactsResponse.isRight()) {
634 if (artifactsResponse.right().value() != StorageOperationStatus.NOT_FOUND) {
635 log.debug("failed to retrieve artifacts for {} {}", parentType, parentId);
636 return Either.right(artifactsResponse.right().value());
639 artifacts.addAll(artifactsResponse.left().value().values());
641 return Either.left(artifacts);
648 * @param dataParamsToReturn - ui list of params to return
652 public Either<UiComponentDataTransfer, ResponseFormat> getComponentDataFilteredByParams(String componentId, User user, List<String> dataParamsToReturn) {
655 validateUserExists(user);
658 UiComponentDataTransfer result = new UiComponentDataTransfer();
660 if(dataParamsToReturn == null || dataParamsToReturn.isEmpty()) {
664 Either<UiComponentDataTransfer, ResponseFormat> uiDataTransferEither = getUiComponentDataTransferByComponentId(componentId, dataParamsToReturn);
665 if(uiDataTransferEither.isRight()){
666 return Either.right(uiDataTransferEither.right().value());
668 result = uiDataTransferEither.left().value();
671 return Either.left(result);
674 protected <T extends Component> void generateAndAddInputsFromGenericTypeProperties(T component, Resource genericType) {
675 List<InputDefinition> genericAndComponentInputs = new ArrayList<>();
676 List<InputDefinition> genericInputs = genericTypeBusinessLogic.generateInputsFromGenericTypeProperties(genericType);
677 genericAndComponentInputs.addAll(genericInputs);
678 if (null != component.getInputs()){
679 List<InputDefinition> nonGenericInputsFromComponent = getAllNonGenericInputsFromComponent(genericInputs, component.getInputs());
680 genericAndComponentInputs.addAll(nonGenericInputsFromComponent);
682 component.setInputs(genericAndComponentInputs);
685 private List<InputDefinition> getAllNonGenericInputsFromComponent(List<InputDefinition> genericInputs, List<InputDefinition> componentInputs) {
686 if (genericInputs == null) {
687 return componentInputs;
690 Map<String, InputDefinition> inputByNameMap = MapUtil.toMap(genericInputs, InputDefinition::getName);
691 List<InputDefinition> componentNonGenericInputs = new ArrayList<>();
692 componentInputs.stream().forEach(input -> {
693 if (!inputByNameMap.containsKey(input.getName())) {
694 componentNonGenericInputs.add(input);
697 return componentNonGenericInputs;
700 protected <T extends Component> Resource fetchAndSetDerivedFromGenericType(T component){
701 Either<Resource, ResponseFormat> genericTypeEither = this.genericTypeBusinessLogic.fetchDerivedFromGenericType(component);
702 if(genericTypeEither.isRight()){
703 log.debug("Failed to fetch latest generic type for component {} of type", component.getName(), component.assetType());
704 throw new ByActionStatusComponentException(ActionStatus.GENERIC_TYPE_NOT_FOUND, component.assetType());
706 Resource genericTypeResource = genericTypeEither.left().value();
707 component.setDerivedFromGenericInfo(genericTypeResource);
708 return genericTypeResource;
711 public Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstanceProperties(String componentId, Map<FilterKeyEnum, List<String>> filters, String userId) {
712 Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> response = null;
713 Either<Component, StorageOperationStatus> getResourceRes = null;
715 if(!filters.containsKey(FilterKeyEnum.NAME_FRAGMENT) && StringUtils.isEmpty(filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0))){
716 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
718 if (userId != null && response == null) {
719 validateUserExists(userId);
721 if(response == null){
722 getResourceRes = toscaOperationFacade.getToscaElement(componentId);
723 if(getResourceRes.isRight()){
724 response = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getResourceRes.right().value())));
727 if(response == null){
728 response = getFilteredComponentInstancesProperties(getResourceRes.left().value(), filters);
730 } catch(Exception e){
731 log.debug("The exception {} occured during filtered instance properties fetching. the containing component is {}. ", e, componentId);
732 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
734 if (response != null && response.isLeft()){
735 toscaOperationFacade.commit();
737 toscaOperationFacade.rollback();
743 private Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstancesProperties(Component component, Map<FilterKeyEnum, List<String>> filters) {
745 Map<String, List<IComponentInstanceConnectedElement>> filteredProperties = new HashMap<>();
746 Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> result = Either.left(filteredProperties);
747 List<ComponentInstance> filteredInstances = getFilteredInstances(component, filters.get(FilterKeyEnum.RESOURCE_TYPE));
748 String propertyNameFragment= filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0);
749 boolean searchByFragment = propertyNameFragment.length() > 3 ;
750 if(CollectionUtils.isNotEmpty(filteredInstances)){
751 for(ComponentInstance instance : filteredInstances){
752 if(component.getComponentInstancesProperties()!=null &&component.getComponentInstancesProperties().containsKey(instance.getUniqueId())){
753 List<IComponentInstanceConnectedElement> currProperties = getFilteredComponentInstanceProperties(component.getComponentInstancesProperties().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
754 setFilteredProperties(filteredProperties, instance, currProperties);
756 if(component.getComponentInstancesInputs()!=null && component.getComponentInstancesInputs().containsKey(instance.getUniqueId())){
757 List<IComponentInstanceConnectedElement> currInputs = getFilteredComponentInstanceInputs(component.getComponentInstancesInputs().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
758 if(CollectionUtils.isNotEmpty(currInputs)){
759 checkFilteredProperties(filteredProperties, instance, currInputs);
767 private void setFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance, List<IComponentInstanceConnectedElement> currProperties) {
768 if(CollectionUtils.isNotEmpty(currProperties)){
769 filteredProperties.put(instance.getUniqueId(), currProperties);
773 private void checkFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance, List<IComponentInstanceConnectedElement> currInputs) {
774 if(filteredProperties.get(instance.getUniqueId())!=null){
775 filteredProperties.get(instance.getUniqueId()).addAll(currInputs);
777 filteredProperties.put(instance.getUniqueId(), currInputs);
781 private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceInputs(List<ComponentInstanceInput> inputs, String propertyNameFragment, boolean searchByFragment) {
782 return inputs.stream().filter(i -> isMatchingInput(i, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
785 private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceProperties(List<ComponentInstanceProperty> instanceProperties, String propertyNameFragment, boolean searchByFragment) {
786 return instanceProperties.stream().filter(p -> isMatchingProperty(p, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
789 private boolean isMatchingInput(ComponentInstanceInput input, String propertyNameFragment, boolean searchByFragment) {
790 boolean isMatching = false;
791 if(searchByFragment && input.getName().toLowerCase().contains(propertyNameFragment)){
794 if(!searchByFragment && input.getName().equalsIgnoreCase(propertyNameFragment)){
800 private boolean isMatchingProperty(ComponentInstanceProperty property, String propertyNameFragment, boolean searchByFragment) {
801 boolean isMatching = false;
802 if(searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment)){
805 if(!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)){
808 if (!isMatching && !ToscaPropertyType.isPrimitiveType(property.getType())){
809 isMatching = isMatchingComplexPropertyByRecursively(property, propertyNameFragment, searchByFragment);
814 private boolean isMatchingComplexPropertyByRecursively(PropertyDataDefinition property, String propertyNameFragment, boolean searchByFragment) {
816 List<PropertyDefinition> dataTypeProperties;
817 DataTypeDefinition currentProperty;
818 if(searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment.toLowerCase())){
821 if(!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)){
825 propertyType = isEmptyInnerType(property) ? property.getType() : property.getSchema().getProperty().getType();
827 if(ToscaPropertyType.isScalarType(propertyType)){
830 Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameRes = propertyOperation.getDataTypeByName(propertyType);
831 if(getDataTypeByNameRes.isRight()){
834 currentProperty = getDataTypeByNameRes.left().value();
835 dataTypeProperties = currentProperty.getProperties();
837 boolean dataPropertiesNotNull = CollectionUtils.isNotEmpty(dataTypeProperties);
838 BooleanSupplier dataMatchesComplexProperty = () -> isMatchingComplexProperty(propertyNameFragment,
839 searchByFragment, dataTypeProperties);
840 BooleanSupplier parentPropertiesNotNull = () -> CollectionUtils
841 .isNotEmpty(currentProperty.getDerivedFrom().getProperties());
842 BooleanSupplier parentDataMatchesComplexProperty = () -> isMatchingComplexProperty(propertyNameFragment,
843 searchByFragment, currentProperty.getDerivedFrom().getProperties());
845 return ((dataPropertiesNotNull && dataMatchesComplexProperty.getAsBoolean())
846 || (parentPropertiesNotNull.getAsBoolean() && parentDataMatchesComplexProperty.getAsBoolean()));
849 private boolean isMatchingComplexProperty(String propertyNameFragment, boolean searchByFragment, List<PropertyDefinition> dataTypeProperties) {
850 for(PropertyDefinition prop : dataTypeProperties){
851 if(isMatchingComplexPropertyByRecursively(prop, propertyNameFragment, searchByFragment)){
858 private boolean isEmptyInnerType(PropertyDataDefinition property) {
859 return property == null|| property.getSchema() == null || property.getSchema().getProperty() == null || property.getSchema().getProperty().getType() == null;
862 public Either<Boolean, ResponseFormat> shouldUpgradeToLatestGeneric(Component clonedComponent) {
864 if(!clonedComponent.deriveFromGeneric())
865 return Either.left(false);
866 Boolean shouldUpgrade = false;
867 String currentGenericType = clonedComponent.getDerivedFromGenericType();
868 String currentGenericVersion = clonedComponent.getDerivedFromGenericVersion();
869 Resource genericTypeResource = fetchAndSetDerivedFromGenericType(clonedComponent);
870 if(null == currentGenericType || !currentGenericType.equals(genericTypeResource.getToscaResourceName()) || !currentGenericVersion.equals(genericTypeResource.getVersion())){
871 shouldUpgrade = upgradeToLatestGeneric(clonedComponent, genericTypeResource);
873 reverntUpdateOfGenericVersion(clonedComponent, currentGenericType, currentGenericVersion);
876 return Either.left(shouldUpgrade);
879 private void reverntUpdateOfGenericVersion(Component clonedComponent, String currentGenericType, String currentGenericVersion) {
880 clonedComponent.setDerivedFromGenericType(currentGenericType);
881 clonedComponent.setDerivedFromGenericVersion(currentGenericVersion);
884 private <T extends ToscaDataDefinition> Either<Map<String, T>, String> validateNoConflictingProperties(List<T> currentList, List<T> upgradedList) {
885 Map<String, T> currentMap = ToscaDataDefinition.listToMapByName(currentList);
886 Map<String, T> upgradedMap = ToscaDataDefinition.listToMapByName(upgradedList);
887 return ToscaDataDefinition.mergeDataMaps(upgradedMap, currentMap, true);
890 private boolean shouldUpgradeNodeType(Component componentToCheckOut, Resource latestGeneric){
892 List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
893 Either<Map<String, PropertyDefinition>, String> validPropertiesMerge = validateNoConflictingProperties(genericTypeProps, ((Resource)componentToCheckOut).getProperties());
894 if (validPropertiesMerge.isRight()) {
895 log.debug("property {} cannot be overriden, check out performed without upgrading to latest generic", validPropertiesMerge.right().value());
898 List<AttributeDataDefinition> genericTypeAttributes = latestGeneric.getAttributes();
899 final Either<Map<String, AttributeDataDefinition>, String> validAttributesMerge = validateNoConflictingProperties(
900 genericTypeAttributes, ((Resource) componentToCheckOut).getAttributes());
901 if (validAttributesMerge.isRight()) {
902 log.debug("attribute {} cannot be overriden, check out performed without upgrading to latest generic", validAttributesMerge.right().value());
908 private boolean upgradeToLatestGeneric(Component componentToCheckOut, Resource latestGeneric) {
910 if (!componentToCheckOut.shouldGenerateInputs()) {
911 //node type - validate properties and attributes
912 return shouldUpgradeNodeType(componentToCheckOut, latestGeneric);
914 List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
915 List<InputDefinition> genericTypeInputs = null == genericTypeProps? null : genericTypeBusinessLogic.convertGenericTypePropertiesToInputsDefintion(genericTypeProps, latestGeneric.getUniqueId());
916 List<InputDefinition> currentList = new ArrayList<>();
917 // nullify existing ownerId from existing list and merge into updated list
918 if (null != componentToCheckOut.getInputs()) {
919 for(InputDefinition input : componentToCheckOut.getInputs()) {
920 InputDefinition copy = new InputDefinition(input);
921 copy.setOwnerId(null);
922 currentList.add(copy);
925 if (null == genericTypeInputs) {
926 componentToCheckOut.setInputs(currentList);
930 Either<Map<String, InputDefinition>, String> eitherMerged = validateNoConflictingProperties(genericTypeInputs, currentList);
931 if (eitherMerged.isRight()) {
932 log.debug("input {} cannot be overriden, check out performed without upgrading to latest generic", eitherMerged.right().value());
935 componentToCheckOut.setInputs(new ArrayList<>(eitherMerged.left().value().values()));
940 private List<ComponentInstance> getFilteredInstances(Component component, List<String> resourceTypes) {
941 List<ComponentInstance> filteredInstances = null;
942 if(CollectionUtils.isEmpty(resourceTypes)){
943 filteredInstances = component.getComponentInstances();
945 else if(CollectionUtils.isNotEmpty(component.getComponentInstances())){
946 filteredInstances = component.getComponentInstances()
947 .stream().filter(i -> isMatchingType(i.getOriginType(), resourceTypes)).collect(Collectors.toList());
949 if(filteredInstances == null){
950 filteredInstances = new ArrayList<>();
952 return filteredInstances;
955 private boolean isMatchingType(OriginTypeEnum originType, List<String> resourceTypes) {
956 boolean isMatchingType = false;
957 for(String resourceType : resourceTypes){
958 if(originType == OriginTypeEnum.findByValue(resourceType.toUpperCase())){
959 isMatchingType = true;
963 return isMatchingType;
966 public Either<Component, ActionStatus> shouldUpgradeToLatestDerived(Component clonedComponent) {
967 //general implementation. Must be error for service, VF . In ResourceBuisnessLogic exist override
968 return Either.right(ActionStatus.GENERAL_ERROR);
971 protected Either<Component, ResponseFormat> updateCatalog(Component component, ChangeTypeEnum changeStatus){
972 log.debug("update Catalog start with Component Type {} And Componet Name {} with change status {}", component.getComponentType().name(), component.getName(), changeStatus.name());
973 ActionStatus status = catalogOperations.updateCatalog(changeStatus,component);
974 if(status != ActionStatus.OK){
975 return Either.right( componentsUtils.getResponseFormat(status));
978 return Either.left(component);
981 public CatalogOperation getCatalogOperations() {
982 return catalogOperations;
986 public void setCatalogOperations(CatalogOperation catalogOperations) {
987 this.catalogOperations = catalogOperations;
990 public List<GroupDefinition> throwComponentException(ResponseFormat responseFormat) {
991 throw new ByResponseFormatComponentException(responseFormat);