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=========================================================
19 * Modifications copyright (c) 2019 Nokia
20 * ================================================================================
23 package org.openecomp.sdc.be.components.impl;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
29 import java.util.Map.Entry;
30 import java.util.stream.Collectors;
32 import fj.data.Either;
33 import org.apache.commons.collections.CollectionUtils;
34 import org.apache.commons.lang3.StringUtils;
35 import org.apache.commons.lang3.tuple.ImmutablePair;
36 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
37 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
38 import org.openecomp.sdc.be.components.impl.generic.GenericTypeBusinessLogic;
39 import org.openecomp.sdc.be.config.BeEcompErrorManager;
40 import org.openecomp.sdc.be.config.ConfigurationManager;
41 import org.openecomp.sdc.be.dao.api.ActionStatus;
42 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
43 import org.openecomp.sdc.be.dao.utils.MapUtil;
44 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
45 import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition;
46 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
47 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
48 import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum;
49 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
50 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
51 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
52 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
53 import org.openecomp.sdc.be.model.ArtifactDefinition;
54 import org.openecomp.sdc.be.model.CapReqDef;
55 import org.openecomp.sdc.be.model.Component;
56 import org.openecomp.sdc.be.model.ComponentInstance;
57 import org.openecomp.sdc.be.model.ComponentInstanceInput;
58 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
59 import org.openecomp.sdc.be.model.ComponentParametersView;
60 import org.openecomp.sdc.be.model.DataTypeDefinition;
61 import org.openecomp.sdc.be.model.GroupDefinition;
62 import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement;
63 import org.openecomp.sdc.be.model.InputDefinition;
64 import org.openecomp.sdc.be.model.LifecycleStateEnum;
65 import org.openecomp.sdc.be.model.Operation;
66 import org.openecomp.sdc.be.model.PropertyDefinition;
67 import org.openecomp.sdc.be.model.Resource;
68 import org.openecomp.sdc.be.model.User;
69 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
70 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
71 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
72 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
73 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
74 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
75 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
76 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
77 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
78 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
79 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
80 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
81 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
82 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
83 import org.openecomp.sdc.be.user.Role;
84 import org.openecomp.sdc.be.utils.CommonBeUtils;
85 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
86 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
87 import org.openecomp.sdc.common.log.wrappers.Logger;
88 import org.openecomp.sdc.common.util.ValidationUtils;
89 import org.openecomp.sdc.exception.ResponseFormat;
90 import org.springframework.beans.factory.annotation.Autowired;
92 public abstract class ComponentBusinessLogic extends BaseBusinessLogic {
94 protected final ArtifactsBusinessLogic artifactsBusinessLogic;
96 protected final GroupBusinessLogic groupBusinessLogic;
98 private GenericTypeBusinessLogic genericTypeBusinessLogic;
100 public ComponentBusinessLogic(IElementOperation elementDao,
101 IGroupOperation groupOperation,
102 IGroupInstanceOperation groupInstanceOperation,
103 IGroupTypeOperation groupTypeOperation,
104 GroupBusinessLogic groupBusinessLogic,
105 InterfaceOperation interfaceOperation,
106 InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
107 ArtifactsBusinessLogic artifactsBusinessLogic,
108 ArtifactsOperations artifactToscaOperation) {
109 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation,
110 interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
111 this.artifactsBusinessLogic = artifactsBusinessLogic;
112 this.groupBusinessLogic = groupBusinessLogic;
116 public void setGenericTypeBusinessLogic(GenericTypeBusinessLogic genericTypeBusinessLogic) {
117 this.genericTypeBusinessLogic = genericTypeBusinessLogic;
120 private static final Logger log = Logger.getLogger(ComponentBusinessLogic.class.getName());
122 private static final String TAG_FIELD_LABEL = "tag";
124 public abstract Either<List<String>, ResponseFormat> deleteMarkedComponents();
126 public abstract ComponentInstanceBusinessLogic getComponentInstanceBL();
128 public abstract Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId);
133 * @param dataParamsToReturn
136 public abstract Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String componentId, List<String> dataParamsToReturn);
138 protected User validateUser(User user, String ecompErrorContext, Component component, AuditingActionEnum auditAction, boolean inTransaction) {
140 ResponseFormat responseFormat;
142 validateUserNotEmpty(user, ecompErrorContext);
143 validatedUser = validateUserExists(user, ecompErrorContext, inTransaction);
144 } catch(ByActionStatusComponentException e){
145 if(e.getActionStatus() == ActionStatus.MISSING_INFORMATION){
146 user.setUserId("UNKNOWN");
148 responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
149 componentsUtils.auditComponentAdmin(responseFormat, user, component, auditAction, component.getComponentType());
151 } catch(ByResponseFormatComponentException e){
152 responseFormat = e.getResponseFormat();
153 componentsUtils.auditComponentAdmin(responseFormat, user, component, auditAction, component.getComponentType());
156 return validatedUser;
159 protected void validateUserRole(User user, Component component, List<Role> roles, AuditingActionEnum auditAction, String comment) {
160 if (roles != null && roles.isEmpty()) {
161 roles.add(Role.ADMIN);
162 roles.add(Role.DESIGNER);
165 validateUserRole(user, roles);
166 }catch (ByActionStatusComponentException e) {
167 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
168 handleComponentException(component, comment, responseFormat, user, auditAction);
170 }catch (ByResponseFormatComponentException e) {
171 ResponseFormat responseFormat = e.getResponseFormat();
172 handleComponentException(component, comment, responseFormat, user, auditAction);
177 private void handleComponentException(Component component, String comment, ResponseFormat responseFormat,
178 User user, AuditingActionEnum auditAction){
179 String commentStr = null;
180 String distrStatus = null;
181 ComponentTypeEnum componentType = component.getComponentType();
182 if (componentType.equals(ComponentTypeEnum.SERVICE)) {
183 distrStatus = ((ServiceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition()).getDistributionStatus();
184 commentStr = comment;
186 componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(componentType.getValue()),
187 ResourceVersionInfo.newBuilder().distributionStatus(distrStatus).build(),
188 ResourceVersionInfo.newBuilder().distributionStatus(distrStatus).build(),
189 commentStr, null, null);
192 protected void validateComponentName(User user, Component component, AuditingActionEnum actionEnum) {
193 ComponentTypeEnum type = component.getComponentType();
194 String componentName = component.getName();
195 if (!ValidationUtils.validateStringNotEmpty(componentName)) {
196 log.debug("component name is empty");
197 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_COMPONENT_NAME, type.getValue());
198 componentsUtils.auditComponentAdmin(errorResponse, user, component, actionEnum, type);
199 throw new ByActionStatusComponentException(ActionStatus.MISSING_COMPONENT_NAME, type.getValue());
202 if (!ValidationUtils.validateComponentNameLength(componentName)) {
203 log.debug("Component name exceeds max length {} ", ValidationUtils.COMPONENT_NAME_MAX_LENGTH);
204 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NAME_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.COMPONENT_NAME_MAX_LENGTH);
205 componentsUtils.auditComponentAdmin(errorResponse, user, component, actionEnum, type);
206 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NAME_EXCEEDS_LIMIT,type.getValue(), "" + ValidationUtils.COMPONENT_NAME_MAX_LENGTH);
209 if (!validateTagPattern(componentName)) {
210 log.debug("Component name {} has invalid format", componentName);
211 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPONENT_NAME, type.getValue());
212 componentsUtils.auditComponentAdmin(errorResponse, user, component, actionEnum, type);
213 throw new ByActionStatusComponentException(ActionStatus.INVALID_COMPONENT_NAME, type.getValue());
215 component.setNormalizedName(ValidationUtils.normaliseComponentName(componentName));
216 component.setSystemName(ValidationUtils.convertToSystemName(componentName));
219 protected void validateDescriptionAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
220 ComponentTypeEnum type = component.getComponentType();
221 String description = component.getDescription();
222 if (!ValidationUtils.validateStringNotEmpty(description)) {
223 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_DESCRIPTION, type.getValue());
224 componentsUtils.auditComponentAdmin(errorResponse, user, component, actionEnum, type);
225 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_DESCRIPTION, type.getValue());
228 description = cleanUpText(description);
230 validateComponentDescription(description, type);
231 } catch(ByActionStatusComponentException e){
232 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
233 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, type);
235 } catch(ByResponseFormatComponentException e){
236 ResponseFormat responseFormat = e.getResponseFormat();
237 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, type);
240 component.setDescription(description);
243 private void validateComponentDescription(String description, ComponentTypeEnum type) {
244 if (description != null) {
245 if (!ValidationUtils.validateDescriptionLength(description)) {
246 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_DESCRIPTION_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.COMPONENT_DESCRIPTION_MAX_LENGTH);
249 if (!ValidationUtils.validateIsEnglish(description)) {
250 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INVALID_DESCRIPTION, type.getValue());
255 protected Either<Boolean, ResponseFormat> validateComponentNameUnique(User user, Component component, AuditingActionEnum actionEnum) {
256 log.debug("validate component name uniqueness for: {}", component.getName());
257 ComponentTypeEnum type = component.getComponentType();
258 ResourceTypeEnum resourceType = null;
259 if(component instanceof Resource){
260 resourceType = ((Resource)component).getResourceType();
262 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateComponentNameExists(component.getName(), resourceType, type);
264 if (dataModelResponse.isLeft()) {
265 if ( !dataModelResponse.left().value()) {
266 return Either.left(true);
268 log.info("Component with name {} already exists", component.getName());
269 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, type.getValue(), component.getName());
270 componentsUtils.auditComponentAdmin(errorResponse, user, component, actionEnum, type);
271 return Either.right(errorResponse);
274 BeEcompErrorManager.getInstance().logBeSystemError("validateComponentNameUnique");
275 log.debug("Error while validateComponentNameUnique for component: {}", component.getName());
276 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
277 componentsUtils.auditComponentAdmin(errorResponse, user, component, actionEnum, type);
278 return Either.right(errorResponse);
281 protected void validateContactId(User user, Component component, AuditingActionEnum actionEnum) {
282 log.debug("validate component contactId");
283 ComponentTypeEnum type = component.getComponentType();
284 String contactId = component.getContactId();
286 if (!ValidationUtils.validateStringNotEmpty(contactId)) {
287 log.info("contact is missing.");
288 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CONTACT, type.getValue());
289 componentsUtils.auditComponentAdmin(errorResponse, user, component, actionEnum, type);
290 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_CONTACT, type.getValue());
292 validateContactId(contactId, user, component, actionEnum, type);
295 private void validateContactId(String contactId, User user, Component component, AuditingActionEnum actionEnum, ComponentTypeEnum type) {
296 if (contactId != null && !ValidationUtils.validateContactId(contactId)) {
297 log.info("contact is invalid.");
298 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CONTACT, type.getValue());
299 componentsUtils.auditComponentAdmin(errorResponse, user, component, actionEnum, type);
300 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INVALID_CONTACT, type.getValue());
305 public Either<Boolean, ResponseFormat> validateConformanceLevel(String componentUuid, ComponentTypeEnum componentTypeEnum, String userId) {
306 log.trace("validate conformance level");
308 if (componentTypeEnum != ComponentTypeEnum.SERVICE) {
309 log.error("conformance level validation for non service component, id {}", componentUuid);
310 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
311 return Either.right(errorResponse);
314 validateUserExists(userId, "validateConformanceLevel", false);
316 Either<ComponentMetadataData, StorageOperationStatus> eitherComponent = toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, null);
317 if (eitherComponent.isRight()) {
318 log.error("can't validate conformance level, component not found, uuid {}", componentUuid);
319 BeEcompErrorManager.getInstance().logBeComponentMissingError("validateConformanceLevel", componentTypeEnum.getValue(), componentUuid);
321 StorageOperationStatus status = eitherComponent.right().value();
322 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(status, componentTypeEnum);
323 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus);
324 return Either.right(responseFormat);
327 String componentConformanceLevel = eitherComponent.left().value().getMetadataDataDefinition().getConformanceLevel();
328 if (StringUtils.isBlank(componentConformanceLevel)) {
329 log.error("component conformance level property is null or empty, uuid {}", componentUuid);
330 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
331 return Either.right(errorResponse);
334 String configConformanceLevel = ConfigurationManager.getConfigurationManager().getConfiguration().getMinToscaConformanceLevel();
335 Boolean result = true;
336 if (CommonBeUtils.conformanceLevelCompare(componentConformanceLevel, configConformanceLevel) < 0) {
337 log.error("invalid asset conformance level, uuid {}, asset conformanceLevel {}, config conformanceLevel {}", componentUuid, componentConformanceLevel, configConformanceLevel);
340 log.trace("conformance level validation finished");
342 return Either.left(result);
345 protected void validateIcon(User user, Component component, AuditingActionEnum actionEnum) {
346 log.debug("validate Icon");
347 ComponentTypeEnum type = component.getComponentType();
348 String icon = component.getIcon();
349 if (!ValidationUtils.validateStringNotEmpty(icon)) {
350 log.info("icon is missing.");
351 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_ICON, type.getValue());
352 componentsUtils.auditComponentAdmin(errorResponse, user, component, actionEnum, type);
353 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_ICON, type.getValue());
356 validateIcon(icon, type);
357 } catch(ByActionStatusComponentException e){
358 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
359 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, type);
361 } catch(ByResponseFormatComponentException e){
362 ResponseFormat responseFormat = e.getResponseFormat();
363 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, type);
368 private void validateIcon(String icon, ComponentTypeEnum type) {
370 if (!ValidationUtils.validateIconLength(icon)) {
371 log.debug("icon exceeds max length");
372 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_ICON_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.ICON_MAX_LENGTH);
375 if (!ValidationUtils.validateIcon(icon)) {
376 log.info("icon is invalid.");
377 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INVALID_ICON, type.getValue());
382 protected void validateTagsListAndRemoveDuplicates(User user, Component component, AuditingActionEnum actionEnum) {
383 List<String> tagsList = component.getTags();
385 validateComponentTags(tagsList, component.getName(), component.getComponentType(), user, component, actionEnum);
386 } catch(ByActionStatusComponentException e){
387 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
388 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, component.getComponentType());
390 } catch(ByResponseFormatComponentException e){
391 ResponseFormat responseFormat = e.getResponseFormat();
392 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, component.getComponentType());
395 ValidationUtils.removeDuplicateFromList(tagsList);
398 protected void validateComponentTags(List<String> tags, String name, ComponentTypeEnum componentType, User user, Component component, AuditingActionEnum action) {
399 log.debug("validate component tags");
400 boolean includesComponentName = false;
402 ResponseFormat responseFormat;
403 if (tags != null && !tags.isEmpty()) {
404 for (String tag : tags) {
405 if (!ValidationUtils.validateTagLength(tag)) {
406 log.debug("tag length exceeds limit {}", ValidationUtils.TAG_MAX_LENGTH);
407 responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_SINGLE_TAG_EXCEED_LIMIT, "" + ValidationUtils.TAG_MAX_LENGTH);
408 componentsUtils.auditComponentAdmin(responseFormat, user, component, action, componentType);
409 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_SINGLE_TAG_EXCEED_LIMIT, "" + ValidationUtils.TAG_MAX_LENGTH);
411 if (validateTagPattern(tag)) {
412 if (!includesComponentName) {
413 includesComponentName = name.equals(tag);
416 log.debug("invalid tag {}", tag);
417 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_FIELD_FORMAT, componentType.getValue(), TAG_FIELD_LABEL);
418 componentsUtils.auditComponentAdmin(responseFormat, user, component, action, componentType);
419 throw new ByActionStatusComponentException(ActionStatus.INVALID_FIELD_FORMAT, componentType.getValue(), TAG_FIELD_LABEL);
421 tagListSize += tag.length() + 1;
423 if (tagListSize > 0) {
427 if (!includesComponentName) {
428 log.debug("tags must include component name");
429 responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_TAGS_NO_COMP_NAME);
430 componentsUtils.auditComponentAdmin(responseFormat, user, component, action, componentType);
431 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INVALID_TAGS_NO_COMP_NAME);
433 if (!ValidationUtils.validateTagListLength(tagListSize)) {
434 log.debug("overall tags length exceeds limit {}", ValidationUtils.TAG_LIST_MAX_LENGTH);
435 responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TAGS_EXCEED_LIMIT, "" + ValidationUtils.TAG_LIST_MAX_LENGTH);
436 componentsUtils.auditComponentAdmin(responseFormat, user, component, action, componentType);
437 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_TAGS_EXCEED_LIMIT, "" + ValidationUtils.TAG_LIST_MAX_LENGTH);
440 responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
441 componentsUtils.auditComponentAdmin(responseFormat, user, component, action, componentType);
442 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_MISSING_TAGS);
446 protected boolean validateTagPattern(String tag) {
447 return ValidationUtils.validateComponentNamePattern(tag);
450 protected Either<Boolean, ResponseFormat> validateProjectCode(User user, Component component, AuditingActionEnum actionEnum) {
451 if (ComponentTypeEnum.RESOURCE.equals(component.getComponentType())) {
452 return Either.left(true);
454 log.debug("validate ProjectCode name ");
455 String projectCode = component.getProjectCode();
457 if (!ValidationUtils.validateStringNotEmpty(projectCode)) {
458 log.info("projectCode is missing.");
459 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_PROJECT_CODE);
460 componentsUtils.auditComponentAdmin(errorResponse, user, component, actionEnum, component.getComponentType(),
461 ResourceVersionInfo.newBuilder()
463 return Either.right(errorResponse);
466 Either<Boolean, ResponseFormat> validateProjectCodeResponse = validateProjectCode(projectCode);
467 if (validateProjectCodeResponse.isRight()) {
468 ResponseFormat responseFormat = validateProjectCodeResponse.right().value();
469 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, component.getComponentType(),
470 ResourceVersionInfo.newBuilder()
473 return validateProjectCodeResponse;
477 private Either<Boolean, ResponseFormat> validateProjectCode(String projectCode) {
478 if (projectCode != null) {
479 if (!ValidationUtils.validateProjectCode(projectCode)) {
480 log.info("projectCode is not valid.");
481 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROJECT_CODE);
482 return Either.right(errorResponse);
484 return Either.left(true);
486 return Either.left(false);
489 protected void checkComponentFieldsForOverrideAttempt(Component component) {
490 if (component.getLifecycleState() != null) {
491 log.info("LifecycleState cannot be defined by user. This field will be overridden by the application");
493 if (component.getVersion() != null) {
494 log.info("Version cannot be defined by user. This field will be overridden by the application");
496 if (component.getCreatorUserId() != null || component.getCreatorFullName() != null) {
497 log.info("Creator cannot be defined by user. This field will be overridden by the application");
499 if (component.getLastUpdaterUserId() != null || component.getLastUpdaterFullName() != null) {
500 log.info("Last Updater cannot be defined by user. This field will be overridden by the application");
502 if (component.getCreationDate() != null) {
503 log.info("Creation Date cannot be defined by user. This field will be overridden by the application");
505 if (component.isHighestVersion() != null) {
506 log.info("Is Highest Version cannot be defined by user. This field will be overridden by the application");
508 if (component.getUUID() != null) {
509 log.info("UUID cannot be defined by user. This field will be overridden by the application");
511 if (component.getLastUpdateDate() != null) {
512 log.info("Last Update Date cannot be defined by user. This field will be overridden by the application");
514 if (component.getUniqueId() != null) {
515 log.info("uid cannot be defined by user. This field will be overridden by the application.");
516 component.setUniqueId(null);
518 if (component.getInvariantUUID() != null) {
519 log.info("Invariant UUID cannot be defined by user. This field will be overridden by the application.");
523 protected void validateComponentFieldsBeforeCreate(User user, Component component, AuditingActionEnum actionEnum) {
524 // validate component name uniqueness
525 log.debug("validate component name ");
526 validateComponentName(user, component, actionEnum);
527 // validate description
528 log.debug("validate description");
529 validateDescriptionAndCleanup(user, component, actionEnum);
531 log.debug("validate tags");
532 validateTagsListAndRemoveDuplicates(user, component, actionEnum);
533 // validate contact info
534 log.debug("validate contact info");
535 validateContactId(user, component, actionEnum);
537 log.debug("validate icon");
538 validateIcon(user, component, actionEnum);
541 public Either<CapReqDef, ResponseFormat> getRequirementsAndCapabilities(String componentId, ComponentTypeEnum componentTypeEnum, String userId) {
543 validateUserExists(userId, "create Component Instance", false);
544 Either<CapReqDef, ResponseFormat> eitherRet = null;
545 ComponentParametersView filter = new ComponentParametersView(true);
546 filter.setIgnoreCapabilities(false);
547 filter.setIgnoreRequirements(false);
548 filter.setIgnoreComponentInstances(false);
549 Either<Component, ResponseFormat> eitherComponent = validateComponentExists(componentId, componentTypeEnum, filter);
550 if (eitherComponent.isLeft()) {
551 eitherRet = Either.left(new CapReqDef(eitherComponent.left().value().getRequirements(), eitherComponent.left().value().getCapabilities()));
553 BeEcompErrorManager.getInstance().logBeComponentMissingError("getRequirementsAndCapabilities", componentTypeEnum.getValue(), componentId);
554 eitherRet = Either.right(eitherComponent.right().value());
559 public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponents(boolean isAbstractAbstract, ComponentTypeEnum componentTypeEnum, String internalComponentType, List<String> componentUids,
562 validateUserExists(userId, "get Latest Version Not Abstract Components", false);
563 List<Component> result = new ArrayList<>();
564 List<String> componentsUidToFetch = new ArrayList<>();
565 componentsUidToFetch.addAll(componentUids);
566 if (!componentsUidToFetch.isEmpty()) {
567 log.debug("Number of Components to fetch from graph is {}", componentsUidToFetch.size());
568 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade.getLatestVersionNotAbstractComponents(isAbstractAbstract, componentTypeEnum, internalComponentType, componentsUidToFetch);
570 if (nonCheckoutCompResponse.isLeft()) {
571 log.debug("Retrived Resource successfully.");
572 result.addAll(nonCheckoutCompResponse.left().value());
574 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value())));
577 return Either.left(result);
580 janusGraphDao.commit();
584 private Boolean isHighest(HighestFilterEnum highestFilter) {
585 Boolean isHighest = null;
586 switch (highestFilter) {
592 case NON_HIGHEST_ONLY:
601 public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponentsMetadata(boolean isAbstractAbstract, HighestFilterEnum highestFilter, ComponentTypeEnum componentTypeEnum, String internalComponentType, String userId) {
602 ResponseFormat responseFormat = null;
605 validateUserExists(userId, "get Latest Version Not Abstract Components", false);
606 Boolean isHighest = isHighest(highestFilter);
607 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade.getLatestVersionNotAbstractMetadataOnly(isAbstractAbstract, componentTypeEnum, internalComponentType);
609 if (nonCheckoutCompResponse.isLeft()) {
610 log.debug("Retrived Resource successfully.");
611 return Either.left(nonCheckoutCompResponse.left().value());
613 responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value()));
615 janusGraphDao.commit();
617 return Either.right(responseFormat);
620 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
624 @SuppressWarnings("unchecked")
625 public void setToscaArtifactsPlaceHolders(Component component, User user) {
626 Map<String, ArtifactDefinition> artifactMap = component.getToscaArtifacts();
627 if (artifactMap == null) {
628 artifactMap = new HashMap<>();
630 String componentUniqueId = component.getUniqueId();
631 String componentSystemName = component.getSystemName();
632 String componentType = component.getComponentType().getValue().toLowerCase();
633 Map<String, Object> toscaArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts();
635 if (toscaArtifacts != null) {
636 for (Entry<String, Object> artifactInfoMap : toscaArtifacts.entrySet()) {
637 Map<String, Object> artifactInfo = (Map<String, Object>) artifactInfoMap.getValue();
638 ArtifactDefinition artifactDefinition = artifactsBusinessLogic.createArtifactPlaceHolderInfo(componentUniqueId, artifactInfoMap.getKey(), artifactInfo, user, ArtifactGroupTypeEnum.TOSCA);
639 artifactDefinition.setArtifactName(ValidationUtils.normalizeFileName(componentType + "-" + componentSystemName + artifactInfo.get("artifactName")));
640 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
643 component.setToscaArtifacts(artifactMap);
646 public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock) {
647 return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true);
650 public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock, boolean fetchTemplatesFromDB) {
651 Either<Component, StorageOperationStatus> toscaElement = toscaOperationFacade.getToscaFullElement(component.getUniqueId());
652 if ( toscaElement.isRight() ){
653 ResponseFormat response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(toscaElement.right().value(), component.getComponentType()));
654 return Either.right(response);
656 component = toscaElement.left().value();
657 Either<Either<ArtifactDefinition, Operation>, ResponseFormat> generateToscaRes = null;
658 if (component.getToscaArtifacts() != null && !component.getToscaArtifacts().isEmpty()) {
659 ArtifactDefinition toscaArtifact = component.getToscaArtifacts().values().stream()
660 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_TEMPLATE.getType()))
662 generateToscaRes = saveToscaArtifactPayload(toscaArtifact, component, user, isInCertificationRequest, shouldLock, inTransaction, fetchTemplatesFromDB);
663 if (generateToscaRes.isRight()) {
664 return generateToscaRes;
666 toscaArtifact = generateToscaRes.left().value().left().value();
667 component.getToscaArtifacts().put(toscaArtifact.getArtifactLabel(), toscaArtifact);
668 if(!isAbstractResource(component)){
669 toscaArtifact = component.getToscaArtifacts().values().stream()
670 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType()))
672 generateToscaRes = saveToscaArtifactPayload(toscaArtifact, component, user, isInCertificationRequest, shouldLock, inTransaction, true);
673 if (generateToscaRes.isRight()) {
674 return generateToscaRes;
676 toscaArtifact = generateToscaRes.left().value().left().value();
677 component.getToscaArtifacts().put(toscaArtifact.getArtifactLabel(), toscaArtifact);
680 return generateToscaRes;
683 private boolean isAbstractResource(Component component) {
684 return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource)component).isAbstract();
687 public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> saveToscaArtifactPayload(ArtifactDefinition artifactDefinition, org.openecomp.sdc.be.model.Component component, User user, boolean isInCertificationRequest, boolean shouldLock,
688 boolean inTransaction, boolean fetchTemplatesFromDB) {
689 return artifactsBusinessLogic.generateAndSaveToscaArtifact(artifactDefinition, component, user, isInCertificationRequest, shouldLock, inTransaction, fetchTemplatesFromDB);
692 public Either<ImmutablePair<String, byte[]>, ResponseFormat> getToscaModelByComponentUuid(ComponentTypeEnum componentType, String uuid, ResourceCommonInfo resourceCommonInfo) {
694 Either<List<Component>, StorageOperationStatus> latestVersionEither = toscaOperationFacade.getComponentListByUuid(uuid, null);
696 if (latestVersionEither.isRight()) {
697 ResponseFormat response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(latestVersionEither.right().value(), componentType));
698 return Either.right(response);
701 List<Component> components = latestVersionEither.left().value();
703 Component component = components.stream().filter(Component::isHighestVersion).findFirst().orElse(null);
704 if(component == null){
705 component = components.stream().filter(c -> c.getLifecycleState() == LifecycleStateEnum.CERTIFIED).findFirst().orElse(null);
708 if(component == null){
709 ResponseFormat response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, componentType));
710 return Either.right(response);
712 resourceCommonInfo.setResourceName(component.getName());
713 // TODO remove after migration - handle artifact not found(no
715 if (null == component.getToscaArtifacts() || component.getToscaArtifacts().isEmpty()) {
716 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ArtifactTypeEnum.TOSCA_CSAR.name()));
718 ArtifactDefinition csarArtifact = component.getToscaArtifacts().values().stream()
719 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType()))
721 return artifactsBusinessLogic.handleDownloadToscaModelRequest(component, csarArtifact);
724 protected StorageOperationStatus markComponentToDelete(Component component) {
726 ComponentTypeEnum componentType = component.getComponentType();
727 String uniqueId = component.getUniqueId();
728 if (Boolean.TRUE.equals(component.getIsDeleted())) {
729 log.info("component {} already marked as deleted. id= {}, type={}", component.getName(), uniqueId, componentType);
730 return StorageOperationStatus.NOT_FOUND;
733 StorageOperationStatus markResourceToDelete = toscaOperationFacade.markComponentToDelete(component);
734 if (StorageOperationStatus.OK != markResourceToDelete) {
735 log.debug("failed to mark component {} of type {} for delete. error = {}", uniqueId, componentType, markResourceToDelete);
736 return markResourceToDelete;
738 log.debug("Component {} of type {} was marked as deleted", uniqueId, componentType);
739 return StorageOperationStatus.OK;
743 public Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Component currentComponent, Component updatedComponent, AuditingActionEnum auditingAction) {
744 String descriptionUpdated = updatedComponent.getDescription();
745 String descriptionCurrent = currentComponent.getDescription();
746 if (descriptionUpdated != null && !descriptionCurrent.equals(descriptionUpdated)) {
747 validateDescriptionAndCleanup(user, updatedComponent, auditingAction);
748 currentComponent.setDescription(updatedComponent.getDescription());
750 return Either.left(true);
753 public Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Component currentComponent, Component updatedComponent) {
754 String projectCodeUpdated = updatedComponent.getProjectCode();
755 String projectCodeCurrent = currentComponent.getProjectCode();
756 if (projectCodeUpdated != null && !projectCodeCurrent.equals(projectCodeUpdated)) {
757 Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, updatedComponent, null);
758 if (validatProjectCodeResponse.isRight()) {
759 ResponseFormat errorRespons = validatProjectCodeResponse.right().value();
760 return Either.right(errorRespons);
762 currentComponent.setProjectCode(updatedComponent.getProjectCode());
764 return Either.left(true);
767 public Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Component currentComponent, Component updatedComponent, boolean hasBeenCertified) {
768 String iconUpdated = updatedComponent.getIcon();
769 String iconCurrent = currentComponent.getIcon();
770 if (iconUpdated != null && !iconCurrent.equals(iconUpdated)) {
771 if (!hasBeenCertified) {
772 validateIcon(user, updatedComponent, null);
773 currentComponent.setIcon(updatedComponent.getIcon());
775 log.info("icon {} cannot be updated once the component has been certified once.", iconUpdated);
776 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_PARAMETER_CANNOT_BE_CHANGED, "Icon", currentComponent.getComponentType().name().toLowerCase());
777 return Either.right(errorResponse);
780 return Either.left(true);
783 protected Either<List<String>, ResponseFormat> deleteMarkedComponents(ComponentTypeEnum componentType) {
785 log.trace("start deleteMarkedComponents");
786 Either<List<String>, StorageOperationStatus> deleteMarkedElements = toscaOperationFacade.deleteMarkedElements(componentType);
789 if ( deleteMarkedElements.isRight()){
790 janusGraphDao.rollback();
791 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteMarkedElements.right().value(), componentType));
792 return Either.right(responseFormat);
794 log.trace("end deleteMarkedComponents");
795 janusGraphDao.commit();
796 return Either.left(deleteMarkedElements.left().value());
799 public Either<List<ArtifactDefinition>, StorageOperationStatus> getComponentArtifactsForDelete(String parentId, NodeTypeEnum parentType) {
800 List<ArtifactDefinition> artifacts = new ArrayList<>();
801 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse = artifactToscaOperation.getArtifacts(parentId);
802 if (artifactsResponse.isRight()) {
803 if (!artifactsResponse.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
804 log.debug("failed to retrieve artifacts for {} {}", parentType, parentId);
805 return Either.right(artifactsResponse.right().value());
808 artifacts.addAll(artifactsResponse.left().value().values());
810 return Either.left(artifacts);
817 * @param dataParamsToReturn - ui list of params to return
821 public Either<UiComponentDataTransfer, ResponseFormat> getComponentDataFilteredByParams(String componentId, User user, List<String> dataParamsToReturn) {
824 validateUserExists(user, "Get Component by filtered by ui params", false);
827 UiComponentDataTransfer result = new UiComponentDataTransfer();
829 if(dataParamsToReturn == null || dataParamsToReturn.isEmpty()) {
833 Either<UiComponentDataTransfer, ResponseFormat> uiDataTransferEither = getUiComponentDataTransferByComponentId(componentId, dataParamsToReturn);
834 if(uiDataTransferEither.isRight()){
835 return Either.right(uiDataTransferEither.right().value());
837 result = uiDataTransferEither.left().value();
840 return Either.left(result);
843 protected <T extends Component> void generateAndAddInputsFromGenericTypeProperties(T component, Resource genericType) {
844 List<InputDefinition> genericAndComponentInputs = new ArrayList<>();
845 List<InputDefinition> genericInputs = genericTypeBusinessLogic.generateInputsFromGenericTypeProperties(genericType);
846 genericAndComponentInputs.addAll(genericInputs);
847 if (null != component.getInputs()){
848 List<InputDefinition> nonGenericInputsFromComponent = getAllNonGenericInputsFromComponent(genericInputs, component.getInputs());
849 genericAndComponentInputs.addAll(nonGenericInputsFromComponent);
851 component.setInputs(genericAndComponentInputs);
854 private List<InputDefinition> getAllNonGenericInputsFromComponent(List<InputDefinition> genericInputs, List<InputDefinition> componentInputs) {
855 if (genericInputs == null) {
856 return componentInputs;
859 Map<String, InputDefinition> inputByNameMap = MapUtil.toMap(genericInputs, InputDefinition::getName);
860 List<InputDefinition> componentNonGenericInputs = new ArrayList<>();
861 componentInputs.stream().forEach(input -> {
862 if (!inputByNameMap.containsKey(input.getName())) {
863 componentNonGenericInputs.add(input);
866 return componentNonGenericInputs;
869 protected <T extends Component> Resource fetchAndSetDerivedFromGenericType(T component){
870 Either<Resource, ResponseFormat> genericTypeEither = this.genericTypeBusinessLogic.fetchDerivedFromGenericType(component);
871 if(genericTypeEither.isRight()){
872 log.debug("Failed to fetch latest generic type for component {} of type", component.getName(), component.assetType());
873 throw new ByActionStatusComponentException(ActionStatus.GENERIC_TYPE_NOT_FOUND, component.assetType());
875 Resource genericTypeResource = genericTypeEither.left().value();
876 component.setDerivedFromGenericInfo(genericTypeResource);
877 return genericTypeResource;
880 public Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstanceProperties(String componentId, Map<FilterKeyEnum, List<String>> filters, String userId) {
881 Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> response = null;
882 Either<Component, StorageOperationStatus> getResourceRes = null;
884 if(!filters.containsKey(FilterKeyEnum.NAME_FRAGMENT) && StringUtils.isEmpty(filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0))){
885 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
887 if (userId != null && response == null) {
888 validateUserExists(userId, "Get filtered component instance properties", false);
890 if(response == null){
891 getResourceRes = toscaOperationFacade.getToscaElement(componentId);
892 if(getResourceRes.isRight()){
893 response = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getResourceRes.right().value())));
896 if(response == null){
897 response = getFilteredComponentInstancesProperties(getResourceRes.left().value(), filters);
899 } catch(Exception e){
900 log.debug("The exception {} occured during filtered instance properties fetching. the containing component is {}. ", e, componentId);
901 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
903 if (response.isLeft()){
904 toscaOperationFacade.commit();
906 toscaOperationFacade.rollback();
912 private Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstancesProperties(Component component, Map<FilterKeyEnum, List<String>> filters) {
914 Map<String, List<IComponentInstanceConnectedElement>> filteredProperties = new HashMap<>();
915 Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> result = Either.left(filteredProperties);
916 List<ComponentInstance> filteredInstances = getFilteredInstances(component, filters.get(FilterKeyEnum.RESOURCE_TYPE));
917 String propertyNameFragment= filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0);
918 boolean searchByFragment = propertyNameFragment.length() > 3 ;
919 if(CollectionUtils.isNotEmpty(filteredInstances)){
920 for(ComponentInstance instance : filteredInstances){
921 if(component.getComponentInstancesProperties()!=null &&component.getComponentInstancesProperties().containsKey(instance.getUniqueId())){
922 List<IComponentInstanceConnectedElement> currProperties = getFilteredComponentInstanceProperties(component.getComponentInstancesProperties().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
923 if(CollectionUtils.isNotEmpty(currProperties)){
924 filteredProperties.put(instance.getUniqueId(), currProperties);
927 if(component.getComponentInstancesInputs()!=null && component.getComponentInstancesInputs().containsKey(instance.getUniqueId())){
928 List<IComponentInstanceConnectedElement> currInputs = getFilteredComponentInstanceInputs(component.getComponentInstancesInputs().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
929 if(CollectionUtils.isNotEmpty(currInputs)){
930 if(filteredProperties.get(instance.getUniqueId())!=null){
931 filteredProperties.get(instance.getUniqueId()).addAll(currInputs);
933 filteredProperties.put(instance.getUniqueId(), currInputs);
942 private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceInputs(List<ComponentInstanceInput> inputs, String propertyNameFragment, boolean searchByFragment) {
943 return inputs.stream().filter(i -> isMatchingInput(i, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
946 private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceProperties(List<ComponentInstanceProperty> instanceProperties, String propertyNameFragment, boolean searchByFragment) {
947 return instanceProperties.stream().filter(p -> isMatchingProperty(p, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
950 private boolean isMatchingInput(ComponentInstanceInput input, String propertyNameFragment, boolean searchByFragment) {
951 boolean isMatching = false;
952 if(searchByFragment && input.getName().toLowerCase().contains(propertyNameFragment)){
955 if(!searchByFragment && input.getName().equalsIgnoreCase(propertyNameFragment)){
961 private boolean isMatchingProperty(ComponentInstanceProperty property, String propertyNameFragment, boolean searchByFragment) {
962 boolean isMatching = false;
963 if(searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment)){
966 if(!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)){
969 if (!isMatching && !ToscaPropertyType.isPrimitiveType(property.getType())){
970 isMatching = isMatchingComplexPropertyByRecursively(property, propertyNameFragment, searchByFragment);
975 private boolean isMatchingComplexPropertyByRecursively(PropertyDataDefinition property, String propertyNameFragment, boolean searchByFragment) {
977 List<PropertyDefinition> dataTypeProperties;
978 DataTypeDefinition currentProperty;
979 if(searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment.toLowerCase())){
982 if(!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)){
986 propertyType = isEmptyInnerType(property) ? property.getType() : property.getSchema().getProperty().getType();
988 if(ToscaPropertyType.isScalarType(propertyType)){
991 Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameRes = propertyOperation.getDataTypeByName(propertyType);
992 if(getDataTypeByNameRes.isRight()){
995 currentProperty = getDataTypeByNameRes.left().value();
996 dataTypeProperties = currentProperty.getProperties();
998 if(CollectionUtils.isNotEmpty(dataTypeProperties)){
999 for(PropertyDefinition prop : dataTypeProperties){
1000 if(isMatchingComplexPropertyByRecursively(prop, propertyNameFragment, searchByFragment)){
1005 dataTypeProperties = currentProperty.getDerivedFrom().getProperties();
1006 if(CollectionUtils.isNotEmpty(dataTypeProperties)){
1007 for(PropertyDefinition prop : dataTypeProperties){
1008 if(isMatchingComplexPropertyByRecursively(prop, propertyNameFragment, searchByFragment)){
1016 private boolean isEmptyInnerType(PropertyDataDefinition property) {
1017 return property == null|| property.getSchema() == null || property.getSchema().getProperty() == null || property.getSchema().getProperty().getType() == null;
1020 public Either<Boolean, ResponseFormat> shouldUpgradeToLatestGeneric(Component clonedComponent) {
1022 if(!clonedComponent.deriveFromGeneric())
1023 return Either.left(false);
1024 Boolean shouldUpgrade = false;
1025 String currentGenericType = clonedComponent.getDerivedFromGenericType();
1026 String currentGenericVersion = clonedComponent.getDerivedFromGenericVersion();
1027 Resource genericTypeResource = fetchAndSetDerivedFromGenericType(clonedComponent);
1028 if(null == currentGenericType || !currentGenericType.equals(genericTypeResource.getToscaResourceName()) || !currentGenericVersion.equals(genericTypeResource.getVersion())){
1029 shouldUpgrade = upgradeToLatestGeneric(clonedComponent, genericTypeResource);
1030 if(!shouldUpgrade) {
1031 reverntUpdateOfGenericVersion(clonedComponent, currentGenericType, currentGenericVersion);
1034 return Either.left(shouldUpgrade);
1037 private void reverntUpdateOfGenericVersion(Component clonedComponent, String currentGenericType, String currentGenericVersion) {
1038 clonedComponent.setDerivedFromGenericType(currentGenericType);
1039 clonedComponent.setDerivedFromGenericVersion(currentGenericVersion);
1042 private <T extends PropertyDataDefinition> Either<Map<String, T>, String> validateNoConflictingProperties(List<T> currentList, List<T> upgradedList) {
1043 Map<String, T> currentMap = ToscaDataDefinition.listToMapByName(currentList);
1044 Map<String, T> upgradedMap = ToscaDataDefinition.listToMapByName(upgradedList);
1045 return ToscaDataDefinition.mergeDataMaps(upgradedMap, currentMap, true);
1048 private boolean shouldUpgradeNodeType(Component componentToCheckOut, Resource latestGeneric){
1050 List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
1051 Either<Map<String, PropertyDefinition>, String> validMerge = validateNoConflictingProperties(genericTypeProps, ((Resource)componentToCheckOut).getProperties());
1052 if (validMerge.isRight()) {
1053 log.debug("property {} cannot be overriden, check out performed without upgrading to latest generic", validMerge.right().value());
1056 List<PropertyDefinition> genericTypeAttributes = latestGeneric.getAttributes();
1057 validMerge = validateNoConflictingProperties(genericTypeAttributes, ((Resource)componentToCheckOut).getAttributes());
1058 if (validMerge.isRight()) {
1059 log.debug("attribute {} cannot be overriden, check out performed without upgrading to latest generic", validMerge.right().value());
1065 private boolean upgradeToLatestGeneric(Component componentToCheckOut, Resource latestGeneric) {
1067 if (!componentToCheckOut.shouldGenerateInputs()) {
1068 //node type - validate properties and attributes
1069 return shouldUpgradeNodeType(componentToCheckOut, latestGeneric);
1071 List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
1072 List<InputDefinition> genericTypeInputs = null == genericTypeProps? null : genericTypeBusinessLogic.convertGenericTypePropertiesToInputsDefintion(genericTypeProps, latestGeneric.getUniqueId());
1073 List<InputDefinition> currentList = new ArrayList<>();
1074 // nullify existing ownerId from existing list and merge into updated list
1075 if (null != componentToCheckOut.getInputs()) {
1076 for(InputDefinition input : componentToCheckOut.getInputs()) {
1077 InputDefinition copy = new InputDefinition(input);
1078 copy.setOwnerId(null);
1079 currentList.add(copy);
1082 if (null == genericTypeInputs) {
1083 componentToCheckOut.setInputs(currentList);
1087 Either<Map<String, InputDefinition>, String> eitherMerged = validateNoConflictingProperties(genericTypeInputs, currentList);
1088 if (eitherMerged.isRight()) {
1089 log.debug("input {} cannot be overriden, check out performed without upgrading to latest generic", eitherMerged.right().value());
1092 componentToCheckOut.setInputs(new ArrayList<>(eitherMerged.left().value().values()));
1097 private List<ComponentInstance> getFilteredInstances(Component component, List<String> resourceTypes) {
1098 List<ComponentInstance> filteredInstances = null;
1099 if(CollectionUtils.isEmpty(resourceTypes)){
1100 filteredInstances = component.getComponentInstances();
1102 else if(CollectionUtils.isNotEmpty(component.getComponentInstances())){
1103 filteredInstances = component.getComponentInstances()
1104 .stream().filter(i -> isMatchingType(i.getOriginType(), resourceTypes)).collect(Collectors.toList());
1106 if(filteredInstances == null){
1107 filteredInstances = new ArrayList<>();
1109 return filteredInstances;
1112 private boolean isMatchingType(OriginTypeEnum originType, List<String> resourceTypes) {
1113 boolean isMatchingType = false;
1114 for(String resourceType : resourceTypes){
1115 if(originType == OriginTypeEnum.findByValue(resourceType.toUpperCase())){
1116 isMatchingType = true;
1120 return isMatchingType;
1123 String cleanUpText(String text){
1124 text = ValidationUtils.removeNoneUtf8Chars(text);
1125 text = ValidationUtils.normaliseWhitespace(text);
1126 text = ValidationUtils.stripOctets(text);
1127 text = ValidationUtils.removeHtmlTagsOnly(text);
1131 public Either<Component, ActionStatus> shouldUpgradeToLatestDerived(Component clonedComponent) {
1132 //general implementation. Must be error for service, VF . In ResourceBuisnessLogic exist override
1133 return Either.right(ActionStatus.GENERAL_ERROR);
1136 public List<GroupDefinition> throwComponentException(ResponseFormat responseFormat) {
1137 throw new ByResponseFormatComponentException(responseFormat);