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