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