2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.be.components.impl;
23 import java.util.ArrayList;
24 import java.util.EnumMap;
25 import java.util.HashMap;
26 import java.util.List;
28 import java.util.Map.Entry;
29 import java.util.stream.Collectors;
31 import org.apache.commons.collections.CollectionUtils;
32 import org.apache.commons.lang3.StringUtils;
33 import org.apache.commons.lang3.tuple.ImmutablePair;
34 import org.openecomp.sdc.be.config.BeEcompErrorManager;
35 import org.openecomp.sdc.be.config.ConfigurationManager;
36 import org.openecomp.sdc.be.dao.api.ActionStatus;
37 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
38 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
39 import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition;
40 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
41 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
42 import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum;
43 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
44 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
45 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
46 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
47 import org.openecomp.sdc.be.model.ArtifactDefinition;
48 import org.openecomp.sdc.be.model.CapReqDef;
49 import org.openecomp.sdc.be.model.Component;
50 import org.openecomp.sdc.be.model.ComponentInstance;
51 import org.openecomp.sdc.be.model.ComponentInstanceInput;
52 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
53 import org.openecomp.sdc.be.model.ComponentParametersView;
54 import org.openecomp.sdc.be.model.DataTypeDefinition;
55 import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement;
56 import org.openecomp.sdc.be.model.InputDefinition;
57 import org.openecomp.sdc.be.model.LifecycleStateEnum;
58 import org.openecomp.sdc.be.model.Operation;
59 import org.openecomp.sdc.be.model.PropertyDefinition;
60 import org.openecomp.sdc.be.model.Resource;
61 import org.openecomp.sdc.be.model.User;
62 import org.openecomp.sdc.be.model.cache.ComponentCache;
63 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
64 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
65 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
66 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
67 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
68 import org.openecomp.sdc.be.user.Role;
69 import org.openecomp.sdc.be.utils.CommonBeUtils;
70 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
71 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
72 import org.openecomp.sdc.common.config.EcompErrorName;
73 import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum;
74 import org.openecomp.sdc.common.util.ValidationUtils;
75 import org.openecomp.sdc.exception.ResponseFormat;
76 import org.slf4j.Logger;
77 import org.slf4j.LoggerFactory;
78 import org.springframework.beans.factory.annotation.Autowired;
80 import fj.data.Either;
82 public abstract class ComponentBusinessLogic extends BaseBusinessLogic {
85 protected ArtifactsBusinessLogic artifactsBusinessLogic;
88 protected ComponentCache componentCache;
91 private static Logger log = LoggerFactory.getLogger(ComponentBusinessLogic.class.getName());
93 private static final String TAG_FIELD_LABEL = "tag";
95 public abstract Either<List<String>, ResponseFormat> deleteMarkedComponents();
97 public abstract ComponentInstanceBusinessLogic getComponentInstanceBL();
99 public abstract Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, ComponentTypeEnum componentTypeEnum, String userId, String searchText);
104 * @param dataParamsToReturn
107 public abstract Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String componentId, List<String> dataParamsToReturn);
109 protected Either<User, ResponseFormat> validateUser(User user, String ecompErrorContext, Component component, AuditingActionEnum auditAction, boolean inTransaction) {
110 Either<User, ResponseFormat> userValidationResult = validateUserNotEmpty(user, ecompErrorContext);
111 ResponseFormat responseFormat;
112 if (userValidationResult.isRight()) {
113 user.setUserId("UNKNOWN");
114 responseFormat = userValidationResult.right().value();
115 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", auditAction, component.getComponentType());
116 return Either.right(responseFormat);
118 Either<User, ResponseFormat> userResult = validateUserExists(user, ecompErrorContext, inTransaction);
119 if (userResult.isRight()) {
120 responseFormat = userResult.right().value();
121 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", auditAction, component.getComponentType());
122 return Either.right(responseFormat);
124 user = userResult.left().value();
128 protected Either<Boolean, ResponseFormat> validateUserRole(User user, Component component, List<Role> roles, AuditingActionEnum auditAction, String comment) {
129 if (roles != null && roles.isEmpty()) {
130 roles.add(Role.ADMIN);
131 roles.add(Role.DESIGNER);
133 Either<Boolean, ResponseFormat> validationResult = validateUserRole(user, roles);
134 if (validationResult.isRight()) {
135 ComponentTypeEnum componentType = component.getComponentType();
136 EnumMap<AuditingFieldsKeysEnum, Object> additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class);
137 if (componentType.equals(ComponentTypeEnum.SERVICE)) {
138 additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, comment);
139 String distributionStatus = ((ServiceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition()).getDistributionStatus();
140 additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, distributionStatus);
141 additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, distributionStatus);
143 componentsUtils.auditComponent(validationResult.right().value(), user, component, "", "", auditAction, componentType, additionalParams);
145 return validationResult;
148 protected Either<Boolean, ResponseFormat> validateComponentName(User user, Component component, AuditingActionEnum actionEnum) {
149 ComponentTypeEnum type = component.getComponentType();
150 String componentName = component.getName();
151 if (!ValidationUtils.validateStringNotEmpty(componentName)) {
152 log.debug("component name is empty");
153 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_COMPONENT_NAME, type.getValue());
154 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
155 return Either.right(errorResponse);
158 if (!ValidationUtils.validateComponentNameLength(componentName)) {
159 log.debug("Component name exceeds max length {} ", ValidationUtils.COMPONENT_NAME_MAX_LENGTH);
160 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NAME_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.COMPONENT_NAME_MAX_LENGTH);
161 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
162 return Either.right(errorResponse);
165 if (!validateTagPattern(componentName)) {
166 log.debug("Component name {} has invalid format", componentName);
167 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPONENT_NAME, type.getValue());
168 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
169 return Either.right(errorResponse);
171 component.setNormalizedName(ValidationUtils.normaliseComponentName(componentName));
172 component.setSystemName(ValidationUtils.convertToSystemName(componentName));
174 return Either.left(true);
177 protected Either<Boolean, ResponseFormat> validateDescriptionAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
178 ComponentTypeEnum type = component.getComponentType();
179 String description = component.getDescription();
180 if (!ValidationUtils.validateStringNotEmpty(description)) {
181 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_DESCRIPTION, type.getValue());
182 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
183 return Either.right(errorResponse);
186 description = ValidationUtils.removeNoneUtf8Chars(description);
187 description = ValidationUtils.normaliseWhitespace(description);
188 description = ValidationUtils.stripOctets(description);
189 description = ValidationUtils.removeHtmlTagsOnly(description);
191 Either<Boolean, ResponseFormat> validatDescription = validateComponentDescription(description, type);
192 if (validatDescription.isRight()) {
193 ResponseFormat responseFormat = validatDescription.right().value();
194 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, type);
195 return Either.right(responseFormat);
197 component.setDescription(description);
198 return Either.left(true);
201 public Either<Boolean, ResponseFormat> validateComponentDescription(String description, ComponentTypeEnum type) {
202 if (description != null) {
203 if (!ValidationUtils.validateDescriptionLength(description)) {
204 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_DESCRIPTION_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.COMPONENT_DESCRIPTION_MAX_LENGTH));
207 if (!ValidationUtils.validateIsEnglish(description)) {
208 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_DESCRIPTION, type.getValue()));
210 return Either.left(true);
212 return Either.left(false);
215 protected Either<Boolean, ResponseFormat> validateComponentNameUnique(User user, Component component, AuditingActionEnum actionEnum) {
216 ComponentTypeEnum type = component.getComponentType();
217 ResourceTypeEnum resourceType = null;
218 if(component instanceof Resource){
219 resourceType = ((Resource)component).getResourceType();
221 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateComponentNameExists(component.getName(), resourceType, type);
223 if (dataModelResponse.isLeft()) {
224 if ( !dataModelResponse.left().value()) {
225 return Either.left(true);
227 log.info("Component with name {} already exists", component.getName());
228 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, type.getValue(), component.getName());
229 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
230 return Either.right(errorResponse);
233 BeEcompErrorManager.getInstance().logBeSystemError("validateComponentNameUnique");
234 log.debug("Error while validateComponentNameUnique for component: {}", component.getName());
235 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
236 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
237 return Either.right(errorResponse);
240 protected Either<Boolean, ResponseFormat> validateContactId(User user, Component component, AuditingActionEnum actionEnum) {
241 log.debug("validate component contactId");
242 ComponentTypeEnum type = component.getComponentType();
243 String contactId = component.getContactId();
245 if (!ValidationUtils.validateStringNotEmpty(contactId)) {
246 log.info("contact is missing.");
247 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CONTACT, type.getValue());
248 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
249 return Either.right(errorResponse);
252 Either<Boolean, ResponseFormat> validateContactIdResponse = validateContactId(contactId, type);
253 if (validateContactIdResponse.isRight()) {
254 ResponseFormat responseFormat = validateContactIdResponse.right().value();
255 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, type);
257 return validateContactIdResponse;
260 private Either<Boolean, ResponseFormat> validateContactId(String contactId, ComponentTypeEnum type) {
261 if (contactId != null) {
262 if (!ValidationUtils.validateContactId(contactId)) {
263 log.info("contact is invalid.");
264 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CONTACT, type.getValue());
265 return Either.right(errorResponse);
267 return Either.left(true);
269 return Either.left(false);
273 public Either<Boolean, ResponseFormat> validateConformanceLevel(String componentUuid, ComponentTypeEnum componentTypeEnum, String userId) {
274 log.trace("validate conformance level");
276 if (componentTypeEnum != ComponentTypeEnum.SERVICE) {
277 log.error("conformance level validation for non service component, id {}", componentUuid);
278 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
279 return Either.right(errorResponse);
282 Either<User, ResponseFormat> resp = validateUserExists(userId, "validateConformanceLevel", false);
283 if (resp.isRight()) {
284 log.error("can't validate conformance level, user is not validated, uuid {}, userId {}", componentUuid, userId);
285 return Either.right(resp.right().value());
288 Either<ComponentMetadataData, StorageOperationStatus> eitherComponent = toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, null);
289 if (eitherComponent.isRight()) {
290 log.error("can't validate conformance level, component not found, uuid {}", componentUuid);
291 BeEcompErrorManager.getInstance().logBeComponentMissingError("validateConformanceLevel", componentTypeEnum.getValue(), componentUuid);
293 StorageOperationStatus status = eitherComponent.right().value();
294 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(status, componentTypeEnum);
295 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus);
296 return Either.right(responseFormat);
299 String componentConformanceLevel = eitherComponent.left().value().getMetadataDataDefinition().getConformanceLevel();
300 if (StringUtils.isBlank(componentConformanceLevel)) {
301 log.error("component conformance level property is null or empty, uuid {}", componentUuid);
302 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
303 return Either.right(errorResponse);
306 String configConformanceLevel = ConfigurationManager.getConfigurationManager().getConfiguration().getMinToscaConformanceLevel();
307 Boolean result = true;
308 if (CommonBeUtils.conformanceLevelCompare(componentConformanceLevel, configConformanceLevel) < 0) {
309 log.error("invalid asset conformance level, uuid {}, asset conformanceLevel {}, config conformanceLevel {}", componentUuid, componentConformanceLevel, configConformanceLevel);
312 log.trace("conformance level validation finished");
314 return Either.left(result);
317 protected Either<Boolean, ResponseFormat> validateIcon(User user, Component component, AuditingActionEnum actionEnum) {
318 log.debug("validate Icon");
319 ComponentTypeEnum type = component.getComponentType();
320 String icon = component.getIcon();
321 if (!ValidationUtils.validateStringNotEmpty(icon)) {
322 log.info("icon is missing.");
323 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_ICON, type.getValue());
324 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
325 return Either.right(errorResponse);
328 Either<Boolean, ResponseFormat> validateIcon = validateIcon(icon, type);
329 if (validateIcon.isRight()) {
330 ResponseFormat responseFormat = validateIcon.right().value();
331 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, type);
336 private Either<Boolean, ResponseFormat> validateIcon(String icon, ComponentTypeEnum type) {
338 if (!ValidationUtils.validateIconLength(icon)) {
339 log.debug("icon exceeds max length");
340 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ICON_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.ICON_MAX_LENGTH));
343 if (!ValidationUtils.validateIcon(icon)) {
344 log.info("icon is invalid.");
345 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_ICON, type.getValue());
346 return Either.right(errorResponse);
348 return Either.left(true);
350 return Either.left(false);
353 protected Either<Boolean, ResponseFormat> validateTagsListAndRemoveDuplicates(User user, Component component, AuditingActionEnum actionEnum) {
354 List<String> tagsList = component.getTags();
356 Either<Boolean, ResponseFormat> validateTags = validateComponentTags(tagsList, component.getName(), component.getComponentType());
357 if (validateTags.isRight()) {
358 ResponseFormat responseFormat = validateTags.right().value();
359 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, component.getComponentType());
360 return Either.right(responseFormat);
362 ValidationUtils.removeDuplicateFromList(tagsList);
363 return Either.left(true);
366 protected Either<Boolean, ResponseFormat> validateComponentTags(List<String> tags, String name, ComponentTypeEnum componentType) {
367 log.debug("validate component tags");
368 boolean includesComponentName = false;
370 if (tags != null && !tags.isEmpty()) {
371 for (String tag : tags) {
372 if (!ValidationUtils.validateTagLength(tag)) {
373 log.debug("tag length exceeds limit {}", ValidationUtils.TAG_MAX_LENGTH);
374 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_SINGLE_TAG_EXCEED_LIMIT, "" + ValidationUtils.TAG_MAX_LENGTH));
376 if (validateTagPattern(tag)) {
377 if (!includesComponentName) {
378 includesComponentName = name.equals(tag);
381 log.debug("invalid tag {}", tag);
382 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_FIELD_FORMAT, componentType.getValue(), TAG_FIELD_LABEL));
384 tagListSize += tag.length() + 1;
386 if (tagListSize > 0) {
390 if (!includesComponentName) {
391 log.debug("tags must include component name");
392 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_TAGS_NO_COMP_NAME));
394 if (!ValidationUtils.validateTagListLength(tagListSize)) {
395 log.debug("overall tags length exceeds limit {}", ValidationUtils.TAG_LIST_MAX_LENGTH);
396 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TAGS_EXCEED_LIMIT, "" + ValidationUtils.TAG_LIST_MAX_LENGTH));
398 return Either.left(true);
400 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS));
403 protected boolean validateTagPattern(String tag) {
404 return ValidationUtils.validateComponentNamePattern(tag);
407 protected Either<Boolean, ResponseFormat> validateProjectCode(User user, Component component, AuditingActionEnum actionEnum) {
408 if (ComponentTypeEnum.RESOURCE.equals(component.getComponentType())) {
409 return Either.left(true);
411 log.debug("validate ProjectCode name ");
412 String projectCode = component.getProjectCode();
414 if (!ValidationUtils.validateStringNotEmpty(projectCode)) {
415 log.info("projectCode is missing.");
416 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_PROJECT_CODE);
417 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, component.getComponentType());
418 return Either.right(errorResponse);
421 Either<Boolean, ResponseFormat> validateProjectCodeResponse = validateProjectCode(projectCode);
422 if (validateProjectCodeResponse.isRight()) {
423 ResponseFormat responseFormat = validateProjectCodeResponse.right().value();
424 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, component.getComponentType());
426 return validateProjectCodeResponse;
430 private Either<Boolean, ResponseFormat> validateProjectCode(String projectCode) {
431 if (projectCode != null) {
432 if (!ValidationUtils.validateProjectCode(projectCode)) {
433 log.info("projectCode is not valid.");
434 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROJECT_CODE);
435 return Either.right(errorResponse);
437 return Either.left(true);
439 return Either.left(false);
442 protected void checkComponentFieldsForOverrideAttempt(Component component) {
443 if (component.getLifecycleState() != null) {
444 log.info("LifecycleState cannot be defined by user. This field will be overridden by the application");
446 if (component.getVersion() != null) {
447 log.info("Version cannot be defined by user. This field will be overridden by the application");
449 if ((component.getCreatorUserId() != null) || (component.getCreatorFullName() != null)) {
450 log.info("Creator cannot be defined by user. This field will be overridden by the application");
452 if ((component.getLastUpdaterUserId() != null) || (component.getLastUpdaterFullName() != null)) {
453 log.info("Last Updater cannot be defined by user. This field will be overridden by the application");
455 if ((component.getCreationDate() != null)) {
456 log.info("Creation Date cannot be defined by user. This field will be overridden by the application");
458 if ((component.isHighestVersion() != null)) {
459 log.info("Is Highest Version cannot be defined by user. This field will be overridden by the application");
461 if ((component.getUUID() != null)) {
462 log.info("UUID cannot be defined by user. This field will be overridden by the application");
464 if ((component.getLastUpdateDate() != null)) {
465 log.info("Last Update Date cannot be defined by user. This field will be overridden by the application");
467 if (component.getUniqueId() != null) {
468 log.info("uid cannot be defined by user. This field will be overridden by the application.");
469 component.setUniqueId(null);
471 if (component.getInvariantUUID() != null) {
472 log.info("Invariant UUID cannot be defined by user. This field will be overridden by the application.");
476 protected Either<Boolean, ResponseFormat> validateComponentFieldsBeforeCreate(User user, Component component, AuditingActionEnum actionEnum) {
477 // validate component name uniqueness
478 log.debug("validate component name ");
479 Either<Boolean, ResponseFormat> componentNameValidation = validateComponentName(user, component, actionEnum);
480 if (componentNameValidation.isRight()) {
481 return componentNameValidation;
484 // validate description
485 log.debug("validate description");
486 Either<Boolean, ResponseFormat> descValidation = validateDescriptionAndCleanup(user, component, actionEnum);
487 if (descValidation.isRight()) {
488 return descValidation;
492 log.debug("validate tags");
493 Either<Boolean, ResponseFormat> tagsValidation = validateTagsListAndRemoveDuplicates(user, component, actionEnum);
494 if (tagsValidation.isRight()) {
495 return tagsValidation;
498 // validate contact info
499 log.debug("validate contact info");
500 Either<Boolean, ResponseFormat> contactIdValidation = validateContactId(user, component, actionEnum);
501 if (contactIdValidation.isRight()) {
502 return contactIdValidation;
506 log.debug("validate icon");
507 Either<Boolean, ResponseFormat> iconValidation = validateIcon(user, component, actionEnum);
508 if (iconValidation.isRight()) {
509 return iconValidation;
511 return Either.left(true);
515 * Fetches Component From the DB
518 * @param componentTypeEnum
521 public <R extends Component> Either<R, StorageOperationStatus> getComponent(String componentId, ComponentTypeEnum componentTypeEnum) {
522 return toscaOperationFacade.getToscaElement(componentId);
525 public Either<CapReqDef, ResponseFormat> getRequirementsAndCapabilities(String componentId, ComponentTypeEnum componentTypeEnum, String userId) {
527 Either<User, ResponseFormat> resp = validateUserExists(userId, "create Component Instance", false);
528 if (resp.isRight()) {
529 return Either.right(resp.right().value());
531 Either<CapReqDef, ResponseFormat> eitherRet = null;
532 ComponentParametersView filter = new ComponentParametersView(true);
533 filter.setIgnoreCapabilities(false);
534 filter.setIgnoreRequirements(false);
535 filter.setIgnoreComponentInstances(false);
536 Either<Component, ResponseFormat> eitherComponent = validateComponentExists(componentId, componentTypeEnum, filter);
537 if (eitherComponent.isLeft()) {
538 eitherRet = Either.left(new CapReqDef(eitherComponent.left().value().getRequirements(), eitherComponent.left().value().getCapabilities()));
540 BeEcompErrorManager.getInstance().logBeComponentMissingError("getRequirementsAndCapabilities", componentTypeEnum.getValue(), componentId);
541 eitherRet = Either.right(eitherComponent.right().value());
546 public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponents(boolean isAbstractAbstract, HighestFilterEnum highestFilter, ComponentTypeEnum componentTypeEnum, String internalComponentType, List<String> componentUids,
548 ResponseFormat responseFormat = null;
550 Either<User, ResponseFormat> resp = validateUserExists(userId, "get Latest Version Not Abstract Components", false);
553 List<Component> result = new ArrayList<>();
554 List<String> componentsUidToFetch = new ArrayList<>();
555 componentsUidToFetch.addAll(componentUids);
557 if (componentsUidToFetch.size() > 0) {
558 log.debug("Number of Components to fetch from graph is {}", componentsUidToFetch.size());
559 Boolean isHighest = isHighest(highestFilter);
560 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade.getLatestVersionNotAbstractComponents(isAbstractAbstract, isHighest, componentTypeEnum, internalComponentType, componentsUidToFetch);
562 if (nonCheckoutCompResponse.isLeft()) {
563 log.debug("Retrived Resource successfully.");
564 result.addAll(nonCheckoutCompResponse.left().value());
566 responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value()));
569 return Either.left(result);
571 responseFormat = resp.right().value();
577 return Either.right(responseFormat);
580 private Boolean isHighest(HighestFilterEnum highestFilter) {
581 Boolean isHighest = null;
582 switch (highestFilter) {
588 case NON_HIGHEST_ONLY:
597 public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponentsMetadata(boolean isAbstractAbstract, HighestFilterEnum highestFilter, ComponentTypeEnum componentTypeEnum, String internalComponentType, String userId) {
598 ResponseFormat responseFormat = null;
601 Either<User, ResponseFormat> resp = validateUserExists(userId, "get Latest Version Not Abstract Components", false);
604 Boolean isHighest = isHighest(highestFilter);
605 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade.getLatestVersionNotAbstractMetadataOnly(isAbstractAbstract, isHighest, componentTypeEnum, internalComponentType);
607 if (nonCheckoutCompResponse.isLeft()) {
608 log.debug("Retrived Resource successfully.");
609 return Either.left(nonCheckoutCompResponse.left().value());
611 responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value()));
613 responseFormat = resp.right().value();
618 return Either.right(responseFormat);
621 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
625 @SuppressWarnings("unchecked")
626 public void setToscaArtifactsPlaceHolders(Component component, User user) {
627 Map<String, ArtifactDefinition> artifactMap = component.getToscaArtifacts();
628 if (artifactMap == null) {
629 artifactMap = new HashMap<String, ArtifactDefinition>();
631 String componentUniqueId = component.getUniqueId();
632 String componentSystemName = component.getSystemName();
633 String componentType = component.getComponentType().getValue().toLowerCase();
634 Map<String, Object> toscaArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts();
636 if (toscaArtifacts != null) {
637 for (Entry<String, Object> artifactInfoMap : toscaArtifacts.entrySet()) {
638 Map<String, Object> artifactInfo = (Map<String, Object>) artifactInfoMap.getValue();
639 ArtifactDefinition artifactDefinition = artifactsBusinessLogic.createArtifactPlaceHolderInfo(componentUniqueId, artifactInfoMap.getKey(), artifactInfo, user, ArtifactGroupTypeEnum.TOSCA);
640 artifactDefinition.setArtifactName(componentType + "-" + componentSystemName + artifactInfo.get("artifactName"));
641 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
644 component.setToscaArtifacts(artifactMap);
647 public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock) {
648 return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true);
651 public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock, boolean fetchTemplatesFromDB) {
652 Either<Component, StorageOperationStatus> toscaElement = toscaOperationFacade.getToscaFullElement(component.getUniqueId());
653 if ( toscaElement.isRight() ){
654 ResponseFormat response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(toscaElement.right().value(), component.getComponentType()));
655 return Either.right(response);
657 component = toscaElement.left().value();
658 Either<Either<ArtifactDefinition, Operation>, ResponseFormat> generateToscaRes = null;
659 if (component.getToscaArtifacts() != null && !component.getToscaArtifacts().isEmpty()) {
660 ArtifactDefinition toscaArtifact = component.getToscaArtifacts().values().stream()
661 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_TEMPLATE.getType()))
663 generateToscaRes = saveToscaArtifactPayload(toscaArtifact, component, user, isInCertificationRequest, shouldLock, inTransaction, fetchTemplatesFromDB);
664 if (generateToscaRes.isRight()) {
665 return generateToscaRes;
667 toscaArtifact = generateToscaRes.left().value().left().value();
668 component.getToscaArtifacts().put(toscaArtifact.getArtifactLabel(), toscaArtifact);
669 toscaArtifact = component.getToscaArtifacts().values().stream()
670 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType()))
672 generateToscaRes = saveToscaArtifactPayload(toscaArtifact, component, user, isInCertificationRequest, shouldLock, inTransaction, true);
674 if (generateToscaRes.isRight()) {
675 return generateToscaRes;
677 ArtifactDefinition toscaArtifact = generateToscaRes.left().value().left().value();
678 component.getToscaArtifacts().put(toscaArtifact.getArtifactLabel(), toscaArtifact);
679 return generateToscaRes;
682 public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> saveToscaArtifactPayload(ArtifactDefinition artifactDefinition, org.openecomp.sdc.be.model.Component component, User user, boolean isInCertificationRequest, boolean shouldLock,
683 boolean inTransaction, boolean fetchTemplatesFromDB) {
684 return artifactsBusinessLogic.generateAndSaveToscaArtifact(artifactDefinition, component, user, isInCertificationRequest, shouldLock, inTransaction, fetchTemplatesFromDB);
687 public Either<ImmutablePair<String, byte[]>, ResponseFormat> getToscaModelByComponentUuid(ComponentTypeEnum componentType, String uuid, EnumMap<AuditingFieldsKeysEnum, Object> additionalParam) {
689 Either<List<Component>, StorageOperationStatus> latestVersionEither = toscaOperationFacade.getComponentListByUuid(uuid, null);
691 if (latestVersionEither.isRight()) {
692 ResponseFormat response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(latestVersionEither.right().value(), componentType));
693 return Either.right(response);
696 List<Component> components = latestVersionEither.left().value();
698 Component component = components.stream().filter(c -> c.isHighestVersion()).findFirst().orElse(null);
699 if(component == null){
700 component = components.stream().filter(c -> c.getLifecycleState() == LifecycleStateEnum.CERTIFIED).findFirst().orElse(null);
703 if(component == null){
704 ResponseFormat response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, componentType));
705 return Either.right(response);
707 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, component.getName());
708 // TODO remove after migration - handle artifact not found(no
710 if (null == component.getToscaArtifacts() || component.getToscaArtifacts().isEmpty()) {
711 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ArtifactTypeEnum.TOSCA_CSAR.name()));
713 ArtifactDefinition csarArtifact = component.getToscaArtifacts().values().stream()
714 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType()))
716 return artifactsBusinessLogic.handleDownloadToscaModelRequest(component, csarArtifact);
719 protected StorageOperationStatus markComponentToDelete(Component component) {
721 ComponentTypeEnum componentType = component.getComponentType();
722 String uniqueId = component.getUniqueId();
723 if ((component.getIsDeleted() != null) && (component.getIsDeleted() == true)) {
724 log.info("component {} already marked as deleted. id= {}, type={}", component.getName(), uniqueId, componentType);
725 return StorageOperationStatus.NOT_FOUND;
728 StorageOperationStatus markResourceToDelete = toscaOperationFacade.markComponentToDelete(component);
729 if (StorageOperationStatus.OK != markResourceToDelete) {
730 log.debug("failed to mark component {} of type {} for delete. error = {}", uniqueId, componentType, markResourceToDelete);
731 return markResourceToDelete;
733 log.debug("Component {} of type {} was marked as deleted", uniqueId, componentType);
734 return StorageOperationStatus.OK;
738 public Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Component currentComponent, Component updatedComponent, AuditingActionEnum audatingAction) {
739 String descriptionUpdated = updatedComponent.getDescription();
740 String descriptionCurrent = currentComponent.getDescription();
741 if (descriptionUpdated != null && !descriptionCurrent.equals(descriptionUpdated)) {
742 Either<Boolean, ResponseFormat> validateDescriptionResponse = validateDescriptionAndCleanup(user, updatedComponent, audatingAction);
743 if (validateDescriptionResponse.isRight()) {
744 ResponseFormat errorRespons = validateDescriptionResponse.right().value();
745 return Either.right(errorRespons);
747 currentComponent.setDescription(updatedComponent.getDescription());
749 return Either.left(true);
752 public Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Component currentComponent, Component updatedComponent) {
753 String projectCodeUpdated = updatedComponent.getProjectCode();
754 String projectCodeCurrent = currentComponent.getProjectCode();
755 if (projectCodeUpdated != null && !projectCodeCurrent.equals(projectCodeUpdated)) {
756 Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, updatedComponent, null);
757 if (validatProjectCodeResponse.isRight()) {
758 ResponseFormat errorRespons = validatProjectCodeResponse.right().value();
759 return Either.right(errorRespons);
761 currentComponent.setProjectCode(updatedComponent.getProjectCode());
763 return Either.left(true);
766 public Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Component currentComponent, Component updatedComponent, boolean hasBeenCertified) {
767 String iconUpdated = updatedComponent.getIcon();
768 String iconCurrent = currentComponent.getIcon();
769 if (iconUpdated != null && !iconCurrent.equals(iconUpdated)) {
770 if (!hasBeenCertified) {
771 Either<Boolean, ResponseFormat> validatIconResponse = validateIcon(user, updatedComponent, null);
772 if (validatIconResponse.isRight()) {
773 ResponseFormat errorRespons = validatIconResponse.right().value();
774 return Either.right(errorRespons);
776 currentComponent.setIcon(updatedComponent.getIcon());
778 log.info("icon {} cannot be updated once the component has been certified once.", iconUpdated);
779 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_PARAMETER_CANNOT_BE_CHANGED, "Icon", currentComponent.getComponentType().name().toLowerCase());
780 return Either.right(errorResponse);
783 return Either.left(true);
786 protected Either<List<String>, ResponseFormat> deleteMarkedComponents(ComponentTypeEnum componentType) {
788 // List<String> deletedComponents = new ArrayList<String>();
789 log.trace("start deleteMarkedComponents");
790 Either<List<String>, StorageOperationStatus> deleteMarkedElements = toscaOperationFacade.deleteMarkedElements(componentType);
793 if ( deleteMarkedElements.isRight()){
794 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteMarkedElements.right().value(), componentType));
795 return Either.right(responseFormat);
797 // ComponentOperation componentOperation = getComponentOperation(componentType);
798 // Either<List<String>, StorageOperationStatus> resourcesToDelete = componentOperation.getAllComponentsMarkedForDeletion();
799 // if (resourcesToDelete.isRight()) {
800 // ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourcesToDelete.right().value(), componentType));
801 // return Either.right(responseFormat);
804 // for (String resourceToDelete : resourcesToDelete.left().value()) {
806 // Either<String, ResponseFormat> deleteMarkedResource = deleteMarkedComponent(resourceToDelete, componentType);
807 // if (deleteMarkedResource.isLeft()) {
808 // deletedComponents.add(deleteMarkedResource.left().value());
811 // if(deletedComponents.size() == 0) {
812 // log.debug("Component list to delete is empty. do commit");
813 // titanGenericDao.commit();
815 log.trace("end deleteMarkedComponents");
816 return Either.left(deleteMarkedElements.left().value());
819 private Either<String, ResponseFormat> deleteMarkedComponent(String componentToDelete, ComponentTypeEnum componentType) {
821 Either<String, ResponseFormat> result = null;
822 NodeTypeEnum compNodeType = componentType.getNodeType();
823 StorageOperationStatus lockResult = graphLockOperation.lockComponent(componentToDelete, compNodeType);
824 if (!lockResult.equals(StorageOperationStatus.OK)) {
825 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedLockObjectError, "Delete marked component");
826 log.debug("Failed to lock component {} error - {}", componentToDelete, lockResult);
827 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
832 // check if resource has relations
833 Either<Boolean, StorageOperationStatus> isResourceInUse = toscaOperationFacade.isComponentInUse(componentToDelete);
834 if (isResourceInUse.isRight()) {
835 log.info("deleteMarkedResource - failed to find relations to resource. id = {}, type = {}, error = {}", componentToDelete, componentType, isResourceInUse.right().value().name());
836 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
837 result = Either.right(responseFormat);
841 if (isResourceInUse.isLeft() && isResourceInUse.left().value() == false) {
843 // delete resource and its artifacts in one transaction
844 Either<List<ArtifactDefinition>, StorageOperationStatus> artifactsRes = getComponentArtifactsForDelete(componentToDelete, compNodeType, true);
845 if (artifactsRes.isRight() && !artifactsRes.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
846 log.info("failed to check artifacts for component node. id = {}, type = {}, error = {}", componentToDelete, componentType, artifactsRes.right().value().name());
847 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
848 result = Either.right(responseFormat);
851 List<ArtifactDefinition> artifactsToDelete = new ArrayList<>();
852 if (artifactsRes.isLeft()) {
853 artifactsToDelete = artifactsRes.left().value();
856 Either<Component, StorageOperationStatus> deleteComponentRes = toscaOperationFacade.deleteToscaComponent(componentToDelete);
857 if (deleteComponentRes.isRight()) {
858 log.info("failed to delete component. id = {}, type = {}, error = {}", componentToDelete, componentType, deleteComponentRes.right().value().name());
859 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(deleteComponentRes.right().value());
860 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, componentToDelete);
861 result = Either.right(responseFormat);
863 log.trace("component was deleted, id = {}, type = {}", componentToDelete, componentType);
864 // delete related artifacts
865 StorageOperationStatus deleteFromEsRes = artifactsBusinessLogic.deleteAllComponentArtifactsIfNotOnGraph(artifactsToDelete);
866 if (!deleteFromEsRes.equals(StorageOperationStatus.OK)) {
867 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(deleteFromEsRes);
868 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, componentToDelete);
869 result = Either.right(responseFormat);
872 log.debug("component and all its artifacts were deleted, id = {}, type = {}", componentToDelete, componentType);
873 result = Either.left(componentToDelete);
877 log.debug("componentis marked for delete but still in use, id = {}, type = {}", componentToDelete, componentType);
878 ActionStatus actionStatus = ActionStatus.RESTRICTED_OPERATION;
879 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, componentToDelete);
880 result = Either.right(responseFormat);
884 if (result == null || result.isRight()) {
885 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "delete marked component");
886 log.debug("operation failed. do rollback");
889 log.debug("operation success. do commit");
892 graphLockOperation.unlockComponent(componentToDelete, compNodeType);
898 public Either<List<ArtifactDefinition>, StorageOperationStatus> getComponentArtifactsForDelete(String parentId, NodeTypeEnum parentType, boolean inTransacton) {
899 List<ArtifactDefinition> artifacts = new ArrayList<ArtifactDefinition>();
900 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse = artifactToscaOperation.getArtifacts(parentId);
901 if (artifactsResponse.isRight()) {
902 if (!artifactsResponse.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
903 log.debug("failed to retrieve artifacts for {} {}", parentType, parentId);
904 return Either.right(artifactsResponse.right().value());
907 artifacts.addAll(artifactsResponse.left().value().values());
910 // if (NodeTypeEnum.Resource.equals(parentType)) {
911 // Either<List<ArtifactDefinition>, StorageOperationStatus> interfacesArtifactsForResource = getAdditionalArtifacts(parentId, false, true);
912 // if (artifactsResponse.isRight() && !interfacesArtifactsForResource.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
913 // log.debug("failed to retrieve interface artifacts for {} {}", parentType, parentId);
914 // return Either.right(interfacesArtifactsForResource.right().value());
915 // } else if (artifactsResponse.isLeft()) {
916 // artifacts.addAll(interfacesArtifactsForResource.left().value());
919 return Either.left(artifacts);
926 * @param dataParamsToReturn - ui list of params to return
930 public Either<UiComponentDataTransfer, ResponseFormat> getComponentDataFilteredByParams(String componentId, User user, List<String> dataParamsToReturn) {
933 Either<User, ResponseFormat> eitherCreator = validateUserExists(user, "Get Component by filtered by ui params", false);
934 if (eitherCreator.isRight()) {
935 return Either.right(eitherCreator.right().value());
939 UiComponentDataTransfer result = new UiComponentDataTransfer();
941 if(dataParamsToReturn == null || dataParamsToReturn.isEmpty()) {
945 Either<UiComponentDataTransfer, ResponseFormat> uiDataTransferEither = getUiComponentDataTransferByComponentId(componentId, dataParamsToReturn);
946 if(uiDataTransferEither.isRight()){
947 return Either.right(uiDataTransferEither.right().value());
949 result = uiDataTransferEither.left().value();
952 return Either.left(result);
955 protected <T extends Component> void generateInputsFromGenericTypeProperties(T component, Resource genericType) {
957 List<PropertyDefinition> genericTypeProps = genericType.getProperties();
958 if(null != genericTypeProps) {
959 String genericUniqueId = genericType.getUniqueId();
960 List<InputDefinition> inputs = convertGenericTypePropertiesToInputsDefintion(genericTypeProps, genericUniqueId);
961 if(null != component.getInputs())
962 inputs.addAll(component.getInputs());
963 component.setInputs(inputs);
967 private List<InputDefinition> convertGenericTypePropertiesToInputsDefintion(List<PropertyDefinition> genericTypeProps, String genericUniqueId) {
968 return genericTypeProps.stream()
969 .map(p -> setInputDefinitionFromProp(p, genericUniqueId))
970 .collect(Collectors.toList());
973 private InputDefinition setInputDefinitionFromProp(PropertyDefinition prop, String genericUniqueId){
974 InputDefinition input = new InputDefinition(prop);
975 input.setOwnerId(genericUniqueId);
979 protected <T extends Component> Either<Resource, ResponseFormat> fetchAndSetDerivedFromGenericType(T component){
981 String genericTypeToscaName = component.fetchGenericTypeToscaNameFromConfig();
982 if(null == genericTypeToscaName)
983 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
984 Either<Resource, StorageOperationStatus> findLatestGeneric = toscaOperationFacade.getLatestCertifiedNodeTypeByToscaResourceName(genericTypeToscaName);
985 if(findLatestGeneric.isRight())
986 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERIC_TYPE_NOT_FOUND, component.assetType(), genericTypeToscaName));
987 Resource genericTypeResource = findLatestGeneric.left().value();
988 component.setDerivedFromGenericInfo(genericTypeResource);
989 return Either.left(genericTypeResource);
992 public Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstanceProperties(String componentId, Map<FilterKeyEnum, List<String>> filters, String userId) {
993 Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> response = null;
994 Either<Component, StorageOperationStatus> getResourceRes = null;
996 if(!filters.containsKey(FilterKeyEnum.NAME_FRAGMENT) && StringUtils.isEmpty(filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0))){
997 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
999 if (userId != null && response == null) {
1000 Either<User, ResponseFormat> validateUserRes = validateUserExists(userId, "Get filtered component instance properties", false);
1001 if (validateUserRes.isRight()) {
1002 response = Either.right(validateUserRes.right().value());
1005 if(response == null){
1006 getResourceRes = toscaOperationFacade.getToscaElement(componentId);
1007 if(getResourceRes.isRight()){
1008 response = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getResourceRes.right().value())));
1011 if(response == null){
1012 response = getFilteredComponentInstancesProperties(getResourceRes.left().value(), filters);
1014 } catch(Exception e){
1015 log.debug("The exception {} occured during filtered instance properties fetching. the containing component is {}. ", e, componentId);
1016 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1018 if (response.isLeft()){
1019 toscaOperationFacade.commit();
1021 toscaOperationFacade.rollback();
1027 private Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstancesProperties(Component component, Map<FilterKeyEnum, List<String>> filters) {
1029 Map<String, List<IComponentInstanceConnectedElement>> filteredProperties = new HashMap<>();
1030 Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> result = Either.left(filteredProperties);
1031 List<ComponentInstance> filteredInstances = getFilteredInstances(component, filters.get(FilterKeyEnum.RESOURCE_TYPE));
1032 String propertyNameFragment= filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0);
1033 boolean searchByFragment = propertyNameFragment.length() > 3 ;
1034 if(CollectionUtils.isNotEmpty(filteredInstances)){
1035 for(ComponentInstance instance : filteredInstances){
1036 if(component.getComponentInstancesProperties()!=null &&component.getComponentInstancesProperties().containsKey(instance.getUniqueId())){
1037 List<IComponentInstanceConnectedElement> currProperties = getFilteredComponentInstanceProperties(component.getComponentInstancesProperties().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
1038 if(CollectionUtils.isNotEmpty(currProperties)){
1039 filteredProperties.put(instance.getUniqueId(), currProperties);
1042 if(component.getComponentInstancesInputs()!=null && component.getComponentInstancesInputs().containsKey(instance.getUniqueId())){
1043 List<IComponentInstanceConnectedElement> currInputs = getFilteredComponentInstanceInputs(component.getComponentInstancesInputs().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
1044 if(CollectionUtils.isNotEmpty(currInputs)){
1045 if(filteredProperties.get(instance.getUniqueId())!=null){
1046 filteredProperties.get(instance.getUniqueId()).addAll(currInputs);
1048 filteredProperties.put(instance.getUniqueId(), currInputs);
1057 private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceInputs(List<ComponentInstanceInput> inputs, String propertyNameFragment, boolean searchByFragment) {
1058 return inputs.stream().filter(i -> isMatchingInput(i, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
1061 private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceProperties(List<ComponentInstanceProperty> instanceProperties, String propertyNameFragment, boolean searchByFragment) {
1062 return instanceProperties.stream().filter(p -> isMatchingProperty(p, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
1065 private boolean isMatchingInput(ComponentInstanceInput input, String propertyNameFragment, boolean searchByFragment) {
1066 boolean isMatching = false;
1067 if(searchByFragment && input.getName().toLowerCase().contains(propertyNameFragment)){
1070 if(!searchByFragment && input.getName().equalsIgnoreCase(propertyNameFragment)){
1076 private boolean isMatchingProperty(ComponentInstanceProperty property, String propertyNameFragment, boolean searchByFragment) {
1077 boolean isMatching = false;
1078 if(searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment)){
1081 if(!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)){
1084 if (!isMatching && !ToscaPropertyType.isPrimitiveType(property.getType())){
1085 isMatching = isMatchingComplexPropertyByRecursively(property, propertyNameFragment, searchByFragment);
1090 private boolean isMatchingComplexPropertyByRecursively(PropertyDataDefinition property, String propertyNameFragment, boolean searchByFragment) {
1091 String propertyType;
1092 List<PropertyDefinition> dataTypeProperties;
1093 DataTypeDefinition currentProperty;
1094 if(searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment.toLowerCase())){
1097 if(!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)){
1101 propertyType = isEmptyInnerType(property) ? property.getType() : property.getSchema().getProperty().getType();
1103 if(ToscaPropertyType.isScalarType(propertyType)){
1106 Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameRes = propertyOperation.getDataTypeByName(propertyType);
1107 if(getDataTypeByNameRes.isRight()){
1110 currentProperty = getDataTypeByNameRes.left().value();
1111 dataTypeProperties = currentProperty.getProperties();
1113 if(CollectionUtils.isNotEmpty(dataTypeProperties)){
1114 for(PropertyDefinition prop : dataTypeProperties){
1115 if(isMatchingComplexPropertyByRecursively(prop, propertyNameFragment, searchByFragment)){
1120 dataTypeProperties = currentProperty.getDerivedFrom().getProperties();
1121 if(CollectionUtils.isNotEmpty(dataTypeProperties)){
1122 for(PropertyDefinition prop : dataTypeProperties){
1123 if(isMatchingComplexPropertyByRecursively(prop, propertyNameFragment, searchByFragment)){
1131 private boolean isEmptyInnerType(PropertyDataDefinition property) {
1132 return property == null|| property.getSchema() == null || property.getSchema().getProperty() == null || property.getSchema().getProperty().getType() == null;
1135 public Either<Boolean, ResponseFormat> shouldUpgradeToLatestGeneric(Component clonedComponent) {
1137 if(!clonedComponent.deriveFromGeneric())
1138 return Either.left(false);
1139 Boolean shouldUpgrade = false;
1140 String currentGenericType = clonedComponent.getDerivedFromGenericType();
1141 String currentGenericVersion = clonedComponent.getDerivedFromGenericVersion();
1142 Either<Resource, ResponseFormat> fetchAndSetLatestGeneric = fetchAndSetDerivedFromGenericType(clonedComponent);
1143 if(fetchAndSetLatestGeneric.isRight())
1144 return Either.right(fetchAndSetLatestGeneric.right().value());
1145 Resource genericTypeResource = fetchAndSetLatestGeneric.left().value();
1146 if(null == currentGenericType || !currentGenericType.equals(genericTypeResource.getToscaResourceName()) || !currentGenericVersion.equals(genericTypeResource.getVersion())){
1147 shouldUpgrade = upgradeToLatestGeneric(clonedComponent, genericTypeResource);
1148 if(!shouldUpgrade) {
1149 reverntUpdateOfGenericVersion(clonedComponent, currentGenericType, currentGenericVersion);
1152 return Either.left(shouldUpgrade);
1155 private void reverntUpdateOfGenericVersion(Component clonedComponent, String currentGenericType, String currentGenericVersion) {
1156 clonedComponent.setDerivedFromGenericType(currentGenericType);
1157 clonedComponent.setDerivedFromGenericVersion(currentGenericVersion);
1160 private <T extends PropertyDataDefinition> Either<Map<String, T>, String> validateNoConflictingProperties(List<T> currentList, List<T> upgradedList) {
1161 Map<String, T> currentMap = ToscaDataDefinition.listToMapByName(currentList);
1162 Map<String, T> upgradedMap = ToscaDataDefinition.listToMapByName(upgradedList);
1163 return ToscaDataDefinition.mergeDataMaps(upgradedMap, currentMap, true);
1166 private boolean shouldUpgradeNodeType(Component componentToCheckOut, Resource latestGeneric){
1168 List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
1169 Either<Map<String, PropertyDefinition>, String> validMerge = validateNoConflictingProperties(genericTypeProps, ((Resource)componentToCheckOut).getProperties());
1170 if (validMerge.isRight()) {
1171 log.debug("property {} cannot be overriden, check out performed without upgrading to latest generic", validMerge.right().value());
1174 List<PropertyDefinition> genericTypeAttributes = latestGeneric.getAttributes();
1175 validMerge = validateNoConflictingProperties(genericTypeAttributes, ((Resource)componentToCheckOut).getAttributes());
1176 if (validMerge.isRight()) {
1177 log.debug("attribute {} cannot be overriden, check out performed without upgrading to latest generic", validMerge.right().value());
1183 private boolean upgradeToLatestGeneric(Component componentToCheckOut, Resource latestGeneric) {
1185 if (!componentToCheckOut.shouldGenerateInputs()) {
1186 //node type - validate properties and attributes
1187 return shouldUpgradeNodeType(componentToCheckOut, latestGeneric);
1189 List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
1190 List<InputDefinition> genericTypeInputs = null == genericTypeProps? null : convertGenericTypePropertiesToInputsDefintion(genericTypeProps, latestGeneric.getUniqueId());
1191 List<InputDefinition> currentList = new ArrayList<>();
1192 // nullify existing ownerId from existing list and merge into updated list
1193 if (null != componentToCheckOut.getInputs()) {
1194 for(InputDefinition input : componentToCheckOut.getInputs()) {
1195 InputDefinition copy = new InputDefinition(input);
1196 copy.setOwnerId(null);
1197 currentList.add(copy);
1200 if (null == genericTypeInputs) {
1201 componentToCheckOut.setInputs(currentList);
1205 Either<Map<String, InputDefinition>, String> eitherMerged = validateNoConflictingProperties(genericTypeInputs, currentList);
1206 if (eitherMerged.isRight()) {
1207 log.debug("input {} cannot be overriden, check out performed without upgrading to latest generic", eitherMerged.right().value());
1210 componentToCheckOut.setInputs(new ArrayList<InputDefinition>(eitherMerged.left().value().values()));
1215 private List<ComponentInstance> getFilteredInstances(Component component, List<String> resourceTypes) {
1216 List<ComponentInstance> filteredInstances = null;
1217 if(CollectionUtils.isEmpty(resourceTypes)){
1218 filteredInstances = component.getComponentInstances();
1220 else if(CollectionUtils.isNotEmpty(component.getComponentInstances())){
1221 filteredInstances = component.getComponentInstances()
1222 .stream().filter(i -> isMatchingType(i.getOriginType(), resourceTypes)).collect(Collectors.toList());
1224 if(filteredInstances == null){
1225 filteredInstances = new ArrayList<>();
1227 return filteredInstances;
1230 private boolean isMatchingType(OriginTypeEnum originType, List<String> resourceTypes) {
1231 boolean isMatchingType = false;
1232 for(String resourceType : resourceTypes){
1233 if(originType == OriginTypeEnum.findByValue(resourceType.toUpperCase())){
1234 isMatchingType = true;
1238 return isMatchingType;