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