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