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