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