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