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