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 static org.apache.commons.collections.CollectionUtils.isEmpty;
24 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
25 import static org.openecomp.sdc.be.components.utils.ConsumptionUtils.handleConsumptionInputMappedToCapabilityProperty;
26 import static org.openecomp.sdc.be.components.utils.ConsumptionUtils.isAssignedValueFromValidType;
27 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getOperationOutputName;
28 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToOtherOperationOutput;
29 import static org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum.UPDATE_SERVICE_METADATA;
30 import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.SELF;
31 import static org.openecomp.sdc.be.types.ServiceConsumptionSource.SERVICE_INPUT;
32 import static org.openecomp.sdc.be.types.ServiceConsumptionSource.STATIC;
34 import com.google.common.annotations.VisibleForTesting;
35 import com.google.common.base.Strings;
36 import com.google.gson.Gson;
37 import com.google.gson.GsonBuilder;
39 import java.nio.charset.StandardCharsets;
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.Collection;
43 import java.util.Collections;
44 import java.util.HashMap;
45 import java.util.List;
47 import java.util.Objects;
48 import java.util.Optional;
50 import java.util.concurrent.Callable;
51 import java.util.function.Function;
52 import java.util.stream.Collectors;
54 import fj.data.Either;
55 import org.apache.commons.collections.CollectionUtils;
56 import org.apache.commons.collections.MapUtils;
57 import org.apache.commons.collections4.ListUtils;
58 import org.apache.commons.lang3.StringUtils;
59 import org.apache.commons.lang3.tuple.ImmutablePair;
60 import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine;
61 import org.openecomp.sdc.be.components.distribution.engine.INotificationData;
62 import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload;
63 import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic;
64 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
65 import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
66 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
67 import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
68 import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
69 import org.openecomp.sdc.be.components.utils.PropertiesUtils;
70 import org.openecomp.sdc.be.components.validation.NodeFilterValidator;
71 import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
72 import org.openecomp.sdc.be.config.BeEcompErrorManager;
73 import org.openecomp.sdc.be.config.ConfigurationManager;
74 import org.openecomp.sdc.be.dao.api.ActionStatus;
75 import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
76 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
77 import org.openecomp.sdc.be.datamodel.ServiceRelations;
78 import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil;
79 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
80 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
81 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
82 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
83 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
84 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
85 import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition;
86 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
87 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
88 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
89 import org.openecomp.sdc.be.datatypes.enums.InstantiationTypes;
90 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
91 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
92 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
93 import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo;
94 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
95 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
96 import org.openecomp.sdc.be.model.ArtifactDefinition;
97 import org.openecomp.sdc.be.model.CapabilityDefinition;
98 import org.openecomp.sdc.be.model.Component;
99 import org.openecomp.sdc.be.model.ComponentInstance;
100 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
101 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
102 import org.openecomp.sdc.be.model.ComponentParametersView;
103 import org.openecomp.sdc.be.model.DistributionStatusEnum;
104 import org.openecomp.sdc.be.model.DistributionTransitionEnum;
105 import org.openecomp.sdc.be.model.GroupInstance;
106 import org.openecomp.sdc.be.model.GroupInstanceProperty;
107 import org.openecomp.sdc.be.model.InputDefinition;
108 import org.openecomp.sdc.be.model.InterfaceDefinition;
109 import org.openecomp.sdc.be.model.LifecycleStateEnum;
110 import org.openecomp.sdc.be.model.Operation;
111 import org.openecomp.sdc.be.model.PropertyDefinition;
112 import org.openecomp.sdc.be.model.Resource;
113 import org.openecomp.sdc.be.model.Service;
114 import org.openecomp.sdc.be.model.User;
115 import org.openecomp.sdc.be.model.category.CategoryDefinition;
116 import org.openecomp.sdc.be.model.jsontitan.operations.ForwardingPathOperation;
117 import org.openecomp.sdc.be.model.jsontitan.operations.NodeFilterOperation;
118 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
119 import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation;
120 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
121 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
122 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
123 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
124 import org.openecomp.sdc.be.model.tosca.ToscaFunctions;
125 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
126 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
127 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
128 import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent;
129 import org.openecomp.sdc.be.resources.data.auditing.DistributionDeployEvent;
130 import org.openecomp.sdc.be.resources.data.auditing.DistributionNotificationEvent;
131 import org.openecomp.sdc.be.resources.data.auditing.ResourceAdminEvent;
132 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
133 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
134 import org.openecomp.sdc.be.types.ServiceConsumptionData;
135 import org.openecomp.sdc.be.types.ServiceConsumptionSource;
136 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
137 import org.openecomp.sdc.be.user.Role;
138 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
139 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
140 import org.openecomp.sdc.common.api.Constants;
141 import org.openecomp.sdc.common.datastructure.Wrapper;
142 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
143 import org.openecomp.sdc.common.log.wrappers.Logger;
144 import org.openecomp.sdc.common.util.GeneralUtility;
145 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
146 import org.openecomp.sdc.common.util.ValidationUtils;
147 import org.openecomp.sdc.exception.ResponseFormat;
148 import org.springframework.beans.factory.annotation.Autowired;
149 import org.springframework.http.HttpStatus;
150 import org.springframework.web.context.WebApplicationContext;
152 import javax.servlet.ServletContext;
153 import javax.servlet.http.HttpServletRequest;
155 @org.springframework.stereotype.Component("serviceBusinessLogic")
156 public class ServiceBusinessLogic extends ComponentBusinessLogic {
158 private static final String CHANGE_SERVICE_DISTRIBUTION = "Change Service Distribution";
159 private static final String THE_SERVICE_WITH_SYSTEM_NAME_LOCKED = "The service with system name {} locked. ";
160 private static final String FAILED_TO_LOCK_SERVICE_RESPONSE_IS = "Failed to lock service {}. Response is {}. ";
161 private static final String AUDIT_BEFORE_SENDING_RESPONSE = "audit before sending response";
162 private static final Logger log = Logger.getLogger(ServiceBusinessLogic.class);
163 private static final String INITIAL_VERSION = "0.1";
164 private static final String STATUS_SUCCESS_200 = "200";
165 private static final String STATUS_DEPLOYED = "DEPLOYED";
167 private IDistributionEngine distributionEngine;
169 private AuditCassandraDao auditCassandraDao;
171 private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
173 private ICacheMangerOperation cacheManagerOperation;
175 private ServiceDistributionValidation serviceDistributionValidation;
178 private ForwardingPathOperation forwardingPathOperation;
180 private ForwardingPathValidator forwardingPathValidator;
182 private UiComponentDataConverter uiComponentDataConverter;
184 private NodeFilterOperation serviceFilterOperation;
186 private NodeFilterValidator serviceFilterValidator;
188 public Either<Service, ResponseFormat> changeServiceDistributionState(String serviceId, String state, LifecycleChangeInfoWithAction commentObj, User user) {
190 validateUserExists(user.getUserId(), "change Service Distribution State", false);
192 log.debug("check request state");
193 Either<DistributionTransitionEnum, ResponseFormat> validateEnum = validateTransitionEnum(state);
194 if (validateEnum.isRight()) {
195 return Either.right(validateEnum.right().value());
197 DistributionTransitionEnum distributionTransition = validateEnum.left().value();
198 AuditingActionEnum auditAction = distributionTransition == DistributionTransitionEnum.APPROVE ? AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_APPROV : AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REJECT;
199 Either<String, ResponseFormat> commentResponse = validateComment(commentObj);
200 if (commentResponse.isRight()) {
201 return Either.right(commentResponse.right().value());
203 String comment = commentResponse.left().value();
205 Either<Service, ResponseFormat> validateService = validateServiceDistributionChange(user, serviceId, auditAction, comment);
206 if (validateService.isRight()) {
207 return Either.right(validateService.right().value());
209 Service service = validateService.left().value();
210 Either<User, ResponseFormat> validateUser = validateUserDistributionChange(user, service, auditAction, comment);
211 if (validateUser.isRight()) {
212 return Either.right(validateUser.right().value());
214 user = validateUser.left().value();
218 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "ChangeServiceDistributionState");
219 if (lockResult.isRight()) {
220 ResponseFormat responseFormat = lockResult.right().value();
221 createAudit(user, auditAction, comment, service, responseFormat);
222 return Either.right(responseFormat);
227 DistributionStatusEnum newState;
228 if (distributionTransition == DistributionTransitionEnum.APPROVE) {
229 newState = DistributionStatusEnum.DISTRIBUTION_APPROVED;
231 newState = DistributionStatusEnum.DISTRIBUTION_REJECTED;
233 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, newState);
234 if (result.isRight()) {
236 BeEcompErrorManager.getInstance().logBeSystemError("ChangeServiceDistributionState");
237 log.debug("service {} is change destribuation status failed", service.getUniqueId());
238 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, service.getVersion(), service.getName());
239 createAudit(user, auditAction, comment, service, responseFormat);
240 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
243 Service updatedService = result.left().value();
244 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
245 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
246 componentsUtils.auditComponent(responseFormat, user, updatedService, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()), ResourceVersionInfo.newBuilder().build(), comment);
247 return Either.left(result.left().value());
249 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
254 public Either<List<Map<String, Object>>, ResponseFormat> getComponentAuditRecords(String componentVersion, String componentUUID, String userId) {
255 validateUserExists(userId, "get Component Audit Records", false);
256 Either<List<Map<String, Object>>, ActionStatus> result;
260 if (componentVersion.endsWith(".0")) {
261 Either<List<ResourceAdminEvent>, ActionStatus> eitherAuditingForCertified = auditCassandraDao.getByServiceInstanceId(componentUUID);
262 if (eitherAuditingForCertified.isLeft()) {
263 result = Either.left(getAuditingFieldsList(eitherAuditingForCertified.left().value()));
265 result = Either.right(eitherAuditingForCertified.right().value());
268 // Uncertified Version
270 result = getAuditRecordsForUncertifiedComponent(componentUUID, componentVersion);
272 } catch (Exception e) {
273 log.debug("get Audit Records failed with exception {}", e);
274 result = Either.right(ActionStatus.GENERAL_ERROR);
277 if (result.isRight()) {
278 return Either.right(componentsUtils.getResponseFormat(result.right().value()));
280 return Either.left(result.left().value());
285 public Either<List<Operation>, ResponseFormat> addServiceConsumptionData(String serviceId,
286 String serviceInstanceId,
288 List<ServiceConsumptionData> serviceConsumptionDataList,
290 List<Operation> operationList = new ArrayList<>();
292 Either<Service, StorageOperationStatus> serviceEither =
293 toscaOperationFacade.getToscaElement(serviceId);
294 if(serviceEither.isRight()) {
295 return Either.right(componentsUtils.getResponseFormat
296 (serviceEither.right().value()));
299 Service service = serviceEither.left().value();
302 StorageOperationStatus storageOperationStatus =
303 graphLockOperation.lockComponent(service.getUniqueId(), NodeTypeEnum.Service);
304 if (storageOperationStatus != StorageOperationStatus.OK) {
305 return Either.right(componentsUtils.getResponseFormat(storageOperationStatus));
309 for (ServiceConsumptionData serviceConsumptionData : serviceConsumptionDataList) {
310 Either<Operation, ResponseFormat> operationEither =
311 addPropertyServiceConsumption(serviceId, serviceInstanceId, operationId,
312 userId, serviceConsumptionData);
314 if (operationEither.isRight()) {
315 return Either.right(operationEither.right().value());
318 operationList.add(operationEither.left().value());
322 return Either.left(operationList);
323 } catch (Exception e) {
325 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
328 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
333 public Either <Operation, ResponseFormat> addPropertyServiceConsumption(String serviceId,
334 String serviceInstanceId,
337 ServiceConsumptionData serviceConsumptionData) {
338 validateUserExists(userId, "create Property", false);
340 Either<Service, StorageOperationStatus> serviceEither =
341 toscaOperationFacade.getToscaElement(serviceId);
342 if(serviceEither.isRight()) {
343 return Either.right(componentsUtils.getResponseFormat(serviceEither.right
347 Service parentService = serviceEither.left().value();
349 List<ComponentInstance> componentInstances = parentService.getComponentInstances();
350 if(CollectionUtils.isEmpty(componentInstances)) {
351 return Either.right(componentsUtils.getResponseFormat(ActionStatus
352 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
355 Optional<ComponentInstance> serviceInstanceCandidate =
356 componentInstances.stream().filter(instance -> instance.getUniqueId().equals
357 (serviceInstanceId)).findAny();
359 if(!serviceInstanceCandidate.isPresent()) {
360 return Either.right(componentsUtils.getResponseFormat(ActionStatus
361 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
364 Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaces =
365 parentService.getComponentInstancesInterfaces();
366 if(MapUtils.isEmpty(componentInstancesInterfaces)) {
367 return Either.right(componentsUtils.getResponseFormat(ActionStatus
368 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
371 List<InterfaceDefinition> interfaces = new ArrayList<>();
372 for(ComponentInstanceInterface componentInstanceInterface :
373 componentInstancesInterfaces.get(serviceInstanceId)) {
374 interfaces.add(componentInstanceInterface);
377 ComponentInstance serviceInstance = serviceInstanceCandidate.get();
378 Optional<InterfaceDefinition> interfaceCandidate = InterfaceOperationUtils
379 .getInterfaceDefinitionFromOperationId(interfaces, operationId);
381 if(!interfaceCandidate.isPresent()) {
382 return Either.right(componentsUtils.getResponseFormat(ActionStatus
383 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
386 InterfaceDefinition interfaceDefinition = interfaceCandidate.get();
387 Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
388 if(MapUtils.isEmpty(operations)) {
389 return Either.right(componentsUtils.getResponseFormat(ActionStatus
390 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
393 Operation operation = operations.get(operationId);
394 Either<Operation, ResponseFormat> operationEither = Either.left(operation);
396 ListDataDefinition<OperationInputDefinition> inputs = operation.getInputs();
397 Optional<OperationInputDefinition> inputCandidate =
398 getOperationInputByInputId(serviceConsumptionData, inputs);
400 if(!inputCandidate.isPresent()) {
401 return Either.right(new ResponseFormat(HttpStatus.NOT_FOUND.value()));
404 OperationInputDefinition operationInputDefinition = inputCandidate.get();
405 // add data to operation
407 if(Objects.nonNull(serviceConsumptionData.getValue())) {
409 handleConsumptionValue(parentService, serviceInstanceId, serviceConsumptionData, operation,
410 operationInputDefinition);
413 if(operationEither.isRight()) {
414 return Either.right(operationEither.right().value());
417 Operation updatedOperation = operationEither.left().value();
418 operations.remove(operationId);
419 operations.put(operationId, updatedOperation);
420 interfaceDefinition.setOperationsMap(operations);
422 parentService.getComponentInstances().remove(serviceInstance);
423 if(CollectionUtils.isEmpty(parentService.getComponentInstances())) {
424 parentService.setComponentInstances(new ArrayList<>());
427 Map<String, Object> instanceInterfaces =
428 MapUtils.isEmpty(serviceInstance.getInterfaces())? new HashMap<>() : serviceInstance.getInterfaces();
429 instanceInterfaces.remove(interfaceDefinition.getUniqueId());
430 instanceInterfaces.put(interfaceDefinition.getUniqueId(), interfaceDefinition);
431 serviceInstance.setInterfaces(instanceInterfaces);
433 removeComponentInstanceInterfaceByInterfaceId(interfaceDefinition.getUniqueId(), componentInstancesInterfaces.get(serviceInstanceId));
434 componentInstancesInterfaces.get(serviceInstanceId).add(new ComponentInstanceInterface(interfaceDefinition.getUniqueId(), interfaceDefinition));
436 parentService.getComponentInstances().add(serviceInstance);
438 StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(parentService, serviceInstanceId);
440 if(status != StorageOperationStatus.OK) {
441 return Either.right(componentsUtils.getResponseFormat(ActionStatus
442 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
445 return Either.left(operation);
448 private void removeComponentInstanceInterfaceByInterfaceId(String interfaceIdToRemove,
449 List<ComponentInstanceInterface> instanceInterfaces) {
450 if(CollectionUtils.isEmpty(instanceInterfaces)) {
454 Optional<ComponentInstanceInterface> interfaceToRemove =
455 instanceInterfaces.stream().filter(instInterface -> instInterface.getUniqueId().equals
456 (interfaceIdToRemove)).findAny();
458 if(interfaceToRemove.isPresent()) {
459 instanceInterfaces.remove(interfaceToRemove.get());
464 private Either<Operation, ResponseFormat> handleConsumptionValue(Service containerService,
465 String serviceInstanceId,
466 ServiceConsumptionData serviceConsumptionData,
468 OperationInputDefinition
469 operationInputDefinition) {
470 String source = serviceConsumptionData.getSource();
471 String consumptionValue = serviceConsumptionData.getValue();
472 String type = serviceConsumptionData.getType();
473 String operationIdentifier = consumptionValue.contains(".")
474 ? consumptionValue.substring(0, consumptionValue.lastIndexOf('.'))
477 ServiceConsumptionSource sourceValue = ServiceConsumptionSource.getSourceValue(source);
479 if(STATIC.equals(sourceValue)) {
480 // Validate constraint on input value
481 Either<Boolean, ResponseFormat> constraintValidationResult =
482 validateOperationInputConstraint(operationInputDefinition, consumptionValue, type);
484 if (constraintValidationResult.isRight()) {
485 return Either.right(constraintValidationResult.right().value());
487 return handleConsumptionStaticValue(consumptionValue, type, operation,
488 operationInputDefinition);
491 if (Objects.isNull(sourceValue)) {
492 List<PropertyDefinition> propertyDefinitions;
493 Map<String, List<CapabilityDefinition>> capabilities = null;
494 String componentName;
495 List<OperationOutputDefinition> outputs = null;
496 if (source.equals(containerService.getUniqueId())) {
497 Either<Service, StorageOperationStatus> serviceToTakePropEither =
498 toscaOperationFacade.getToscaElement(source);
499 if (serviceToTakePropEither.isRight()) {
500 return Either.right(componentsUtils.getResponseFormat(serviceToTakePropEither.right().value()));
502 Service service = serviceToTakePropEither.left().value();
503 operationInputDefinition.setSource(service.getUniqueId());
504 sourceValue = SERVICE_INPUT;
505 propertyDefinitions = service.getProperties();
506 componentName = service.getName();
507 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier,
508 service.getInterfaces()).getListToscaDataDefinition();
510 Optional<ComponentInstance> getComponentInstance = containerService.getComponentInstanceById(source);
511 if(!getComponentInstance.isPresent()){
512 return Either.right(componentsUtils.getResponseFormat(
513 ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, source));
515 ComponentInstance componentInstance = getComponentInstance.get();
516 operationInputDefinition.setSource(componentInstance.getUniqueId());
517 propertyDefinitions = componentInstance.getProperties();
518 capabilities = componentInstance.getCapabilities();
519 componentName = source.equals(serviceInstanceId) ? SELF : componentInstance.getName();
520 if (MapUtils.isNotEmpty(componentInstance.getInterfaces())) {
521 Map<String, InterfaceDataDefinition> componentInstanceInterfaces =
522 componentInstance.getInterfaces().entrySet().stream()
523 .collect(Collectors.toMap((Map.Entry::getKey),
524 (interfaceEntry -> (InterfaceDataDefinition) interfaceEntry.getValue())));
525 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier,
526 componentInstanceInterfaces).getListToscaDataDefinition();
530 if(sourceValue == ServiceConsumptionSource.SERVICE_INPUT) {
531 //The operation input in service consumption has been mapped to an input in the parent service
532 return handleConsumptionInputValue(consumptionValue, containerService, operation,
533 operationInputDefinition);
535 return handleConsumptionPropertyValue(operation, operationInputDefinition,
536 serviceConsumptionData, propertyDefinitions, capabilities, outputs, componentName);
539 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.SOURCE, source);
540 operationInputDefinition.setSource(source);
542 return Either.left(operation);
545 private Optional<OperationInputDefinition> getOperationInputByInputId(ServiceConsumptionData serviceConsumptionData,
546 ListDataDefinition<OperationInputDefinition> inputs) {
548 if(CollectionUtils.isEmpty(inputs.getListToscaDataDefinition())) {
549 return Optional.empty();
552 return inputs.getListToscaDataDefinition().stream().filter(operationInput -> operationInput.getInputId().equals
553 (serviceConsumptionData.getInputId()))
557 private Either<Operation, ResponseFormat> handleConsumptionPropertyValue(
558 Operation operation, OperationInputDefinition operationInputDefinition,
559 ServiceConsumptionData serviceConsumptionData, List<PropertyDefinition> properties,Map<String,
560 List<CapabilityDefinition>> capabilities,
561 List<OperationOutputDefinition> outputs, String componentName) {
563 if (CollectionUtils.isEmpty(properties) && CollectionUtils.isEmpty(outputs)) {
564 return Either.left(operation);
566 String consumptionValue = serviceConsumptionData.getValue();
568 if (CollectionUtils.isNotEmpty(outputs)
569 && isOperationInputMappedToOtherOperationOutput(getOperationOutputName(consumptionValue), outputs)) {
570 return handleConsumptionInputMappedToOperationOutput(operation, operationInputDefinition, outputs,
571 consumptionValue, componentName);
574 if (CollectionUtils.isNotEmpty(properties) && PropertiesUtils.isNodeProperty(consumptionValue, properties)) {
575 return handleConsumptionInputMappedToProperty(operation, operationInputDefinition, serviceConsumptionData,
576 properties, componentName);
579 if (MapUtils.isNotEmpty(capabilities)) {
580 return handleConsumptionInputMappedToCapabilityProperty(operation, operationInputDefinition,
581 serviceConsumptionData, capabilities, componentName);
584 return Either.left(operation);
587 private Either<Operation, ResponseFormat> handleConsumptionInputMappedToProperty(Operation operation,
588 OperationInputDefinition operationInputDefinition, ServiceConsumptionData serviceConsumptionData,
589 List<PropertyDefinition> properties, String componentName) {
590 Optional<PropertyDefinition> servicePropertyCandidate =
591 properties.stream().filter(property -> property.getName()
592 .equals(serviceConsumptionData.getValue())).findAny();
594 if (servicePropertyCandidate.isPresent()) {
595 boolean isInputTypeSimilarToOperation =
596 isAssignedValueFromValidType(operationInputDefinition.getType(),
597 servicePropertyCandidate.get());
599 if (!isInputTypeSimilarToOperation) {
600 return Either.right(componentsUtils.getResponseFormat(
601 ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
604 addPropertyToInputValue(componentName, operation, operationInputDefinition,
605 servicePropertyCandidate.get());
607 return Either.left(operation);
610 private Either<Operation, ResponseFormat> handleConsumptionInputMappedToOperationOutput(Operation operation,
611 OperationInputDefinition operationInputDefinition, List<OperationOutputDefinition> outputs,
612 String consumptionValue, String componentName) {
613 String outputName = getOperationOutputName(consumptionValue);
614 Optional<OperationOutputDefinition> servicePropertyOutputCandidate = outputs.stream()
615 .filter(output -> output.getName().equals(outputName)).findAny();
616 if (servicePropertyOutputCandidate.isPresent()) {
617 boolean isInputTypeSimilarToOperation =
618 isAssignedValueFromValidType(operationInputDefinition.getType(),
619 servicePropertyOutputCandidate.get());
620 if (!isInputTypeSimilarToOperation) {
621 return Either.right(componentsUtils.getResponseFormat(
622 ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
624 addOutputToInputValue(componentName, consumptionValue, operation, operationInputDefinition);
626 return Either.left(operation);
629 private void addPropertyToInputValue(String componentName, Operation operation,
630 OperationInputDefinition operationInputDefinition,
631 PropertyDefinition serviceProperty) {
632 Map<String, List<String>> getProperty = new HashMap<>();
633 List<String> getPropertyValues = new ArrayList<>();
634 getPropertyValues.add(componentName);
635 getPropertyValues.add(serviceProperty.getName());
636 getProperty.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), getPropertyValues);
638 operationInputDefinition.setSourceProperty(serviceProperty.getUniqueId());
639 operation.getInputs().delete(operationInputDefinition);
640 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_PROPERTY,
642 operationInputDefinition.setValue((new Gson()).toJson(getProperty));
643 operation.getInputs().add(operationInputDefinition);
646 private void addOutputToInputValue(String componentName, String consumptionValue,
647 Operation operation, OperationInputDefinition operationInputDefinition) {
648 Map<String, List<String>> getOperationOutput =
649 InterfaceOperationUtils.createMappedOutputDefaultValue(componentName, consumptionValue);
650 operation.getInputs().delete(operationInputDefinition);
651 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_OPERATION_OUTPUT,
653 operationInputDefinition.setValue((new Gson()).toJson(getOperationOutput));
654 operation.getInputs().add(operationInputDefinition);
657 public Either<Operation, ResponseFormat> handleConsumptionStaticValue(String value, String type,
659 OperationInputDefinition
660 operationInputDefinition) {
661 boolean isInputTypeSimilarToOperation =
662 isAssignedValueFromValidType(type, value);
664 if(!isInputTypeSimilarToOperation) {
665 return Either.right(componentsUtils.getResponseFormat(
666 ActionStatus.INVALID_CONSUMPTION_TYPE, type));
669 //Validate Constraint and Value
670 Either<Boolean, ResponseFormat> constraintValidationResponse =
671 validateOperationInputConstraint(operationInputDefinition, value, type);
672 if(constraintValidationResponse.isRight()) {
673 return Either.right(constraintValidationResponse.right().value());
676 addStaticValueToInputOperation(value, operation, operationInputDefinition);
678 return Either.left(operation);
681 private Either<Boolean, ResponseFormat> validateOperationInputConstraint(
682 OperationInputDefinition operationInputDefinition, String value, String type) {
684 if (Objects.nonNull(operationInputDefinition.getParentPropertyType())
685 && !operationInputDefinition.getParentPropertyType().equals(operationInputDefinition.getType())) {
686 InputDefinition inputDefinition = new InputDefinition();
687 inputDefinition.setDefaultValue(value);
688 inputDefinition.setInputPath(operationInputDefinition.getSubPropertyInputPath());
689 inputDefinition.setName(operationInputDefinition.getName());
690 inputDefinition.setType(type);
692 ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
693 propertyDefinition.setType(operationInputDefinition.getParentPropertyType());
694 if (operationInputDefinition.getParentPropertyType() != null) {
695 inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
698 return PropertyValueConstraintValidationUtil.getInstance()
699 .validatePropertyConstraints(Collections.singletonList(inputDefinition), applicationDataTypeCache);
701 PropertyDefinition propertyDefinition = new PropertyDefinition();
702 propertyDefinition.setType(operationInputDefinition.getType());
703 propertyDefinition.setValue(value);
704 propertyDefinition.setName(operationInputDefinition.getName());
706 return PropertyValueConstraintValidationUtil.getInstance()
707 .validatePropertyConstraints(Collections.singletonList(propertyDefinition), applicationDataTypeCache);
711 private void addStaticValueToInputOperation(String value, Operation operation,
712 OperationInputDefinition operationInputDefinition) {
713 operation.getInputs().delete(operationInputDefinition);
714 operationInputDefinition.setSource(STATIC.getSource());
715 operationInputDefinition.setSourceProperty(null);
716 operationInputDefinition.setValue(value);
717 operation.getInputs().add(operationInputDefinition);
720 private Either<Operation, ResponseFormat> handleConsumptionInputValue(String inputId,
723 OperationInputDefinition
724 operationInputDefinition) {
725 List<InputDefinition> serviceInputs = service.getInputs();
726 Optional<InputDefinition> inputForValue =
727 serviceInputs.stream().filter(input -> input.getUniqueId().contains(inputId)).findAny();
729 if(inputForValue.isPresent()) {
730 boolean isInputTypeSimilarToOperation =
731 isAssignedValueFromValidType(operationInputDefinition.getType(), inputForValue.get());
733 if(!isInputTypeSimilarToOperation) {
734 return Either.right(componentsUtils.getResponseFormat(
735 ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
737 addGetInputValueToOperationInput(operation, operationInputDefinition, inputForValue.get());
740 return Either.left(operation);
743 private void addGetInputValueToOperationInput(Operation operation,
744 OperationInputDefinition operationInputDefinition,
745 InputDefinition inputForValue) {
746 operation.getInputs().delete(operationInputDefinition);
747 Map<String, String> getInputMap = new HashMap<>();
748 getInputMap.put(ToscaFunctions.GET_INPUT.getFunctionName(), inputForValue.getName());
749 operationInputDefinition.setSourceProperty(inputForValue.getUniqueId());
750 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_INPUT, getInputMap);
751 operationInputDefinition.setValue(new Gson().toJson(getInputMap));
752 operation.getInputs().add(operationInputDefinition);
755 private Either<List<Map<String, Object>>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) {
757 Either<List<ResourceAdminEvent>, ActionStatus> eitherprevVerAudit = auditCassandraDao.getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion);
759 if (eitherprevVerAudit.isRight()) {
760 return Either.right(eitherprevVerAudit.right().value());
764 Either<List<ResourceAdminEvent>, ActionStatus> eitherCurrVerAudit = auditCassandraDao.getAuditByServiceIdAndCurrVersion(componentUUID, componentVersion);
765 if (eitherCurrVerAudit.isRight()) {
766 return Either.right(eitherCurrVerAudit.right().value());
770 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveRestoreList = getArchiveRestoreEventList(componentUUID);
771 if (eitherArchiveRestoreList.isRight()) {
772 return Either.right(eitherArchiveRestoreList.right().value());
775 List<Map<String, Object>> prevVerAuditList = getAuditingFieldsList(eitherprevVerAudit.left().value());
776 List<Map<String, Object>> currVerAuditList = getAuditingFieldsList(eitherCurrVerAudit.left().value());
778 List<Map<String, Object>> duplicateElements = new ArrayList<>();
779 duplicateElements.addAll(prevVerAuditList);
780 duplicateElements.retainAll(currVerAuditList);
782 List<Map<String, Object>> joinedNonDuplicatedList = new ArrayList<>();
783 joinedNonDuplicatedList.addAll(prevVerAuditList);
784 joinedNonDuplicatedList.removeAll(duplicateElements);
785 joinedNonDuplicatedList.addAll(currVerAuditList);
786 joinedNonDuplicatedList.addAll(getAuditingFieldsList(eitherArchiveRestoreList.left().value()));
789 return Either.left(joinedNonDuplicatedList);
792 private Either<List<ResourceAdminEvent>, ActionStatus> getArchiveRestoreEventList(String componentUUID) {
794 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveAudit = auditCassandraDao.getArchiveAuditByServiceInstanceId(componentUUID);
795 if (eitherArchiveAudit.isRight()) {
796 return Either.right(eitherArchiveAudit.right().value());
800 Either<List<ResourceAdminEvent>, ActionStatus> eitherRestoreAudit = auditCassandraDao.getRestoreAuditByServiceInstanceId(componentUUID);
801 if (eitherRestoreAudit.isRight()) {
802 return Either.right(eitherRestoreAudit.right().value());
805 List<ResourceAdminEvent> archiveAudit = new ArrayList<>();
806 archiveAudit.addAll(eitherArchiveAudit.left().value());
807 archiveAudit.addAll(eitherRestoreAudit.left().value());
809 return Either.left(archiveAudit);
812 private List<Map<String, Object>> getAuditingFieldsList(List<? extends AuditingGenericEvent> prevVerAuditList) {
814 List<Map<String, Object>> prevVerAudit = new ArrayList<>();
815 for (AuditingGenericEvent auditEvent : prevVerAuditList) {
816 auditEvent.fillFields();
817 prevVerAudit.add(auditEvent.getFields());
828 * - modifier data (userId)
829 * @return Either<Service, responseFormat>
831 public Either<Service, ResponseFormat> createService(Service service, User user) {
834 user = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false);
835 // validate user role
836 validateUserRole(user, service, new ArrayList<>(), AuditingActionEnum.CREATE_RESOURCE, null);
837 service.setCreatorUserId(user.getUserId());
838 // warn on overridden fields
839 checkFieldsForOverideAttampt(service);
841 log.debug("enrich service with version and state");
842 service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
843 service.setVersion(INITIAL_VERSION);
844 service.setConformanceLevel(ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
845 service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED);
847 Either<Service, ResponseFormat> createServiceResponse = validateServiceBeforeCreate(service, user, AuditingActionEnum.CREATE_RESOURCE);
848 if (createServiceResponse.isRight()) {
849 return createServiceResponse;
851 return createServiceByDao(service, AuditingActionEnum.CREATE_RESOURCE, user);
854 private void checkFieldsForOverideAttampt(Service service) {
855 checkComponentFieldsForOverrideAttempt(service);
856 if (service.getDistributionStatus() != null) {
857 log.info("Distribution Status cannot be defined by user. This field will be overridden by the application");
861 private Either<Service, ResponseFormat> createServiceByDao(Service service, AuditingActionEnum actionEnum, User user) {
862 log.debug("send service {} to dao for create", service.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
864 Either<Boolean, ResponseFormat> lockResult = lockComponentByName(service.getSystemName(), service, "Create Service");
865 if (lockResult.isRight()) {
866 ResponseFormat responseFormat = lockResult.right().value();
867 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
868 return Either.right(responseFormat);
871 log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult);
875 createMandatoryArtifactsData(service, user);
876 createServiceApiArtifactsData(service, user);
877 setToscaArtifactsPlaceHolders(service, user);
878 generateAndAddInputsFromGenericTypeProperties(service, fetchAndSetDerivedFromGenericType(service));
880 Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
882 // service created successfully!!!
883 if (dataModelResponse.isLeft()) {
884 log.debug("Service created successfully!!!");
885 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
886 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
887 ASDCKpiApi.countCreatedServicesKPI();
888 return Either.left(dataModelResponse.left().value());
891 ResponseFormat responseFormat = componentsUtils.getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service, ComponentTypeEnum.SERVICE);
892 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
893 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
894 return Either.right(responseFormat);
897 graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service);
901 @SuppressWarnings("unchecked")
902 private void createServiceApiArtifactsData(Service service, User user) {
903 // create mandatory artifacts
905 // TODO it must be removed after that artifact uniqueId creation will be
906 // moved to ArtifactOperation
907 String serviceUniqueId = service.getUniqueId();
908 Map<String, ArtifactDefinition> artifactMap = service.getServiceApiArtifacts();
909 if (artifactMap == null)
910 artifactMap = new HashMap<>();
912 Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts();
913 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
915 List<CategoryDefinition> categories = service.getCategories();
916 boolean isCreateArtifact = true;
917 if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
918 for (String exlude : exludeServiceCategory) {
919 if (exlude.equalsIgnoreCase(categories.get(0).getName())) {
920 isCreateArtifact = false;
927 if (serviceApiArtifacts != null && isCreateArtifact) {
928 Set<String> keys = serviceApiArtifacts.keySet();
929 for (String serviceApiArtifactName : keys) {
930 Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName);
931 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user, true);
932 artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API);
933 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
936 service.setServiceApiArtifacts(artifactMap);
940 private Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) {
942 Either<Boolean, ResponseFormat> validationResponse = validateServiceFieldsBeforeCreate(user, service, actionEnum);
943 if (validationResponse.isRight()) {
944 return Either.right(validationResponse.right().value());
946 service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
947 service.setContactId(service.getContactId().toLowerCase());
949 // Generate invariant UUID - must be here and not in operation since it
950 // should stay constant during clone
951 String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
952 service.setInvariantUUID(invariantUUID);
954 return Either.left(service);
959 private Either<Boolean, ResponseFormat> validateServiceFieldsBeforeCreate(User user, Service service, AuditingActionEnum actionEnum) {
961 validateComponentFieldsBeforeCreate(user, service, actionEnum);
963 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, service, actionEnum);
964 if (serviceNameUniquenessValidation.isRight()) {
965 throw new ComponentException(serviceNameUniquenessValidation.right().value());
967 Either<Boolean, ResponseFormat> categoryValidation = validateServiceCategory(user, service, actionEnum);
968 if (categoryValidation.isRight()) {
969 return categoryValidation;
971 Either<Boolean, ResponseFormat> projectCodeValidation = validateProjectCode(user, service, actionEnum);
972 if (projectCodeValidation.isRight()) {
973 return projectCodeValidation;
975 validateServiceTypeAndCleanup(service);
977 Either<Boolean, ResponseFormat> serviceRoleValidation = validateServiceRoleAndCleanup(user, service, actionEnum);
978 if (serviceRoleValidation.isRight()) {
979 return serviceRoleValidation;
981 return validateInstantiationTypeValue(user, service, actionEnum);
982 } catch (ComponentException exception) {
983 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
984 componentsUtils.auditComponentAdmin(responseFormat, user, service,
985 AuditingActionEnum.CREATE_SERVICE, ComponentTypeEnum.SERVICE);
986 return Either.right(responseFormat);
990 private Either<Boolean, ResponseFormat> validateServiceCategory(User user, Service service, AuditingActionEnum actionEnum) {
991 log.debug("validate Service category");
992 if (isEmpty(service.getCategories())) {
993 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
994 componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
995 return Either.right(errorResponse);
997 Either<Boolean, ResponseFormat> validatCategory = validateServiceCategory(service.getCategories());
998 if (validatCategory.isRight()) {
999 ResponseFormat responseFormat = validatCategory.right().value();
1000 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
1001 return Either.right(responseFormat);
1003 return Either.left(true);
1006 public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) {
1007 validateUserExists(userId, "validate Service Name Exists", false);
1009 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateComponentNameUniqueness(serviceName, null, ComponentTypeEnum.SERVICE);
1013 if (dataModelResponse.isLeft()) {
1014 Map<String, Boolean> result = new HashMap<>();
1015 result.put("isValid", dataModelResponse.left().value());
1016 log.debug("validation was successfully performed.");
1017 return Either.left(result);
1019 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
1020 return Either.right(responseFormat);
1023 public void setElementDao(IElementOperation elementDao) {
1024 this.elementDao = elementDao;
1027 public void setCassandraAuditingDao(AuditCassandraDao auditingDao) {
1028 this.auditCassandraDao = auditingDao;
1031 public ArtifactsBusinessLogic getArtifactBl() {
1032 return artifactsBusinessLogic;
1035 public void setArtifactBl(ArtifactsBusinessLogic artifactBl) {
1036 this.artifactsBusinessLogic = artifactBl;
1039 public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) {
1040 user = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false);
1041 // validate user role
1042 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1044 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1045 if (storageStatus.isRight()) {
1046 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1049 Service currentService = storageStatus.left().value();
1051 if (!ComponentValidationUtils.canWorkOnComponent(currentService, user.getUserId())) {
1052 log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
1053 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
1056 Either<Service, ResponseFormat> validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate);
1057 if (validationRsponse.isRight()) {
1058 log.info("service update metadata: validations field.");
1059 return validationRsponse;
1061 Service serviceToUpdate = validationRsponse.left().value();
1064 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, currentService, "Update Service Metadata");
1065 if (lockResult.isRight()) {
1066 return Either.right(lockResult.right().value());
1069 Either<Service, StorageOperationStatus> updateResponse = toscaOperationFacade.updateToscaElement(serviceToUpdate);
1070 if (updateResponse.isRight()) {
1071 titanDao.rollback();
1072 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
1073 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
1074 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1077 return Either.left(updateResponse.left().value());
1079 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1083 public Either<Set<String>, ResponseFormat> deleteForwardingPaths(String serviceId, Set<String> pathIdsToDelete, User user, boolean lock) {
1084 Service serviceToDelete = initServiceToDeletePaths(serviceId, pathIdsToDelete);
1085 user = validateUser(user, "deleteForwardingPaths", serviceToDelete, null, false);
1086 // validate user role
1087 validateUserRole(user, serviceToDelete, new ArrayList<>(), null, null);
1088 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1089 if (storageStatus.isRight()) {
1090 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1092 Service service = storageStatus.left().value();
1093 Either<Set<String>, StorageOperationStatus> result = null;
1095 Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Forwarding Path on Service");
1096 if (lockResult.isRight()) {
1097 titanDao.rollback();
1098 return Either.right(componentsUtils.getResponseFormat(componentsUtils
1099 .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1103 result = forwardingPathOperation.deleteForwardingPath(service ,pathIdsToDelete);
1104 if (result.isRight()) {
1105 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, service.getName(), result.right().value());
1106 titanDao.rollback();
1107 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
1110 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, service.getSystemName());
1112 } catch (Exception e){
1113 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
1114 titanDao.rollback();
1115 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1117 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1119 return Either.left(result.left().value());
1122 private Service initServiceToDeletePaths(String serviceId, Collection<String> pathIdsToDelete) {
1123 Service serviceToDelete = new Service();
1124 serviceToDelete.setUniqueId(serviceId);
1125 serviceToDelete.setForwardingPaths(new HashMap<>());
1126 pathIdsToDelete.forEach(pathIdToDelete -> serviceToDelete.getForwardingPaths().put(pathIdToDelete, new ForwardingPathDataDefinition()));
1127 return serviceToDelete;
1130 public Either<Service, ResponseFormat> updateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
1131 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, true,"updateForwardingPath", lock);
1134 public Either<Service, ResponseFormat> createForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
1135 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, false, "createForwardingPath", lock);
1138 private ForwardingPathDataDefinition getTrimmedValues(ForwardingPathDataDefinition path){
1139 ForwardingPathDataDefinition dataDefinition = new ForwardingPathDataDefinition(path.getName());
1140 dataDefinition.setName(Strings.nullToEmpty(path.getName()).trim());
1141 dataDefinition.setProtocol(Strings.nullToEmpty(path.getProtocol()).trim());
1142 dataDefinition.setDestinationPortNumber(Strings.nullToEmpty(path.getDestinationPortNumber()).trim());
1143 dataDefinition.setUniqueId(path.getUniqueId());
1144 dataDefinition.setPathElements(path.getPathElements());
1145 dataDefinition.setDescription(path.getDescription());
1146 dataDefinition.setToscaResourceName(path.getToscaResourceName());
1147 return dataDefinition;
1150 private Either<Service, ResponseFormat> createOrUpdateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean isUpdate, String errorContext, boolean lock) {
1151 validateUserAndRole(serviceUpdate, user, errorContext);
1153 Map<String, ForwardingPathDataDefinition> forwardingPaths = serviceUpdate.getForwardingPaths();
1155 Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths =
1156 forwardingPaths.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
1157 entry -> new ForwardingPathDataDefinition(getTrimmedValues(entry.getValue()))));
1159 Either<Boolean, ResponseFormat> booleanResponseFormatEither = forwardingPathValidator.validateForwardingPaths(trimmedForwardingPaths.values(),
1160 serviceId, isUpdate);
1161 if(booleanResponseFormatEither.isRight()){
1162 return Either.right(booleanResponseFormatEither.right().value());
1165 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
1167 if(serviceStorageOperationStatusEither.isRight()){
1168 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
1169 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
1170 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
1172 Service storedService = serviceStorageOperationStatusEither.left().value();
1174 Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
1175 Either<Component, StorageOperationStatus> forwardingPathOrigin = toscaOperationFacade.getLatestByName(ForwardingPathUtils.FORWARDING_PATH_NODE_NAME);
1176 if (forwardingPathOrigin.isRight()) {
1177 StorageOperationStatus errorStatus = forwardingPathOrigin.right().value();
1178 log.debug("Failed to fetch normative forwarding path resource by tosca name, error {}", errorStatus);
1179 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
1181 Component component = forwardingPathOrigin.left().value();
1182 final String toscaResourceName;
1183 if ( component.getComponentType() == ComponentTypeEnum.RESOURCE) {
1184 toscaResourceName = ((Resource) component).getToscaResourceName();
1186 toscaResourceName = "";
1188 Either<Boolean, ResponseFormat> lockResult = null;
1191 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Forwarding Path on Service");
1192 if (lockResult.isRight()) {
1193 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, storedService.getName(),
1194 lockResult.right().value().getFormattedMessage());
1195 return Either.right(lockResult.right().value());
1197 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, storedService.getSystemName());
1200 Map<String, ForwardingPathDataDefinition> resultMap = new HashMap<>();
1202 trimmedForwardingPaths.values().forEach(fp -> fp.setToscaResourceName(toscaResourceName));
1205 for (ForwardingPathDataDefinition forwardingPathDataDefinition : trimmedForwardingPaths.values()) {
1207 result = forwardingPathOperation.updateForwardingPath(serviceId, forwardingPathDataDefinition);
1209 result = forwardingPathOperation.addForwardingPath(serviceId, forwardingPathDataDefinition);
1211 if (result.isRight()) {
1212 titanDao.rollback();
1213 return Either.right(componentsUtils.getResponseFormat(
1214 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
1217 ForwardingPathDataDefinition fpDataDefinition = result.left().value();
1218 resultMap.put(fpDataDefinition.getUniqueId(), forwardingPathDataDefinition);
1222 } catch (Exception e) {
1223 titanDao.rollback();
1224 log.error("Exception occurred during add or update forwarding path property values: {}", e.getMessage(),
1226 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1230 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
1231 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
1234 Service service = createServiceWithForwardingPathForResponse(serviceId, resultMap);
1235 return Either.left(service);
1238 private Service createServiceWithForwardingPathForResponse(String serviceId, Map<String,ForwardingPathDataDefinition> forwardingPathDataDefinitionMap) {
1239 Service service = new Service();
1240 service.setUniqueId(serviceId);
1241 service.setForwardingPaths(forwardingPathDataDefinitionMap);
1245 private void validateUserAndRole(Service serviceUpdate, User user, String errorContext) {
1246 user = validateUser(user, errorContext, serviceUpdate, null, false);
1247 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1252 Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) {
1255 boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
1256 Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1257 if (response.isRight()) {
1258 ResponseFormat errorResponse = response.right().value();
1259 return Either.right(errorResponse);
1262 verifyValuesAreIdentical(serviceUpdate.getCreatorUserId(), currentService.getCreatorUserId(), "creatorUserId");
1263 verifyValuesAreIdentical(serviceUpdate.getCreatorFullName(), currentService.getCreatorFullName(), "creatorFullName");
1264 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterUserId(), currentService.getLastUpdaterUserId(), "lastUpdaterUserId");
1265 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterFullName(), currentService.getLastUpdaterFullName(), "lastUpdaterFullName");
1267 response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null);
1268 if (response.isRight()) {
1269 return Either.right(response.right().value());
1272 verifyValuesAreIdentical(serviceUpdate.getDistributionStatus(), currentService.getDistributionStatus(), "distributionStatus");
1274 if (serviceUpdate.getProjectCode() != null) {
1275 response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1276 if (response.isRight()) {
1277 return Either.right(response.right().value());
1281 response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1282 if (response.isRight()) {
1283 return Either.right(response.right().value());
1286 verifyValuesAreIdentical(serviceUpdate.getCreationDate(), currentService.getCreationDate(), "creationDate");
1287 verifyValuesAreIdentical(serviceUpdate.getVersion(), currentService.getVersion(), "version");
1289 response = validateAndUpdateDescription(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1290 if (response.isRight()) {
1291 return Either.right(response.right().value());
1294 response = validateAndUpdateTags(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1295 if (response.isRight()) {
1296 return Either.right(response.right().value());
1299 response = validateAndUpdateContactId(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1300 if (response.isRight()) {
1301 return Either.right(response.right().value());
1304 verifyValuesAreIdentical(serviceUpdate.getLastUpdateDate(), currentService.getLastUpdateDate(), "lastUpdateDate");
1305 verifyValuesAreIdentical(serviceUpdate.getLifecycleState(), currentService.getLifecycleState(), "lifecycleState");
1306 verifyValuesAreIdentical(serviceUpdate.isHighestVersion(), currentService.isHighestVersion(), "isHighestVersion");
1307 verifyValuesAreIdentical(serviceUpdate.getUUID(), currentService.getUUID(), "uuid");
1309 validateAndUpdateServiceType(currentService, serviceUpdate);
1311 response = validateAndUpdateServiceRole(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1312 if (response.isRight()) {
1313 return Either.right(response.right().value());
1316 response = validateAndUpdateInstantiationTypeValue(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1317 if (response.isRight()) {
1318 return Either.right(response.right().value());
1321 verifyValuesAreIdentical(serviceUpdate.getInvariantUUID(), currentService.getInvariantUUID(), "invariantUUID");
1323 validateAndUpdateEcompNaming(currentService, serviceUpdate);
1325 currentService.setEnvironmentContext(serviceUpdate.getEnvironmentContext());
1326 return Either.left(currentService);
1328 } catch (ComponentException exception) {
1329 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
1330 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate,
1331 AuditingActionEnum.UPDATE_SERVICE_METADATA, ComponentTypeEnum.SERVICE);
1332 return Either.right(responseFormat);
1336 private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
1337 if (updatedValue != null && !updatedValue.equals(originalValue)) {
1338 log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
1342 private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
1343 Boolean isEcompGeneratedCurr = currentService.isEcompGeneratedNaming();
1344 Boolean isEcompGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
1345 if (isEcompGeneratedUpdate != null && !isEcompGeneratedUpdate.equals(isEcompGeneratedCurr)) {
1346 currentService.setEcompGeneratedNaming(isEcompGeneratedUpdate);
1348 String namingPolicyUpdate = serviceUpdate.getNamingPolicy();
1349 if (currentService.isEcompGeneratedNaming()) {
1350 currentService.setNamingPolicy(namingPolicyUpdate);
1352 if (!StringUtils.isEmpty(namingPolicyUpdate)) {
1353 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
1355 currentService.setNamingPolicy("");
1359 private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1360 String contactIdUpdated = serviceUpdate.getContactId();
1361 String contactIdCurrent = currentService.getContactId();
1362 if (!contactIdCurrent.equals(contactIdUpdated)) {
1363 validateContactId(user, serviceUpdate, audatingAction);
1364 currentService.setContactId(contactIdUpdated.toLowerCase());
1366 return Either.left(true);
1369 private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1370 List<String> tagsUpdated = serviceUpdate.getTags();
1371 List<String> tagsCurrent = currentService.getTags();
1372 if (tagsUpdated == null || tagsUpdated.isEmpty()) {
1373 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
1374 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
1375 return Either.right(responseFormat);
1378 if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
1379 validateTagsListAndRemoveDuplicates(user, serviceUpdate, audatingAction);
1380 currentService.setTags(tagsUpdated);
1382 return Either.left(true);
1385 private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1386 String descriptionUpdated = serviceUpdate.getDescription();
1387 String descriptionCurrent = currentService.getDescription();
1388 if (!descriptionCurrent.equals(descriptionUpdated)) {
1389 validateDescriptionAndCleanup(user, serviceUpdate, audatingAction);
1390 currentService.setDescription(serviceUpdate.getDescription());
1392 return Either.left(true);
1395 private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1396 String projectCodeUpdated = serviceUpdate.getProjectCode();
1397 String projectCodeCurrent = currentService.getProjectCode();
1398 if (!projectCodeCurrent.equals(projectCodeUpdated)) {
1400 Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, serviceUpdate, audatingAction);
1401 if (validatProjectCodeResponse.isRight()) {
1402 ResponseFormat errorRespons = validatProjectCodeResponse.right().value();
1403 return Either.right(errorRespons);
1405 currentService.setProjectCode(projectCodeUpdated);
1408 return Either.left(true);
1411 private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1412 String iconUpdated = serviceUpdate.getIcon();
1413 String iconCurrent = currentService.getIcon();
1414 if (!iconCurrent.equals(iconUpdated)) {
1415 if (!hasBeenCertified) {
1416 validateIcon(user, serviceUpdate, audatingAction);
1417 currentService.setIcon(iconUpdated);
1419 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
1420 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
1421 return Either.right(errorResponse);
1424 return Either.left(true);
1427 private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum auditingAction) {
1428 String serviceNameUpdated = serviceUpdate.getName();
1429 String serviceNameCurrent = currentService.getName();
1430 if (!serviceNameCurrent.equals(serviceNameUpdated)) {
1431 if (!hasBeenCertified) {
1432 validateComponentName(user, serviceUpdate, auditingAction);
1433 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, serviceUpdate, auditingAction);
1434 if (serviceNameUniquenessValidation.isRight()) {
1435 return serviceNameUniquenessValidation;
1437 currentService.setName(serviceNameUpdated);
1438 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
1439 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
1442 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
1443 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
1444 return Either.right(errorResponse);
1447 return Either.left(true);
1450 private void validateAndUpdateServiceType(Service currentService, Service updatedService) {
1451 String updatedServiceType = updatedService.getServiceType();
1452 String currentServiceType = currentService.getServiceType();
1453 if (!currentServiceType.equals(updatedServiceType)) {
1454 validateServiceTypeAndCleanup(updatedService);
1455 currentService.setServiceType(updatedServiceType);
1459 private void validateServiceTypeAndCleanup(Component component) {
1460 log.debug("validate service type");
1461 String serviceType = ((Service)component).getServiceType();
1462 if (serviceType == null) {
1463 log.info("service type is not valid.");
1464 throw new ComponentException(ActionStatus.INVALID_SERVICE_TYPE);
1466 serviceType = cleanUpText(serviceType);
1467 validateServiceType(serviceType);
1471 private void validateServiceType(String serviceType) {
1472 if (serviceType.isEmpty()) {
1475 if (!ValidationUtils.validateServiceTypeLength(serviceType)) {
1476 log.info("service type exceeds limit.");
1477 throw new ComponentException(ActionStatus.SERVICE_TYPE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_TYPE_MAX_LENGTH);
1479 if (!ValidationUtils.validateIsEnglish(serviceType)) {
1480 log.info("service type is not valid.");
1481 throw new ComponentException(ActionStatus.INVALID_SERVICE_TYPE);
1485 private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1486 String updatedServiceRole = updatedService.getServiceRole();
1487 String currentServiceRole = currentService.getServiceRole();
1488 if (!currentServiceRole.equals(updatedServiceRole)) {
1489 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRoleAndCleanup(user, updatedService , auditingAction);
1490 if (validateServiceRole.isRight()) {
1491 ResponseFormat errorResponse = validateServiceRole.right().value();
1492 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1493 return Either.right(errorResponse);
1495 currentService.setServiceRole(updatedServiceRole);
1497 return Either.left(true);
1500 protected Either<Boolean, ResponseFormat> validateServiceRoleAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
1501 log.debug("validate service role");
1502 String serviceRole = ((Service)component).getServiceRole();
1503 if (serviceRole != null){
1504 serviceRole = cleanUpText(serviceRole);
1506 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRole(serviceRole);
1507 if (validateServiceRole.isRight()) {
1508 ResponseFormat responseFormat = validateServiceRole.right().value();
1509 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, ComponentTypeEnum.SERVICE);
1510 return Either.right(responseFormat);
1512 return Either.left(true);
1514 return Either.left(false);
1518 private Either<Boolean, ResponseFormat> validateAndUpdateInstantiationTypeValue(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1519 String updatedInstaType= updatedService.getInstantiationType();
1520 String currentInstaType = currentService.getInstantiationType();
1521 if (!currentInstaType.equals(updatedInstaType)) {
1522 Either<Boolean, ResponseFormat> validateInstantiationType = validateInstantiationTypeValue(user, updatedService , auditingAction);
1523 if (validateInstantiationType.isRight()) {
1524 ResponseFormat errorResponse = validateInstantiationType.right().value();
1525 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1526 return Either.right(errorResponse);
1528 currentService.setInstantiationType(updatedInstaType);
1530 return Either.left(true);
1533 private Either<Boolean, ResponseFormat> validateInstantiationTypeValue(User user, Service service, AuditingActionEnum actionEnum) {
1534 log.debug("validate instantiation type");
1535 String instantiationType = service.getInstantiationType();
1536 if (!InstantiationTypes.containsName(instantiationType) || instantiationType == null){
1537 log.error("Recieved Instantiation type {} is not valid.", instantiationType);
1538 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_INSTANTIATION_TYPE);
1539 componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
1540 return Either.right(errorResponse);
1542 return Either.left(true);
1545 private Either<Boolean, ResponseFormat> validateServiceRole(String serviceRole) {
1546 if (serviceRole.equals("")){
1547 return Either.left(true);
1549 if (!ValidationUtils.validateServiceRoleLength(serviceRole)) {
1550 log.info("service role exceeds limit.");
1551 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ROLE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_ROLE_MAX_LENGTH);
1552 return Either.right(errorResponse);
1555 if (!ValidationUtils.validateIsEnglish(serviceRole)) {
1556 log.info("service role is not valid.");
1557 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_ROLE);
1558 return Either.right(errorResponse);
1560 return Either.left(true);
1564 private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1565 List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1566 List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1567 Either<Boolean, ResponseFormat> validateCategoryResponse = validateServiceCategory(user, serviceUpdate, audatingAction);
1568 if (validateCategoryResponse.isRight()) {
1569 return Either.right(validateCategoryResponse.right().value());
1571 if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1572 if (!hasBeenCertified) {
1573 currentService.setCategories(categoryUpdated);
1575 log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1576 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1577 return Either.right(errorResponse);
1580 return Either.left(true);
1584 private Either<Boolean, ResponseFormat> validateServiceCategory(List<CategoryDefinition> list) {
1586 if (list.size() > 1) {
1587 log.debug("Must be only one category for service");
1588 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.SERVICE.getValue());
1589 return Either.right(responseFormat);
1591 CategoryDefinition category = list.get(0);
1592 if (category.getSubcategories() != null) {
1593 log.debug("Subcategories cannot be defined for service");
1594 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CANNOT_CONTAIN_SUBCATEGORY);
1595 return Either.right(responseFormat);
1597 if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
1598 log.debug("Resource category is empty");
1599 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
1600 return Either.right(responseFormat);
1603 log.debug("validating service category {} against valid categories list", list);
1604 Either<List<CategoryDefinition>, ActionStatus> categorys = elementDao.getAllServiceCategories();
1605 if (categorys.isRight()) {
1606 log.debug("failed to retrieve service categories from Titan");
1607 ResponseFormat responseFormat = componentsUtils.getResponseFormat(categorys.right().value());
1608 return Either.right(responseFormat);
1610 List<CategoryDefinition> categoryList = categorys.left().value();
1611 for (CategoryDefinition value : categoryList) {
1612 if (value.getName().equals(category.getName())) {
1613 return Either.left(true);
1616 log.debug("Category {} is not part of service category group. Service category valid values are {}", list, categoryList);
1617 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.SERVICE.getValue()));
1619 return Either.left(false);
1622 public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1623 Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1624 if (serviceResponseFormatEither.isRight()){
1625 return Either.right(serviceResponseFormatEither.right().value());
1627 final ServiceRelations serviceRelations = new ForwardingPathUtils().convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1628 return Either.left(serviceRelations);
1633 public ResponseFormat deleteService(String serviceId, User user) {
1634 ResponseFormat responseFormat;
1635 String ecompErrorContext = "delete service";
1637 validateUserExists(user, ecompErrorContext, false);
1638 Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1639 if (serviceStatus.isRight()) {
1640 log.debug("failed to get service {}", serviceId);
1641 return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1644 Service service = serviceStatus.left().value();
1646 StorageOperationStatus result = StorageOperationStatus.OK;
1647 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1648 if (lockResult.isRight()) {
1649 return lockResult.right().value();
1652 result = markComponentToDelete(service);
1653 if (result.equals(StorageOperationStatus.OK)) {
1654 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1656 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1657 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1659 return responseFormat;
1661 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1662 log.warn("operation failed. do rollback");
1663 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1664 titanDao.rollback();
1666 log.debug("operation success. do commit");
1669 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1673 public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1674 ResponseFormat responseFormat;
1675 String ecompErrorContext = "delete service";
1676 validateUserNotEmpty(user, ecompErrorContext);
1677 user = validateUserExists(user, ecompErrorContext, false);
1679 Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1680 if (getResult.isRight()) {
1681 return getResult.right().value();
1683 Service service = getResult.left().value();
1685 StorageOperationStatus result = StorageOperationStatus.OK;
1686 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1687 if (lockResult.isRight()) {
1688 result = StorageOperationStatus.GENERAL_ERROR;
1689 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1693 result = markComponentToDelete(service);
1694 if (result.equals(StorageOperationStatus.OK)) {
1695 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1697 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1698 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1700 return responseFormat;
1703 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1704 log.warn("operation failed. do rollback");
1705 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1706 titanDao.rollback();
1708 log.debug("operation success. do commit");
1711 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1715 public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1716 String ecompErrorContext = "Get service";
1717 validateUserNotEmpty(user, ecompErrorContext);
1718 validateUserExists(user, ecompErrorContext, false);
1720 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1721 if (storageStatus.isRight()) {
1722 log.debug("failed to get service by id {}", serviceId);
1723 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1726 if(!(storageStatus.left().value() instanceof Service)){
1727 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1729 Service service = storageStatus.left().value();
1730 return Either.left(service);
1737 public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1738 validateUserExists(userId, "get Service By Name And Version", false);
1739 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1740 if (storageStatus.isRight()) {
1741 log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1742 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceName));
1744 Service service = storageStatus.left().value();
1745 return Either.left(service);
1748 @SuppressWarnings("unchecked")
1749 private void createMandatoryArtifactsData(Service service, User user) {
1750 // create mandatory artifacts
1752 // TODO it must be removed after that artifact uniqueId creation will be
1753 // moved to ArtifactOperation
1754 String serviceUniqueId = service.getUniqueId();
1755 Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1756 if (artifactMap == null)
1757 artifactMap = new HashMap<>();
1759 Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalServiceArtifacts();
1760 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1762 String category = service.getCategories().get(0).getName();
1763 boolean isCreateArtifact = true;
1764 if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1765 for (String exlude : exludeServiceCategory) {
1766 if (exlude.equalsIgnoreCase(category)) {
1767 isCreateArtifact = false;
1774 if (informationalServiceArtifacts != null && isCreateArtifact) {
1775 Set<String> keys = informationalServiceArtifacts.keySet();
1776 for (String informationalServiceArtifactName : keys) {
1777 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1778 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap, user, false);
1779 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1783 service.setArtifacts(artifactMap);
1787 private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user, Boolean isServiceApi) {
1789 ArtifactDefinition artifactInfo = artifactsBusinessLogic.createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1792 artifactInfo.setMandatory(false);
1793 artifactInfo.setServiceApi(true);
1795 return artifactInfo;
1798 private Either<DistributionTransitionEnum, ResponseFormat> validateTransitionEnum(String distributionTransition) {
1799 DistributionTransitionEnum transitionEnum = null;
1801 transitionEnum = DistributionTransitionEnum.getFromDisplayName(distributionTransition);
1802 if (transitionEnum == null) {
1803 BeEcompErrorManager.getInstance().logBeSystemError(CHANGE_SERVICE_DISTRIBUTION);
1804 log.info("state operation is not valid. operations allowed are: {}", DistributionTransitionEnum.valuesAsString());
1805 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1806 return Either.right(error);
1809 return Either.left(transitionEnum);
1812 private Either<String, ResponseFormat> validateComment(LifecycleChangeInfoWithAction comment) {
1813 String data = comment.getUserRemarks();
1815 if (data == null || data.trim().isEmpty()) {
1816 BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1817 log.debug("user comment cannot be empty or null.");
1818 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1820 data = ValidationUtils.removeNoneUtf8Chars(data);
1821 data = ValidationUtils.removeHtmlTags(data);
1822 data = ValidationUtils.normaliseWhitespace(data);
1823 data = ValidationUtils.stripOctets(data);
1825 if (!ValidationUtils.validateLength(data, ValidationUtils.COMMENT_MAX_LENGTH)) {
1826 BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1827 log.debug("user comment exceeds limit.");
1828 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, "comment", String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH)));
1830 if (!ValidationUtils.validateIsEnglish(data)) {
1831 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1833 return Either.left(data);
1836 private Either<Service, ResponseFormat> validateServiceDistributionChange(User user, String serviceId, AuditingActionEnum auditAction, String comment) {
1837 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1838 if (storageStatus.isRight()) {
1839 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId);
1840 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1841 componentsUtils.auditComponent(responseFormat, user, auditAction, new ResourceCommonInfo(serviceId, ComponentTypeEnum.SERVICE.getValue()), comment);
1842 return Either.right(responseFormat);
1844 Service service = storageStatus.left().value();
1846 if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1847 log.info("service {} is not available for distribution. Should be in certified state", service.getUniqueId());
1848 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1849 createAudit(user, auditAction, comment, service, responseFormat);
1850 return Either.right(responseFormat);
1852 return Either.left(service);
1855 private Either<User, ResponseFormat> validateUserDistributionChange(User user, Service service, AuditingActionEnum auditAction, String comment) {
1856 log.debug("get user from DB");
1859 user = validateUser(user, "Activate Distribution", service, auditAction, false);
1860 // validate user role
1861 List<Role> roles = new ArrayList<>();
1862 roles.add(Role.ADMIN);
1863 roles.add(Role.GOVERNOR);
1864 roles.add(Role.OPS);
1865 validateUserRole(user, service, roles, auditAction, comment);
1866 return Either.left(user);
1869 private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat) {
1870 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1871 componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1872 ResourceVersionInfo.newBuilder()
1873 .state(component.getLifecycleState().name())
1874 .version(component.getVersion())
1879 private String getEnvNameFromConfiguration() {
1880 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1881 log.trace("Update environment name to be {}", configuredEnvName);
1882 return configuredEnvName;
1885 public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier, ServiceDistributionReqInfo data) {
1887 Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation.validateActivateServiceRequest(serviceId, envId, modifier, data);
1888 if (activationRequestInformationEither.isRight()) {
1889 return Either.right(activationRequestInformationEither.right().value());
1892 ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1894 Either<String, ResponseFormat> result = null;
1895 String did = ThreadLocalsHolder.getUuid();
1896 Service service = activationRequestInformation.getServiceToActivate();
1897 result = buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1901 public Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext, User modifier) {
1902 String envName = getEnvNameFromConfiguration();
1903 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1904 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1905 if (notifyServiceResponse == ActionStatus.OK) {
1906 return Either.left(did);
1908 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1909 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1910 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1911 return Either.right(error);
1915 public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1917 User user = validateUserExists(modifier.getUserId(), "activate Distribution", false);
1918 Either<Service, ResponseFormat> result = null;
1919 ResponseFormat response = null;
1920 Service updatedService = null;
1921 String did = ThreadLocalsHolder.getUuid();
1923 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1924 if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1925 log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1926 envName = configuredEnvName;
1930 ServletContext servletContext = request.getSession().getServletContext();
1931 boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1932 if (!isDistributionEngineUp) {
1933 BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1934 log.debug("Distribution Engine is DOWN");
1935 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1936 return Either.right(response);
1939 Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1940 if (serviceRes.isRight()) {
1941 log.debug("failed retrieving service");
1942 response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1943 componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1944 new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1945 ResourceVersionInfo.newBuilder()
1948 return Either.right(response);
1950 Service service = serviceRes.left().value();
1951 String dcurrStatus = service.getDistributionStatus().name();
1952 String updatedStatus = dcurrStatus;
1953 StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1954 if (readyForDistribution.equals(StorageOperationStatus.OK)) {
1955 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1956 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1957 if (notifyServiceResponse == ActionStatus.OK) {
1958 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED);
1959 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1960 updatedService = updateStateRes.left().value();
1961 updatedStatus = updatedService.getDistributionStatus().name();
1963 // The response is not relevant
1964 updatedService = service;
1966 ASDCKpiApi.countActivatedDistribution();
1967 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1968 result = Either.left(updatedService);
1970 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1971 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1972 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1973 result = Either.right(response);
1976 response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution), envName);
1977 result = Either.right(response);
1979 componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1980 new ResourceCommonInfo(service.getName(),ComponentTypeEnum.SERVICE.getValue()),
1981 ResourceVersionInfo.newBuilder()
1982 .distributionStatus(dcurrStatus)
1984 ResourceVersionInfo.newBuilder()
1985 .distributionStatus(updatedStatus)
1991 // convert to private after deletion of temp url
1992 public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1994 validateUserExists(user.getUserId(), "update Distribution Status For Activation", false);
1996 String serviceId = service.getUniqueId();
1997 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1998 if (lockResult.isRight()) {
1999 return Either.right(lockResult.right().value());
2002 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
2003 if (result.isRight()) {
2004 titanDao.rollback();
2005 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
2006 log.debug("service {} change distribution status failed", serviceId);
2007 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2010 return Either.left(result.left().value());
2012 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
2016 public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
2018 validateUserExists(user.getUserId(), "mark Distribution As Deployed", false);
2019 log.debug("mark distribution deployed");
2021 AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
2022 Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
2023 if (getServiceResponse.isRight()) {
2024 BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
2025 log.debug("service {} not found", serviceId);
2026 ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
2028 return Either.right(responseFormat);
2031 Service service = getServiceResponse.left().value();
2032 user = validateRoleForDeploy(did, user, auditAction, service);
2033 return checkDistributionAndDeploy(did, user, auditAction, service);
2037 public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2038 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
2039 // Only one VF Module Artifact per instance - add it to a list of one
2040 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
2042 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2046 private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock, boolean inTransaction, ComponentInstance ri) {
2047 List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
2049 if (ri.getOriginType() == OriginTypeEnum.VF) {
2050 asList = Arrays.asList(new VfModuleArtifactGenerator(modifier, ri, service, shouldLock, inTransaction));
2055 private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
2056 Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
2057 if(currVF.getGroupInstances() != null){
2058 currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
2060 return currVF.getGroupInstances();
2063 private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) {
2064 ArtifactDefinition vfModuleAertifact = null;
2065 if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
2066 Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.name())).findAny();
2067 if (optionalVfModuleArtifact.isPresent()) {
2068 vfModuleAertifact = optionalVfModuleArtifact.get();
2071 if (vfModuleAertifact == null) {
2072 Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service, payloadWrapper.getInnerElement());
2073 if (createVfModuleArtifact.isLeft()) {
2074 vfModuleAertifact = createVfModuleArtifact.left().value();
2076 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
2079 return vfModuleAertifact;
2082 private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
2083 List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
2084 if (groupsForCurrVF != null) {
2085 for (GroupInstance groupInstance : groupsForCurrVF) {
2086 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
2087 vfModulePayloads.add(modulePayload);
2089 vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
2091 final Gson gson = new GsonBuilder().setPrettyPrinting().create();
2093 String vfModulePayloadString = gson.toJson(vfModulePayloads);
2094 payloadWrapper.setInnerElement(vfModulePayloadString);
2099 private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock, boolean inTransaction) {
2100 ArtifactDefinition vfModuleArtifact = null;
2101 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
2102 Wrapper<String> payloadWrapper = new Wrapper<>();
2103 List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
2104 if (responseWrapper.isEmpty()) {
2105 fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
2107 if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
2108 vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
2110 if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
2111 vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper, responseWrapper, service);
2114 Either<ArtifactDefinition, ResponseFormat> result;
2115 if (responseWrapper.isEmpty()) {
2116 result = Either.left(vfModuleArtifact);
2118 result = Either.right(responseWrapper.getInnerElement());
2124 private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper, Service service) {
2125 ArtifactDefinition result = null;
2126 Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, inTransaction, System::currentTimeMillis,
2127 () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), currVF.getUniqueId());
2128 if (eitherPayload.isLeft()) {
2129 result = eitherPayload.left().value();
2131 responseWrapper.setInnerElement(eitherPayload.right().value());
2133 if (result == null) {
2134 result = vfModuleArtifact;
2140 private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service, String vfModulePayloadString) {
2142 ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
2143 String newCheckSum = null;
2145 vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
2146 vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
2147 vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
2148 vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
2149 vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
2150 vfModuleArtifactDefinition.setTimeout(0);
2151 vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
2152 vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
2153 if (vfModulePayloadString != null) {
2154 newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
2156 vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
2158 Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent = artifactToscaOperation.addArifactToComponent(vfModuleArtifactDefinition, service.getUniqueId(), NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
2160 Either<ArtifactDefinition, ResponseFormat> result;
2161 if (addArifactToComponent.isLeft()) {
2162 result = Either.left(addArifactToComponent.left().value());
2164 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArifactToComponent.right().value())));
2170 public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2172 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
2173 // Get All Deployment Artifacts
2174 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
2175 // Filter in Only Heat Env
2176 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
2177 // Create ArtifactGenerator from those Artifacts
2178 map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction, resourceInstance.getUniqueId())).collect(Collectors.toList());
2180 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2184 private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
2186 // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
2188 if (service.getComponentInstances() != null) {
2189 List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
2190 if (artifactGenList != null && !artifactGenList.isEmpty()) {
2191 for (ArtifactGenerator<CallVal> entry : artifactGenList) {
2192 Either<CallVal, ResponseFormat> callRes;
2194 callRes = entry.call();
2195 if (callRes.isRight()) {
2196 log.debug("Failed to generate artifact error : {}", callRes.right().value());
2197 return Either.right(callRes.right().value());
2199 } catch (Exception e) {
2200 log.debug("Failed to generate artifact exception : {}", e);
2201 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2206 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
2207 if (storageStatus.isRight()) {
2208 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2211 Service currentService = storageStatus.left().value();
2213 return Either.left(currentService);
2217 abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
2221 class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2222 ArtifactDefinition artifactDefinition;
2224 String resourceInstanceName;
2228 boolean inTransaction;
2230 HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock, boolean inTransaction, String instanceId) {
2231 this.artifactDefinition = artifactDefinition;
2232 this.service = service;
2233 this.resourceInstanceName = resourceInstanceName;
2234 this.modifier = modifier;
2235 this.shouldLock = shouldLock;
2236 this.instanceId = instanceId;
2237 this.inTransaction = inTransaction;
2241 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2242 return artifactsBusinessLogic.forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier, shouldLock, inTransaction, instanceId);
2245 public ArtifactDefinition getArtifactDefinition() {
2246 return artifactDefinition;
2251 class VfModuleArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2253 private ComponentInstance componentInstance;
2254 private Service service;
2256 boolean inTransaction;
2259 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2260 return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
2263 private VfModuleArtifactGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock, boolean inTransaction) {
2266 this.componentInstance = componentInstance;
2267 this.service = service;
2268 this.shouldLock = shouldLock;
2269 this.inTransaction = inTransaction;
2274 private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction, Service service) {
2275 boolean isDeployed = isDistributionDeployed(distributionId);
2277 return Either.left(service);
2279 Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
2280 if (distributionSuccess.isRight()) {
2281 return Either.right(distributionSuccess.right().value());
2284 log.debug("mark distribution {} as deployed - success", distributionId);
2285 componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK", user);
2286 return Either.left(service);
2289 private boolean isDistributionDeployed(String distributionId) {
2290 Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
2292 boolean isDeployed = false;
2293 if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
2295 log.debug("distribution {} is already deployed", distributionId);
2301 protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
2303 log.trace("checkDistributionSuccess");
2304 // get all "DRequest" records for this distribution
2306 Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
2307 if (distRequestsResponse.isRight()) {
2308 ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
2309 return Either.right(error);
2312 List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
2313 if (distributionRequests.isEmpty()) {
2314 BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
2315 log.info("distribution {} is not found", did);
2316 ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
2317 return Either.right(error);
2319 boolean isRequestSucceeded = false;
2320 for (ResourceAdminEvent event : distributionRequests) {
2321 String eventStatus = event.getStatus();
2322 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2323 isRequestSucceeded = true;
2328 // get all "DNotify" records for this distribution
2329 Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
2330 if (distNotificationsResponse.isRight()) {
2331 ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
2332 return Either.right(error);
2335 List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
2336 boolean isNotificationsSucceeded = false;
2337 for (DistributionNotificationEvent event : distributionNotifications) {
2338 String eventStatus = event.getStatus();
2339 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2340 isNotificationsSucceeded = true;
2345 // if request failed OR there are notifications that failed
2346 if (!(isRequestSucceeded && isNotificationsSucceeded)) {
2348 log.info("distribution {} has failed", did);
2349 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2350 auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2351 return Either.right(error);
2353 return Either.left(true);
2356 private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) {
2358 ResponseFormat error = componentsUtils.getResponseFormat(status, params);
2359 String message = "";
2360 if (error.getMessageId() != null) {
2361 message = error.getMessageId() + ": ";
2363 message += error.getFormattedMessage();
2365 if (service != null) {
2366 componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user);
2368 componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
2373 private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
2374 Either<User, ActionStatus> eitherCreator = userAdmin.getUser(user.getUserId(), false);
2375 if (eitherCreator.isRight() || eitherCreator.left().value() == null) {
2376 BeEcompErrorManager.getInstance().logBeUserMissingError("Deploy Service", user.getUserId());
2377 log.debug("validateRoleForDeploy method - user is not listed. userId= {}", user.getUserId());
2378 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, user.getUserId());
2379 auditDeployError(did, user, auditAction, service, ActionStatus.USER_NOT_FOUND);
2380 throw new ComponentException(ActionStatus.USER_NOT_FOUND, user.getUserId());
2382 user = eitherCreator.left().value();
2383 log.debug("validate user role");
2384 List<Role> roles = new ArrayList<>();
2385 roles.add(Role.ADMIN);
2386 roles.add(Role.OPS);
2388 validateUserRole(user, service, roles, auditAction, null);
2389 } catch (ComponentException e){
2390 log.info("role {} is not allowed to perform this action", user.getRole());
2391 auditDeployError(did, user, auditAction, service, e.getActionStatus());
2398 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
2399 Service service = (Service) component;
2400 Map<String, ArtifactDefinition> artifactMap = service.getDeploymentArtifacts();
2401 if (artifactMap == null) {
2402 artifactMap = new HashMap<>();
2404 service.setDeploymentArtifacts(artifactMap);
2408 public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
2409 return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
2412 private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
2413 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
2414 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
2415 return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
2419 public ComponentInstanceBusinessLogic getComponentInstanceBL() {
2420 return componentInstanceBusinessLogic;
2424 public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
2426 validateUserExists(userId, "Get Component Instances", false);
2427 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2428 if (getComponentRes.isRight()) {
2429 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
2430 return Either.right(responseFormat);
2433 List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
2435 return Either.left(componentInstances);
2438 public ICacheMangerOperation getCacheManagerOperation() {
2439 return cacheManagerOperation;
2442 public void setCacheManagerOperation(ICacheMangerOperation cacheManagerOperation) {
2443 this.cacheManagerOperation = cacheManagerOperation;
2446 public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
2447 this.forwardingPathOperation = forwardingPathOperation;
2451 public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
2452 this.toscaOperationFacade = toscaOperationFacade;
2454 * updates group instance with new property values in case of successful update of group instance related component instance will be updated with new modification time and related service will be updated with new last update date
2457 public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2459 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2460 Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
2461 Component component = null;
2462 Either<Boolean, ResponseFormat> lockResult = null;
2463 log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
2465 validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2466 if (validateUserAndComponentRes.isRight()) {
2467 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed. ", groupInstanceId, serviceId);
2468 actionResult = Either.right(validateUserAndComponentRes.right().value());
2470 if (actionResult == null) {
2471 component = validateUserAndComponentRes.left().value().getKey();
2472 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2473 if (lockResult.isRight()) {
2474 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
2475 actionResult = Either.right(lockResult.right().value());
2477 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
2480 if (actionResult == null) {
2481 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId, newProperties);
2482 if (actionResult.isRight()) {
2483 log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ", groupInstanceId, actionResult.right().value().getFormattedMessage());
2486 } catch (Exception e) {
2487 log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2488 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2490 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2491 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2494 return actionResult;
2497 private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2499 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2500 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2501 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2502 ComponentInstance relatedComponentInstance = null;
2503 GroupInstance oldGroupInstance = null;
2504 Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2505 GroupInstance updatedGroupInstance = null;
2506 boolean inTransaction = true;
2507 findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2508 if (findGroupInstanceRes.isRight()) {
2509 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
2510 actionResult = Either.right(findGroupInstanceRes.right().value());
2512 if (actionResult == null) {
2513 oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2514 relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2515 updateGroupInstanceResult = groupBusinessLogic.validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
2516 if (updateGroupInstanceResult.isRight()) {
2517 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ", oldGroupInstance.getName());
2518 actionResult = Either.right(updateGroupInstanceResult.right().value());
2521 if (actionResult == null) {
2522 updatedGroupInstance = updateGroupInstanceResult.left().value();
2523 if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2524 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance, updatedGroupInstance, inTransaction);
2525 if (updateParentsModificationTimeRes.isRight()) {
2526 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ", oldGroupInstance.getName());
2527 actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2531 if (actionResult == null) {
2532 actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2534 return actionResult;
2537 private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance,
2538 boolean inTranscation) {
2540 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2541 Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2542 Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic.updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2543 updatedGroupInstance.getModificationTime(), inTranscation);
2544 if (updateComponentInstanceRes.isRight()) {
2545 log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(), updatedGroupInstance.getName());
2546 actionResult = Either.right(updateComponentInstanceRes.right().value());
2548 serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2549 if (serviceMetadataUpdateResult.isRight()) {
2550 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ", component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2551 actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2553 actionResult = Either.left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2556 return actionResult;
2559 private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2561 Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2562 Either<Component, ResponseFormat> validateComponentExistsRes = null;
2563 User currUser = null;
2564 Component component = null;
2565 Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2566 if (validationUserResult.isRight()) {
2567 log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2568 result = Either.right(validationUserResult.right().value());
2570 if (result == null) {
2571 currUser = validationUserResult.left().value();
2572 validateComponentExistsRes = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2573 if (validateComponentExistsRes.isRight()) {
2574 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2575 result = Either.right(validateComponentExistsRes.right().value());
2578 if (result == null) {
2579 component = validateComponentExistsRes.left().value();
2580 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2581 log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(), component.getCreatorUserId());
2582 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2585 if (result == null) {
2586 result = Either.left(new ImmutablePair<>(component, currUser));
2591 private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component, String componentInstanceId, String groupInstanceId) {
2593 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2594 GroupInstance groupInstance = null;
2595 ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2596 if (foundComponentInstance == null) {
2597 log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2598 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service", component.getName()));
2600 else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2601 groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst().orElse(null);
2602 if (groupInstance == null) {
2603 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2604 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId, foundComponentInstance.getName()));
2607 if (actionResult == null) {
2608 actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2610 return actionResult;
2613 private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2614 ComponentInstance componentInstance = null;
2615 if (isNotEmpty(component.getComponentInstances())) {
2616 componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst().orElse(null);
2618 return componentInstance;
2621 private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2622 User user = validateUser(modifier, ecompErrorContext, null, null, false);
2623 List<Role> roles = new ArrayList<>();
2624 roles.add(Role.ADMIN);
2625 roles.add(Role.DESIGNER);
2626 validateUserRole(user, roles);
2627 return Either.left(user);
2630 public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId, List<String> dataParamsToReturn) {
2632 ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2633 paramsToReturn.setIgnoreComponentInstancesProperties(false);
2634 Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2636 if (serviceResultEither.isRight()) {
2637 if(serviceResultEither.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
2638 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2639 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2642 log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2643 return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2646 Service service = serviceResultEither.left().value();
2647 if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
2648 ListUtils.emptyIfNull(service.getInputs())
2649 .forEach(input -> input.setConstraints(setInputConstraint(input)));
2652 UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2653 return Either.left(dataTransfer);
2656 public Either<String, ResponseFormat> deleteIfNotAlreadyDeletedServiceFilter(String serviceId, String resourceId, String userId, boolean lock) {
2657 Service serviceToDelete = initServiceToDeleteServiceFilter(serviceId);
2658 User user = validateUserExists(userId, "Create service Filter", false);
2661 validateUser(user, "deleteIfNotAlreadyDeletedServiceFilter", serviceToDelete, null, false);
2663 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
2664 if (storageStatus.isRight()) {
2665 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2667 Service service = storageStatus.left().value();
2669 Either<Boolean, ResponseFormat> response = serviceFilterValidator.validateComponentInstanceExist(service, resourceId);
2670 if (storageStatus.isRight()) {
2671 return Either.right(response.right().value());
2673 final Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(resourceId);
2674 if (!optionalComponentInstance.isPresent() ){
2675 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2677 CINodeFilterDataDefinition nodeFilter = optionalComponentInstance.get().getNodeFilter();
2678 if (nodeFilter == null){
2679 return Either.left(resourceId);
2682 Either<String, StorageOperationStatus> result;
2684 Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Service Filter from service");
2685 if (lockResult.isRight()) {
2686 titanDao.rollback();
2687 return Either.right(componentsUtils.getResponseFormat(componentsUtils
2688 .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2692 result = serviceFilterOperation.deleteNodeFilter(service , resourceId);
2693 if (result.isRight()) {
2694 log.debug("Failed to delete node filter in service {}. Response is {}. ", service.getName(), result.right().value());
2695 titanDao.rollback();
2696 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
2699 log.debug("Node filter successfully changed in service {} . ", service.getSystemName());
2701 } catch (Exception e){
2702 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
2703 titanDao.rollback();
2704 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2706 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2708 return Either.left(result.left().value());
2712 private Service initServiceToDeleteServiceFilter(String serviceId) {
2713 Service serviceToDelete = new Service();
2714 serviceToDelete.setUniqueId(serviceId);
2715 return serviceToDelete;
2719 public Either<CINodeFilterDataDefinition, ResponseFormat> createIfNotAlreadyExistServiceFilter(String serviceId, String componentInstanceId, String userId, boolean lock) {
2720 String errorContext = "createIfNotAlreadyExistServiceFilter";
2721 User user = validateUserExists(userId, "Create service Filter", false);
2723 Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
2724 if (serviceEither.isRight()) {
2725 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceEither.right().value(), ComponentTypeEnum.SERVICE), ""));
2727 final Service service = serviceEither.left().value();
2728 validateUserAndRole(service, user, errorContext);
2730 Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(componentInstanceId);
2731 if (!optionalComponentInstance.isPresent()){
2732 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2734 ComponentInstance componentInstance = optionalComponentInstance.get();
2735 CINodeFilterDataDefinition serviceFilter = componentInstance.getNodeFilter();
2736 if (serviceFilter != null){
2737 return Either.left(serviceFilter);
2740 Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2742 Either<Boolean, ResponseFormat> lockResult = null;
2745 lockComponent(service.getUniqueId(), service, "Create Service Filter");
2746 if (lockResult.isRight()) {
2747 log.debug("Failed to lock service {}. Response is {}. ", service.getName(),
2748 lockResult.right().value().getFormattedMessage());
2749 return Either.right(lockResult.right().value());
2751 log.debug("The service with system name {} locked. ", service.getSystemName());
2754 CINodeFilterDataDefinition serviceFilterResult;
2756 result = serviceFilterOperation.createNodeFilter(serviceId, componentInstanceId);
2757 if (result.isRight()) {
2758 titanDao.rollback();
2759 return Either.right(componentsUtils.getResponseFormat(
2760 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2763 serviceFilterResult = result.left().value();
2767 } catch (Exception e) {
2768 titanDao.rollback();
2769 log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2771 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2774 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2775 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2778 return Either.left(serviceFilterResult);
2782 public Either<CINodeFilterDataDefinition, ResponseFormat> updateServiceFilter(String serviceId, String componentInstanceId,
2783 List<String> constraints, User inUser, boolean lock) {
2784 String errorContext = "createIfNotAlreadyExistServiceFilter";
2785 User user = validateUserExists(inUser, errorContext, true);
2786 validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2787 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2789 if(serviceStorageOperationStatusEither.isRight()){
2790 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2791 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2792 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2794 Service storedService = serviceStorageOperationStatusEither.left().value();
2796 Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2797 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId, constraints,
2798 NodeFilterConstraintAction.UPDATE);
2799 if(booleanResponseFormatEither.isRight()){
2800 return Either.right(booleanResponseFormatEither.right().value());
2804 Either<Boolean, ResponseFormat> lockResult = null;
2807 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2808 if (lockResult.isRight()) {
2809 log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
2810 lockResult.right().value().getFormattedMessage());
2811 return Either.right(lockResult.right().value());
2813 log.debug("The service with system name {} locked. ", storedService.getSystemName());
2816 Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2817 if (!componentInstanceOptional.isPresent()){
2818 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2820 CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2821 if(serviceFilter == null){
2822 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2824 CINodeFilterDataDefinition serviceFilterResult;
2826 List<RequirementNodeFilterPropertyDataDefinition> properties = constraints.stream().map(this::getRequirementNodeFilterPropertyDataDefinition).collect(Collectors.toList());
2827 Either<CINodeFilterDataDefinition, StorageOperationStatus> result = serviceFilterOperation.updateProperties(serviceId, componentInstanceId, serviceFilter ,properties);
2829 if (result.isRight()) {
2830 titanDao.rollback();
2831 return Either.right(componentsUtils.getResponseFormat(
2832 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2835 serviceFilterResult = result.left().value();
2839 } catch (Exception e) {
2840 titanDao.rollback();
2841 log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2843 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2846 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2847 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2850 return Either.left(serviceFilterResult);
2853 private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition(String constraint){
2854 RequirementNodeFilterPropertyDataDefinition pdd = new RequirementNodeFilterPropertyDataDefinition();
2855 pdd.setConstraints(Arrays.asList(constraint));
2859 public Either<CINodeFilterDataDefinition, ResponseFormat> addOrDeleteServiceFilter(String serviceId, String componentInstanceId,
2860 NodeFilterConstraintAction action, String constraint, int position, User inUser, boolean lock) {
2861 String errorContext = "createIfNotAlreadyExistServiceFilter";
2862 User user = validateUserExists(inUser, errorContext, true);
2863 validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2865 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2867 if(serviceStorageOperationStatusEither.isRight()){
2868 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2869 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2870 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2872 Service storedService = serviceStorageOperationStatusEither.left().value();
2874 Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2875 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId,
2876 Collections.singletonList(constraint), action);
2877 if(booleanResponseFormatEither.isRight()){
2878 return Either.right(booleanResponseFormatEither.right().value());
2881 Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2883 Either<Boolean, ResponseFormat> lockResult = null;
2884 CINodeFilterDataDefinition serviceFilterResult = null;
2888 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2889 if (lockResult.isRight()) {
2890 log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
2891 lockResult.right().value().getFormattedMessage());
2892 return Either.right(lockResult.right().value());
2894 log.debug("The service with system name {} locked. ", storedService.getSystemName());
2898 Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2899 if (!componentInstanceOptional.isPresent()){
2900 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2902 CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2903 if(serviceFilter == null){
2904 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2910 RequirementNodeFilterPropertyDataDefinition newProperty = new RequirementNodeFilterPropertyDataDefinition();
2911 newProperty.setConstraints(Collections.singletonList(constraint));
2912 result = serviceFilterOperation.addNewProperty(serviceId, componentInstanceId,serviceFilter,newProperty);
2915 result = serviceFilterOperation.deleteConstraint(serviceId, componentInstanceId, serviceFilter, position);
2918 log.error("Unsupported operation "+action);
2919 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2923 if (result.isRight()) {
2924 titanDao.rollback();
2925 return Either.right(componentsUtils.getResponseFormat(
2926 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2929 serviceFilterResult = result.left().value();
2933 } catch (Exception e) {
2934 titanDao.rollback();
2935 log.error("Exception occurred during add or update node filter property values: {}", e.getMessage(),
2937 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2940 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2941 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2944 return Either.left(serviceFilterResult);