Improve test coverage
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ComponentBusinessLogic.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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  * ================================================================================
21  */
22 package org.openecomp.sdc.be.components.impl;
23
24 import fj.data.Either;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Map.Entry;
30 import java.util.Optional;
31 import java.util.function.BiFunction;
32 import java.util.function.BooleanSupplier;
33 import java.util.stream.Collectors;
34 import org.apache.commons.collections.CollectionUtils;
35 import org.apache.commons.lang3.StringUtils;
36 import org.apache.commons.lang3.tuple.ImmutablePair;
37 import org.openecomp.sdc.be.catalog.enums.ChangeTypeEnum;
38 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
39 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
40 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
41 import org.openecomp.sdc.be.components.impl.generic.GenericTypeBusinessLogic;
42 import org.openecomp.sdc.be.components.validation.component.ComponentContactIdValidator;
43 import org.openecomp.sdc.be.components.validation.component.ComponentDescriptionValidator;
44 import org.openecomp.sdc.be.components.validation.component.ComponentIconValidator;
45 import org.openecomp.sdc.be.components.validation.component.ComponentNameValidator;
46 import org.openecomp.sdc.be.components.validation.component.ComponentProjectCodeValidator;
47 import org.openecomp.sdc.be.components.validation.component.ComponentTagsValidator;
48 import org.openecomp.sdc.be.components.validation.component.ComponentValidator;
49 import org.openecomp.sdc.be.config.BeEcompErrorManager;
50 import org.openecomp.sdc.be.config.ConfigurationManager;
51 import org.openecomp.sdc.be.dao.api.ActionStatus;
52 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
53 import org.openecomp.sdc.be.dao.utils.MapUtil;
54 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
55 import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition;
56 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
57 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
58 import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum;
59 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
60 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
61 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
62 import org.openecomp.sdc.be.facade.operations.CatalogOperation;
63 import org.openecomp.sdc.be.impl.ComponentsUtils;
64 import org.openecomp.sdc.be.model.ArtifactDefinition;
65 import org.openecomp.sdc.be.model.AttributeDefinition;
66 import org.openecomp.sdc.be.model.CapReqDef;
67 import org.openecomp.sdc.be.model.Component;
68 import org.openecomp.sdc.be.model.ComponentInstance;
69 import org.openecomp.sdc.be.model.ComponentInstanceInput;
70 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
71 import org.openecomp.sdc.be.model.ComponentParametersView;
72 import org.openecomp.sdc.be.model.DataTypeDefinition;
73 import org.openecomp.sdc.be.model.GroupDefinition;
74 import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement;
75 import org.openecomp.sdc.be.model.InputDefinition;
76 import org.openecomp.sdc.be.model.LifecycleStateEnum;
77 import org.openecomp.sdc.be.model.Operation;
78 import org.openecomp.sdc.be.model.PropertyDefinition;
79 import org.openecomp.sdc.be.model.Resource;
80 import org.openecomp.sdc.be.model.User;
81 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
82 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
83 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
84 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
85 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
86 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
87 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
88 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
89 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
90 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
91 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
92 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
93 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
94 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
95 import org.openecomp.sdc.be.user.Role;
96 import org.openecomp.sdc.be.utils.CommonBeUtils;
97 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
98 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
99 import org.openecomp.sdc.common.log.wrappers.Logger;
100 import org.openecomp.sdc.common.util.ValidationUtils;
101 import org.openecomp.sdc.exception.ResponseFormat;
102 import org.springframework.beans.factory.annotation.Autowired;
103
104 public abstract class ComponentBusinessLogic extends BaseBusinessLogic {
105
106     private static final Logger log = Logger.getLogger(ComponentBusinessLogic.class.getName());
107
108     protected final GroupBusinessLogic groupBusinessLogic;
109     protected ArtifactsBusinessLogic artifactsBusinessLogic;
110     protected GenericTypeBusinessLogic genericTypeBusinessLogic;
111     protected ComponentDescriptionValidator componentDescriptionValidator;
112     protected ComponentProjectCodeValidator componentProjectCodeValidator;
113     protected CatalogOperation catalogOperations;
114     protected ComponentIconValidator componentIconValidator;
115     protected ComponentTagsValidator componentTagsValidator;
116     protected ComponentNameValidator componentNameValidator;
117     protected ComponentContactIdValidator componentContactIdValidator;
118
119     public ComponentBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation,
120                                   IGroupTypeOperation groupTypeOperation, GroupBusinessLogic groupBusinessLogic,
121                                   InterfaceOperation interfaceOperation, InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
122                                   ArtifactsBusinessLogic artifactsBusinessLogic, ArtifactsOperations artifactToscaOperation,
123                                   ComponentContactIdValidator componentContactIdValidator, ComponentNameValidator componentNameValidator,
124                                   ComponentTagsValidator componentTagsValidator, ComponentValidator componentValidator,
125                                   ComponentIconValidator componentIconValidator, ComponentProjectCodeValidator componentProjectCodeValidator,
126                                   ComponentDescriptionValidator componentDescriptionValidator) {
127         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
128             artifactToscaOperation);
129         this.artifactsBusinessLogic = artifactsBusinessLogic;
130         this.groupBusinessLogic = groupBusinessLogic;
131         this.componentContactIdValidator = componentContactIdValidator;
132         this.componentNameValidator = componentNameValidator;
133         this.componentTagsValidator = componentTagsValidator;
134         this.componentIconValidator = componentIconValidator;
135         this.componentProjectCodeValidator = componentProjectCodeValidator;
136         this.componentDescriptionValidator = componentDescriptionValidator;
137     }
138
139     private static Either<ArtifactDefinition, Operation> saveToscaArtifactAndPopulateToscaArtifactsWithResult(Component component,
140                                                                                                               final ComponentsUtils componentsUtils,
141                                                                                                               final ArtifactTypeEnum artifactEnum,
142                                                                                                               final BiFunction<Component, ArtifactDefinition, Either<ArtifactDefinition, Operation>> saveToscaArtifactPayloadFunction) {
143         ArtifactDefinition artifactDefinition = getToscaArtifactByTypeOrThrowException(component, artifactEnum, componentsUtils);
144         Either<ArtifactDefinition, Operation> result = saveToscaArtifactPayloadFunction.apply(component, artifactDefinition);
145         if (result.isLeft()) {
146             ArtifactDefinition def = result.left().value();
147             component.getToscaArtifacts().put(def.getArtifactLabel(), def);
148         }
149         return result;
150     }
151
152     private static Optional<ArtifactDefinition> getToscaArtifactByType(final Map<String, ArtifactDefinition> toscaArtifacts,
153                                                                        final ArtifactTypeEnum typeEnum) {
154         return toscaArtifacts.values().stream().filter(p -> p.getArtifactType().equals(typeEnum.getType())).findAny();
155     }
156
157     private static ArtifactDefinition getToscaArtifactByTypeOrThrowException(final Component component, final ArtifactTypeEnum typeEnum,
158                                                                              final ComponentsUtils componentsUtils) {
159         return Optional.ofNullable(component.getToscaArtifacts()).flatMap(toscaArtifacts -> getToscaArtifactByType(toscaArtifacts, typeEnum))
160             .orElseThrow(() -> {
161                 log.debug("Impossible to find a ToscaArtifact with type '{}' for {}", typeEnum.getType(), component);
162                 return new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, typeEnum.name()));
163             });
164     }
165
166     public void setComponentDescriptionValidator(ComponentDescriptionValidator componentDescriptionValidator) {
167         this.componentDescriptionValidator = componentDescriptionValidator;
168     }
169
170     public void setComponentProjectCodeValidator(ComponentProjectCodeValidator componentProjectCodeValidator) {
171         this.componentProjectCodeValidator = componentProjectCodeValidator;
172     }
173
174     public void setComponentIconValidator(ComponentIconValidator componentIconValidator) {
175         this.componentIconValidator = componentIconValidator;
176     }
177
178     public void setComponentContactIdValidator(ComponentContactIdValidator componentContactIdValidator) {
179         this.componentContactIdValidator = componentContactIdValidator;
180     }
181
182     public void setComponentTagsValidator(ComponentTagsValidator componentTagsValidator) {
183         this.componentTagsValidator = componentTagsValidator;
184     }
185
186     public void setComponentNameValidator(ComponentNameValidator componentNameValidator) {
187         this.componentNameValidator = componentNameValidator;
188     }
189
190     @Autowired
191     public void setGenericTypeBusinessLogic(GenericTypeBusinessLogic genericTypeBusinessLogic) {
192         this.genericTypeBusinessLogic = genericTypeBusinessLogic;
193     }
194
195     public abstract Either<List<String>, ResponseFormat> deleteMarkedComponents();
196
197     public abstract ComponentInstanceBusinessLogic getComponentInstanceBL();
198
199     public abstract Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId,
200                                                                                                                        String userId);
201
202     /**
203      * @param componentId
204      * @param dataParamsToReturn
205      * @return
206      */
207     public abstract Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String componentId,
208                                                                                                             List<String> dataParamsToReturn);
209     
210     public Either<ComponentMetadataData, StorageOperationStatus> getComponentMetadata(final String componentId) {
211         return toscaOperationFacade.getComponentMetadata(componentId);
212     }
213
214     User validateUser(User user, String ecompErrorContext, Component component, AuditingActionEnum auditAction, boolean inTransaction) {
215         User validatedUser;
216         ResponseFormat responseFormat;
217         try {
218             validateUserNotEmpty(user, ecompErrorContext);
219             validatedUser = validateUserExists(user);
220         } catch (ByActionStatusComponentException e) {
221             if (e.getActionStatus() == ActionStatus.MISSING_INFORMATION) {
222                 user.setUserId("UNKNOWN");
223             }
224             responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
225             componentsUtils.auditComponentAdmin(responseFormat, user, component, auditAction, component.getComponentType());
226             throw e;
227         } catch (ByResponseFormatComponentException e) {
228             responseFormat = e.getResponseFormat();
229             componentsUtils.auditComponentAdmin(responseFormat, user, component, auditAction, component.getComponentType());
230             throw e;
231         }
232         return validatedUser;
233     }
234
235     protected void validateUserRole(User user, Component component, List<Role> roles, AuditingActionEnum auditAction, String comment) {
236         if (roles != null && roles.isEmpty()) {
237             roles.add(Role.ADMIN);
238             roles.add(Role.DESIGNER);
239         }
240         try {
241             validateUserRole(user, roles);
242         } catch (ByActionStatusComponentException e) {
243             ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
244             handleComponentException(component, comment, responseFormat, user, auditAction);
245             throw e;
246         } catch (ByResponseFormatComponentException e) {
247             ResponseFormat responseFormat = e.getResponseFormat();
248             handleComponentException(component, comment, responseFormat, user, auditAction);
249             throw e;
250         }
251     }
252
253     private void handleComponentException(Component component, String comment, ResponseFormat responseFormat, User user,
254                                           AuditingActionEnum auditAction) {
255         String commentStr = null;
256         String distrStatus = null;
257         ComponentTypeEnum componentType = component.getComponentType();
258         if (componentType == ComponentTypeEnum.SERVICE) {
259             distrStatus = ((ServiceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition())
260                 .getDistributionStatus();
261             commentStr = comment;
262         }
263         componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(componentType.getValue()),
264             ResourceVersionInfo.newBuilder().distributionStatus(distrStatus).build(),
265             ResourceVersionInfo.newBuilder().distributionStatus(distrStatus).build(), commentStr, null, null);
266     }
267
268     public Either<Boolean, ResponseFormat> validateConformanceLevel(String componentUuid, ComponentTypeEnum componentTypeEnum, String userId) {
269         log.trace("validate conformance level");
270         if (componentTypeEnum != ComponentTypeEnum.SERVICE) {
271             log.error("conformance level validation for non service component, id {}", componentUuid);
272             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
273             return Either.right(errorResponse);
274         }
275         validateUserExists(userId);
276         Either<ComponentMetadataData, StorageOperationStatus> eitherComponent = toscaOperationFacade
277             .getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, null);
278         if (eitherComponent.isRight()) {
279             log.error("can't validate conformance level, component not found, uuid {}", componentUuid);
280             BeEcompErrorManager.getInstance().logBeComponentMissingError("validateConformanceLevel", componentTypeEnum.getValue(), componentUuid);
281             StorageOperationStatus status = eitherComponent.right().value();
282             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(status, componentTypeEnum);
283             ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus);
284             return Either.right(responseFormat);
285         }
286         String componentConformanceLevel = eitherComponent.left().value().getMetadataDataDefinition().getConformanceLevel();
287         if (StringUtils.isBlank(componentConformanceLevel)) {
288             log.error("component conformance level property is null or empty, uuid {}", componentUuid);
289             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
290             return Either.right(errorResponse);
291         }
292         String configConformanceLevel = ConfigurationManager.getConfigurationManager().getConfiguration().getMinToscaConformanceLevel();
293         Boolean result = true;
294         if (CommonBeUtils.conformanceLevelCompare(componentConformanceLevel, configConformanceLevel) < 0) {
295             log.error("invalid asset conformance level, uuid {}, asset conformanceLevel {}, config conformanceLevel {}", componentUuid,
296                 componentConformanceLevel, configConformanceLevel);
297             result = false;
298         }
299         log.trace("conformance level validation finished");
300         return Either.left(result);
301     }
302
303     protected void validateIcon(User user, Component component, AuditingActionEnum actionEnum) {
304         log.debug("validate Icon");
305         ComponentTypeEnum type = component.getComponentType();
306         String icon = component.getIcon();
307         if (StringUtils.isEmpty(icon)) {
308             log.info("icon is missing.");
309             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_ICON, type.getValue());
310             componentsUtils.auditComponentAdmin(errorResponse, user, component, actionEnum, type);
311             throw new ComponentException(ActionStatus.COMPONENT_MISSING_ICON, type.getValue());
312         }
313         try {
314             validateIcon(icon, type);
315         } catch (ComponentException e) {
316             ResponseFormat responseFormat =
317                 e.getResponseFormat() != null ? e.getResponseFormat() : componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
318             componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, type);
319             throw e;
320         }
321     }
322
323     private void validateIcon(String icon, ComponentTypeEnum type) {
324         if (icon != null) {
325             if (!ValidationUtils.validateIconLength(icon)) {
326                 log.debug("icon exceeds max length");
327                 throw new ComponentException(ActionStatus.COMPONENT_ICON_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.ICON_MAX_LENGTH);
328             }
329             if (!ValidationUtils.validateIcon(icon)) {
330                 log.info("icon is invalid.");
331                 throw new ComponentException(ActionStatus.COMPONENT_INVALID_ICON, type.getValue());
332             }
333         }
334     }
335
336     protected void checkComponentFieldsForOverrideAttempt(Component component) {
337         if (component.getLifecycleState() != null) {
338             log.info("LifecycleState cannot be defined by user. This field will be overridden by the application");
339         }
340         if (component.getVersion() != null) {
341             log.info("Version cannot be defined by user. This field will be overridden by the application");
342         }
343         if (component.getCreatorUserId() != null || component.getCreatorFullName() != null) {
344             log.info("Creator cannot be defined by user. This field will be overridden by the application");
345         }
346         if (component.getLastUpdaterUserId() != null || component.getLastUpdaterFullName() != null) {
347             log.info("Last Updater cannot be defined by user. This field will be overridden by the application");
348         }
349         if (component.getCreationDate() != null) {
350             log.info("Creation Date cannot be defined by user. This field will be overridden by the application");
351         }
352         if (component.isHighestVersion() != null) {
353             log.info("Is Highest Version cannot be defined by user. This field will be overridden by the application");
354         }
355         if (component.getUUID() != null) {
356             log.info("UUID cannot be defined by user. This field will be overridden by the application");
357         }
358         if (component.getLastUpdateDate() != null) {
359             log.info("Last Update Date cannot be defined by user. This field will be overridden by the application");
360         }
361         if (component.getUniqueId() != null) {
362             log.info("uid cannot be defined by user. This field will be overridden by the application.");
363             component.setUniqueId(null);
364         }
365         if (component.getInvariantUUID() != null) {
366             log.info("Invariant UUID cannot be defined by user. This field will be overridden by the application.");
367         }
368     }
369
370     protected void validateComponentFieldsBeforeCreate(User user, Component component, AuditingActionEnum actionEnum) {
371         // validate component name uniqueness
372         log.debug("validate component name ");
373         componentNameValidator.validateAndCorrectField(user, component, actionEnum);
374         // validate description
375         log.debug("validate description");
376         componentDescriptionValidator.validateAndCorrectField(user, component, actionEnum);
377         // validate tags
378         log.debug("validate tags");
379         componentTagsValidator.validateAndCorrectField(user, component, actionEnum);
380         // validate contact info
381         log.debug("validate contact info");
382         componentContactIdValidator.validateAndCorrectField(user, component, actionEnum);
383         // validate icon
384         log.debug("validate icon");
385         validateIcon(user, component, actionEnum);
386     }
387
388     public CapReqDef getRequirementsAndCapabilities(String componentId, ComponentTypeEnum componentTypeEnum, String userId) {
389         validateUserExists(userId);
390         ComponentParametersView filter = new ComponentParametersView(true);
391         filter.setIgnoreCapabilities(false);
392         filter.setIgnoreRequirements(false);
393         filter.setIgnoreComponentInstances(false);
394         try {
395             Component component = validateComponentExists(componentId, componentTypeEnum, filter);
396             return new CapReqDef(component.getRequirements(), component.getCapabilities());
397         } catch (ComponentException e) {
398             BeEcompErrorManager.getInstance().logBeComponentMissingError("getRequirementsAndCapabilities", componentTypeEnum.getValue(), componentId);
399             throwComponentException(e.getResponseFormat());
400         }
401         return null;
402     }
403
404     public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponents(boolean isAbstractAbstract,
405                                                                                          ComponentTypeEnum componentTypeEnum,
406                                                                                          String internalComponentType, List<String> componentUids,
407                                                                                          String userId) {
408         try {
409             validateUserExists(userId);
410             List<Component> result = new ArrayList<>();
411             List<String> componentsUidToFetch = new ArrayList<>();
412             componentsUidToFetch.addAll(componentUids);
413             if (!componentsUidToFetch.isEmpty()) {
414                 log.debug("Number of Components to fetch from graph is {}", componentsUidToFetch.size());
415                 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade
416                     .getLatestVersionNotAbstractComponents(isAbstractAbstract, componentTypeEnum, internalComponentType, componentsUidToFetch);
417                 if (nonCheckoutCompResponse.isLeft()) {
418                     log.debug("Retrived Resource successfully.");
419                     result.addAll(nonCheckoutCompResponse.left().value());
420                 } else {
421                     return Either.right(
422                         componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value())));
423                 }
424             }
425             return Either.left(result);
426         } finally {
427             janusGraphDao.commit();
428         }
429     }
430
431     public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponentsMetadata(final boolean isAbstractAbstract,
432                                                                                                  final HighestFilterEnum highestFilter,
433                                                                                                  final ComponentTypeEnum componentTypeEnum,
434                                                                                                  final String internalComponentType, String userId,
435                                                                                                  final String modelName,
436                                                                                                  final boolean includeNormativeExtensionModels) {
437         Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = null;
438         try {
439             validateUserExists(userId);
440             nonCheckoutCompResponse = toscaOperationFacade
441                 .getLatestVersionNotAbstractMetadataOnly(isAbstractAbstract, componentTypeEnum, internalComponentType, modelName,
442                     includeNormativeExtensionModels);
443             if (nonCheckoutCompResponse.isLeft()) {
444                 log.debug("Retrieved Resource successfully.");
445                 return Either.left(nonCheckoutCompResponse.left().value());
446             }
447             return Either
448                 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value())));
449         } finally {
450             if (nonCheckoutCompResponse != null && nonCheckoutCompResponse.isLeft()) {
451                 janusGraphDao.commit();
452             }
453         }
454     }
455
456     public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
457     }
458
459     @SuppressWarnings("unchecked")
460     public void setToscaArtifactsPlaceHolders(Component component, User user) {
461         Map<String, ArtifactDefinition> artifactMap = component.getToscaArtifacts();
462         if (artifactMap == null) {
463             artifactMap = new HashMap<>();
464         }
465         String componentUniqueId = component.getUniqueId();
466         String componentSystemName = component.getSystemName();
467         String componentType = component.getComponentType().getValue().toLowerCase();
468         Map<String, Object> toscaArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts();
469         if (toscaArtifacts != null) {
470             for (Entry<String, Object> artifactInfoMap : toscaArtifacts.entrySet()) {
471                 Map<String, Object> artifactInfo = (Map<String, Object>) artifactInfoMap.getValue();
472                 ArtifactDefinition artifactDefinition = artifactsBusinessLogic
473                     .createArtifactPlaceHolderInfo(componentUniqueId, artifactInfoMap.getKey(), artifactInfo, user, ArtifactGroupTypeEnum.TOSCA);
474                 artifactDefinition
475                     .setArtifactName(ValidationUtils.normalizeFileName(componentType + "-" + componentSystemName + artifactInfo.get("artifactName")));
476                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
477             }
478         }
479         component.setToscaArtifacts(artifactMap);
480     }
481
482     public Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest,
483                                                                         boolean inTransaction, boolean shouldLock) {
484         return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true, true);
485     }
486
487     public Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest,
488                                                                         boolean inTransaction, boolean shouldLock, boolean retrieveResource) {
489         return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true, retrieveResource);
490     }
491
492     private Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest,
493                                                                          boolean inTransaction, boolean shouldLock, boolean fetchTemplatesFromDB,
494                                                                          boolean retrieveResource) {
495         if (retrieveResource) {
496             Either<Component, StorageOperationStatus> toscaElement = toscaOperationFacade.getToscaFullElement(component.getUniqueId());
497             if (toscaElement.isRight()) {
498                 throw new ByActionStatusComponentException(
499                     componentsUtils.convertFromStorageResponse(toscaElement.right().value(), component.getComponentType()));
500             }
501             component = toscaElement.left().value();
502         }
503         Either<ArtifactDefinition, Operation> generateToscaRes = saveToscaArtifactAndPopulateToscaArtifactsWithResult(component, componentsUtils,
504             ArtifactTypeEnum.TOSCA_TEMPLATE,
505             (comp, toscaArtifact) -> saveToscaArtifactPayload(toscaArtifact, comp, user, isInCertificationRequest, shouldLock, inTransaction,
506                 fetchTemplatesFromDB));
507         if (!isAbstractResource(component)) {
508             generateToscaRes = saveToscaArtifactAndPopulateToscaArtifactsWithResult(component, componentsUtils, ArtifactTypeEnum.TOSCA_CSAR,
509                 (comp, toscaArtifactArg) -> saveToscaArtifactPayload(toscaArtifactArg, comp, user, isInCertificationRequest, shouldLock,
510                     inTransaction, true));
511         }
512         return generateToscaRes;
513     }
514
515     private boolean isAbstractResource(Component component) {
516         return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).isAbstract();
517     }
518
519     private Either<ArtifactDefinition, Operation> saveToscaArtifactPayload(ArtifactDefinition artifactDefinition,
520                                                                            org.openecomp.sdc.be.model.Component component, User user,
521                                                                            boolean isInCertificationRequest, boolean shouldLock,
522                                                                            boolean inTransaction, boolean fetchTemplatesFromDB) {
523         return artifactsBusinessLogic
524             .generateAndSaveToscaArtifact(artifactDefinition, component, user, isInCertificationRequest, shouldLock, inTransaction,
525                 fetchTemplatesFromDB);
526     }
527
528     public ImmutablePair<String, byte[]> getToscaModelByComponentUuid(ComponentTypeEnum componentType, String uuid,
529                                                                       ResourceCommonInfo resourceCommonInfo) {
530         Either<List<Component>, StorageOperationStatus> latestVersionEither = toscaOperationFacade.getComponentListByUuid(uuid, null);
531         if (latestVersionEither.isRight()) {
532             throw new ByActionStatusComponentException(
533                 componentsUtils.convertFromStorageResponse(latestVersionEither.right().value(), componentType));
534         }
535         List<Component> components = latestVersionEither.left().value();
536         Component component = components.stream().filter(Component::isHighestVersion).findFirst().orElse(null);
537         if (component == null) {
538             component = components.stream().filter(c -> c.getLifecycleState() == LifecycleStateEnum.CERTIFIED).findFirst().orElse(null);
539         }
540         if (component == null) {
541             throw new ByResponseFormatComponentException(
542                 componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, componentType)));
543         }
544         resourceCommonInfo.setResourceName(component.getName());
545         // TODO remove after migration - handle artifact not found(no
546
547         // placeholder)
548         if (null == component.getToscaArtifacts() || component.getToscaArtifacts().isEmpty()) {
549             throw new ByResponseFormatComponentException(
550                 componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ArtifactTypeEnum.TOSCA_CSAR.name()));
551         }
552
553         final ArtifactDefinition csarArtifact = component.getToscaArtifacts().values().stream()
554             .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType())).findAny().orElseThrow(() -> {
555                 throw new ByResponseFormatComponentException(
556                     componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ArtifactTypeEnum.TOSCA_CSAR.name()));
557             });
558         return artifactsBusinessLogic.handleDownloadToscaModelRequest(component, csarArtifact);
559     }
560
561     protected StorageOperationStatus markComponentToDelete(Component component) {
562         ComponentTypeEnum componentType = component.getComponentType();
563         String uniqueId = component.getUniqueId();
564         if (Boolean.TRUE.equals(component.getIsDeleted())) {
565             log.info("component {} already marked as deleted. id= {}, type={}", component.getName(), uniqueId, componentType);
566             return StorageOperationStatus.NOT_FOUND;
567         }
568         StorageOperationStatus markResourceToDelete = toscaOperationFacade.markComponentToDelete(component);
569         if (StorageOperationStatus.OK != markResourceToDelete) {
570             log.debug("failed to mark component {} of type {} for delete. error = {}", uniqueId, componentType, markResourceToDelete);
571             return markResourceToDelete;
572         } else {
573             log.debug("Component {}  of type {} was marked as deleted", uniqueId, componentType);
574             updateCatalog(component, ChangeTypeEnum.DELETE);
575             return StorageOperationStatus.OK;
576         }
577     }
578
579     public Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Component currentComponent, Component updatedComponent,
580                                                                         AuditingActionEnum auditingAction) {
581         String descriptionUpdated = updatedComponent.getDescription();
582         String descriptionCurrent = currentComponent.getDescription();
583         if (descriptionUpdated != null && !descriptionCurrent.equals(descriptionUpdated)) {
584             componentDescriptionValidator.validateAndCorrectField(user, updatedComponent, auditingAction);
585             currentComponent.setDescription(updatedComponent.getDescription());
586         }
587         return Either.left(true);
588     }
589
590     public Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Component currentComponent, Component updatedComponent) {
591         String projectCodeUpdated = updatedComponent.getProjectCode();
592         String projectCodeCurrent = currentComponent.getProjectCode();
593         if (projectCodeUpdated != null && !projectCodeCurrent.equals(projectCodeUpdated)) {
594             try {
595                 componentProjectCodeValidator.validateAndCorrectField(user, updatedComponent, null);
596             } catch (ComponentException exp) {
597                 ResponseFormat errorRespons = exp.getResponseFormat();
598                 return Either.right(errorRespons);
599             }
600             currentComponent.setProjectCode(updatedComponent.getProjectCode());
601         }
602         return Either.left(true);
603     }
604
605     public Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Component currentComponent, Component updatedComponent,
606                                                                  boolean hasBeenCertified) {
607         String iconUpdated = updatedComponent.getIcon();
608         String iconCurrent = currentComponent.getIcon();
609         if (iconUpdated != null && !iconCurrent.equals(iconUpdated)) {
610             if (!hasBeenCertified) {
611                 componentIconValidator.validateAndCorrectField(user, updatedComponent, null);
612                 currentComponent.setIcon(updatedComponent.getIcon());
613             } else {
614                 log.info("icon {} cannot be updated once the component has been certified once.", iconUpdated);
615                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_PARAMETER_CANNOT_BE_CHANGED, "Icon",
616                     currentComponent.getComponentType().name().toLowerCase());
617                 return Either.right(errorResponse);
618             }
619         }
620         return Either.left(true);
621     }
622
623     protected Either<List<String>, ResponseFormat> deleteMarkedComponents(ComponentTypeEnum componentType) {
624         log.trace("start deleteMarkedComponents");
625         Either<List<String>, StorageOperationStatus> deleteMarkedElements = toscaOperationFacade.deleteMarkedElements(componentType);
626         if (deleteMarkedElements.isRight()) {
627             janusGraphDao.rollback();
628             ResponseFormat responseFormat = componentsUtils
629                 .getResponseFormat(componentsUtils.convertFromStorageResponse(deleteMarkedElements.right().value(), componentType));
630             return Either.right(responseFormat);
631         }
632         log.trace("end deleteMarkedComponents");
633         janusGraphDao.commit();
634         return Either.left(deleteMarkedElements.left().value());
635     }
636
637     /**
638      * @param componentId
639      * @param user
640      * @param dataParamsToReturn - ui list of params to return
641      * @return
642      */
643     public Either<UiComponentDataTransfer, ResponseFormat> getComponentDataFilteredByParams(String componentId, User user,
644                                                                                             List<String> dataParamsToReturn) {
645         if (user != null) {
646             validateUserExists(user);
647         }
648         UiComponentDataTransfer result = new UiComponentDataTransfer();
649         if (dataParamsToReturn == null || dataParamsToReturn.isEmpty()) {
650             Either.left(result);
651         } else {
652             Either<UiComponentDataTransfer, ResponseFormat> uiDataTransferEither = getUiComponentDataTransferByComponentId(componentId,
653                 dataParamsToReturn);
654             if (uiDataTransferEither.isRight()) {
655                 return Either.right(uiDataTransferEither.right().value());
656             }
657             result = uiDataTransferEither.left().value();
658         }
659         return Either.left(result);
660     }
661
662     protected <T extends Component> void generateAndAddInputsFromGenericTypeProperties(T component, Resource genericType) {
663         List<InputDefinition> genericAndComponentInputs = new ArrayList<>();
664         List<InputDefinition> genericInputs = genericTypeBusinessLogic.generateInputsFromGenericTypeProperties(genericType);
665         genericAndComponentInputs.addAll(genericInputs);
666         if (null != component.getInputs()) {
667             List<InputDefinition> nonGenericInputsFromComponent = getAllNonGenericInputsFromComponent(genericInputs, component.getInputs());
668             genericAndComponentInputs.addAll(nonGenericInputsFromComponent);
669         }
670         component.setInputs(genericAndComponentInputs);
671     }
672
673     private List<InputDefinition> getAllNonGenericInputsFromComponent(List<InputDefinition> genericInputs, List<InputDefinition> componentInputs) {
674         if (genericInputs == null) {
675             return componentInputs;
676         }
677         Map<String, InputDefinition> inputByNameMap = MapUtil.toMap(genericInputs, InputDefinition::getName);
678         List<InputDefinition> componentNonGenericInputs = new ArrayList<>();
679         componentInputs.stream().forEach(input -> {
680             if (!inputByNameMap.containsKey(input.getName())) {
681                 componentNonGenericInputs.add(input);
682             }
683         });
684         return componentNonGenericInputs;
685     }
686
687     protected void generatePropertiesFromGenericType(final Component component, final Resource genericType) {
688         if (CollectionUtils.isEmpty(genericType.getProperties())) {
689             return;
690         }
691         final List<PropertyDefinition> genericTypePropertyList = genericType.getProperties().stream().map(PropertyDefinition::new)
692             .peek(propertyDefinition -> propertyDefinition.setUniqueId(null)).collect(Collectors.toList());
693         if (component.getProperties() == null) {
694             component.setProperties(new ArrayList<>(genericTypePropertyList));
695         } else {
696             List<PropertyDefinition> servicePropertyList = component.getProperties();
697             genericTypePropertyList.stream()
698                 .filter(property -> servicePropertyList.stream().noneMatch(property1 -> property1.getName().equals(property.getName())))
699                 .forEach(servicePropertyList::add);
700         }
701         component.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(null));
702     }
703
704     protected <T extends Component> Resource fetchAndSetDerivedFromGenericType(final T component) {
705         return fetchAndSetDerivedFromGenericType(component, null);
706     }
707
708     protected <T extends Component> Resource fetchAndSetDerivedFromGenericType(final T component, final String toscaType) {
709         final Resource genericTypeResource = fetchDerivedFromGenericType(component, toscaType);
710         component.setDerivedFromGenericInfo(genericTypeResource);
711         return genericTypeResource;
712     }
713
714     public <T extends Component> Resource fetchDerivedFromGenericType(final T component, final String toscaType) {
715         final Either<Resource, ResponseFormat> genericTypeEither = this.genericTypeBusinessLogic.fetchDerivedFromGenericType(component, toscaType);
716         if (genericTypeEither.isRight()) {
717             log.debug("Failed to fetch latest generic type for component {} of type {}", component.getName(), component.assetType());
718             throw new ByActionStatusComponentException(ActionStatus.GENERIC_TYPE_NOT_FOUND, component.assetType());
719         }
720         return genericTypeEither.left().value();
721     }
722
723
724     public Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstanceProperties(String componentId,
725                                                                                                                                 Map<FilterKeyEnum, List<String>> filters,
726                                                                                                                                 String userId) {
727         Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> response = null;
728         Either<Component, StorageOperationStatus> getResourceRes = null;
729         try {
730             if (!filters.containsKey(FilterKeyEnum.NAME_FRAGMENT) && StringUtils.isEmpty(filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0))) {
731                 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
732             }
733             if (userId != null && response == null) {
734                 validateUserExists(userId);
735             }
736             if (response == null) {
737                 getResourceRes = toscaOperationFacade.getToscaElement(componentId);
738                 if (getResourceRes.isRight()) {
739                     response = Either
740                         .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getResourceRes.right().value())));
741                 }
742             }
743             if (response == null) {
744                 response = getFilteredComponentInstancesProperties(getResourceRes.left().value(), filters);
745             }
746         } catch (Exception e) {
747             log.debug("The exception {} occured during filtered instance properties fetching. the  containing component is {}. ", e, componentId);
748             response = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
749         } finally {
750             if (response != null && response.isLeft()) {
751                 toscaOperationFacade.commit();
752             } else {
753                 toscaOperationFacade.rollback();
754             }
755         }
756         return response;
757     }
758
759     private Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstancesProperties(Component component,
760                                                                                                                                   Map<FilterKeyEnum, List<String>> filters) {
761         Map<String, List<IComponentInstanceConnectedElement>> filteredProperties = new HashMap<>();
762         Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> result = Either.left(filteredProperties);
763         List<ComponentInstance> filteredInstances = getFilteredInstances(component, filters.get(FilterKeyEnum.RESOURCE_TYPE));
764         String propertyNameFragment = filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0);
765         boolean searchByFragment = propertyNameFragment.length() > 3;
766         if (CollectionUtils.isNotEmpty(filteredInstances)) {
767             for (ComponentInstance instance : filteredInstances) {
768                 if (component.getComponentInstancesProperties() != null && component.getComponentInstancesProperties()
769                     .containsKey(instance.getUniqueId())) {
770                     List<IComponentInstanceConnectedElement> currProperties = getFilteredComponentInstanceProperties(
771                         component.getComponentInstancesProperties().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
772                     setFilteredProperties(filteredProperties, instance, currProperties);
773                 }
774                 if (component.getComponentInstancesInputs() != null && component.getComponentInstancesInputs().containsKey(instance.getUniqueId())) {
775                     List<IComponentInstanceConnectedElement> currInputs = getFilteredComponentInstanceInputs(
776                         component.getComponentInstancesInputs().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
777                     if (CollectionUtils.isNotEmpty(currInputs)) {
778                         checkFilteredProperties(filteredProperties, instance, currInputs);
779                     }
780                 }
781             }
782         }
783         return result;
784     }
785
786     private void setFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance,
787                                        List<IComponentInstanceConnectedElement> currProperties) {
788         if (CollectionUtils.isNotEmpty(currProperties)) {
789             filteredProperties.put(instance.getUniqueId(), currProperties);
790         }
791     }
792
793     private void checkFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance,
794                                          List<IComponentInstanceConnectedElement> currInputs) {
795         if (filteredProperties.get(instance.getUniqueId()) != null) {
796             filteredProperties.get(instance.getUniqueId()).addAll(currInputs);
797         } else {
798             filteredProperties.put(instance.getUniqueId(), currInputs);
799         }
800     }
801
802     private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceInputs(List<ComponentInstanceInput> inputs,
803                                                                                         String propertyNameFragment, boolean searchByFragment) {
804         return inputs.stream().filter(i -> isMatchingInput(i, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
805     }
806
807     private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceProperties(List<ComponentInstanceProperty> instanceProperties,
808                                                                                             String propertyNameFragment, boolean searchByFragment) {
809         return instanceProperties.stream().filter(p -> isMatchingProperty(p, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
810     }
811
812     private boolean isMatchingInput(ComponentInstanceInput input, String propertyNameFragment, boolean searchByFragment) {
813         boolean isMatching = false;
814         if (searchByFragment && input.getName().toLowerCase().contains(propertyNameFragment)) {
815             isMatching = true;
816         }
817         if (!searchByFragment && input.getName().equalsIgnoreCase(propertyNameFragment)) {
818             isMatching = true;
819         }
820         return isMatching;
821     }
822
823     private boolean isMatchingProperty(ComponentInstanceProperty property, String propertyNameFragment, boolean searchByFragment) {
824         boolean isMatching = false;
825         if (searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment)) {
826             isMatching = true;
827         }
828         if (!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)) {
829             isMatching = true;
830         }
831         if (!isMatching && !ToscaPropertyType.isPrimitiveType(property.getType())) {
832             isMatching = isMatchingComplexPropertyByRecursively(property, propertyNameFragment, searchByFragment);
833         }
834         return isMatching;
835     }
836
837     private boolean isMatchingComplexPropertyByRecursively(PropertyDataDefinition property, String propertyNameFragment, boolean searchByFragment) {
838         String propertyType;
839         List<PropertyDefinition> dataTypeProperties;
840         DataTypeDefinition currentProperty;
841         if (searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment.toLowerCase())) {
842             return true;
843         }
844         if (!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)) {
845             return true;
846         }
847         propertyType = isEmptyInnerType(property) ? property.getType() : property.getSchema().getProperty().getType();
848         if (ToscaPropertyType.isScalarType(propertyType)) {
849             return false;
850         }
851         Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameRes = propertyOperation.getDataTypeByName(propertyType, null);
852         if (getDataTypeByNameRes.isRight()) {
853             return false;
854         }
855         currentProperty = getDataTypeByNameRes.left().value();
856         dataTypeProperties = currentProperty.getProperties();
857         boolean dataPropertiesNotNull = CollectionUtils.isNotEmpty(dataTypeProperties);
858         BooleanSupplier dataMatchesComplexProperty = () -> isMatchingComplexProperty(propertyNameFragment, searchByFragment, dataTypeProperties);
859         BooleanSupplier parentPropertiesNotNull = () -> CollectionUtils.isNotEmpty(currentProperty.getDerivedFrom().getProperties());
860         BooleanSupplier parentDataMatchesComplexProperty = () -> isMatchingComplexProperty(propertyNameFragment, searchByFragment,
861             currentProperty.getDerivedFrom().getProperties());
862         return ((dataPropertiesNotNull && dataMatchesComplexProperty.getAsBoolean()) || (parentPropertiesNotNull.getAsBoolean()
863             && parentDataMatchesComplexProperty.getAsBoolean()));
864     }
865
866     private boolean isMatchingComplexProperty(String propertyNameFragment, boolean searchByFragment, List<PropertyDefinition> dataTypeProperties) {
867         for (PropertyDefinition prop : dataTypeProperties) {
868             if (isMatchingComplexPropertyByRecursively(prop, propertyNameFragment, searchByFragment)) {
869                 return true;
870             }
871         }
872         return false;
873     }
874
875     private boolean isEmptyInnerType(PropertyDataDefinition property) {
876         return property == null || property.getSchema() == null || property.getSchema().getProperty() == null
877             || property.getSchema().getProperty().getType() == null;
878     }
879
880     public Either<Boolean, ResponseFormat> shouldUpgradeToLatestGeneric(Component clonedComponent) {
881         if (!clonedComponent.deriveFromGeneric() || StringUtils.isNotEmpty(clonedComponent.getModel())) {
882             return Either.left(false);
883         }
884         Boolean shouldUpgrade = false;
885         String currentGenericType = clonedComponent.getDerivedFromGenericType();
886         String currentGenericVersion = clonedComponent.getDerivedFromGenericVersion();
887         Resource genericTypeResource = fetchAndSetDerivedFromGenericType(clonedComponent);
888         if (null == currentGenericType || !currentGenericType.equals(genericTypeResource.getToscaResourceName()) || !currentGenericVersion
889             .equals(genericTypeResource.getVersion())) {
890             shouldUpgrade = upgradeToLatestGeneric(clonedComponent, genericTypeResource);
891             if (!shouldUpgrade) {
892                 reverntUpdateOfGenericVersion(clonedComponent, currentGenericType, currentGenericVersion);
893             }
894         }
895         return Either.left(shouldUpgrade);
896     }
897
898     private void reverntUpdateOfGenericVersion(Component clonedComponent, String currentGenericType, String currentGenericVersion) {
899         clonedComponent.setDerivedFromGenericType(currentGenericType);
900         clonedComponent.setDerivedFromGenericVersion(currentGenericVersion);
901     }
902
903     private <T extends ToscaDataDefinition> Either<Map<String, T>, String> validateNoConflictingProperties(List<T> currentList,
904                                                                                                            List<T> upgradedList) {
905         Map<String, T> currentMap = ToscaDataDefinition.listToMapByName(currentList);
906         Map<String, T> upgradedMap = ToscaDataDefinition.listToMapByName(upgradedList);
907         return ToscaDataDefinition.mergeDataMaps(upgradedMap, currentMap, true);
908     }
909
910     private boolean shouldUpgradeNodeType(Component componentToCheckOut, Resource latestGeneric) {
911         List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
912         Either<Map<String, PropertyDefinition>, String> validPropertiesMerge = validateNoConflictingProperties(genericTypeProps,
913             ((Resource) componentToCheckOut).getProperties());
914         if (validPropertiesMerge.isRight()) {
915             if (log.isDebugEnabled()) {
916                 log.debug("property {} cannot be overriden, check out performed without upgrading to latest generic",
917                     validPropertiesMerge.right().value());
918             }
919             return false;
920         }
921         List<AttributeDefinition> genericTypeAttributes = latestGeneric.getAttributes();
922         final Either<Map<String, AttributeDefinition>, String> validAttributesMerge = validateNoConflictingProperties(genericTypeAttributes,
923             ((Resource) componentToCheckOut).getAttributes());
924         if (validAttributesMerge.isRight()) {
925             if (log.isDebugEnabled()) {
926                 log.debug("attribute {} cannot be overriden, check out performed without upgrading to latest generic",
927                     validAttributesMerge.right().value());
928             }
929             return false;
930         }
931         return true;
932     }
933
934     private boolean upgradeToLatestGeneric(Component componentToCheckOut, Resource latestGeneric) {
935         if (!componentToCheckOut.shouldGenerateInputs()) {
936             //node type - validate properties and attributes
937             return shouldUpgradeNodeType(componentToCheckOut, latestGeneric);
938         }
939         List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
940         List<InputDefinition> genericTypeInputs = null == genericTypeProps ? null
941             : genericTypeBusinessLogic.convertGenericTypePropertiesToInputsDefintion(genericTypeProps, latestGeneric.getUniqueId());
942         List<InputDefinition> currentList = new ArrayList<>();
943         // nullify existing ownerId from existing list and merge into updated list
944         if (null != componentToCheckOut.getInputs()) {
945             for (InputDefinition input : componentToCheckOut.getInputs()) {
946                 InputDefinition copy = new InputDefinition(input);
947                 copy.setOwnerId(null);
948                 currentList.add(copy);
949             }
950         }
951         if (null == genericTypeInputs) {
952             componentToCheckOut.setInputs(currentList);
953             return true;
954         }
955         Either<Map<String, InputDefinition>, String> eitherMerged = validateNoConflictingProperties(genericTypeInputs, currentList);
956         if (eitherMerged.isRight()) {
957             if (log.isDebugEnabled()) {
958                 log.debug("input {} cannot be overriden, check out performed without upgrading to latest generic", eitherMerged.right().value());
959             }
960             return false;
961         }
962         componentToCheckOut.setInputs(new ArrayList<>(eitherMerged.left().value().values()));
963         return true;
964     }
965
966     private List<ComponentInstance> getFilteredInstances(Component component, List<String> resourceTypes) {
967         List<ComponentInstance> filteredInstances = null;
968         if (CollectionUtils.isEmpty(resourceTypes)) {
969             filteredInstances = component.getComponentInstances();
970         } else if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
971             filteredInstances = component.getComponentInstances().stream().filter(i -> isMatchingType(i.getOriginType(), resourceTypes))
972                 .collect(Collectors.toList());
973         }
974         if (filteredInstances == null) {
975             filteredInstances = new ArrayList<>();
976         }
977         return filteredInstances;
978     }
979
980     private boolean isMatchingType(OriginTypeEnum originType, List<String> resourceTypes) {
981         boolean isMatchingType = false;
982         for (String resourceType : resourceTypes) {
983             if (originType == OriginTypeEnum.findByValue(resourceType.toUpperCase())) {
984                 isMatchingType = true;
985                 break;
986             }
987         }
988         return isMatchingType;
989     }
990
991     public Either<Component, ActionStatus> shouldUpgradeToLatestDerived(Component clonedComponent) {
992         //general implementation. Must be error for service, VF . In ResourceBuisnessLogic exist override
993         return Either.right(ActionStatus.GENERAL_ERROR);
994     }
995
996     protected Either<Component, ResponseFormat> updateCatalog(Component component, ChangeTypeEnum changeStatus) {
997         if (log.isDebugEnabled()) {
998             log.debug("update Catalog start with Component Type {} And Componet Name {} with change status {}",
999                 component.getComponentType().name(), component.getName(), changeStatus.name());
1000         }
1001         ActionStatus status = catalogOperations.updateCatalog(changeStatus, component);
1002         if (status != ActionStatus.OK) {
1003             return Either.right(componentsUtils.getResponseFormat(status));
1004         }
1005         return Either.left(component);
1006     }
1007
1008     @Autowired
1009     public void setCatalogOperations(CatalogOperation catalogOperations) {
1010         this.catalogOperations = catalogOperations;
1011     }
1012
1013     public List<GroupDefinition> throwComponentException(ResponseFormat responseFormat) {
1014         throw new ByResponseFormatComponentException(responseFormat);
1015     }
1016 }