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