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