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