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.Collection;
25 import java.util.EnumMap;
26 import java.util.HashMap;
27 import java.util.List;
29 import java.util.Map.Entry;
30 import java.util.function.Function;
31 import java.util.function.Predicate;
32 import java.util.stream.Collectors;
34 import org.apache.commons.collections.CollectionUtils;
35 import org.apache.commons.collections.MapUtils;
36 import org.apache.commons.lang3.StringUtils;
37 import org.apache.commons.lang3.tuple.ImmutablePair;
38 import org.openecomp.sdc.be.config.BeEcompErrorManager;
39 import org.openecomp.sdc.be.config.ConfigurationManager;
40 import org.openecomp.sdc.be.dao.api.ActionStatus;
41 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
42 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
43 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
44 import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition;
45 import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition;
46 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
47 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
48 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
49 import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum;
50 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
51 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
52 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
53 import org.openecomp.sdc.be.model.ArtifactDefinition;
54 import org.openecomp.sdc.be.model.CapReqDef;
55 import org.openecomp.sdc.be.model.CapabilityDefinition;
56 import org.openecomp.sdc.be.model.Component;
57 import org.openecomp.sdc.be.model.ComponentInstance;
58 import org.openecomp.sdc.be.model.ComponentInstanceInput;
59 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
60 import org.openecomp.sdc.be.model.ComponentParametersView;
61 import org.openecomp.sdc.be.model.DataTypeDefinition;
62 import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement;
63 import org.openecomp.sdc.be.model.InputDefinition;
64 import org.openecomp.sdc.be.model.LifecycleStateEnum;
65 import org.openecomp.sdc.be.model.Operation;
66 import org.openecomp.sdc.be.model.PropertyDefinition;
67 import org.openecomp.sdc.be.model.RequirementDefinition;
68 import org.openecomp.sdc.be.model.Resource;
69 import org.openecomp.sdc.be.model.User;
70 import org.openecomp.sdc.be.model.cache.ComponentCache;
71 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
72 import org.openecomp.sdc.be.model.operations.impl.ComponentOperation;
73 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
74 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
75 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
76 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
77 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
78 import org.openecomp.sdc.be.user.Role;
79 import org.openecomp.sdc.be.utils.CommonBeUtils;
80 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
81 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
82 import org.openecomp.sdc.common.config.EcompErrorName;
83 import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum;
84 import org.openecomp.sdc.common.util.ValidationUtils;
85 import org.openecomp.sdc.exception.ResponseFormat;
86 import org.slf4j.Logger;
87 import org.slf4j.LoggerFactory;
88 import org.springframework.beans.factory.annotation.Autowired;
90 import com.datastax.driver.core.UserType.Field;
91 import com.wordnik.swagger.models.auth.In;
93 import fj.data.Either;
95 public abstract class ComponentBusinessLogic extends BaseBusinessLogic {
98 protected ArtifactsBusinessLogic artifactsBusinessLogic;
101 protected ComponentCache componentCache;
104 private static Logger log = LoggerFactory.getLogger(ComponentBusinessLogic.class.getName());
106 private static final String TAG_FIELD_LABEL = "tag";
108 public abstract Either<List<String>, ResponseFormat> deleteMarkedComponents();
110 public abstract ComponentInstanceBusinessLogic getComponentInstanceBL();
112 public abstract Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, ComponentTypeEnum componentTypeEnum, String userId, String searchText);
117 * @param dataParamsToReturn
120 public abstract Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String componentId, List<String> dataParamsToReturn);
122 protected Either<User, ResponseFormat> validateUser(User user, String ecompErrorContext, Component component, AuditingActionEnum auditAction, boolean inTransaction) {
123 Either<User, ResponseFormat> userValidationResult = validateUserNotEmpty(user, ecompErrorContext);
124 ResponseFormat responseFormat;
125 if (userValidationResult.isRight()) {
126 user.setUserId("UNKNOWN");
127 responseFormat = userValidationResult.right().value();
128 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", auditAction, component.getComponentType());
129 return Either.right(responseFormat);
131 Either<User, ResponseFormat> userResult = validateUserExists(user, ecompErrorContext, inTransaction);
132 if (userResult.isRight()) {
133 responseFormat = userResult.right().value();
134 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", auditAction, component.getComponentType());
135 return Either.right(responseFormat);
137 user = userResult.left().value();
141 protected Either<Boolean, ResponseFormat> validateUserRole(User user, Component component, List<Role> roles, AuditingActionEnum auditAction, String comment) {
142 if (roles != null && roles.isEmpty()) {
143 roles.add(Role.ADMIN);
144 roles.add(Role.DESIGNER);
146 Either<Boolean, ResponseFormat> validationResult = validateUserRole(user, roles);
147 if (validationResult.isRight()) {
148 ComponentTypeEnum componentType = component.getComponentType();
149 EnumMap<AuditingFieldsKeysEnum, Object> additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class);
150 if (componentType.equals(ComponentTypeEnum.SERVICE)) {
151 additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, comment);
152 String distributionStatus = ((ServiceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition()).getDistributionStatus();
153 additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, distributionStatus);
154 additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, distributionStatus);
156 componentsUtils.auditComponent(validationResult.right().value(), user, component, "", "", auditAction, componentType, additionalParams);
158 return validationResult;
161 protected Either<Boolean, ResponseFormat> validateComponentName(User user, Component component, AuditingActionEnum actionEnum) {
162 ComponentTypeEnum type = component.getComponentType();
163 String componentName = component.getName();
164 if (!ValidationUtils.validateStringNotEmpty(componentName)) {
165 log.debug("component name is empty");
166 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_COMPONENT_NAME, type.getValue());
167 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
168 return Either.right(errorResponse);
171 if (!ValidationUtils.validateComponentNameLength(componentName)) {
172 log.debug("Component name exceeds max length {} ", ValidationUtils.COMPONENT_NAME_MAX_LENGTH);
173 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NAME_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.COMPONENT_NAME_MAX_LENGTH);
174 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
175 return Either.right(errorResponse);
178 if (!validateTagPattern(componentName)) {
179 log.debug("Component name {} has invalid format", componentName);
180 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPONENT_NAME, type.getValue());
181 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
182 return Either.right(errorResponse);
184 component.setNormalizedName(ValidationUtils.normaliseComponentName(componentName));
185 component.setSystemName(ValidationUtils.convertToSystemName(componentName));
187 return Either.left(true);
190 protected Either<Boolean, ResponseFormat> validateDescriptionAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
191 ComponentTypeEnum type = component.getComponentType();
192 String description = component.getDescription();
193 if (!ValidationUtils.validateStringNotEmpty(description)) {
194 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_DESCRIPTION, type.getValue());
195 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
196 return Either.right(errorResponse);
199 description = ValidationUtils.removeNoneUtf8Chars(description);
200 description = ValidationUtils.normaliseWhitespace(description);
201 description = ValidationUtils.stripOctets(description);
202 description = ValidationUtils.removeHtmlTagsOnly(description);
204 Either<Boolean, ResponseFormat> validatDescription = validateComponentDescription(description, type);
205 if (validatDescription.isRight()) {
206 ResponseFormat responseFormat = validatDescription.right().value();
207 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, type);
208 return Either.right(responseFormat);
210 component.setDescription(description);
211 return Either.left(true);
214 public Either<Boolean, ResponseFormat> validateComponentDescription(String description, ComponentTypeEnum type) {
215 if (description != null) {
216 if (!ValidationUtils.validateDescriptionLength(description)) {
217 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_DESCRIPTION_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.COMPONENT_DESCRIPTION_MAX_LENGTH));
220 if (!ValidationUtils.validateIsEnglish(description)) {
221 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_DESCRIPTION, type.getValue()));
223 return Either.left(true);
225 return Either.left(false);
228 protected Either<Boolean, ResponseFormat> validateComponentNameUnique(User user, Component component, AuditingActionEnum actionEnum) {
229 ComponentTypeEnum type = component.getComponentType();
230 ResourceTypeEnum resourceType = null;
231 if(component instanceof Resource){
232 resourceType = ((Resource)component).getResourceType();
234 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateComponentNameExists(component.getName(), resourceType, type);
236 if (dataModelResponse.isLeft()) {
237 if ( !dataModelResponse.left().value()) {
238 return Either.left(true);
240 log.info("Component with name {} already exists", component.getName());
241 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, type.getValue(), component.getName());
242 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
243 return Either.right(errorResponse);
246 BeEcompErrorManager.getInstance().logBeSystemError("validateComponentNameUnique");
247 log.debug("Error while validateComponentNameUnique for component: {}", component.getName());
248 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
249 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
250 return Either.right(errorResponse);
253 protected Either<Boolean, ResponseFormat> validateContactId(User user, Component component, AuditingActionEnum actionEnum) {
254 log.debug("validate component contactId");
255 ComponentTypeEnum type = component.getComponentType();
256 String contactId = component.getContactId();
258 if (!ValidationUtils.validateStringNotEmpty(contactId)) {
259 log.info("contact is missing.");
260 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CONTACT, type.getValue());
261 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
262 return Either.right(errorResponse);
265 Either<Boolean, ResponseFormat> validateContactIdResponse = validateContactId(contactId, type);
266 if (validateContactIdResponse.isRight()) {
267 ResponseFormat responseFormat = validateContactIdResponse.right().value();
268 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, type);
270 return validateContactIdResponse;
273 private Either<Boolean, ResponseFormat> validateContactId(String contactId, ComponentTypeEnum type) {
274 if (contactId != null) {
275 if (!ValidationUtils.validateContactId(contactId)) {
276 log.info("contact is invalid.");
277 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CONTACT, type.getValue());
278 return Either.right(errorResponse);
280 return Either.left(true);
282 return Either.left(false);
286 public Either<Boolean, ResponseFormat> validateConformanceLevel(String componentId, ComponentTypeEnum componentTypeEnum, String userId) {
287 log.trace("validate conformance level");
289 if (componentTypeEnum != ComponentTypeEnum.SERVICE) {
290 log.error("conformance level validation for non service component, id {}", componentId);
291 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
292 return Either.right(errorResponse);
295 Either<User, ResponseFormat> resp = validateUserExists(userId, "validateConformanceLevel", false);
296 if (resp.isRight()) {
297 log.error("can't validate conformance level, user is not validated, id {}, userId {}", componentId, userId);
298 return Either.right(resp.right().value());
301 ComponentParametersView filter = new ComponentParametersView(true);
302 Either<Component, ResponseFormat> eitherComponent = validateComponentExists(componentId, componentTypeEnum, filter);
303 if (eitherComponent.isRight()) {
304 log.error("can't validate conformance level, component not found, id {}", componentId);
305 BeEcompErrorManager.getInstance().logBeComponentMissingError("validateConformanceLevel", componentTypeEnum.getValue(), componentId);
306 return Either.right(eitherComponent.right().value());
309 Component component = eitherComponent.left().value();
310 if (component.getConformanceLevel() == null || "".equals(component.getConformanceLevel())) {
311 log.error("component conformance level property is null or empty, id {}", componentId);
312 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
313 return Either.right(errorResponse);
316 String configConformanceLevel = ConfigurationManager.getConfigurationManager().getConfiguration().getMinToscaConformanceLevel();
317 Boolean result = true;
318 if (CommonBeUtils.conformanceLevelCompare(component.getConformanceLevel(), configConformanceLevel) < 0) {
319 log.error("invalid asset conformance level, id {}, asset conformanceLevel {}, config conformanceLevel {}", componentId, component.getConformanceLevel(), configConformanceLevel);
322 log.trace("conformance level validation finished");
324 return Either.left(result);
327 protected Either<Boolean, ResponseFormat> validateIcon(User user, Component component, AuditingActionEnum actionEnum) {
328 log.debug("validate Icon");
329 ComponentTypeEnum type = component.getComponentType();
330 String icon = component.getIcon();
331 if (!ValidationUtils.validateStringNotEmpty(icon)) {
332 log.info("icon is missing.");
333 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_ICON, type.getValue());
334 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
335 return Either.right(errorResponse);
338 Either<Boolean, ResponseFormat> validateIcon = validateIcon(icon, type);
339 if (validateIcon.isRight()) {
340 ResponseFormat responseFormat = validateIcon.right().value();
341 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, type);
346 private Either<Boolean, ResponseFormat> validateIcon(String icon, ComponentTypeEnum type) {
348 if (!ValidationUtils.validateIconLength(icon)) {
349 log.debug("icon exceeds max length");
350 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ICON_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.ICON_MAX_LENGTH));
353 if (!ValidationUtils.validateIcon(icon)) {
354 log.info("icon is invalid.");
355 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_ICON, type.getValue());
356 return Either.right(errorResponse);
358 return Either.left(true);
360 return Either.left(false);
363 protected Either<Boolean, ResponseFormat> validateTagsListAndRemoveDuplicates(User user, Component component, AuditingActionEnum actionEnum) {
364 List<String> tagsList = component.getTags();
366 Either<Boolean, ResponseFormat> validateTags = validateComponentTags(tagsList, component.getName(), component.getComponentType());
367 if (validateTags.isRight()) {
368 ResponseFormat responseFormat = validateTags.right().value();
369 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, component.getComponentType());
370 return Either.right(responseFormat);
372 ValidationUtils.removeDuplicateFromList(tagsList);
373 return Either.left(true);
376 protected Either<Boolean, ResponseFormat> validateComponentTags(List<String> tags, String name, ComponentTypeEnum componentType) {
377 log.debug("validate component tags");
378 boolean includesComponentName = false;
380 if (tags != null && !tags.isEmpty()) {
381 for (String tag : tags) {
382 if (!ValidationUtils.validateTagLength(tag)) {
383 log.debug("tag length exceeds limit {}", ValidationUtils.TAG_MAX_LENGTH);
384 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_SINGLE_TAG_EXCEED_LIMIT, "" + ValidationUtils.TAG_MAX_LENGTH));
386 if (validateTagPattern(tag)) {
387 if (!includesComponentName) {
388 includesComponentName = name.equals(tag);
391 log.debug("invalid tag {}", tag);
392 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_FIELD_FORMAT, componentType.getValue(), TAG_FIELD_LABEL));
394 tagListSize += tag.length() + 1;
396 if (tagListSize > 0) {
400 if (!includesComponentName) {
401 log.debug("tags must include component name");
402 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_TAGS_NO_COMP_NAME));
404 if (!ValidationUtils.validateTagListLength(tagListSize)) {
405 log.debug("overall tags length exceeds limit {}", ValidationUtils.TAG_LIST_MAX_LENGTH);
406 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TAGS_EXCEED_LIMIT, "" + ValidationUtils.TAG_LIST_MAX_LENGTH));
408 return Either.left(true);
410 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS));
413 protected boolean validateTagPattern(String tag) {
414 return ValidationUtils.validateComponentNamePattern(tag);
417 protected Either<Boolean, ResponseFormat> validateProjectCode(User user, Component component, AuditingActionEnum actionEnum) {
418 if (ComponentTypeEnum.RESOURCE.equals(component.getComponentType())) {
419 return Either.left(true);
421 log.debug("validate ProjectCode name ");
422 String projectCode = component.getProjectCode();
424 if (!ValidationUtils.validateStringNotEmpty(projectCode)) {
425 log.info("projectCode is missing.");
426 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_PROJECT_CODE);
427 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, component.getComponentType());
428 return Either.right(errorResponse);
431 Either<Boolean, ResponseFormat> validateProjectCodeResponse = validateProjectCode(projectCode);
432 if (validateProjectCodeResponse.isRight()) {
433 ResponseFormat responseFormat = validateProjectCodeResponse.right().value();
434 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, component.getComponentType());
436 return validateProjectCodeResponse;
440 private Either<Boolean, ResponseFormat> validateProjectCode(String projectCode) {
441 if (projectCode != null) {
442 if (!ValidationUtils.validateProjectCode(projectCode)) {
443 log.info("projectCode is not valid.");
444 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROJECT_CODE);
445 return Either.right(errorResponse);
447 return Either.left(true);
449 return Either.left(false);
452 protected void checkComponentFieldsForOverrideAttempt(Component component) {
453 if (component.getLifecycleState() != null) {
454 log.info("LifecycleState cannot be defined by user. This field will be overridden by the application");
456 if (component.getVersion() != null) {
457 log.info("Version cannot be defined by user. This field will be overridden by the application");
459 if ((component.getCreatorUserId() != null) || (component.getCreatorFullName() != null)) {
460 log.info("Creator cannot be defined by user. This field will be overridden by the application");
462 if ((component.getLastUpdaterUserId() != null) || (component.getLastUpdaterFullName() != null)) {
463 log.info("Last Updater cannot be defined by user. This field will be overridden by the application");
465 if ((component.getCreationDate() != null)) {
466 log.info("Creation Date cannot be defined by user. This field will be overridden by the application");
468 if ((component.isHighestVersion() != null)) {
469 log.info("Is Highest Version cannot be defined by user. This field will be overridden by the application");
471 if ((component.getUUID() != null)) {
472 log.info("UUID cannot be defined by user. This field will be overridden by the application");
474 if ((component.getLastUpdateDate() != null)) {
475 log.info("Last Update Date cannot be defined by user. This field will be overridden by the application");
477 if (component.getUniqueId() != null) {
478 log.info("uid cannot be defined by user. This field will be overridden by the application.");
479 component.setUniqueId(null);
481 if (component.getInvariantUUID() != null) {
482 log.info("Invariant UUID cannot be defined by user. This field will be overridden by the application.");
486 protected Either<Boolean, ResponseFormat> validateComponentFieldsBeforeCreate(User user, Component component, AuditingActionEnum actionEnum) {
487 // validate component name uniqueness
488 log.debug("validate component name ");
489 Either<Boolean, ResponseFormat> componentNameValidation = validateComponentName(user, component, actionEnum);
490 if (componentNameValidation.isRight()) {
491 return componentNameValidation;
494 // validate description
495 log.debug("validate description");
496 Either<Boolean, ResponseFormat> descValidation = validateDescriptionAndCleanup(user, component, actionEnum);
497 if (descValidation.isRight()) {
498 return descValidation;
502 log.debug("validate tags");
503 Either<Boolean, ResponseFormat> tagsValidation = validateTagsListAndRemoveDuplicates(user, component, actionEnum);
504 if (tagsValidation.isRight()) {
505 return tagsValidation;
508 // validate contact info
509 log.debug("validate contact info");
510 Either<Boolean, ResponseFormat> contactIdValidation = validateContactId(user, component, actionEnum);
511 if (contactIdValidation.isRight()) {
512 return contactIdValidation;
516 log.debug("validate icon");
517 Either<Boolean, ResponseFormat> iconValidation = validateIcon(user, component, actionEnum);
518 if (iconValidation.isRight()) {
519 return iconValidation;
521 return Either.left(true);
525 * Fetches Component From the DB
528 * @param componentTypeEnum
531 public <R extends Component> Either<R, StorageOperationStatus> getComponent(String componentId, ComponentTypeEnum componentTypeEnum) {
532 return toscaOperationFacade.getToscaElement(componentId);
535 public Either<CapReqDef, ResponseFormat> getRequirementsAndCapabilities(String componentId, ComponentTypeEnum componentTypeEnum, String userId) {
537 Either<User, ResponseFormat> resp = validateUserExists(userId, "create Component Instance", false);
538 if (resp.isRight()) {
539 return Either.right(resp.right().value());
541 Either<CapReqDef, ResponseFormat> eitherRet = null;
542 ComponentParametersView filter = new ComponentParametersView(true);
543 filter.setIgnoreCapabilities(false);
544 filter.setIgnoreRequirements(false);
545 filter.setIgnoreComponentInstances(false);
546 Either<Component, ResponseFormat> eitherComponent = validateComponentExists(componentId, componentTypeEnum, filter);
547 if (eitherComponent.isLeft()) {
548 eitherRet = Either.left(new CapReqDef(eitherComponent.left().value().getRequirements(), eitherComponent.left().value().getCapabilities()));
550 BeEcompErrorManager.getInstance().logBeComponentMissingError("getRequirementsAndCapabilities", componentTypeEnum.getValue(), componentId);
551 eitherRet = Either.right(eitherComponent.right().value());
556 public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponents(boolean isAbstractAbstract, HighestFilterEnum highestFilter, ComponentTypeEnum componentTypeEnum, String internalComponentType, List<String> componentUids,
558 ResponseFormat responseFormat = null;
560 Either<User, ResponseFormat> resp = validateUserExists(userId, "get Latest Version Not Abstract Components", false);
563 List<Component> result = new ArrayList<>();
564 List<String> componentsUidToFetch = new ArrayList<>();
565 componentsUidToFetch.addAll(componentUids);
567 if (componentsUidToFetch.size() > 0) {
568 log.debug("Number of Components to fetch from graph is {}", componentsUidToFetch.size());
569 Boolean isHighest = isHighest(highestFilter);
570 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade.getLatestVersionNotAbstractComponents(isAbstractAbstract, isHighest, componentTypeEnum, internalComponentType, componentsUidToFetch);
572 if (nonCheckoutCompResponse.isLeft()) {
573 log.debug("Retrived Resource successfully.");
574 result.addAll(nonCheckoutCompResponse.left().value());
576 responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value()));
579 return Either.left(result);
581 responseFormat = resp.right().value();
587 return Either.right(responseFormat);
590 private Boolean isHighest(HighestFilterEnum highestFilter) {
591 Boolean isHighest = null;
592 switch (highestFilter) {
598 case NON_HIGHEST_ONLY:
607 public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponentsMetadata(boolean isAbstractAbstract, HighestFilterEnum highestFilter, ComponentTypeEnum componentTypeEnum, String internalComponentType, String userId) {
608 ResponseFormat responseFormat = null;
611 Either<User, ResponseFormat> resp = validateUserExists(userId, "get Latest Version Not Abstract Components", false);
614 Boolean isHighest = isHighest(highestFilter);
615 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade.getLatestVersionNotAbstractMetadataOnly(isAbstractAbstract, isHighest, componentTypeEnum, internalComponentType);
617 if (nonCheckoutCompResponse.isLeft()) {
618 log.debug("Retrived Resource successfully.");
619 return Either.left(nonCheckoutCompResponse.left().value());
621 responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value()));
623 responseFormat = resp.right().value();
628 return Either.right(responseFormat);
631 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
635 @SuppressWarnings("unchecked")
636 public void setToscaArtifactsPlaceHolders(Component component, User user) {
637 Map<String, ArtifactDefinition> artifactMap = component.getToscaArtifacts();
638 if (artifactMap == null) {
639 artifactMap = new HashMap<String, ArtifactDefinition>();
641 String componentUniqueId = component.getUniqueId();
642 String componentSystemName = component.getSystemName();
643 String componentType = component.getComponentType().getValue().toLowerCase();
644 Map<String, Object> toscaArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts();
646 if (toscaArtifacts != null) {
647 for (Entry<String, Object> artifactInfoMap : toscaArtifacts.entrySet()) {
648 Map<String, Object> artifactInfo = (Map<String, Object>) artifactInfoMap.getValue();
649 ArtifactDefinition artifactDefinition = artifactsBusinessLogic.createArtifactPlaceHolderInfo(componentUniqueId, artifactInfoMap.getKey(), artifactInfo, user, ArtifactGroupTypeEnum.TOSCA);
650 artifactDefinition.setArtifactName(componentType + "-" + componentSystemName + artifactInfo.get("artifactName"));
651 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
654 component.setToscaArtifacts(artifactMap);
657 public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock) {
658 return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true);
661 public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock, boolean fetchTemplatesFromDB) {
662 Either<Component, StorageOperationStatus> toscaElement = toscaOperationFacade.getToscaFullElement(component.getUniqueId());
663 if ( toscaElement.isRight() ){
664 ResponseFormat response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(toscaElement.right().value(), component.getComponentType()));
665 return Either.right(response);
667 component = toscaElement.left().value();
668 Either<Either<ArtifactDefinition, Operation>, ResponseFormat> generateToscaRes = null;
669 if (component.getToscaArtifacts() != null && !component.getToscaArtifacts().isEmpty()) {
670 ArtifactDefinition toscaArtifact = component.getToscaArtifacts().values().stream()
671 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_TEMPLATE.getType()))
673 generateToscaRes = saveToscaArtifactPayload(toscaArtifact, component, user, isInCertificationRequest, shouldLock, inTransaction, fetchTemplatesFromDB);
674 if (generateToscaRes.isRight()) {
675 return generateToscaRes;
677 toscaArtifact = generateToscaRes.left().value().left().value();
678 component.getToscaArtifacts().put(toscaArtifact.getArtifactLabel(), toscaArtifact);
679 toscaArtifact = component.getToscaArtifacts().values().stream()
680 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType()))
682 generateToscaRes = saveToscaArtifactPayload(toscaArtifact, component, user, isInCertificationRequest, shouldLock, inTransaction, true);
684 if (generateToscaRes.isRight()) {
685 return generateToscaRes;
687 ArtifactDefinition toscaArtifact = generateToscaRes.left().value().left().value();
688 component.getToscaArtifacts().put(toscaArtifact.getArtifactLabel(), toscaArtifact);
689 return generateToscaRes;
692 public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> saveToscaArtifactPayload(ArtifactDefinition artifactDefinition, org.openecomp.sdc.be.model.Component component, User user, boolean isInCertificationRequest, boolean shouldLock,
693 boolean inTransaction, boolean fetchTemplatesFromDB) {
694 return artifactsBusinessLogic.generateAndSaveToscaArtifact(artifactDefinition, component, user, isInCertificationRequest, shouldLock, inTransaction, fetchTemplatesFromDB);
697 public Either<ImmutablePair<String, byte[]>, ResponseFormat> getToscaModelByComponentUuid(ComponentTypeEnum componentType, String uuid, EnumMap<AuditingFieldsKeysEnum, Object> additionalParam) {
699 Either<List<Component>, StorageOperationStatus> latestVersionEither = toscaOperationFacade.getComponentListByUuid(uuid, null);
701 if (latestVersionEither.isRight()) {
702 ResponseFormat response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(latestVersionEither.right().value(), componentType));
703 return Either.right(response);
706 List<Component> components = latestVersionEither.left().value();
708 Component component = components.stream().filter(c -> c.isHighestVersion()).findFirst().orElse(null);
709 if(component == null){
710 component = components.stream().filter(c -> c.getLifecycleState() == LifecycleStateEnum.CERTIFIED).findFirst().orElse(null);
713 if(component == null){
714 ResponseFormat response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, componentType));
715 return Either.right(response);
717 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, component.getName());
718 // TODO remove after migration - handle artifact not found(no
720 if (null == component.getToscaArtifacts() || component.getToscaArtifacts().isEmpty()) {
721 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ArtifactTypeEnum.TOSCA_CSAR.name()));
723 ArtifactDefinition csarArtifact = component.getToscaArtifacts().values().stream()
724 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType()))
726 return artifactsBusinessLogic.handleDownloadToscaModelRequest(component, csarArtifact);
729 protected StorageOperationStatus markComponentToDelete(Component component) {
731 ComponentTypeEnum componentType = component.getComponentType();
732 String uniqueId = component.getUniqueId();
733 if ((component.getIsDeleted() != null) && (component.getIsDeleted() == true)) {
734 log.info("component {} already marked as deleted. id= {}, type={}", component.getName(), uniqueId, componentType);
735 return StorageOperationStatus.NOT_FOUND;
738 StorageOperationStatus markResourceToDelete = toscaOperationFacade.markComponentToDelete(component);
739 if (StorageOperationStatus.OK != markResourceToDelete) {
740 log.debug("failed to mark component {} of type {} for delete. error = {}", uniqueId, componentType, markResourceToDelete);
741 return markResourceToDelete;
743 log.debug("Component {} of type {} was marked as deleted", uniqueId, componentType);
744 return StorageOperationStatus.OK;
748 public Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Component currentComponent, Component updatedComponent, AuditingActionEnum audatingAction) {
749 String descriptionUpdated = updatedComponent.getDescription();
750 String descriptionCurrent = currentComponent.getDescription();
751 if (descriptionUpdated != null && !descriptionCurrent.equals(descriptionUpdated)) {
752 Either<Boolean, ResponseFormat> validateDescriptionResponse = validateDescriptionAndCleanup(user, updatedComponent, audatingAction);
753 if (validateDescriptionResponse.isRight()) {
754 ResponseFormat errorRespons = validateDescriptionResponse.right().value();
755 return Either.right(errorRespons);
757 currentComponent.setDescription(updatedComponent.getDescription());
759 return Either.left(true);
762 public Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Component currentComponent, Component updatedComponent) {
763 String projectCodeUpdated = updatedComponent.getProjectCode();
764 String projectCodeCurrent = currentComponent.getProjectCode();
765 if (projectCodeUpdated != null && !projectCodeCurrent.equals(projectCodeUpdated)) {
766 Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, updatedComponent, null);
767 if (validatProjectCodeResponse.isRight()) {
768 ResponseFormat errorRespons = validatProjectCodeResponse.right().value();
769 return Either.right(errorRespons);
771 currentComponent.setProjectCode(updatedComponent.getProjectCode());
773 return Either.left(true);
776 public Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Component currentComponent, Component updatedComponent, boolean hasBeenCertified) {
777 String iconUpdated = updatedComponent.getIcon();
778 String iconCurrent = currentComponent.getIcon();
779 if (iconUpdated != null && !iconCurrent.equals(iconUpdated)) {
780 if (!hasBeenCertified) {
781 Either<Boolean, ResponseFormat> validatIconResponse = validateIcon(user, updatedComponent, null);
782 if (validatIconResponse.isRight()) {
783 ResponseFormat errorRespons = validatIconResponse.right().value();
784 return Either.right(errorRespons);
786 currentComponent.setIcon(updatedComponent.getIcon());
788 log.info("icon {} cannot be updated once the component has been certified once.", iconUpdated);
789 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_PARAMETER_CANNOT_BE_CHANGED, "Icon", currentComponent.getComponentType().name().toLowerCase());
790 return Either.right(errorResponse);
793 return Either.left(true);
796 protected Either<List<String>, ResponseFormat> deleteMarkedComponents(ComponentTypeEnum componentType) {
798 // List<String> deletedComponents = new ArrayList<String>();
799 log.trace("start deleteMarkedComponents");
800 Either<List<String>, StorageOperationStatus> deleteMarkedElements = toscaOperationFacade.deleteMarkedElements(componentType);
803 if ( deleteMarkedElements.isRight()){
804 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteMarkedElements.right().value(), componentType));
805 return Either.right(responseFormat);
807 // ComponentOperation componentOperation = getComponentOperation(componentType);
808 // Either<List<String>, StorageOperationStatus> resourcesToDelete = componentOperation.getAllComponentsMarkedForDeletion();
809 // if (resourcesToDelete.isRight()) {
810 // ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourcesToDelete.right().value(), componentType));
811 // return Either.right(responseFormat);
814 // for (String resourceToDelete : resourcesToDelete.left().value()) {
816 // Either<String, ResponseFormat> deleteMarkedResource = deleteMarkedComponent(resourceToDelete, componentType);
817 // if (deleteMarkedResource.isLeft()) {
818 // deletedComponents.add(deleteMarkedResource.left().value());
821 // if(deletedComponents.size() == 0) {
822 // log.debug("Component list to delete is empty. do commit");
823 // titanGenericDao.commit();
825 log.trace("end deleteMarkedComponents");
826 return Either.left(deleteMarkedElements.left().value());
829 private Either<String, ResponseFormat> deleteMarkedComponent(String componentToDelete, ComponentTypeEnum componentType) {
831 Either<String, ResponseFormat> result = null;
832 NodeTypeEnum compNodeType = componentType.getNodeType();
833 StorageOperationStatus lockResult = graphLockOperation.lockComponent(componentToDelete, compNodeType);
834 if (!lockResult.equals(StorageOperationStatus.OK)) {
835 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedLockObjectError, "Delete marked component");
836 log.debug("Failed to lock component {} error - {}", componentToDelete, lockResult);
837 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
842 // check if resource has relations
843 Either<Boolean, StorageOperationStatus> isResourceInUse = toscaOperationFacade.isComponentInUse(componentToDelete);
844 if (isResourceInUse.isRight()) {
845 log.info("deleteMarkedResource - failed to find relations to resource. id = {}, type = {}, error = {}", componentToDelete, componentType, isResourceInUse.right().value().name());
846 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
847 result = Either.right(responseFormat);
851 if (isResourceInUse.isLeft() && isResourceInUse.left().value() == false) {
853 // delete resource and its artifacts in one transaction
854 Either<List<ArtifactDefinition>, StorageOperationStatus> artifactsRes = getComponentArtifactsForDelete(componentToDelete, compNodeType, true);
855 if (artifactsRes.isRight() && !artifactsRes.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
856 log.info("failed to check artifacts for component node. id = {}, type = {}, error = {}", componentToDelete, componentType, artifactsRes.right().value().name());
857 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
858 result = Either.right(responseFormat);
861 List<ArtifactDefinition> artifactsToDelete = new ArrayList<>();
862 if (artifactsRes.isLeft()) {
863 artifactsToDelete = artifactsRes.left().value();
866 Either<Component, StorageOperationStatus> deleteComponentRes = toscaOperationFacade.deleteToscaComponent(componentToDelete);
867 if (deleteComponentRes.isRight()) {
868 log.info("failed to delete component. id = {}, type = {}, error = {}", componentToDelete, componentType, deleteComponentRes.right().value().name());
869 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(deleteComponentRes.right().value());
870 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, componentToDelete);
871 result = Either.right(responseFormat);
873 log.trace("component was deleted, id = {}, type = {}", componentToDelete, componentType);
874 // delete related artifacts
875 StorageOperationStatus deleteFromEsRes = artifactsBusinessLogic.deleteAllComponentArtifactsIfNotOnGraph(artifactsToDelete);
876 if (!deleteFromEsRes.equals(StorageOperationStatus.OK)) {
877 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(deleteFromEsRes);
878 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, componentToDelete);
879 result = Either.right(responseFormat);
882 log.debug("component and all its artifacts were deleted, id = {}, type = {}", componentToDelete, componentType);
883 result = Either.left(componentToDelete);
887 log.debug("componentis marked for delete but still in use, id = {}, type = {}", componentToDelete, componentType);
888 ActionStatus actionStatus = ActionStatus.RESTRICTED_OPERATION;
889 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, componentToDelete);
890 result = Either.right(responseFormat);
894 if (result == null || result.isRight()) {
895 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "delete marked component");
896 log.debug("operation failed. do rollback");
899 log.debug("operation success. do commit");
902 graphLockOperation.unlockComponent(componentToDelete, compNodeType);
908 public Either<List<ArtifactDefinition>, StorageOperationStatus> getComponentArtifactsForDelete(String parentId, NodeTypeEnum parentType, boolean inTransacton) {
909 List<ArtifactDefinition> artifacts = new ArrayList<ArtifactDefinition>();
910 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse = artifactToscaOperation.getArtifacts(parentId);
911 if (artifactsResponse.isRight()) {
912 if (!artifactsResponse.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
913 log.debug("failed to retrieve artifacts for {} {}", parentType, parentId);
914 return Either.right(artifactsResponse.right().value());
917 artifacts.addAll(artifactsResponse.left().value().values());
920 // if (NodeTypeEnum.Resource.equals(parentType)) {
921 // Either<List<ArtifactDefinition>, StorageOperationStatus> interfacesArtifactsForResource = getAdditionalArtifacts(parentId, false, true);
922 // if (artifactsResponse.isRight() && !interfacesArtifactsForResource.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
923 // log.debug("failed to retrieve interface artifacts for {} {}", parentType, parentId);
924 // return Either.right(interfacesArtifactsForResource.right().value());
925 // } else if (artifactsResponse.isLeft()) {
926 // artifacts.addAll(interfacesArtifactsForResource.left().value());
929 return Either.left(artifacts);
936 * @param dataParamsToReturn - ui list of params to return
940 public Either<UiComponentDataTransfer, ResponseFormat> getComponentDataFilteredByParams(String componentId, User user, List<String> dataParamsToReturn) {
943 Either<User, ResponseFormat> eitherCreator = validateUserExists(user, "Get Component by filtered by ui params", false);
944 if (eitherCreator.isRight()) {
945 return Either.right(eitherCreator.right().value());
949 UiComponentDataTransfer result = new UiComponentDataTransfer();
951 if(dataParamsToReturn == null || dataParamsToReturn.isEmpty()) {
955 Either<UiComponentDataTransfer, ResponseFormat> uiDataTransferEither = getUiComponentDataTransferByComponentId(componentId, dataParamsToReturn);
956 if(uiDataTransferEither.isRight()){
957 return Either.right(uiDataTransferEither.right().value());
959 result = uiDataTransferEither.left().value();
962 return Either.left(result);
965 protected <T extends Component> void generateInputsFromGenericTypeProperties(T component, Resource genericType) {
967 List<PropertyDefinition> genericTypeProps = genericType.getProperties();
968 if(null != genericTypeProps) {
969 String genericUniqueId = genericType.getUniqueId();
970 List<InputDefinition> inputs = convertGenericTypePropertiesToInputsDefintion(genericTypeProps, genericUniqueId);
971 if(null != component.getInputs())
972 inputs.addAll(component.getInputs());
973 component.setInputs(inputs);
977 private List<InputDefinition> convertGenericTypePropertiesToInputsDefintion(List<PropertyDefinition> genericTypeProps, String genericUniqueId) {
978 return genericTypeProps.stream()
979 .map(p -> setInputDefinitionFromProp(p, genericUniqueId))
980 .collect(Collectors.toList());
983 private InputDefinition setInputDefinitionFromProp(PropertyDefinition prop, String genericUniqueId){
984 InputDefinition input = new InputDefinition(prop);
985 input.setOwnerId(genericUniqueId);
989 protected <T extends Component> Either<Resource, ResponseFormat> fetchAndSetDerivedFromGenericType(T component){
991 String genericTypeToscaName = component.fetchGenericTypeToscaNameFromConfig();
992 if(null == genericTypeToscaName)
993 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
994 Either<Resource, StorageOperationStatus> findLatestGeneric = toscaOperationFacade.getLatestCertifiedNodeTypeByToscaResourceName(genericTypeToscaName);
995 if(findLatestGeneric.isRight())
996 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERIC_TYPE_NOT_FOUND, component.assetType(), genericTypeToscaName));
997 Resource genericTypeResource = findLatestGeneric.left().value();
998 component.setDerivedFromGenericInfo(genericTypeResource);
999 return Either.left(genericTypeResource);
1002 public Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstanceProperties(String componentId, Map<FilterKeyEnum, List<String>> filters, String userId) {
1003 Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> response = null;
1004 Either<Component, StorageOperationStatus> getResourceRes = null;
1006 if(!filters.containsKey(FilterKeyEnum.NAME_FRAGMENT) && StringUtils.isEmpty(filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0))){
1007 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1009 if (userId != null && response == null) {
1010 Either<User, ResponseFormat> validateUserRes = validateUserExists(userId, "Get filtered component instance properties", false);
1011 if (validateUserRes.isRight()) {
1012 response = Either.right(validateUserRes.right().value());
1015 if(response == null){
1016 getResourceRes = toscaOperationFacade.getToscaElement(componentId);
1017 if(getResourceRes.isRight()){
1018 response = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getResourceRes.right().value())));
1021 if(response == null){
1022 response = getFilteredComponentInstancesProperties(getResourceRes.left().value(), filters);
1024 } catch(Exception e){
1025 log.debug("The exception {} occured during filtered instance properties fetching. the containing component is {}. ", e, componentId);
1026 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1028 if (response.isLeft()){
1029 toscaOperationFacade.commit();
1031 toscaOperationFacade.rollback();
1037 private Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstancesProperties(Component component, Map<FilterKeyEnum, List<String>> filters) {
1039 Map<String, List<IComponentInstanceConnectedElement>> filteredProperties = new HashMap<>();
1040 Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> result = Either.left(filteredProperties);
1041 List<ComponentInstance> filteredInstances = getFilteredInstances(component, filters.get(FilterKeyEnum.RESOURCE_TYPE));
1042 String propertyNameFragment= filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0);
1043 boolean searchByFragment = propertyNameFragment.length() > 3 ;
1044 if(CollectionUtils.isNotEmpty(filteredInstances)){
1045 for(ComponentInstance instance : filteredInstances){
1046 if(component.getComponentInstancesProperties()!=null &&component.getComponentInstancesProperties().containsKey(instance.getUniqueId())){
1047 List<IComponentInstanceConnectedElement> currProperties = getFilteredComponentInstanceProperties(component.getComponentInstancesProperties().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
1048 if(CollectionUtils.isNotEmpty(currProperties)){
1049 filteredProperties.put(instance.getUniqueId(), currProperties);
1052 if(component.getComponentInstancesInputs()!=null && component.getComponentInstancesInputs().containsKey(instance.getUniqueId())){
1053 List<IComponentInstanceConnectedElement> currInputs = getFilteredComponentInstanceInputs(component.getComponentInstancesInputs().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
1054 if(CollectionUtils.isNotEmpty(currInputs)){
1055 if(filteredProperties.get(instance.getUniqueId())!=null){
1056 filteredProperties.get(instance.getUniqueId()).addAll(currInputs);
1058 filteredProperties.put(instance.getUniqueId(), currInputs);
1067 private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceInputs(List<ComponentInstanceInput> inputs, String propertyNameFragment, boolean searchByFragment) {
1068 return inputs.stream().filter(i -> isMatchingInput(i, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
1071 private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceProperties(List<ComponentInstanceProperty> instanceProperties, String propertyNameFragment, boolean searchByFragment) {
1072 return instanceProperties.stream().filter(p -> isMatchingProperty(p, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
1075 private boolean isMatchingInput(ComponentInstanceInput input, String propertyNameFragment, boolean searchByFragment) {
1076 boolean isMatching = false;
1077 if(searchByFragment && input.getName().toLowerCase().contains(propertyNameFragment)){
1080 if(!searchByFragment && input.getName().equalsIgnoreCase(propertyNameFragment)){
1086 private boolean isMatchingProperty(ComponentInstanceProperty property, String propertyNameFragment, boolean searchByFragment) {
1087 boolean isMatching = false;
1088 if(searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment)){
1091 if(!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)){
1094 if (!isMatching && !ToscaPropertyType.isPrimitiveType(property.getType())){
1095 isMatching = isMatchingComplexPropertyByRecursively(property, propertyNameFragment, searchByFragment);
1100 private boolean isMatchingComplexPropertyByRecursively(PropertyDataDefinition property, String propertyNameFragment, boolean searchByFragment) {
1101 String propertyType;
1102 List<PropertyDefinition> dataTypeProperties;
1103 DataTypeDefinition currentProperty;
1104 if(searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment.toLowerCase())){
1107 if(!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)){
1111 propertyType = isEmptyInnerType(property) ? property.getType() : property.getSchema().getProperty().getType();
1113 if(ToscaPropertyType.isScalarType(propertyType)){
1116 Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameRes = propertyOperation.getDataTypeByName(propertyType);
1117 if(getDataTypeByNameRes.isRight()){
1120 currentProperty = getDataTypeByNameRes.left().value();
1121 dataTypeProperties = currentProperty.getProperties();
1123 if(CollectionUtils.isNotEmpty(dataTypeProperties)){
1124 for(PropertyDefinition prop : dataTypeProperties){
1125 if(isMatchingComplexPropertyByRecursively(prop, propertyNameFragment, searchByFragment)){
1130 dataTypeProperties = currentProperty.getDerivedFrom().getProperties();
1131 if(CollectionUtils.isNotEmpty(dataTypeProperties)){
1132 for(PropertyDefinition prop : dataTypeProperties){
1133 if(isMatchingComplexPropertyByRecursively(prop, propertyNameFragment, searchByFragment)){
1141 private boolean isEmptyInnerType(PropertyDataDefinition property) {
1142 return property == null|| property.getSchema() == null || property.getSchema().getProperty() == null || property.getSchema().getProperty().getType() == null;
1145 public Either<Boolean, ResponseFormat> shouldUpgradeToLatestGeneric(Component clonedComponent) {
1147 if(!clonedComponent.deriveFromGeneric())
1148 return Either.left(false);
1149 Boolean shouldUpgrade = false;
1150 String currentGenericType = clonedComponent.getDerivedFromGenericType();
1151 String currentGenericVersion = clonedComponent.getDerivedFromGenericVersion();
1152 Either<Resource, ResponseFormat> fetchAndSetLatestGeneric = fetchAndSetDerivedFromGenericType(clonedComponent);
1153 if(fetchAndSetLatestGeneric.isRight())
1154 return Either.right(fetchAndSetLatestGeneric.right().value());
1155 Resource genericTypeResource = fetchAndSetLatestGeneric.left().value();
1156 if(null == currentGenericType || !currentGenericType.equals(genericTypeResource.getToscaResourceName()) || !currentGenericVersion.equals(genericTypeResource.getVersion())){
1157 List<PropertyDefinition> genericTypeProps = genericTypeResource.getProperties();
1158 List<InputDefinition> genericTypeInputs = null == genericTypeProps? null : convertGenericTypePropertiesToInputsDefintion(genericTypeProps, genericTypeResource.getUniqueId());
1159 shouldUpgrade = upgradeToLatestGeneric(clonedComponent, genericTypeInputs);
1160 if(!shouldUpgrade) {
1161 reverntUpdateOfGenericVersion(clonedComponent, currentGenericType, currentGenericVersion);
1164 return Either.left(shouldUpgrade);
1167 private void reverntUpdateOfGenericVersion(Component clonedComponent, String currentGenericType, String currentGenericVersion) {
1168 clonedComponent.setDerivedFromGenericType(currentGenericType);
1169 clonedComponent.setDerivedFromGenericVersion(currentGenericVersion);
1173 private boolean upgradeToLatestGeneric(Component componentToCheckOut, List<InputDefinition> upgradedList) {
1175 if (!componentToCheckOut.shouldGenerateInputs())
1178 List<InputDefinition> currentList = new ArrayList<>();
1179 // nullify existing ownerId from existing list and merge into updated list
1180 if (null != componentToCheckOut.getInputs()) {
1181 for(InputDefinition input : componentToCheckOut.getInputs()) {
1182 InputDefinition copy = new InputDefinition(input);
1183 copy.setOwnerId(null);
1184 currentList.add(copy);
1187 if (null == upgradedList) {
1188 componentToCheckOut.setInputs(currentList);
1191 Map<String, InputDefinition> currentMap = PropertyDataDefinition.listToMapByName(currentList);
1192 Map<String, InputDefinition> upgradedMap = PropertyDataDefinition.listToMapByName(upgradedList);
1193 Either<Map<String, InputDefinition>, String> eitherMerged = PropertyDataDefinition.mergeProperties(upgradedMap, currentMap, true);
1194 if (eitherMerged.isRight()) {
1195 log.debug("property {} cannot be overriden, check out performed without upgrading to latest generic", eitherMerged.right().value());
1198 componentToCheckOut.setInputs(new ArrayList<InputDefinition>(eitherMerged.left().value().values()));
1202 private List<ComponentInstance> getFilteredInstances(Component component, List<String> resourceTypes) {
1203 List<ComponentInstance> filteredInstances = null;
1204 if(CollectionUtils.isEmpty(resourceTypes)){
1205 filteredInstances = component.getComponentInstances();
1207 else if(CollectionUtils.isNotEmpty(component.getComponentInstances())){
1208 filteredInstances = component.getComponentInstances()
1209 .stream().filter(i -> isMatchingType(i.getOriginType(), resourceTypes)).collect(Collectors.toList());
1211 if(filteredInstances == null){
1212 filteredInstances = new ArrayList<>();
1214 return filteredInstances;
1217 private boolean isMatchingType(OriginTypeEnum originType, List<String> resourceTypes) {
1218 boolean isMatchingType = false;
1219 for(String resourceType : resourceTypes){
1220 if(originType == OriginTypeEnum.findByValue(resourceType.toUpperCase())){
1221 isMatchingType = true;
1225 return isMatchingType;