Support querying of model by type
[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         ArtifactDefinition csarArtifact = component.getToscaArtifacts().values().stream()
547             .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType())).findAny().get();
548         return artifactsBusinessLogic.handleDownloadToscaModelRequest(component, csarArtifact);
549     }
550
551     protected StorageOperationStatus markComponentToDelete(Component component) {
552         ComponentTypeEnum componentType = component.getComponentType();
553         String uniqueId = component.getUniqueId();
554         if (Boolean.TRUE.equals(component.getIsDeleted())) {
555             log.info("component {} already marked as deleted. id= {}, type={}", component.getName(), uniqueId, componentType);
556             return StorageOperationStatus.NOT_FOUND;
557         }
558         StorageOperationStatus markResourceToDelete = toscaOperationFacade.markComponentToDelete(component);
559         if (StorageOperationStatus.OK != markResourceToDelete) {
560             log.debug("failed to mark component {} of type {} for delete. error = {}", uniqueId, componentType, markResourceToDelete);
561             return markResourceToDelete;
562         } else {
563             log.debug("Component {}  of type {} was marked as deleted", uniqueId, componentType);
564             updateCatalog(component, ChangeTypeEnum.DELETE);
565             return StorageOperationStatus.OK;
566         }
567     }
568
569     public Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Component currentComponent, Component updatedComponent,
570                                                                         AuditingActionEnum auditingAction) {
571         String descriptionUpdated = updatedComponent.getDescription();
572         String descriptionCurrent = currentComponent.getDescription();
573         if (descriptionUpdated != null && !descriptionCurrent.equals(descriptionUpdated)) {
574             componentDescriptionValidator.validateAndCorrectField(user, updatedComponent, auditingAction);
575             currentComponent.setDescription(updatedComponent.getDescription());
576         }
577         return Either.left(true);
578     }
579
580     public Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Component currentComponent, Component updatedComponent) {
581         String projectCodeUpdated = updatedComponent.getProjectCode();
582         String projectCodeCurrent = currentComponent.getProjectCode();
583         if (projectCodeUpdated != null && !projectCodeCurrent.equals(projectCodeUpdated)) {
584             try {
585                 componentProjectCodeValidator.validateAndCorrectField(user, updatedComponent, null);
586             } catch (ComponentException exp) {
587                 ResponseFormat errorRespons = exp.getResponseFormat();
588                 return Either.right(errorRespons);
589             }
590             currentComponent.setProjectCode(updatedComponent.getProjectCode());
591         }
592         return Either.left(true);
593     }
594
595     public Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Component currentComponent, Component updatedComponent,
596                                                                  boolean hasBeenCertified) {
597         String iconUpdated = updatedComponent.getIcon();
598         String iconCurrent = currentComponent.getIcon();
599         if (iconUpdated != null && !iconCurrent.equals(iconUpdated)) {
600             if (!hasBeenCertified) {
601                 componentIconValidator.validateAndCorrectField(user, updatedComponent, null);
602                 currentComponent.setIcon(updatedComponent.getIcon());
603             } else {
604                 log.info("icon {} cannot be updated once the component has been certified once.", iconUpdated);
605                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_PARAMETER_CANNOT_BE_CHANGED, "Icon",
606                     currentComponent.getComponentType().name().toLowerCase());
607                 return Either.right(errorResponse);
608             }
609         }
610         return Either.left(true);
611     }
612
613     protected Either<List<String>, ResponseFormat> deleteMarkedComponents(ComponentTypeEnum componentType) {
614         log.trace("start deleteMarkedComponents");
615         Either<List<String>, StorageOperationStatus> deleteMarkedElements = toscaOperationFacade.deleteMarkedElements(componentType);
616         if (deleteMarkedElements.isRight()) {
617             janusGraphDao.rollback();
618             ResponseFormat responseFormat = componentsUtils
619                 .getResponseFormat(componentsUtils.convertFromStorageResponse(deleteMarkedElements.right().value(), componentType));
620             return Either.right(responseFormat);
621         }
622         log.trace("end deleteMarkedComponents");
623         janusGraphDao.commit();
624         return Either.left(deleteMarkedElements.left().value());
625     }
626
627     public Either<List<ArtifactDefinition>, StorageOperationStatus> getComponentArtifactsForDelete(String parentId, NodeTypeEnum parentType) {
628         List<ArtifactDefinition> artifacts = new ArrayList<>();
629         Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse = artifactToscaOperation.getArtifacts(parentId);
630         if (artifactsResponse.isRight()) {
631             if (artifactsResponse.right().value() != StorageOperationStatus.NOT_FOUND) {
632                 log.debug("failed to retrieve artifacts for {} {}", parentType, parentId);
633                 return Either.right(artifactsResponse.right().value());
634             }
635         } else {
636             artifacts.addAll(artifactsResponse.left().value().values());
637         }
638         return Either.left(artifacts);
639     }
640
641     /**
642      * @param componentId
643      * @param user
644      * @param dataParamsToReturn - ui list of params to return
645      * @return
646      */
647     public Either<UiComponentDataTransfer, ResponseFormat> getComponentDataFilteredByParams(String componentId, User user,
648                                                                                             List<String> dataParamsToReturn) {
649         if (user != null) {
650             validateUserExists(user);
651         }
652         UiComponentDataTransfer result = new UiComponentDataTransfer();
653         if (dataParamsToReturn == null || dataParamsToReturn.isEmpty()) {
654             Either.left(result);
655         } else {
656             Either<UiComponentDataTransfer, ResponseFormat> uiDataTransferEither = getUiComponentDataTransferByComponentId(componentId,
657                 dataParamsToReturn);
658             if (uiDataTransferEither.isRight()) {
659                 return Either.right(uiDataTransferEither.right().value());
660             }
661             result = uiDataTransferEither.left().value();
662         }
663         return Either.left(result);
664     }
665
666     protected <T extends Component> void generateAndAddInputsFromGenericTypeProperties(T component, Resource genericType) {
667         List<InputDefinition> genericAndComponentInputs = new ArrayList<>();
668         List<InputDefinition> genericInputs = genericTypeBusinessLogic.generateInputsFromGenericTypeProperties(genericType);
669         genericAndComponentInputs.addAll(genericInputs);
670         if (null != component.getInputs()) {
671             List<InputDefinition> nonGenericInputsFromComponent = getAllNonGenericInputsFromComponent(genericInputs, component.getInputs());
672             genericAndComponentInputs.addAll(nonGenericInputsFromComponent);
673         }
674         component.setInputs(genericAndComponentInputs);
675     }
676
677     private List<InputDefinition> getAllNonGenericInputsFromComponent(List<InputDefinition> genericInputs, List<InputDefinition> componentInputs) {
678         if (genericInputs == null) {
679             return componentInputs;
680         }
681         Map<String, InputDefinition> inputByNameMap = MapUtil.toMap(genericInputs, InputDefinition::getName);
682         List<InputDefinition> componentNonGenericInputs = new ArrayList<>();
683         componentInputs.stream().forEach(input -> {
684             if (!inputByNameMap.containsKey(input.getName())) {
685                 componentNonGenericInputs.add(input);
686             }
687         });
688         return componentNonGenericInputs;
689     }
690     
691     protected void generatePropertiesFromGenericType(final Component component, final Resource genericType) {
692         if (CollectionUtils.isEmpty(genericType.getProperties())) {
693             return;
694         }
695         final List<PropertyDefinition> genericTypePropertyList = genericType.getProperties().stream().map(PropertyDefinition::new)
696             .peek(propertyDefinition -> propertyDefinition.setUniqueId(null)).collect(Collectors.toList());
697         if (component.getProperties() == null) {
698             component.setProperties(new ArrayList<>(genericTypePropertyList));
699         } else {
700             List<PropertyDefinition> servicePropertyList = component.getProperties();
701             genericTypePropertyList.stream()
702                 .filter(property -> servicePropertyList.stream().noneMatch(property1 -> property1.getName().equals(property.getName())))
703                 .forEach(servicePropertyList::add);
704         }
705         component.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(null));
706     }
707     protected <T extends Component> Resource fetchAndSetDerivedFromGenericType(final T component) {
708         return fetchAndSetDerivedFromGenericType(component, null);
709     }
710
711     protected <T extends Component> Resource fetchAndSetDerivedFromGenericType(final T component, final String toscaType) {
712         final Either<Resource, ResponseFormat> genericTypeEither = this.genericTypeBusinessLogic.fetchDerivedFromGenericType(component, toscaType);
713         if (genericTypeEither.isRight()) {
714             log.debug("Failed to fetch latest generic type for component {} of type", component.getName(), component.assetType());
715             throw new ByActionStatusComponentException(ActionStatus.GENERIC_TYPE_NOT_FOUND, component.assetType());
716         }
717         final Resource genericTypeResource = genericTypeEither.left().value();
718         component.setDerivedFromGenericInfo(genericTypeResource);
719         return genericTypeResource;
720     }
721
722     public Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstanceProperties(String componentId,
723                                                                                                                                 Map<FilterKeyEnum, List<String>> filters,
724                                                                                                                                 String userId) {
725         Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> response = null;
726         Either<Component, StorageOperationStatus> getResourceRes = null;
727         try {
728             if (!filters.containsKey(FilterKeyEnum.NAME_FRAGMENT) && StringUtils.isEmpty(filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0))) {
729                 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
730             }
731             if (userId != null && response == null) {
732                 validateUserExists(userId);
733             }
734             if (response == null) {
735                 getResourceRes = toscaOperationFacade.getToscaElement(componentId);
736                 if (getResourceRes.isRight()) {
737                     response = Either
738                         .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getResourceRes.right().value())));
739                 }
740             }
741             if (response == null) {
742                 response = getFilteredComponentInstancesProperties(getResourceRes.left().value(), filters);
743             }
744         } catch (Exception e) {
745             log.debug("The exception {} occured during filtered instance properties fetching. the  containing component is {}. ", e, componentId);
746             response = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
747         } finally {
748             if (response != null && response.isLeft()) {
749                 toscaOperationFacade.commit();
750             } else {
751                 toscaOperationFacade.rollback();
752             }
753         }
754         return response;
755     }
756
757     private Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstancesProperties(Component component,
758                                                                                                                                   Map<FilterKeyEnum, List<String>> filters) {
759         Map<String, List<IComponentInstanceConnectedElement>> filteredProperties = new HashMap<>();
760         Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> result = Either.left(filteredProperties);
761         List<ComponentInstance> filteredInstances = getFilteredInstances(component, filters.get(FilterKeyEnum.RESOURCE_TYPE));
762         String propertyNameFragment = filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0);
763         boolean searchByFragment = propertyNameFragment.length() > 3;
764         if (CollectionUtils.isNotEmpty(filteredInstances)) {
765             for (ComponentInstance instance : filteredInstances) {
766                 if (component.getComponentInstancesProperties() != null && component.getComponentInstancesProperties()
767                     .containsKey(instance.getUniqueId())) {
768                     List<IComponentInstanceConnectedElement> currProperties = getFilteredComponentInstanceProperties(
769                         component.getComponentInstancesProperties().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
770                     setFilteredProperties(filteredProperties, instance, currProperties);
771                 }
772                 if (component.getComponentInstancesInputs() != null && component.getComponentInstancesInputs().containsKey(instance.getUniqueId())) {
773                     List<IComponentInstanceConnectedElement> currInputs = getFilteredComponentInstanceInputs(
774                         component.getComponentInstancesInputs().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
775                     if (CollectionUtils.isNotEmpty(currInputs)) {
776                         checkFilteredProperties(filteredProperties, instance, currInputs);
777                     }
778                 }
779             }
780         }
781         return result;
782     }
783
784     private void setFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance,
785                                        List<IComponentInstanceConnectedElement> currProperties) {
786         if (CollectionUtils.isNotEmpty(currProperties)) {
787             filteredProperties.put(instance.getUniqueId(), currProperties);
788         }
789     }
790
791     private void checkFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance,
792                                          List<IComponentInstanceConnectedElement> currInputs) {
793         if (filteredProperties.get(instance.getUniqueId()) != null) {
794             filteredProperties.get(instance.getUniqueId()).addAll(currInputs);
795         } else {
796             filteredProperties.put(instance.getUniqueId(), currInputs);
797         }
798     }
799
800     private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceInputs(List<ComponentInstanceInput> inputs,
801                                                                                         String propertyNameFragment, boolean searchByFragment) {
802         return inputs.stream().filter(i -> isMatchingInput(i, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
803     }
804
805     private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceProperties(List<ComponentInstanceProperty> instanceProperties,
806                                                                                             String propertyNameFragment, boolean searchByFragment) {
807         return instanceProperties.stream().filter(p -> isMatchingProperty(p, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
808     }
809
810     private boolean isMatchingInput(ComponentInstanceInput input, String propertyNameFragment, boolean searchByFragment) {
811         boolean isMatching = false;
812         if (searchByFragment && input.getName().toLowerCase().contains(propertyNameFragment)) {
813             isMatching = true;
814         }
815         if (!searchByFragment && input.getName().equalsIgnoreCase(propertyNameFragment)) {
816             isMatching = true;
817         }
818         return isMatching;
819     }
820
821     private boolean isMatchingProperty(ComponentInstanceProperty property, String propertyNameFragment, boolean searchByFragment) {
822         boolean isMatching = false;
823         if (searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment)) {
824             isMatching = true;
825         }
826         if (!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)) {
827             isMatching = true;
828         }
829         if (!isMatching && !ToscaPropertyType.isPrimitiveType(property.getType())) {
830             isMatching = isMatchingComplexPropertyByRecursively(property, propertyNameFragment, searchByFragment);
831         }
832         return isMatching;
833     }
834
835     private boolean isMatchingComplexPropertyByRecursively(PropertyDataDefinition property, String propertyNameFragment, boolean searchByFragment) {
836         String propertyType;
837         List<PropertyDefinition> dataTypeProperties;
838         DataTypeDefinition currentProperty;
839         if (searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment.toLowerCase())) {
840             return true;
841         }
842         if (!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)) {
843             return true;
844         }
845         propertyType = isEmptyInnerType(property) ? property.getType() : property.getSchema().getProperty().getType();
846         if (ToscaPropertyType.isScalarType(propertyType)) {
847             return false;
848         }
849         Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameRes = propertyOperation.getDataTypeByName(propertyType, null);
850         if (getDataTypeByNameRes.isRight()) {
851             return false;
852         }
853         currentProperty = getDataTypeByNameRes.left().value();
854         dataTypeProperties = currentProperty.getProperties();
855         boolean dataPropertiesNotNull = CollectionUtils.isNotEmpty(dataTypeProperties);
856         BooleanSupplier dataMatchesComplexProperty = () -> isMatchingComplexProperty(propertyNameFragment, searchByFragment, dataTypeProperties);
857         BooleanSupplier parentPropertiesNotNull = () -> CollectionUtils.isNotEmpty(currentProperty.getDerivedFrom().getProperties());
858         BooleanSupplier parentDataMatchesComplexProperty = () -> isMatchingComplexProperty(propertyNameFragment, searchByFragment,
859             currentProperty.getDerivedFrom().getProperties());
860         return ((dataPropertiesNotNull && dataMatchesComplexProperty.getAsBoolean()) || (parentPropertiesNotNull.getAsBoolean()
861             && parentDataMatchesComplexProperty.getAsBoolean()));
862     }
863
864     private boolean isMatchingComplexProperty(String propertyNameFragment, boolean searchByFragment, List<PropertyDefinition> dataTypeProperties) {
865         for (PropertyDefinition prop : dataTypeProperties) {
866             if (isMatchingComplexPropertyByRecursively(prop, propertyNameFragment, searchByFragment)) {
867                 return true;
868             }
869         }
870         return false;
871     }
872
873     private boolean isEmptyInnerType(PropertyDataDefinition property) {
874         return property == null || property.getSchema() == null || property.getSchema().getProperty() == null
875             || property.getSchema().getProperty().getType() == null;
876     }
877
878     public Either<Boolean, ResponseFormat> shouldUpgradeToLatestGeneric(Component clonedComponent) {
879         if (!clonedComponent.deriveFromGeneric() || StringUtils.isNotEmpty(clonedComponent.getModel())) {
880             return Either.left(false);
881         }
882         Boolean shouldUpgrade = false;
883         String currentGenericType = clonedComponent.getDerivedFromGenericType();
884         String currentGenericVersion = clonedComponent.getDerivedFromGenericVersion();
885         Resource genericTypeResource = fetchAndSetDerivedFromGenericType(clonedComponent);
886         if (null == currentGenericType || !currentGenericType.equals(genericTypeResource.getToscaResourceName()) || !currentGenericVersion
887             .equals(genericTypeResource.getVersion())) {
888             shouldUpgrade = upgradeToLatestGeneric(clonedComponent, genericTypeResource);
889             if (!shouldUpgrade) {
890                 reverntUpdateOfGenericVersion(clonedComponent, currentGenericType, currentGenericVersion);
891             }
892         }
893         return Either.left(shouldUpgrade);
894     }
895
896     private void reverntUpdateOfGenericVersion(Component clonedComponent, String currentGenericType, String currentGenericVersion) {
897         clonedComponent.setDerivedFromGenericType(currentGenericType);
898         clonedComponent.setDerivedFromGenericVersion(currentGenericVersion);
899     }
900
901     private <T extends ToscaDataDefinition> Either<Map<String, T>, String> validateNoConflictingProperties(List<T> currentList,
902                                                                                                            List<T> upgradedList) {
903         Map<String, T> currentMap = ToscaDataDefinition.listToMapByName(currentList);
904         Map<String, T> upgradedMap = ToscaDataDefinition.listToMapByName(upgradedList);
905         return ToscaDataDefinition.mergeDataMaps(upgradedMap, currentMap, true);
906     }
907
908     private boolean shouldUpgradeNodeType(Component componentToCheckOut, Resource latestGeneric) {
909         List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
910         Either<Map<String, PropertyDefinition>, String> validPropertiesMerge = validateNoConflictingProperties(genericTypeProps,
911             ((Resource) componentToCheckOut).getProperties());
912         if (validPropertiesMerge.isRight()) {
913             if (log.isDebugEnabled()) {
914                 log.debug("property {} cannot be overriden, check out performed without upgrading to latest generic",
915                         validPropertiesMerge.right().value());
916             }
917             return false;
918         }
919         List<AttributeDefinition> genericTypeAttributes = latestGeneric.getAttributes();
920         final Either<Map<String, AttributeDefinition>, String> validAttributesMerge = validateNoConflictingProperties(genericTypeAttributes,
921             ((Resource) componentToCheckOut).getAttributes());
922         if (validAttributesMerge.isRight()) {
923             if (log.isDebugEnabled()) {
924                 log.debug("attribute {} cannot be overriden, check out performed without upgrading to latest generic",
925                         validAttributesMerge.right().value());
926             }
927             return false;
928         }
929         return true;
930     }
931
932     private boolean upgradeToLatestGeneric(Component componentToCheckOut, Resource latestGeneric) {
933         if (!componentToCheckOut.shouldGenerateInputs()) {
934             //node type - validate properties and attributes
935             return shouldUpgradeNodeType(componentToCheckOut, latestGeneric);
936         }
937         List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
938         List<InputDefinition> genericTypeInputs = null == genericTypeProps ? null
939             : genericTypeBusinessLogic.convertGenericTypePropertiesToInputsDefintion(genericTypeProps, latestGeneric.getUniqueId());
940         List<InputDefinition> currentList = new ArrayList<>();
941         // nullify existing ownerId from existing list and merge into updated list
942         if (null != componentToCheckOut.getInputs()) {
943             for (InputDefinition input : componentToCheckOut.getInputs()) {
944                 InputDefinition copy = new InputDefinition(input);
945                 copy.setOwnerId(null);
946                 currentList.add(copy);
947             }
948         }
949         if (null == genericTypeInputs) {
950             componentToCheckOut.setInputs(currentList);
951             return true;
952         }
953         Either<Map<String, InputDefinition>, String> eitherMerged = validateNoConflictingProperties(genericTypeInputs, currentList);
954         if (eitherMerged.isRight()) {
955             if (log.isDebugEnabled()) {
956                 log.debug("input {} cannot be overriden, check out performed without upgrading to latest generic", eitherMerged.right().value());
957             }
958             return false;
959         }
960         componentToCheckOut.setInputs(new ArrayList<>(eitherMerged.left().value().values()));
961         return true;
962     }
963
964     private List<ComponentInstance> getFilteredInstances(Component component, List<String> resourceTypes) {
965         List<ComponentInstance> filteredInstances = null;
966         if (CollectionUtils.isEmpty(resourceTypes)) {
967             filteredInstances = component.getComponentInstances();
968         } else if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
969             filteredInstances = component.getComponentInstances().stream().filter(i -> isMatchingType(i.getOriginType(), resourceTypes))
970                 .collect(Collectors.toList());
971         }
972         if (filteredInstances == null) {
973             filteredInstances = new ArrayList<>();
974         }
975         return filteredInstances;
976     }
977
978     private boolean isMatchingType(OriginTypeEnum originType, List<String> resourceTypes) {
979         boolean isMatchingType = false;
980         for (String resourceType : resourceTypes) {
981             if (originType == OriginTypeEnum.findByValue(resourceType.toUpperCase())) {
982                 isMatchingType = true;
983                 break;
984             }
985         }
986         return isMatchingType;
987     }
988
989     public Either<Component, ActionStatus> shouldUpgradeToLatestDerived(Component clonedComponent) {
990         //general implementation. Must be error for service, VF . In ResourceBuisnessLogic exist override
991         return Either.right(ActionStatus.GENERAL_ERROR);
992     }
993
994     protected Either<Component, ResponseFormat> updateCatalog(Component component, ChangeTypeEnum changeStatus) {
995         if (log.isDebugEnabled()) {
996             log.debug("update Catalog start with Component Type {} And Componet Name {} with change status {}",
997                     component.getComponentType().name(),component.getName(), changeStatus.name());
998         }
999         ActionStatus status = catalogOperations.updateCatalog(changeStatus, component);
1000         if (status != ActionStatus.OK) {
1001             return Either.right(componentsUtils.getResponseFormat(status));
1002         }
1003         return Either.left(component);
1004     }
1005
1006     public CatalogOperation getCatalogOperations() {
1007         return catalogOperations;
1008     }
1009
1010     @Autowired
1011     public void setCatalogOperations(CatalogOperation catalogOperations) {
1012         this.catalogOperations = catalogOperations;
1013     }
1014
1015     public List<GroupDefinition> throwComponentException(ResponseFormat responseFormat) {
1016         throw new ByResponseFormatComponentException(responseFormat);
1017     }
1018 }