Support adding data types to model
[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(boolean isAbstractAbstract,
427                                                                                                  HighestFilterEnum highestFilter,
428                                                                                                  ComponentTypeEnum componentTypeEnum,
429                                                                                                  String internalComponentType, String userId) {
430         try {
431             validateUserExists(userId);
432             Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade
433                 .getLatestVersionNotAbstractMetadataOnly(isAbstractAbstract, componentTypeEnum, internalComponentType);
434             if (nonCheckoutCompResponse.isLeft()) {
435                 log.debug("Retrieved Resource successfully.");
436                 return Either.left(nonCheckoutCompResponse.left().value());
437             }
438             return Either
439                 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value())));
440         } finally {
441             janusGraphDao.commit();
442         }
443     }
444
445     public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
446     }
447
448     @SuppressWarnings("unchecked")
449     public void setToscaArtifactsPlaceHolders(Component component, User user) {
450         Map<String, ArtifactDefinition> artifactMap = component.getToscaArtifacts();
451         if (artifactMap == null) {
452             artifactMap = new HashMap<>();
453         }
454         String componentUniqueId = component.getUniqueId();
455         String componentSystemName = component.getSystemName();
456         String componentType = component.getComponentType().getValue().toLowerCase();
457         Map<String, Object> toscaArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts();
458         if (toscaArtifacts != null) {
459             for (Entry<String, Object> artifactInfoMap : toscaArtifacts.entrySet()) {
460                 Map<String, Object> artifactInfo = (Map<String, Object>) artifactInfoMap.getValue();
461                 ArtifactDefinition artifactDefinition = artifactsBusinessLogic
462                     .createArtifactPlaceHolderInfo(componentUniqueId, artifactInfoMap.getKey(), artifactInfo, user, ArtifactGroupTypeEnum.TOSCA);
463                 artifactDefinition
464                     .setArtifactName(ValidationUtils.normalizeFileName(componentType + "-" + componentSystemName + artifactInfo.get("artifactName")));
465                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
466             }
467         }
468         component.setToscaArtifacts(artifactMap);
469     }
470
471     public Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest,
472                                                                         boolean inTransaction, boolean shouldLock) {
473         return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true, true);
474     }
475
476     public Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest,
477                                                                         boolean inTransaction, boolean shouldLock, boolean retrieveResource) {
478         return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true, retrieveResource);
479     }
480
481     private Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest,
482                                                                          boolean inTransaction, boolean shouldLock, boolean fetchTemplatesFromDB,
483                                                                          boolean retrieveResource) {
484         if (retrieveResource) {
485             Either<Component, StorageOperationStatus> toscaElement = toscaOperationFacade.getToscaFullElement(component.getUniqueId());
486             if (toscaElement.isRight()) {
487                 throw new ByActionStatusComponentException(
488                     componentsUtils.convertFromStorageResponse(toscaElement.right().value(), component.getComponentType()));
489             }
490             component = toscaElement.left().value();
491         }
492         Either<ArtifactDefinition, Operation> generateToscaRes = saveToscaArtifactAndPopulateToscaArtifactsWithResult(component, componentsUtils,
493             ArtifactTypeEnum.TOSCA_TEMPLATE,
494             (comp, toscaArtifact) -> saveToscaArtifactPayload(toscaArtifact, comp, user, isInCertificationRequest, shouldLock, inTransaction,
495                 fetchTemplatesFromDB));
496         if (!isAbstractResource(component)) {
497             generateToscaRes = saveToscaArtifactAndPopulateToscaArtifactsWithResult(component, componentsUtils, ArtifactTypeEnum.TOSCA_CSAR,
498                 (comp, toscaArtifactArg) -> saveToscaArtifactPayload(toscaArtifactArg, comp, user, isInCertificationRequest, shouldLock,
499                     inTransaction, true));
500         }
501         return generateToscaRes;
502     }
503
504     private boolean isAbstractResource(Component component) {
505         return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).isAbstract();
506     }
507
508     private Either<ArtifactDefinition, Operation> saveToscaArtifactPayload(ArtifactDefinition artifactDefinition,
509                                                                            org.openecomp.sdc.be.model.Component component, User user,
510                                                                            boolean isInCertificationRequest, boolean shouldLock,
511                                                                            boolean inTransaction, boolean fetchTemplatesFromDB) {
512         return artifactsBusinessLogic
513             .generateAndSaveToscaArtifact(artifactDefinition, component, user, isInCertificationRequest, shouldLock, inTransaction,
514                 fetchTemplatesFromDB);
515     }
516
517     public ImmutablePair<String, byte[]> getToscaModelByComponentUuid(ComponentTypeEnum componentType, String uuid,
518                                                                       ResourceCommonInfo resourceCommonInfo) {
519         Either<List<Component>, StorageOperationStatus> latestVersionEither = toscaOperationFacade.getComponentListByUuid(uuid, null);
520         if (latestVersionEither.isRight()) {
521             throw new ByActionStatusComponentException(
522                 componentsUtils.convertFromStorageResponse(latestVersionEither.right().value(), componentType));
523         }
524         List<Component> components = latestVersionEither.left().value();
525         Component component = components.stream().filter(Component::isHighestVersion).findFirst().orElse(null);
526         if (component == null) {
527             component = components.stream().filter(c -> c.getLifecycleState() == LifecycleStateEnum.CERTIFIED).findFirst().orElse(null);
528         }
529         if (component == null) {
530             throw new ByResponseFormatComponentException(
531                 componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, componentType)));
532         }
533         resourceCommonInfo.setResourceName(component.getName());
534         // TODO remove after migration - handle artifact not found(no
535
536         // placeholder)
537         if (null == component.getToscaArtifacts() || component.getToscaArtifacts().isEmpty()) {
538             throw new ByResponseFormatComponentException(
539                 componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ArtifactTypeEnum.TOSCA_CSAR.name()));
540         }
541         ArtifactDefinition csarArtifact = component.getToscaArtifacts().values().stream()
542             .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType())).findAny().get();
543         return artifactsBusinessLogic.handleDownloadToscaModelRequest(component, csarArtifact);
544     }
545
546     protected StorageOperationStatus markComponentToDelete(Component component) {
547         ComponentTypeEnum componentType = component.getComponentType();
548         String uniqueId = component.getUniqueId();
549         if (Boolean.TRUE.equals(component.getIsDeleted())) {
550             log.info("component {} already marked as deleted. id= {}, type={}", component.getName(), uniqueId, componentType);
551             return StorageOperationStatus.NOT_FOUND;
552         }
553         StorageOperationStatus markResourceToDelete = toscaOperationFacade.markComponentToDelete(component);
554         if (StorageOperationStatus.OK != markResourceToDelete) {
555             log.debug("failed to mark component {} of type {} for delete. error = {}", uniqueId, componentType, markResourceToDelete);
556             return markResourceToDelete;
557         } else {
558             log.debug("Component {}  of type {} was marked as deleted", uniqueId, componentType);
559             updateCatalog(component, ChangeTypeEnum.DELETE);
560             return StorageOperationStatus.OK;
561         }
562     }
563
564     public Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Component currentComponent, Component updatedComponent,
565                                                                         AuditingActionEnum auditingAction) {
566         String descriptionUpdated = updatedComponent.getDescription();
567         String descriptionCurrent = currentComponent.getDescription();
568         if (descriptionUpdated != null && !descriptionCurrent.equals(descriptionUpdated)) {
569             componentDescriptionValidator.validateAndCorrectField(user, updatedComponent, auditingAction);
570             currentComponent.setDescription(updatedComponent.getDescription());
571         }
572         return Either.left(true);
573     }
574
575     public Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Component currentComponent, Component updatedComponent) {
576         String projectCodeUpdated = updatedComponent.getProjectCode();
577         String projectCodeCurrent = currentComponent.getProjectCode();
578         if (projectCodeUpdated != null && !projectCodeCurrent.equals(projectCodeUpdated)) {
579             try {
580                 componentProjectCodeValidator.validateAndCorrectField(user, updatedComponent, null);
581             } catch (ComponentException exp) {
582                 ResponseFormat errorRespons = exp.getResponseFormat();
583                 return Either.right(errorRespons);
584             }
585             currentComponent.setProjectCode(updatedComponent.getProjectCode());
586         }
587         return Either.left(true);
588     }
589
590     public Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Component currentComponent, Component updatedComponent,
591                                                                  boolean hasBeenCertified) {
592         String iconUpdated = updatedComponent.getIcon();
593         String iconCurrent = currentComponent.getIcon();
594         if (iconUpdated != null && !iconCurrent.equals(iconUpdated)) {
595             if (!hasBeenCertified) {
596                 componentIconValidator.validateAndCorrectField(user, updatedComponent, null);
597                 currentComponent.setIcon(updatedComponent.getIcon());
598             } else {
599                 log.info("icon {} cannot be updated once the component has been certified once.", iconUpdated);
600                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_PARAMETER_CANNOT_BE_CHANGED, "Icon",
601                     currentComponent.getComponentType().name().toLowerCase());
602                 return Either.right(errorResponse);
603             }
604         }
605         return Either.left(true);
606     }
607
608     protected Either<List<String>, ResponseFormat> deleteMarkedComponents(ComponentTypeEnum componentType) {
609         log.trace("start deleteMarkedComponents");
610         Either<List<String>, StorageOperationStatus> deleteMarkedElements = toscaOperationFacade.deleteMarkedElements(componentType);
611         if (deleteMarkedElements.isRight()) {
612             janusGraphDao.rollback();
613             ResponseFormat responseFormat = componentsUtils
614                 .getResponseFormat(componentsUtils.convertFromStorageResponse(deleteMarkedElements.right().value(), componentType));
615             return Either.right(responseFormat);
616         }
617         log.trace("end deleteMarkedComponents");
618         janusGraphDao.commit();
619         return Either.left(deleteMarkedElements.left().value());
620     }
621
622     public Either<List<ArtifactDefinition>, StorageOperationStatus> getComponentArtifactsForDelete(String parentId, NodeTypeEnum parentType) {
623         List<ArtifactDefinition> artifacts = new ArrayList<>();
624         Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse = artifactToscaOperation.getArtifacts(parentId);
625         if (artifactsResponse.isRight()) {
626             if (artifactsResponse.right().value() != StorageOperationStatus.NOT_FOUND) {
627                 log.debug("failed to retrieve artifacts for {} {}", parentType, parentId);
628                 return Either.right(artifactsResponse.right().value());
629             }
630         } else {
631             artifacts.addAll(artifactsResponse.left().value().values());
632         }
633         return Either.left(artifacts);
634     }
635
636     /**
637      * @param componentId
638      * @param user
639      * @param dataParamsToReturn - ui list of params to return
640      * @return
641      */
642     public Either<UiComponentDataTransfer, ResponseFormat> getComponentDataFilteredByParams(String componentId, User user,
643                                                                                             List<String> dataParamsToReturn) {
644         if (user != null) {
645             validateUserExists(user);
646         }
647         UiComponentDataTransfer result = new UiComponentDataTransfer();
648         if (dataParamsToReturn == null || dataParamsToReturn.isEmpty()) {
649             Either.left(result);
650         } else {
651             Either<UiComponentDataTransfer, ResponseFormat> uiDataTransferEither = getUiComponentDataTransferByComponentId(componentId,
652                 dataParamsToReturn);
653             if (uiDataTransferEither.isRight()) {
654                 return Either.right(uiDataTransferEither.right().value());
655             }
656             result = uiDataTransferEither.left().value();
657         }
658         return Either.left(result);
659     }
660
661     protected <T extends Component> void generateAndAddInputsFromGenericTypeProperties(T component, Resource genericType) {
662         List<InputDefinition> genericAndComponentInputs = new ArrayList<>();
663         List<InputDefinition> genericInputs = genericTypeBusinessLogic.generateInputsFromGenericTypeProperties(genericType);
664         genericAndComponentInputs.addAll(genericInputs);
665         if (null != component.getInputs()) {
666             List<InputDefinition> nonGenericInputsFromComponent = getAllNonGenericInputsFromComponent(genericInputs, component.getInputs());
667             genericAndComponentInputs.addAll(nonGenericInputsFromComponent);
668         }
669         component.setInputs(genericAndComponentInputs);
670     }
671
672     private List<InputDefinition> getAllNonGenericInputsFromComponent(List<InputDefinition> genericInputs, List<InputDefinition> componentInputs) {
673         if (genericInputs == null) {
674             return componentInputs;
675         }
676         Map<String, InputDefinition> inputByNameMap = MapUtil.toMap(genericInputs, InputDefinition::getName);
677         List<InputDefinition> componentNonGenericInputs = new ArrayList<>();
678         componentInputs.stream().forEach(input -> {
679             if (!inputByNameMap.containsKey(input.getName())) {
680                 componentNonGenericInputs.add(input);
681             }
682         });
683         return componentNonGenericInputs;
684     }
685
686     protected <T extends Component> Resource fetchAndSetDerivedFromGenericType(T component) {
687         Either<Resource, ResponseFormat> genericTypeEither = this.genericTypeBusinessLogic.fetchDerivedFromGenericType(component);
688         if (genericTypeEither.isRight()) {
689             log.debug("Failed to fetch latest generic type for component {} of type", component.getName(), component.assetType());
690             throw new ByActionStatusComponentException(ActionStatus.GENERIC_TYPE_NOT_FOUND, component.assetType());
691         }
692         Resource genericTypeResource = genericTypeEither.left().value();
693         component.setDerivedFromGenericInfo(genericTypeResource);
694         return genericTypeResource;
695     }
696
697     public Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstanceProperties(String componentId,
698                                                                                                                                 Map<FilterKeyEnum, List<String>> filters,
699                                                                                                                                 String userId) {
700         Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> response = null;
701         Either<Component, StorageOperationStatus> getResourceRes = null;
702         try {
703             if (!filters.containsKey(FilterKeyEnum.NAME_FRAGMENT) && StringUtils.isEmpty(filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0))) {
704                 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
705             }
706             if (userId != null && response == null) {
707                 validateUserExists(userId);
708             }
709             if (response == null) {
710                 getResourceRes = toscaOperationFacade.getToscaElement(componentId);
711                 if (getResourceRes.isRight()) {
712                     response = Either
713                         .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getResourceRes.right().value())));
714                 }
715             }
716             if (response == null) {
717                 response = getFilteredComponentInstancesProperties(getResourceRes.left().value(), filters);
718             }
719         } catch (Exception e) {
720             log.debug("The exception {} occured during filtered instance properties fetching. the  containing component is {}. ", e, componentId);
721             response = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
722         } finally {
723             if (response != null && response.isLeft()) {
724                 toscaOperationFacade.commit();
725             } else {
726                 toscaOperationFacade.rollback();
727             }
728         }
729         return response;
730     }
731
732     private Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstancesProperties(Component component,
733                                                                                                                                   Map<FilterKeyEnum, List<String>> filters) {
734         Map<String, List<IComponentInstanceConnectedElement>> filteredProperties = new HashMap<>();
735         Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> result = Either.left(filteredProperties);
736         List<ComponentInstance> filteredInstances = getFilteredInstances(component, filters.get(FilterKeyEnum.RESOURCE_TYPE));
737         String propertyNameFragment = filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0);
738         boolean searchByFragment = propertyNameFragment.length() > 3;
739         if (CollectionUtils.isNotEmpty(filteredInstances)) {
740             for (ComponentInstance instance : filteredInstances) {
741                 if (component.getComponentInstancesProperties() != null && component.getComponentInstancesProperties()
742                     .containsKey(instance.getUniqueId())) {
743                     List<IComponentInstanceConnectedElement> currProperties = getFilteredComponentInstanceProperties(
744                         component.getComponentInstancesProperties().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
745                     setFilteredProperties(filteredProperties, instance, currProperties);
746                 }
747                 if (component.getComponentInstancesInputs() != null && component.getComponentInstancesInputs().containsKey(instance.getUniqueId())) {
748                     List<IComponentInstanceConnectedElement> currInputs = getFilteredComponentInstanceInputs(
749                         component.getComponentInstancesInputs().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
750                     if (CollectionUtils.isNotEmpty(currInputs)) {
751                         checkFilteredProperties(filteredProperties, instance, currInputs);
752                     }
753                 }
754             }
755         }
756         return result;
757     }
758
759     private void setFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance,
760                                        List<IComponentInstanceConnectedElement> currProperties) {
761         if (CollectionUtils.isNotEmpty(currProperties)) {
762             filteredProperties.put(instance.getUniqueId(), currProperties);
763         }
764     }
765
766     private void checkFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance,
767                                          List<IComponentInstanceConnectedElement> currInputs) {
768         if (filteredProperties.get(instance.getUniqueId()) != null) {
769             filteredProperties.get(instance.getUniqueId()).addAll(currInputs);
770         } else {
771             filteredProperties.put(instance.getUniqueId(), currInputs);
772         }
773     }
774
775     private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceInputs(List<ComponentInstanceInput> inputs,
776                                                                                         String propertyNameFragment, boolean searchByFragment) {
777         return inputs.stream().filter(i -> isMatchingInput(i, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
778     }
779
780     private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceProperties(List<ComponentInstanceProperty> instanceProperties,
781                                                                                             String propertyNameFragment, boolean searchByFragment) {
782         return instanceProperties.stream().filter(p -> isMatchingProperty(p, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
783     }
784
785     private boolean isMatchingInput(ComponentInstanceInput input, String propertyNameFragment, boolean searchByFragment) {
786         boolean isMatching = false;
787         if (searchByFragment && input.getName().toLowerCase().contains(propertyNameFragment)) {
788             isMatching = true;
789         }
790         if (!searchByFragment && input.getName().equalsIgnoreCase(propertyNameFragment)) {
791             isMatching = true;
792         }
793         return isMatching;
794     }
795
796     private boolean isMatchingProperty(ComponentInstanceProperty property, String propertyNameFragment, boolean searchByFragment) {
797         boolean isMatching = false;
798         if (searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment)) {
799             isMatching = true;
800         }
801         if (!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)) {
802             isMatching = true;
803         }
804         if (!isMatching && !ToscaPropertyType.isPrimitiveType(property.getType())) {
805             isMatching = isMatchingComplexPropertyByRecursively(property, propertyNameFragment, searchByFragment);
806         }
807         return isMatching;
808     }
809
810     private boolean isMatchingComplexPropertyByRecursively(PropertyDataDefinition property, String propertyNameFragment, boolean searchByFragment) {
811         String propertyType;
812         List<PropertyDefinition> dataTypeProperties;
813         DataTypeDefinition currentProperty;
814         if (searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment.toLowerCase())) {
815             return true;
816         }
817         if (!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)) {
818             return true;
819         }
820         propertyType = isEmptyInnerType(property) ? property.getType() : property.getSchema().getProperty().getType();
821         if (ToscaPropertyType.isScalarType(propertyType)) {
822             return false;
823         }
824         Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameRes = propertyOperation.getDataTypeByName(propertyType, null);
825         if (getDataTypeByNameRes.isRight()) {
826             return false;
827         }
828         currentProperty = getDataTypeByNameRes.left().value();
829         dataTypeProperties = currentProperty.getProperties();
830         boolean dataPropertiesNotNull = CollectionUtils.isNotEmpty(dataTypeProperties);
831         BooleanSupplier dataMatchesComplexProperty = () -> isMatchingComplexProperty(propertyNameFragment, searchByFragment, dataTypeProperties);
832         BooleanSupplier parentPropertiesNotNull = () -> CollectionUtils.isNotEmpty(currentProperty.getDerivedFrom().getProperties());
833         BooleanSupplier parentDataMatchesComplexProperty = () -> isMatchingComplexProperty(propertyNameFragment, searchByFragment,
834             currentProperty.getDerivedFrom().getProperties());
835         return ((dataPropertiesNotNull && dataMatchesComplexProperty.getAsBoolean()) || (parentPropertiesNotNull.getAsBoolean()
836             && parentDataMatchesComplexProperty.getAsBoolean()));
837     }
838
839     private boolean isMatchingComplexProperty(String propertyNameFragment, boolean searchByFragment, List<PropertyDefinition> dataTypeProperties) {
840         for (PropertyDefinition prop : dataTypeProperties) {
841             if (isMatchingComplexPropertyByRecursively(prop, propertyNameFragment, searchByFragment)) {
842                 return true;
843             }
844         }
845         return false;
846     }
847
848     private boolean isEmptyInnerType(PropertyDataDefinition property) {
849         return property == null || property.getSchema() == null || property.getSchema().getProperty() == null
850             || property.getSchema().getProperty().getType() == null;
851     }
852
853     public Either<Boolean, ResponseFormat> shouldUpgradeToLatestGeneric(Component clonedComponent) {
854         if (!clonedComponent.deriveFromGeneric()) {
855             return Either.left(false);
856         }
857         Boolean shouldUpgrade = false;
858         String currentGenericType = clonedComponent.getDerivedFromGenericType();
859         String currentGenericVersion = clonedComponent.getDerivedFromGenericVersion();
860         Resource genericTypeResource = fetchAndSetDerivedFromGenericType(clonedComponent);
861         if (null == currentGenericType || !currentGenericType.equals(genericTypeResource.getToscaResourceName()) || !currentGenericVersion
862             .equals(genericTypeResource.getVersion())) {
863             shouldUpgrade = upgradeToLatestGeneric(clonedComponent, genericTypeResource);
864             if (!shouldUpgrade) {
865                 reverntUpdateOfGenericVersion(clonedComponent, currentGenericType, currentGenericVersion);
866             }
867         }
868         return Either.left(shouldUpgrade);
869     }
870
871     private void reverntUpdateOfGenericVersion(Component clonedComponent, String currentGenericType, String currentGenericVersion) {
872         clonedComponent.setDerivedFromGenericType(currentGenericType);
873         clonedComponent.setDerivedFromGenericVersion(currentGenericVersion);
874     }
875
876     private <T extends ToscaDataDefinition> Either<Map<String, T>, String> validateNoConflictingProperties(List<T> currentList,
877                                                                                                            List<T> upgradedList) {
878         Map<String, T> currentMap = ToscaDataDefinition.listToMapByName(currentList);
879         Map<String, T> upgradedMap = ToscaDataDefinition.listToMapByName(upgradedList);
880         return ToscaDataDefinition.mergeDataMaps(upgradedMap, currentMap, true);
881     }
882
883     private boolean shouldUpgradeNodeType(Component componentToCheckOut, Resource latestGeneric) {
884         List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
885         Either<Map<String, PropertyDefinition>, String> validPropertiesMerge = validateNoConflictingProperties(genericTypeProps,
886             ((Resource) componentToCheckOut).getProperties());
887         if (validPropertiesMerge.isRight()) {
888             if (log.isDebugEnabled()) {
889                 log.debug("property {} cannot be overriden, check out performed without upgrading to latest generic",
890                         validPropertiesMerge.right().value());
891             }
892             return false;
893         }
894         List<AttributeDefinition> genericTypeAttributes = latestGeneric.getAttributes();
895         final Either<Map<String, AttributeDefinition>, String> validAttributesMerge = validateNoConflictingProperties(genericTypeAttributes,
896             ((Resource) componentToCheckOut).getAttributes());
897         if (validAttributesMerge.isRight()) {
898             if (log.isDebugEnabled()) {
899                 log.debug("attribute {} cannot be overriden, check out performed without upgrading to latest generic",
900                         validAttributesMerge.right().value());
901             }
902             return false;
903         }
904         return true;
905     }
906
907     private boolean upgradeToLatestGeneric(Component componentToCheckOut, Resource latestGeneric) {
908         if (!componentToCheckOut.shouldGenerateInputs()) {
909             //node type - validate properties and attributes
910             return shouldUpgradeNodeType(componentToCheckOut, latestGeneric);
911         }
912         List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
913         List<InputDefinition> genericTypeInputs = null == genericTypeProps ? null
914             : genericTypeBusinessLogic.convertGenericTypePropertiesToInputsDefintion(genericTypeProps, latestGeneric.getUniqueId());
915         List<InputDefinition> currentList = new ArrayList<>();
916         // nullify existing ownerId from existing list and merge into updated list
917         if (null != componentToCheckOut.getInputs()) {
918             for (InputDefinition input : componentToCheckOut.getInputs()) {
919                 InputDefinition copy = new InputDefinition(input);
920                 copy.setOwnerId(null);
921                 currentList.add(copy);
922             }
923         }
924         if (null == genericTypeInputs) {
925             componentToCheckOut.setInputs(currentList);
926             return true;
927         }
928         Either<Map<String, InputDefinition>, String> eitherMerged = validateNoConflictingProperties(genericTypeInputs, currentList);
929         if (eitherMerged.isRight()) {
930             if (log.isDebugEnabled()) {
931                 log.debug("input {} cannot be overriden, check out performed without upgrading to latest generic", eitherMerged.right().value());
932             }
933             return false;
934         }
935         componentToCheckOut.setInputs(new ArrayList<>(eitherMerged.left().value().values()));
936         return true;
937     }
938
939     private List<ComponentInstance> getFilteredInstances(Component component, List<String> resourceTypes) {
940         List<ComponentInstance> filteredInstances = null;
941         if (CollectionUtils.isEmpty(resourceTypes)) {
942             filteredInstances = component.getComponentInstances();
943         } else if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
944             filteredInstances = component.getComponentInstances().stream().filter(i -> isMatchingType(i.getOriginType(), resourceTypes))
945                 .collect(Collectors.toList());
946         }
947         if (filteredInstances == null) {
948             filteredInstances = new ArrayList<>();
949         }
950         return filteredInstances;
951     }
952
953     private boolean isMatchingType(OriginTypeEnum originType, List<String> resourceTypes) {
954         boolean isMatchingType = false;
955         for (String resourceType : resourceTypes) {
956             if (originType == OriginTypeEnum.findByValue(resourceType.toUpperCase())) {
957                 isMatchingType = true;
958                 break;
959             }
960         }
961         return isMatchingType;
962     }
963
964     public Either<Component, ActionStatus> shouldUpgradeToLatestDerived(Component clonedComponent) {
965         //general implementation. Must be error for service, VF . In ResourceBuisnessLogic exist override
966         return Either.right(ActionStatus.GENERAL_ERROR);
967     }
968
969     protected Either<Component, ResponseFormat> updateCatalog(Component component, ChangeTypeEnum changeStatus) {
970         if (log.isDebugEnabled()) {
971             log.debug("update Catalog start with Component Type {} And Componet Name {} with change status {}",
972                     component.getComponentType().name(),component.getName(), changeStatus.name());
973         }
974         ActionStatus status = catalogOperations.updateCatalog(changeStatus, component);
975         if (status != ActionStatus.OK) {
976             return Either.right(componentsUtils.getResponseFormat(status));
977         }
978         return Either.left(component);
979     }
980
981     public CatalogOperation getCatalogOperations() {
982         return catalogOperations;
983     }
984
985     @Autowired
986     public void setCatalogOperations(CatalogOperation catalogOperations) {
987         this.catalogOperations = catalogOperations;
988     }
989
990     public List<GroupDefinition> throwComponentException(ResponseFormat responseFormat) {
991         throw new ByResponseFormatComponentException(responseFormat);
992     }
993 }