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