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