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