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