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.InterfaceOperationUtils.getOperationOutputName;
26 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToOtherOperationOutput;
27 import static org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum.UPDATE_SERVICE_METADATA;
28 import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.SELF;
29 import static org.openecomp.sdc.be.types.ServiceConsumptionSource.SERVICE_INPUT;
30 import static org.openecomp.sdc.be.types.ServiceConsumptionSource.STATIC;
32 import com.google.common.annotations.VisibleForTesting;
33 import com.google.common.base.Strings;
34 import com.google.gson.Gson;
35 import com.google.gson.GsonBuilder;
37 import java.nio.charset.StandardCharsets;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.Collection;
41 import java.util.Collections;
42 import java.util.HashMap;
43 import java.util.List;
45 import java.util.Objects;
46 import java.util.Optional;
48 import java.util.concurrent.Callable;
49 import java.util.function.Function;
50 import java.util.stream.Collectors;
52 import fj.data.Either;
53 import org.apache.commons.collections.CollectionUtils;
54 import org.apache.commons.collections.MapUtils;
55 import org.apache.commons.collections4.ListUtils;
56 import org.apache.commons.lang3.StringUtils;
57 import org.apache.commons.lang3.tuple.ImmutablePair;
58 import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine;
59 import org.openecomp.sdc.be.components.distribution.engine.INotificationData;
60 import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload;
61 import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic;
62 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
63 import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
64 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
65 import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
66 import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
67 import org.openecomp.sdc.be.components.validation.NodeFilterValidator;
68 import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
69 import org.openecomp.sdc.be.config.BeEcompErrorManager;
70 import org.openecomp.sdc.be.config.ConfigurationManager;
71 import org.openecomp.sdc.be.dao.api.ActionStatus;
72 import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
73 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
74 import org.openecomp.sdc.be.datamodel.ServiceRelations;
75 import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil;
76 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
77 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
78 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
79 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
80 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
81 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
82 import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition;
83 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
84 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
85 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
86 import org.openecomp.sdc.be.datatypes.enums.InstantiationTypes;
87 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
88 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
89 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
90 import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo;
91 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
92 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
93 import org.openecomp.sdc.be.model.ArtifactDefinition;
94 import org.openecomp.sdc.be.model.Component;
95 import org.openecomp.sdc.be.model.ComponentInstance;
96 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
97 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
98 import org.openecomp.sdc.be.model.ComponentParametersView;
99 import org.openecomp.sdc.be.model.DistributionStatusEnum;
100 import org.openecomp.sdc.be.model.DistributionTransitionEnum;
101 import org.openecomp.sdc.be.model.GroupInstance;
102 import org.openecomp.sdc.be.model.GroupInstanceProperty;
103 import org.openecomp.sdc.be.model.InputDefinition;
104 import org.openecomp.sdc.be.model.InterfaceDefinition;
105 import org.openecomp.sdc.be.model.LifecycleStateEnum;
106 import org.openecomp.sdc.be.model.Operation;
107 import org.openecomp.sdc.be.model.PropertyDefinition;
108 import org.openecomp.sdc.be.model.Resource;
109 import org.openecomp.sdc.be.model.Service;
110 import org.openecomp.sdc.be.model.User;
111 import org.openecomp.sdc.be.model.category.CategoryDefinition;
112 import org.openecomp.sdc.be.model.jsontitan.operations.ForwardingPathOperation;
113 import org.openecomp.sdc.be.model.jsontitan.operations.NodeFilterOperation;
114 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
115 import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation;
116 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
117 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
118 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
119 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
120 import org.openecomp.sdc.be.model.tosca.ToscaFunctions;
121 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
122 import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
123 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
124 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
125 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
126 import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent;
127 import org.openecomp.sdc.be.resources.data.auditing.DistributionDeployEvent;
128 import org.openecomp.sdc.be.resources.data.auditing.DistributionNotificationEvent;
129 import org.openecomp.sdc.be.resources.data.auditing.ResourceAdminEvent;
130 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
131 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
132 import org.openecomp.sdc.be.types.ServiceConsumptionData;
133 import org.openecomp.sdc.be.types.ServiceConsumptionSource;
134 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
135 import org.openecomp.sdc.be.user.Role;
136 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
137 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
138 import org.openecomp.sdc.common.api.Constants;
139 import org.openecomp.sdc.common.datastructure.Wrapper;
140 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
141 import org.openecomp.sdc.common.log.wrappers.Logger;
142 import org.openecomp.sdc.common.util.GeneralUtility;
143 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
144 import org.openecomp.sdc.common.util.ValidationUtils;
145 import org.openecomp.sdc.exception.ResponseFormat;
146 import org.springframework.beans.factory.annotation.Autowired;
147 import org.springframework.http.HttpStatus;
148 import org.springframework.web.context.WebApplicationContext;
150 import javax.servlet.ServletContext;
151 import javax.servlet.http.HttpServletRequest;
153 @org.springframework.stereotype.Component("serviceBusinessLogic")
154 public class ServiceBusinessLogic extends ComponentBusinessLogic {
156 private static final String CHANGE_SERVICE_DISTRIBUTION = "Change Service Distribution";
157 private static final String THE_SERVICE_WITH_SYSTEM_NAME_LOCKED = "The service with system name {} locked. ";
158 private static final String FAILED_TO_LOCK_SERVICE_RESPONSE_IS = "Failed to lock service {}. Response is {}. ";
159 private static final String AUDIT_BEFORE_SENDING_RESPONSE = "audit before sending response";
160 private static final Logger log = Logger.getLogger(ServiceBusinessLogic.class);
161 private static final String INITIAL_VERSION = "0.1";
162 private static final String STATUS_SUCCESS_200 = "200";
163 private static final String STATUS_DEPLOYED = "DEPLOYED";
165 private IDistributionEngine distributionEngine;
167 private AuditCassandraDao auditCassandraDao;
169 private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
171 private ICacheMangerOperation cacheManagerOperation;
173 private ServiceDistributionValidation serviceDistributionValidation;
176 private ForwardingPathOperation forwardingPathOperation;
178 private ForwardingPathValidator forwardingPathValidator;
180 private UiComponentDataConverter uiComponentDataConverter;
182 private NodeFilterOperation serviceFilterOperation;
184 private NodeFilterValidator serviceFilterValidator;
186 public Either<Service, ResponseFormat> changeServiceDistributionState(String serviceId, String state, LifecycleChangeInfoWithAction commentObj, User user) {
188 validateUserExists(user.getUserId(), "change Service Distribution State", false);
190 log.debug("check request state");
191 Either<DistributionTransitionEnum, ResponseFormat> validateEnum = validateTransitionEnum(state);
192 if (validateEnum.isRight()) {
193 return Either.right(validateEnum.right().value());
195 DistributionTransitionEnum distributionTransition = validateEnum.left().value();
196 AuditingActionEnum auditAction = distributionTransition == DistributionTransitionEnum.APPROVE ? AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_APPROV : AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REJECT;
197 Either<String, ResponseFormat> commentResponse = validateComment(commentObj);
198 if (commentResponse.isRight()) {
199 return Either.right(commentResponse.right().value());
201 String comment = commentResponse.left().value();
203 Either<Service, ResponseFormat> validateService = validateServiceDistributionChange(user, serviceId, auditAction, comment);
204 if (validateService.isRight()) {
205 return Either.right(validateService.right().value());
207 Service service = validateService.left().value();
208 Either<User, ResponseFormat> validateUser = validateUserDistributionChange(user, service, auditAction, comment);
209 if (validateUser.isRight()) {
210 return Either.right(validateUser.right().value());
212 user = validateUser.left().value();
216 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "ChangeServiceDistributionState");
217 if (lockResult.isRight()) {
218 ResponseFormat responseFormat = lockResult.right().value();
219 createAudit(user, auditAction, comment, service, responseFormat);
220 return Either.right(responseFormat);
225 DistributionStatusEnum newState;
226 if (distributionTransition == DistributionTransitionEnum.APPROVE) {
227 newState = DistributionStatusEnum.DISTRIBUTION_APPROVED;
229 newState = DistributionStatusEnum.DISTRIBUTION_REJECTED;
231 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, newState);
232 if (result.isRight()) {
234 BeEcompErrorManager.getInstance().logBeSystemError("ChangeServiceDistributionState");
235 log.debug("service {} is change destribuation status failed", service.getUniqueId());
236 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, service.getVersion(), service.getName());
237 createAudit(user, auditAction, comment, service, responseFormat);
238 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
241 Service updatedService = result.left().value();
242 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
243 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
244 componentsUtils.auditComponent(responseFormat, user, updatedService, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()), ResourceVersionInfo.newBuilder().build(), comment);
245 return Either.left(result.left().value());
247 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
252 public Either<List<Map<String, Object>>, ResponseFormat> getComponentAuditRecords(String componentVersion, String componentUUID, String userId) {
253 validateUserExists(userId, "get Component Audit Records", false);
254 Either<List<Map<String, Object>>, ActionStatus> result;
258 if (componentVersion.endsWith(".0")) {
259 Either<List<ResourceAdminEvent>, ActionStatus> eitherAuditingForCertified = auditCassandraDao.getByServiceInstanceId(componentUUID);
260 if (eitherAuditingForCertified.isLeft()) {
261 result = Either.left(getAuditingFieldsList(eitherAuditingForCertified.left().value()));
263 result = Either.right(eitherAuditingForCertified.right().value());
266 // Uncertified Version
268 result = getAuditRecordsForUncertifiedComponent(componentUUID, componentVersion);
270 } catch (Exception e) {
271 log.debug("get Audit Records failed with exception {}", e);
272 result = Either.right(ActionStatus.GENERAL_ERROR);
275 if (result.isRight()) {
276 return Either.right(componentsUtils.getResponseFormat(result.right().value()));
278 return Either.left(result.left().value());
283 public Either<List<Operation>, ResponseFormat> addServiceConsumptionData(String serviceId,
284 String serviceInstanceId,
286 List<ServiceConsumptionData> serviceConsumptionDataList,
288 List<Operation> operationList = new ArrayList<>();
290 Either<Service, StorageOperationStatus> serviceEither =
291 toscaOperationFacade.getToscaElement(serviceId);
292 if(serviceEither.isRight()) {
293 return Either.right(componentsUtils.getResponseFormat
294 (serviceEither.right().value()));
297 Service service = serviceEither.left().value();
300 StorageOperationStatus storageOperationStatus =
301 graphLockOperation.lockComponent(service.getUniqueId(), NodeTypeEnum.Service);
302 if (storageOperationStatus != StorageOperationStatus.OK) {
303 return Either.right(componentsUtils.getResponseFormat(storageOperationStatus));
307 for (ServiceConsumptionData serviceConsumptionData : serviceConsumptionDataList) {
308 Either<Operation, ResponseFormat> operationEither =
309 addPropertyServiceConsumption(serviceId, serviceInstanceId, operationId,
310 userId, serviceConsumptionData);
312 if (operationEither.isRight()) {
313 return Either.right(operationEither.right().value());
316 operationList.add(operationEither.left().value());
320 return Either.left(operationList);
321 } catch (Exception e) {
323 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
326 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
331 public Either <Operation, ResponseFormat> addPropertyServiceConsumption(String serviceId,
332 String serviceInstanceId,
335 ServiceConsumptionData serviceConsumptionData) {
336 validateUserExists(userId, "create Property", false);
338 Either<Service, StorageOperationStatus> serviceEither =
339 toscaOperationFacade.getToscaElement(serviceId);
340 if(serviceEither.isRight()) {
341 return Either.right(componentsUtils.getResponseFormat(serviceEither.right
345 Service parentService = serviceEither.left().value();
347 List<ComponentInstance> componentInstances = parentService.getComponentInstances();
348 if(CollectionUtils.isEmpty(componentInstances)) {
349 return Either.right(componentsUtils.getResponseFormat(ActionStatus
350 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
353 Optional<ComponentInstance> serviceInstanceCandidate =
354 componentInstances.stream().filter(instance -> instance.getUniqueId().equals
355 (serviceInstanceId)).findAny();
357 if(!serviceInstanceCandidate.isPresent()) {
358 return Either.right(componentsUtils.getResponseFormat(ActionStatus
359 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
362 Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaces =
363 parentService.getComponentInstancesInterfaces();
364 if(MapUtils.isEmpty(componentInstancesInterfaces)) {
365 return Either.right(componentsUtils.getResponseFormat(ActionStatus
366 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
369 List<InterfaceDefinition> interfaces = new ArrayList<>();
370 for(ComponentInstanceInterface componentInstanceInterface :
371 componentInstancesInterfaces.get(serviceInstanceId)) {
372 interfaces.add(componentInstanceInterface);
375 ComponentInstance serviceInstance = serviceInstanceCandidate.get();
376 Optional<InterfaceDefinition> interfaceCandidate = InterfaceOperationUtils
377 .getInterfaceDefinitionFromOperationId(interfaces, operationId);
379 if(!interfaceCandidate.isPresent()) {
380 return Either.right(componentsUtils.getResponseFormat(ActionStatus
381 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
384 InterfaceDefinition interfaceDefinition = interfaceCandidate.get();
385 Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
386 if(MapUtils.isEmpty(operations)) {
387 return Either.right(componentsUtils.getResponseFormat(ActionStatus
388 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
391 Operation operation = operations.get(operationId);
392 Either<Operation, ResponseFormat> operationEither = Either.left(operation);
394 ListDataDefinition<OperationInputDefinition> inputs = operation.getInputs();
395 Optional<OperationInputDefinition> inputCandidate =
396 getOperationInputByInputId(serviceConsumptionData, inputs);
398 if(!inputCandidate.isPresent()) {
399 return Either.right(new ResponseFormat(HttpStatus.NOT_FOUND.value()));
402 OperationInputDefinition operationInputDefinition = inputCandidate.get();
403 // add data to operation
405 if(Objects.nonNull(serviceConsumptionData.getValue())) {
407 handleConsumptionValue(parentService, serviceInstanceId, serviceConsumptionData, operation,
408 operationInputDefinition);
411 if(operationEither.isRight()) {
412 return Either.right(operationEither.right().value());
415 Operation updatedOperation = operationEither.left().value();
416 operations.remove(operationId);
417 operations.put(operationId, updatedOperation);
418 interfaceDefinition.setOperationsMap(operations);
420 parentService.getComponentInstances().remove(serviceInstance);
421 if(CollectionUtils.isEmpty(parentService.getComponentInstances())) {
422 parentService.setComponentInstances(new ArrayList<>());
425 Map<String, Object> instanceInterfaces =
426 MapUtils.isEmpty(serviceInstance.getInterfaces())? new HashMap<>() : serviceInstance.getInterfaces();
427 instanceInterfaces.remove(interfaceDefinition.getUniqueId());
428 instanceInterfaces.put(interfaceDefinition.getUniqueId(), interfaceDefinition);
429 serviceInstance.setInterfaces(instanceInterfaces);
431 removeComponentInstanceInterfaceByInterfaceId(interfaceDefinition.getUniqueId(), componentInstancesInterfaces.get(serviceInstanceId));
432 componentInstancesInterfaces.get(serviceInstanceId).add(new ComponentInstanceInterface(interfaceDefinition.getUniqueId(), interfaceDefinition));
434 parentService.getComponentInstances().add(serviceInstance);
436 StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(parentService, serviceInstanceId);
438 if(status != StorageOperationStatus.OK) {
439 return Either.right(componentsUtils.getResponseFormat(ActionStatus
440 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
443 return Either.left(operation);
446 private void removeComponentInstanceInterfaceByInterfaceId(String interfaceIdToRemove,
447 List<ComponentInstanceInterface> instanceInterfaces) {
448 if(CollectionUtils.isEmpty(instanceInterfaces)) {
452 Optional<ComponentInstanceInterface> interfaceToRemove =
453 instanceInterfaces.stream().filter(instInterface -> instInterface.getUniqueId().equals
454 (interfaceIdToRemove)).findAny();
456 if(interfaceToRemove.isPresent()) {
457 instanceInterfaces.remove(interfaceToRemove.get());
462 private Either<Operation, ResponseFormat> handleConsumptionValue(Service containerService,
463 String serviceInstanceId,
464 ServiceConsumptionData serviceConsumptionData,
466 OperationInputDefinition
467 operationInputDefinition) {
468 String source = serviceConsumptionData.getSource();
469 String consumptionValue = serviceConsumptionData.getValue();
470 String type = serviceConsumptionData.getType();
471 String operationIdentifier = consumptionValue.contains(".")
472 ? consumptionValue.substring(0, consumptionValue.lastIndexOf('.'))
475 ServiceConsumptionSource sourceValue = ServiceConsumptionSource.getSourceValue(source);
477 if(STATIC.equals(sourceValue)) {
478 // Validate constraint on input value
479 /*Either<Boolean, ResponseFormat> constraintValidationResult =
480 validateOperationInputConstraint(operationInputDefinition, serviceConsumptionData);
482 if (constraintValidationResult.isRight()) {
483 return Either.right(constraintValidationResult.right().value());
486 return handleConsumptionStaticValue(consumptionValue, type, operation,
487 operationInputDefinition);
490 if (Objects.isNull(sourceValue)) {
491 List<PropertyDefinition> propertyDefinitions;
492 String componentName;
493 List<OperationOutputDefinition> outputs = null;
494 if (source.equals(containerService.getUniqueId())) {
495 Either<Service, StorageOperationStatus> serviceToTakePropEither =
496 toscaOperationFacade.getToscaElement(source);
497 if (serviceToTakePropEither.isRight()) {
498 return Either.right(componentsUtils.getResponseFormat(serviceToTakePropEither.right().value()));
500 Service service = serviceToTakePropEither.left().value();
501 operationInputDefinition.setSource(service.getUniqueId());
502 sourceValue = SERVICE_INPUT;
503 propertyDefinitions = service.getProperties();
504 componentName = service.getName();
505 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier,
506 service.getInterfaces()).getListToscaDataDefinition();
508 Optional<ComponentInstance> getComponentInstance = containerService.getComponentInstanceById(source);
509 if(!getComponentInstance.isPresent()){
510 return Either.right(componentsUtils.getResponseFormat(
511 ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, source));
513 ComponentInstance componentInstance = getComponentInstance.get();
514 operationInputDefinition.setSource(componentInstance.getUniqueId());
515 propertyDefinitions = componentInstance.getProperties();
516 componentName = source.equals(serviceInstanceId) ? SELF : componentInstance.getName();
517 if (MapUtils.isNotEmpty(componentInstance.getInterfaces())) {
518 Map<String, InterfaceDataDefinition> componentInstanceInterfaces =
519 componentInstance.getInterfaces().entrySet().stream()
520 .collect(Collectors.toMap((Map.Entry::getKey),
521 (interfaceEntry -> (InterfaceDataDefinition) interfaceEntry.getValue())));
522 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier,
523 componentInstanceInterfaces).getListToscaDataDefinition();
527 if(sourceValue == ServiceConsumptionSource.SERVICE_INPUT) {
528 //The operation input in service consumption has been mapped to an input in the parent service
529 return handleConsumptionInputValue(consumptionValue, containerService, operation,
530 operationInputDefinition);
532 return handleConsumptionPropertyValue(operation, operationInputDefinition,
533 serviceConsumptionData, propertyDefinitions, outputs, consumptionValue, componentName);
536 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.SOURCE, source);
537 operationInputDefinition.setSource(source);
539 return Either.left(operation);
542 private Optional<OperationInputDefinition> getOperationInputByInputId(ServiceConsumptionData serviceConsumptionData,
543 ListDataDefinition<OperationInputDefinition> inputs) {
545 if(CollectionUtils.isEmpty(inputs.getListToscaDataDefinition())) {
546 return Optional.empty();
549 return inputs.getListToscaDataDefinition().stream().filter(operationInput -> operationInput.getInputId().equals
550 (serviceConsumptionData.getInputId()))
554 private Either<Operation, ResponseFormat> handleConsumptionPropertyValue(
555 Operation operation, OperationInputDefinition operationInputDefinition,
556 ServiceConsumptionData serviceConsumptionData, List<PropertyDefinition> properties,
557 List<OperationOutputDefinition> outputs, String consumptionValue, String componentName) {
559 if (CollectionUtils.isEmpty(properties) && CollectionUtils.isEmpty(outputs)) {
560 return Either.left(operation);
563 if (CollectionUtils.isNotEmpty(outputs)
564 && isOperationInputMappedToOtherOperationOutput(getOperationOutputName(consumptionValue), outputs)) {
565 return handleConsumptionInputMappedToOperationOutput(operation, operationInputDefinition, outputs,
566 consumptionValue, componentName);
569 if (CollectionUtils.isNotEmpty(properties)) {
570 return handleConsumptionInputMappedToProperty(operation, operationInputDefinition, serviceConsumptionData,
571 properties, componentName);
573 return Either.left(operation);
576 private Either<Operation, ResponseFormat> handleConsumptionInputMappedToProperty(Operation operation,
577 OperationInputDefinition operationInputDefinition, ServiceConsumptionData serviceConsumptionData,
578 List<PropertyDefinition> properties, String componentName) {
579 Optional<PropertyDefinition> servicePropertyCandidate =
580 properties.stream().filter(property -> property.getName()
581 .equals(serviceConsumptionData.getValue())).findAny();
583 if (servicePropertyCandidate.isPresent()) {
584 boolean isInputTypeSimilarToOperation =
585 isAssignedValueFromValidType(operationInputDefinition.getType(),
586 servicePropertyCandidate.get());
588 if (!isInputTypeSimilarToOperation) {
589 return Either.right(componentsUtils.getResponseFormat(
590 ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
593 addPropertyToInputValue(componentName, operation, operationInputDefinition,
594 servicePropertyCandidate.get());
596 return Either.left(operation);
599 private Either<Operation, ResponseFormat> handleConsumptionInputMappedToOperationOutput(Operation operation,
600 OperationInputDefinition operationInputDefinition, List<OperationOutputDefinition> outputs,
601 String consumptionValue, String componentName) {
602 String outputName = getOperationOutputName(consumptionValue);
603 Optional<OperationOutputDefinition> servicePropertyOutputCandidate = outputs.stream()
604 .filter(output -> output.getName().equals(outputName)).findAny();
605 if (servicePropertyOutputCandidate.isPresent()) {
606 boolean isInputTypeSimilarToOperation =
607 isAssignedValueFromValidType(operationInputDefinition.getType(),
608 servicePropertyOutputCandidate.get());
609 if (!isInputTypeSimilarToOperation) {
610 return Either.right(componentsUtils.getResponseFormat(
611 ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
613 addOutputToInputValue(componentName, consumptionValue, operation, operationInputDefinition);
615 return Either.left(operation);
618 private void addPropertyToInputValue(String componentName, Operation operation,
619 OperationInputDefinition operationInputDefinition,
620 PropertyDefinition serviceProperty) {
621 Map<String, List<String>> getProperty = new HashMap<>();
622 List<String> getPropertyValues = new ArrayList<>();
623 getPropertyValues.add(componentName);
624 getPropertyValues.add(serviceProperty.getName());
625 getProperty.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), getPropertyValues);
627 operationInputDefinition.setSourceProperty(serviceProperty.getUniqueId());
628 operation.getInputs().delete(operationInputDefinition);
629 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_PROPERTY,
631 operationInputDefinition.setValue((new Gson()).toJson(getProperty));
632 operation.getInputs().add(operationInputDefinition);
635 private void addOutputToInputValue(String componentName, String consumptionValue,
636 Operation operation, OperationInputDefinition operationInputDefinition) {
637 Map<String, List<String>> getOperationOutput =
638 InterfaceOperationUtils.createMappedOutputDefaultValue(componentName, consumptionValue);
639 operation.getInputs().delete(operationInputDefinition);
640 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_OPERATION_OUTPUT,
642 operationInputDefinition.setValue((new Gson()).toJson(getOperationOutput));
643 operation.getInputs().add(operationInputDefinition);
646 public Either<Operation, ResponseFormat> handleConsumptionStaticValue(String value, String type,
648 OperationInputDefinition
649 operationInputDefinition) {
650 boolean isInputTypeSimilarToOperation =
651 isAssignedValueFromValidType(type, value);
653 if(!isInputTypeSimilarToOperation) {
654 return Either.right(componentsUtils.getResponseFormat(
655 ActionStatus.INVALID_CONSUMPTION_TYPE, type));
658 //Validate Constraint and Value
659 Either<Boolean, ResponseFormat> constraintValidationResponse =
660 validateOperationInputConstraint(operationInputDefinition, value, type);
661 if(constraintValidationResponse.isRight()) {
662 return Either.right(constraintValidationResponse.right().value());
665 addStaticValueToInputOperation(value, operation, operationInputDefinition);
667 return Either.left(operation);
670 private Either<Boolean, ResponseFormat> validateOperationInputConstraint(
671 OperationInputDefinition operationInputDefinition, String value, String type) {
673 if (Objects.nonNull(operationInputDefinition.getParentPropertyType())
674 && !operationInputDefinition.getParentPropertyType().equals(operationInputDefinition.getType())) {
675 InputDefinition inputDefinition = new InputDefinition();
676 inputDefinition.setDefaultValue(value);
677 inputDefinition.setInputPath(operationInputDefinition.getSubPropertyInputPath());
678 inputDefinition.setName(operationInputDefinition.getName());
679 inputDefinition.setType(type);
681 ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
682 propertyDefinition.setType(operationInputDefinition.getParentPropertyType());
683 inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
685 return PropertyValueConstraintValidationUtil.getInstance()
686 .validatePropertyConstraints(Collections.singletonList(inputDefinition), applicationDataTypeCache);
688 PropertyDefinition propertyDefinition = new PropertyDefinition();
689 propertyDefinition.setType(operationInputDefinition.getType());
690 propertyDefinition.setValue(value);
691 propertyDefinition.setName(operationInputDefinition.getName());
693 return PropertyValueConstraintValidationUtil.getInstance()
694 .validatePropertyConstraints(Collections.singletonList(propertyDefinition), applicationDataTypeCache);
698 private void addStaticValueToInputOperation(String value, Operation operation,
699 OperationInputDefinition operationInputDefinition) {
700 operation.getInputs().delete(operationInputDefinition);
701 operationInputDefinition.setSource(STATIC.getSource());
702 operationInputDefinition.setSourceProperty(null);
703 operationInputDefinition.setValue(value);
704 operation.getInputs().add(operationInputDefinition);
707 private Either<Operation, ResponseFormat> handleConsumptionInputValue(String inputId,
710 OperationInputDefinition
711 operationInputDefinition) {
712 List<InputDefinition> serviceInputs = service.getInputs();
713 Optional<InputDefinition> inputForValue =
714 serviceInputs.stream().filter(input -> input.getUniqueId().contains(inputId)).findAny();
716 if(inputForValue.isPresent()) {
717 boolean isInputTypeSimilarToOperation =
718 isAssignedValueFromValidType(operationInputDefinition.getType(), inputForValue.get());
720 if(!isInputTypeSimilarToOperation) {
721 return Either.right(componentsUtils.getResponseFormat(
722 ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
724 addGetInputValueToOperationInput(operation, operationInputDefinition, inputForValue.get());
727 return Either.left(operation);
731 private boolean isAssignedValueFromValidType(String operationInputType, Object actualValue) {
732 if (actualValue instanceof String) {
733 // validate static value
734 ToscaPropertyType actualType = ToscaPropertyType.isValidType(operationInputType);
735 PropertyTypeValidator validator = actualType.getValidator();
736 return validator.isValid((String)actualValue, operationInputType);
737 } else if (actualValue instanceof PropertyDefinition) {
738 // validate input / property value
739 String actualType = ((PropertyDefinition) actualValue).getType();
740 return actualType.equalsIgnoreCase(operationInputType);
741 } else if (actualValue instanceof OperationOutputDefinition) {
742 // validate input / output value
743 String actualType = ((OperationOutputDefinition) actualValue).getType();
744 return actualType.equalsIgnoreCase(operationInputType);
749 private void addGetInputValueToOperationInput(Operation operation,
750 OperationInputDefinition operationInputDefinition,
751 InputDefinition inputForValue) {
752 operation.getInputs().delete(operationInputDefinition);
753 Map<String, String> getInputMap = new HashMap<>();
754 getInputMap.put(ToscaFunctions.GET_INPUT.getFunctionName(), inputForValue.getName());
755 operationInputDefinition.setSourceProperty(inputForValue.getUniqueId());
756 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_INPUT, getInputMap);
757 operationInputDefinition.setValue(new Gson().toJson(getInputMap));
758 operation.getInputs().add(operationInputDefinition);
761 private Either<List<Map<String, Object>>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) {
763 Either<List<ResourceAdminEvent>, ActionStatus> eitherprevVerAudit = auditCassandraDao.getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion);
765 if (eitherprevVerAudit.isRight()) {
766 return Either.right(eitherprevVerAudit.right().value());
770 Either<List<ResourceAdminEvent>, ActionStatus> eitherCurrVerAudit = auditCassandraDao.getAuditByServiceIdAndCurrVersion(componentUUID, componentVersion);
771 if (eitherCurrVerAudit.isRight()) {
772 return Either.right(eitherCurrVerAudit.right().value());
776 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveRestoreList = getArchiveRestoreEventList(componentUUID);
777 if (eitherArchiveRestoreList.isRight()) {
778 return Either.right(eitherArchiveRestoreList.right().value());
781 List<Map<String, Object>> prevVerAuditList = getAuditingFieldsList(eitherprevVerAudit.left().value());
782 List<Map<String, Object>> currVerAuditList = getAuditingFieldsList(eitherCurrVerAudit.left().value());
784 List<Map<String, Object>> duplicateElements = new ArrayList<>();
785 duplicateElements.addAll(prevVerAuditList);
786 duplicateElements.retainAll(currVerAuditList);
788 List<Map<String, Object>> joinedNonDuplicatedList = new ArrayList<>();
789 joinedNonDuplicatedList.addAll(prevVerAuditList);
790 joinedNonDuplicatedList.removeAll(duplicateElements);
791 joinedNonDuplicatedList.addAll(currVerAuditList);
792 joinedNonDuplicatedList.addAll(getAuditingFieldsList(eitherArchiveRestoreList.left().value()));
795 return Either.left(joinedNonDuplicatedList);
798 private Either<List<ResourceAdminEvent>, ActionStatus> getArchiveRestoreEventList(String componentUUID) {
800 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveAudit = auditCassandraDao.getArchiveAuditByServiceInstanceId(componentUUID);
801 if (eitherArchiveAudit.isRight()) {
802 return Either.right(eitherArchiveAudit.right().value());
806 Either<List<ResourceAdminEvent>, ActionStatus> eitherRestoreAudit = auditCassandraDao.getRestoreAuditByServiceInstanceId(componentUUID);
807 if (eitherRestoreAudit.isRight()) {
808 return Either.right(eitherRestoreAudit.right().value());
811 List<ResourceAdminEvent> archiveAudit = new ArrayList<>();
812 archiveAudit.addAll(eitherArchiveAudit.left().value());
813 archiveAudit.addAll(eitherRestoreAudit.left().value());
815 return Either.left(archiveAudit);
818 private List<Map<String, Object>> getAuditingFieldsList(List<? extends AuditingGenericEvent> prevVerAuditList) {
820 List<Map<String, Object>> prevVerAudit = new ArrayList<>();
821 for (AuditingGenericEvent auditEvent : prevVerAuditList) {
822 auditEvent.fillFields();
823 prevVerAudit.add(auditEvent.getFields());
834 * - modifier data (userId)
835 * @return Either<Service, responseFormat>
837 public Either<Service, ResponseFormat> createService(Service service, User user) {
840 user = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false);
841 // validate user role
842 validateUserRole(user, service, new ArrayList<>(), AuditingActionEnum.CREATE_RESOURCE, null);
843 service.setCreatorUserId(user.getUserId());
844 // warn on overridden fields
845 checkFieldsForOverideAttampt(service);
847 log.debug("enrich service with version and state");
848 service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
849 service.setVersion(INITIAL_VERSION);
850 service.setConformanceLevel(ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
851 service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED);
853 Either<Service, ResponseFormat> createServiceResponse = validateServiceBeforeCreate(service, user, AuditingActionEnum.CREATE_RESOURCE);
854 if (createServiceResponse.isRight()) {
855 return createServiceResponse;
857 return createServiceByDao(service, AuditingActionEnum.CREATE_RESOURCE, user);
860 private void checkFieldsForOverideAttampt(Service service) {
861 checkComponentFieldsForOverrideAttempt(service);
862 if (service.getDistributionStatus() != null) {
863 log.info("Distribution Status cannot be defined by user. This field will be overridden by the application");
867 private Either<Service, ResponseFormat> createServiceByDao(Service service, AuditingActionEnum actionEnum, User user) {
868 log.debug("send service {} to dao for create", service.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
870 Either<Boolean, ResponseFormat> lockResult = lockComponentByName(service.getSystemName(), service, "Create Service");
871 if (lockResult.isRight()) {
872 ResponseFormat responseFormat = lockResult.right().value();
873 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
874 return Either.right(responseFormat);
877 log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult);
881 createMandatoryArtifactsData(service, user);
882 createServiceApiArtifactsData(service, user);
883 setToscaArtifactsPlaceHolders(service, user);
884 generateAndAddInputsFromGenericTypeProperties(service, fetchAndSetDerivedFromGenericType(service));
886 Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
888 // service created successfully!!!
889 if (dataModelResponse.isLeft()) {
890 log.debug("Service created successfully!!!");
891 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
892 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
893 ASDCKpiApi.countCreatedServicesKPI();
894 return Either.left(dataModelResponse.left().value());
897 ResponseFormat responseFormat = componentsUtils.getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service, ComponentTypeEnum.SERVICE);
898 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
899 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
900 return Either.right(responseFormat);
903 graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service);
907 @SuppressWarnings("unchecked")
908 private void createServiceApiArtifactsData(Service service, User user) {
909 // create mandatory artifacts
911 // TODO it must be removed after that artifact uniqueId creation will be
912 // moved to ArtifactOperation
913 String serviceUniqueId = service.getUniqueId();
914 Map<String, ArtifactDefinition> artifactMap = service.getServiceApiArtifacts();
915 if (artifactMap == null)
916 artifactMap = new HashMap<>();
918 Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts();
919 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
921 List<CategoryDefinition> categories = service.getCategories();
922 boolean isCreateArtifact = true;
923 if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
924 for (String exlude : exludeServiceCategory) {
925 if (exlude.equalsIgnoreCase(categories.get(0).getName())) {
926 isCreateArtifact = false;
933 if (serviceApiArtifacts != null && isCreateArtifact) {
934 Set<String> keys = serviceApiArtifacts.keySet();
935 for (String serviceApiArtifactName : keys) {
936 Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName);
937 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user, true);
938 artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API);
939 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
942 service.setServiceApiArtifacts(artifactMap);
946 private Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) {
948 Either<Boolean, ResponseFormat> validationResponse = validateServiceFieldsBeforeCreate(user, service, actionEnum);
949 if (validationResponse.isRight()) {
950 return Either.right(validationResponse.right().value());
952 service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
953 service.setContactId(service.getContactId().toLowerCase());
955 // Generate invariant UUID - must be here and not in operation since it
956 // should stay constant during clone
957 String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
958 service.setInvariantUUID(invariantUUID);
960 return Either.left(service);
965 private Either<Boolean, ResponseFormat> validateServiceFieldsBeforeCreate(User user, Service service, AuditingActionEnum actionEnum) {
967 validateComponentFieldsBeforeCreate(user, service, actionEnum);
969 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, service, actionEnum);
970 if (serviceNameUniquenessValidation.isRight()) {
971 throw new ComponentException(serviceNameUniquenessValidation.right().value());
973 Either<Boolean, ResponseFormat> categoryValidation = validateServiceCategory(user, service, actionEnum);
974 if (categoryValidation.isRight()) {
975 return categoryValidation;
977 Either<Boolean, ResponseFormat> projectCodeValidation = validateProjectCode(user, service, actionEnum);
978 if (projectCodeValidation.isRight()) {
979 return projectCodeValidation;
981 validateServiceTypeAndCleanup(service);
983 Either<Boolean, ResponseFormat> serviceRoleValidation = validateServiceRoleAndCleanup(user, service, actionEnum);
984 if (serviceRoleValidation.isRight()) {
985 return serviceRoleValidation;
987 return validateInstantiationTypeValue(user, service, actionEnum);
988 } catch (ComponentException exception) {
989 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
990 componentsUtils.auditComponentAdmin(responseFormat, user, service,
991 AuditingActionEnum.CREATE_SERVICE, ComponentTypeEnum.SERVICE);
992 return Either.right(responseFormat);
996 private Either<Boolean, ResponseFormat> validateServiceCategory(User user, Service service, AuditingActionEnum actionEnum) {
997 log.debug("validate Service category");
998 if (isEmpty(service.getCategories())) {
999 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
1000 componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
1001 return Either.right(errorResponse);
1003 Either<Boolean, ResponseFormat> validatCategory = validateServiceCategory(service.getCategories());
1004 if (validatCategory.isRight()) {
1005 ResponseFormat responseFormat = validatCategory.right().value();
1006 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
1007 return Either.right(responseFormat);
1009 return Either.left(true);
1012 public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) {
1013 validateUserExists(userId, "validate Service Name Exists", false);
1015 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateComponentNameUniqueness(serviceName, null, ComponentTypeEnum.SERVICE);
1019 if (dataModelResponse.isLeft()) {
1020 Map<String, Boolean> result = new HashMap<>();
1021 result.put("isValid", dataModelResponse.left().value());
1022 log.debug("validation was successfully performed.");
1023 return Either.left(result);
1025 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
1026 return Either.right(responseFormat);
1029 public void setElementDao(IElementOperation elementDao) {
1030 this.elementDao = elementDao;
1033 public void setCassandraAuditingDao(AuditCassandraDao auditingDao) {
1034 this.auditCassandraDao = auditingDao;
1037 public ArtifactsBusinessLogic getArtifactBl() {
1038 return artifactsBusinessLogic;
1041 public void setArtifactBl(ArtifactsBusinessLogic artifactBl) {
1042 this.artifactsBusinessLogic = artifactBl;
1045 public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) {
1046 user = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false);
1047 // validate user role
1048 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1050 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1051 if (storageStatus.isRight()) {
1052 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1055 Service currentService = storageStatus.left().value();
1057 if (!ComponentValidationUtils.canWorkOnComponent(currentService, user.getUserId())) {
1058 log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
1059 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
1062 Either<Service, ResponseFormat> validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate);
1063 if (validationRsponse.isRight()) {
1064 log.info("service update metadata: validations field.");
1065 return validationRsponse;
1067 Service serviceToUpdate = validationRsponse.left().value();
1070 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, currentService, "Update Service Metadata");
1071 if (lockResult.isRight()) {
1072 return Either.right(lockResult.right().value());
1075 Either<Service, StorageOperationStatus> updateResponse = toscaOperationFacade.updateToscaElement(serviceToUpdate);
1076 if (updateResponse.isRight()) {
1077 titanDao.rollback();
1078 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
1079 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
1080 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1083 return Either.left(updateResponse.left().value());
1085 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1089 public Either<Set<String>, ResponseFormat> deleteForwardingPaths(String serviceId, Set<String> pathIdsToDelete, User user, boolean lock) {
1090 Service serviceToDelete = initServiceToDeletePaths(serviceId, pathIdsToDelete);
1091 user = validateUser(user, "deleteForwardingPaths", serviceToDelete, null, false);
1092 // validate user role
1093 validateUserRole(user, serviceToDelete, new ArrayList<>(), null, null);
1094 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1095 if (storageStatus.isRight()) {
1096 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1098 Service service = storageStatus.left().value();
1099 Either<Set<String>, StorageOperationStatus> result = null;
1101 Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Forwarding Path on Service");
1102 if (lockResult.isRight()) {
1103 titanDao.rollback();
1104 return Either.right(componentsUtils.getResponseFormat(componentsUtils
1105 .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1109 result = forwardingPathOperation.deleteForwardingPath(service ,pathIdsToDelete);
1110 if (result.isRight()) {
1111 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, service.getName(), result.right().value());
1112 titanDao.rollback();
1113 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
1116 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, service.getSystemName());
1118 } catch (Exception e){
1119 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
1120 titanDao.rollback();
1121 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1123 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1125 return Either.left(result.left().value());
1128 private Service initServiceToDeletePaths(String serviceId, Collection<String> pathIdsToDelete) {
1129 Service serviceToDelete = new Service();
1130 serviceToDelete.setUniqueId(serviceId);
1131 serviceToDelete.setForwardingPaths(new HashMap<>());
1132 pathIdsToDelete.forEach(pathIdToDelete -> serviceToDelete.getForwardingPaths().put(pathIdToDelete, new ForwardingPathDataDefinition()));
1133 return serviceToDelete;
1136 public Either<Service, ResponseFormat> updateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
1137 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, true,"updateForwardingPath", lock);
1140 public Either<Service, ResponseFormat> createForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
1141 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, false, "createForwardingPath", lock);
1144 private ForwardingPathDataDefinition getTrimmedValues(ForwardingPathDataDefinition path){
1145 ForwardingPathDataDefinition dataDefinition = new ForwardingPathDataDefinition(path.getName());
1146 dataDefinition.setName(Strings.nullToEmpty(path.getName()).trim());
1147 dataDefinition.setProtocol(Strings.nullToEmpty(path.getProtocol()).trim());
1148 dataDefinition.setDestinationPortNumber(Strings.nullToEmpty(path.getDestinationPortNumber()).trim());
1149 dataDefinition.setUniqueId(path.getUniqueId());
1150 dataDefinition.setPathElements(path.getPathElements());
1151 dataDefinition.setDescription(path.getDescription());
1152 dataDefinition.setToscaResourceName(path.getToscaResourceName());
1153 return dataDefinition;
1156 private Either<Service, ResponseFormat> createOrUpdateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean isUpdate, String errorContext, boolean lock) {
1157 validateUserAndRole(serviceUpdate, user, errorContext);
1159 Map<String, ForwardingPathDataDefinition> forwardingPaths = serviceUpdate.getForwardingPaths();
1161 Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths =
1162 forwardingPaths.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
1163 entry -> new ForwardingPathDataDefinition(getTrimmedValues(entry.getValue()))));
1165 Either<Boolean, ResponseFormat> booleanResponseFormatEither = forwardingPathValidator.validateForwardingPaths(trimmedForwardingPaths.values(),
1166 serviceId, isUpdate);
1167 if(booleanResponseFormatEither.isRight()){
1168 return Either.right(booleanResponseFormatEither.right().value());
1171 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
1173 if(serviceStorageOperationStatusEither.isRight()){
1174 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
1175 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
1176 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
1178 Service storedService = serviceStorageOperationStatusEither.left().value();
1180 Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
1181 Either<Component, StorageOperationStatus> forwardingPathOrigin = toscaOperationFacade.getLatestByName(ForwardingPathUtils.FORWARDING_PATH_NODE_NAME);
1182 if (forwardingPathOrigin.isRight()) {
1183 StorageOperationStatus errorStatus = forwardingPathOrigin.right().value();
1184 log.debug("Failed to fetch normative forwarding path resource by tosca name, error {}", errorStatus);
1185 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
1187 Component component = forwardingPathOrigin.left().value();
1188 final String toscaResourceName;
1189 if ( component.getComponentType() == ComponentTypeEnum.RESOURCE) {
1190 toscaResourceName = ((Resource) component).getToscaResourceName();
1192 toscaResourceName = "";
1194 Either<Boolean, ResponseFormat> lockResult = null;
1197 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Forwarding Path on Service");
1198 if (lockResult.isRight()) {
1199 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, storedService.getName(),
1200 lockResult.right().value().getFormattedMessage());
1201 return Either.right(lockResult.right().value());
1203 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, storedService.getSystemName());
1206 Map<String, ForwardingPathDataDefinition> resultMap = new HashMap<>();
1208 trimmedForwardingPaths.values().forEach(fp -> fp.setToscaResourceName(toscaResourceName));
1211 for (ForwardingPathDataDefinition forwardingPathDataDefinition : trimmedForwardingPaths.values()) {
1213 result = forwardingPathOperation.updateForwardingPath(serviceId, forwardingPathDataDefinition);
1215 result = forwardingPathOperation.addForwardingPath(serviceId, forwardingPathDataDefinition);
1217 if (result.isRight()) {
1218 titanDao.rollback();
1219 return Either.right(componentsUtils.getResponseFormat(
1220 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
1223 ForwardingPathDataDefinition fpDataDefinition = result.left().value();
1224 resultMap.put(fpDataDefinition.getUniqueId(), forwardingPathDataDefinition);
1228 } catch (Exception e) {
1229 titanDao.rollback();
1230 log.error("Exception occurred during add or update forwarding path property values: {}", e.getMessage(),
1232 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1236 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
1237 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
1240 Service service = createServiceWithForwardingPathForResponse(serviceId, resultMap);
1241 return Either.left(service);
1244 private Service createServiceWithForwardingPathForResponse(String serviceId, Map<String,ForwardingPathDataDefinition> forwardingPathDataDefinitionMap) {
1245 Service service = new Service();
1246 service.setUniqueId(serviceId);
1247 service.setForwardingPaths(forwardingPathDataDefinitionMap);
1251 private void validateUserAndRole(Service serviceUpdate, User user, String errorContext) {
1252 user = validateUser(user, errorContext, serviceUpdate, null, false);
1253 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1258 Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) {
1261 boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
1262 Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1263 if (response.isRight()) {
1264 ResponseFormat errorResponse = response.right().value();
1265 return Either.right(errorResponse);
1268 verifyValuesAreIdentical(serviceUpdate.getCreatorUserId(), currentService.getCreatorUserId(), "creatorUserId");
1269 verifyValuesAreIdentical(serviceUpdate.getCreatorFullName(), currentService.getCreatorFullName(), "creatorFullName");
1270 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterUserId(), currentService.getLastUpdaterUserId(), "lastUpdaterUserId");
1271 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterFullName(), currentService.getLastUpdaterFullName(), "lastUpdaterFullName");
1273 response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null);
1274 if (response.isRight()) {
1275 return Either.right(response.right().value());
1278 verifyValuesAreIdentical(serviceUpdate.getDistributionStatus(), currentService.getDistributionStatus(), "distributionStatus");
1280 if (serviceUpdate.getProjectCode() != null) {
1281 response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1282 if (response.isRight()) {
1283 return Either.right(response.right().value());
1287 response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1288 if (response.isRight()) {
1289 return Either.right(response.right().value());
1292 verifyValuesAreIdentical(serviceUpdate.getCreationDate(), currentService.getCreationDate(), "creationDate");
1293 verifyValuesAreIdentical(serviceUpdate.getVersion(), currentService.getVersion(), "version");
1295 response = validateAndUpdateDescription(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1296 if (response.isRight()) {
1297 return Either.right(response.right().value());
1300 response = validateAndUpdateTags(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1301 if (response.isRight()) {
1302 return Either.right(response.right().value());
1305 response = validateAndUpdateContactId(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1306 if (response.isRight()) {
1307 return Either.right(response.right().value());
1310 verifyValuesAreIdentical(serviceUpdate.getLastUpdateDate(), currentService.getLastUpdateDate(), "lastUpdateDate");
1311 verifyValuesAreIdentical(serviceUpdate.getLifecycleState(), currentService.getLifecycleState(), "lifecycleState");
1312 verifyValuesAreIdentical(serviceUpdate.isHighestVersion(), currentService.isHighestVersion(), "isHighestVersion");
1313 verifyValuesAreIdentical(serviceUpdate.getUUID(), currentService.getUUID(), "uuid");
1315 validateAndUpdateServiceType(currentService, serviceUpdate);
1317 response = validateAndUpdateServiceRole(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1318 if (response.isRight()) {
1319 return Either.right(response.right().value());
1322 response = validateAndUpdateInstantiationTypeValue(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1323 if (response.isRight()) {
1324 return Either.right(response.right().value());
1327 verifyValuesAreIdentical(serviceUpdate.getInvariantUUID(), currentService.getInvariantUUID(), "invariantUUID");
1329 validateAndUpdateEcompNaming(currentService, serviceUpdate);
1331 currentService.setEnvironmentContext(serviceUpdate.getEnvironmentContext());
1332 return Either.left(currentService);
1334 } catch (ComponentException exception) {
1335 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
1336 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate,
1337 AuditingActionEnum.UPDATE_SERVICE_METADATA, ComponentTypeEnum.SERVICE);
1338 return Either.right(responseFormat);
1342 private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
1343 if (updatedValue != null && !updatedValue.equals(originalValue)) {
1344 log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
1348 private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
1349 Boolean isEcompGeneratedCurr = currentService.isEcompGeneratedNaming();
1350 Boolean isEcompGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
1351 if (isEcompGeneratedUpdate != null && !isEcompGeneratedUpdate.equals(isEcompGeneratedCurr)) {
1352 currentService.setEcompGeneratedNaming(isEcompGeneratedUpdate);
1354 String namingPolicyUpdate = serviceUpdate.getNamingPolicy();
1355 if (currentService.isEcompGeneratedNaming()) {
1356 currentService.setNamingPolicy(namingPolicyUpdate);
1358 if (!StringUtils.isEmpty(namingPolicyUpdate)) {
1359 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
1361 currentService.setNamingPolicy("");
1365 private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1366 String contactIdUpdated = serviceUpdate.getContactId();
1367 String contactIdCurrent = currentService.getContactId();
1368 if (!contactIdCurrent.equals(contactIdUpdated)) {
1369 validateContactId(user, serviceUpdate, audatingAction);
1370 currentService.setContactId(contactIdUpdated.toLowerCase());
1372 return Either.left(true);
1375 private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1376 List<String> tagsUpdated = serviceUpdate.getTags();
1377 List<String> tagsCurrent = currentService.getTags();
1378 if (tagsUpdated == null || tagsUpdated.isEmpty()) {
1379 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
1380 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
1381 return Either.right(responseFormat);
1384 if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
1385 validateTagsListAndRemoveDuplicates(user, serviceUpdate, audatingAction);
1386 currentService.setTags(tagsUpdated);
1388 return Either.left(true);
1391 private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1392 String descriptionUpdated = serviceUpdate.getDescription();
1393 String descriptionCurrent = currentService.getDescription();
1394 if (!descriptionCurrent.equals(descriptionUpdated)) {
1395 validateDescriptionAndCleanup(user, serviceUpdate, audatingAction);
1396 currentService.setDescription(serviceUpdate.getDescription());
1398 return Either.left(true);
1401 private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1402 String projectCodeUpdated = serviceUpdate.getProjectCode();
1403 String projectCodeCurrent = currentService.getProjectCode();
1404 if (!projectCodeCurrent.equals(projectCodeUpdated)) {
1406 Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, serviceUpdate, audatingAction);
1407 if (validatProjectCodeResponse.isRight()) {
1408 ResponseFormat errorRespons = validatProjectCodeResponse.right().value();
1409 return Either.right(errorRespons);
1411 currentService.setProjectCode(projectCodeUpdated);
1414 return Either.left(true);
1417 private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1418 String iconUpdated = serviceUpdate.getIcon();
1419 String iconCurrent = currentService.getIcon();
1420 if (!iconCurrent.equals(iconUpdated)) {
1421 if (!hasBeenCertified) {
1422 validateIcon(user, serviceUpdate, audatingAction);
1423 currentService.setIcon(iconUpdated);
1425 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
1426 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
1427 return Either.right(errorResponse);
1430 return Either.left(true);
1433 private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum auditingAction) {
1434 String serviceNameUpdated = serviceUpdate.getName();
1435 String serviceNameCurrent = currentService.getName();
1436 if (!serviceNameCurrent.equals(serviceNameUpdated)) {
1437 if (!hasBeenCertified) {
1438 validateComponentName(user, serviceUpdate, auditingAction);
1439 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, serviceUpdate, auditingAction);
1440 if (serviceNameUniquenessValidation.isRight()) {
1441 return serviceNameUniquenessValidation;
1443 currentService.setName(serviceNameUpdated);
1444 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
1445 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
1448 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
1449 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
1450 return Either.right(errorResponse);
1453 return Either.left(true);
1456 private void validateAndUpdateServiceType(Service currentService, Service updatedService) {
1457 String updatedServiceType = updatedService.getServiceType();
1458 String currentServiceType = currentService.getServiceType();
1459 if (!currentServiceType.equals(updatedServiceType)) {
1460 validateServiceTypeAndCleanup(updatedService);
1461 currentService.setServiceType(updatedServiceType);
1465 private void validateServiceTypeAndCleanup(Component component) {
1466 log.debug("validate service type");
1467 String serviceType = ((Service)component).getServiceType();
1468 if (serviceType == null) {
1469 log.info("service type is not valid.");
1470 throw new ComponentException(ActionStatus.INVALID_SERVICE_TYPE);
1472 serviceType = cleanUpText(serviceType);
1473 validateServiceType(serviceType);
1477 private void validateServiceType(String serviceType) {
1478 if (serviceType.isEmpty()) {
1481 if (!ValidationUtils.validateServiceTypeLength(serviceType)) {
1482 log.info("service type exceeds limit.");
1483 throw new ComponentException(ActionStatus.SERVICE_TYPE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_TYPE_MAX_LENGTH);
1485 if (!ValidationUtils.validateIsEnglish(serviceType)) {
1486 log.info("service type is not valid.");
1487 throw new ComponentException(ActionStatus.INVALID_SERVICE_TYPE);
1491 private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1492 String updatedServiceRole = updatedService.getServiceRole();
1493 String currentServiceRole = currentService.getServiceRole();
1494 if (!currentServiceRole.equals(updatedServiceRole)) {
1495 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRoleAndCleanup(user, updatedService , auditingAction);
1496 if (validateServiceRole.isRight()) {
1497 ResponseFormat errorResponse = validateServiceRole.right().value();
1498 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1499 return Either.right(errorResponse);
1501 currentService.setServiceRole(updatedServiceRole);
1503 return Either.left(true);
1506 protected Either<Boolean, ResponseFormat> validateServiceRoleAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
1507 log.debug("validate service role");
1508 String serviceRole = ((Service)component).getServiceRole();
1509 if (serviceRole != null){
1510 serviceRole = cleanUpText(serviceRole);
1512 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRole(serviceRole);
1513 if (validateServiceRole.isRight()) {
1514 ResponseFormat responseFormat = validateServiceRole.right().value();
1515 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, ComponentTypeEnum.SERVICE);
1516 return Either.right(responseFormat);
1518 return Either.left(true);
1520 return Either.left(false);
1524 private Either<Boolean, ResponseFormat> validateAndUpdateInstantiationTypeValue(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1525 String updatedInstaType= updatedService.getInstantiationType();
1526 String currentInstaType = currentService.getInstantiationType();
1527 if (!currentInstaType.equals(updatedInstaType)) {
1528 Either<Boolean, ResponseFormat> validateInstantiationType = validateInstantiationTypeValue(user, updatedService , auditingAction);
1529 if (validateInstantiationType.isRight()) {
1530 ResponseFormat errorResponse = validateInstantiationType.right().value();
1531 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1532 return Either.right(errorResponse);
1534 currentService.setInstantiationType(updatedInstaType);
1536 return Either.left(true);
1539 private Either<Boolean, ResponseFormat> validateInstantiationTypeValue(User user, Service service, AuditingActionEnum actionEnum) {
1540 log.debug("validate instantiation type");
1541 String instantiationType = service.getInstantiationType();
1542 if (!InstantiationTypes.containsName(instantiationType) || instantiationType == null){
1543 log.error("Recieved Instantiation type {} is not valid.", instantiationType);
1544 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_INSTANTIATION_TYPE);
1545 componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
1546 return Either.right(errorResponse);
1548 return Either.left(true);
1551 private Either<Boolean, ResponseFormat> validateServiceRole(String serviceRole) {
1552 if (serviceRole.equals("")){
1553 return Either.left(true);
1555 if (!ValidationUtils.validateServiceRoleLength(serviceRole)) {
1556 log.info("service role exceeds limit.");
1557 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ROLE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_ROLE_MAX_LENGTH);
1558 return Either.right(errorResponse);
1561 if (!ValidationUtils.validateIsEnglish(serviceRole)) {
1562 log.info("service role is not valid.");
1563 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_ROLE);
1564 return Either.right(errorResponse);
1566 return Either.left(true);
1570 private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1571 List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1572 List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1573 Either<Boolean, ResponseFormat> validateCategoryResponse = validateServiceCategory(user, serviceUpdate, audatingAction);
1574 if (validateCategoryResponse.isRight()) {
1575 return Either.right(validateCategoryResponse.right().value());
1577 if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1578 if (!hasBeenCertified) {
1579 currentService.setCategories(categoryUpdated);
1581 log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1582 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1583 return Either.right(errorResponse);
1586 return Either.left(true);
1590 private Either<Boolean, ResponseFormat> validateServiceCategory(List<CategoryDefinition> list) {
1592 if (list.size() > 1) {
1593 log.debug("Must be only one category for service");
1594 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.SERVICE.getValue());
1595 return Either.right(responseFormat);
1597 CategoryDefinition category = list.get(0);
1598 if (category.getSubcategories() != null) {
1599 log.debug("Subcategories cannot be defined for service");
1600 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CANNOT_CONTAIN_SUBCATEGORY);
1601 return Either.right(responseFormat);
1603 if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
1604 log.debug("Resource category is empty");
1605 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
1606 return Either.right(responseFormat);
1609 log.debug("validating service category {} against valid categories list", list);
1610 Either<List<CategoryDefinition>, ActionStatus> categorys = elementDao.getAllServiceCategories();
1611 if (categorys.isRight()) {
1612 log.debug("failed to retrieve service categories from Titan");
1613 ResponseFormat responseFormat = componentsUtils.getResponseFormat(categorys.right().value());
1614 return Either.right(responseFormat);
1616 List<CategoryDefinition> categoryList = categorys.left().value();
1617 for (CategoryDefinition value : categoryList) {
1618 if (value.getName().equals(category.getName())) {
1619 return Either.left(true);
1622 log.debug("Category {} is not part of service category group. Service category valid values are {}", list, categoryList);
1623 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.SERVICE.getValue()));
1625 return Either.left(false);
1628 public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1629 Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1630 if (serviceResponseFormatEither.isRight()){
1631 return Either.right(serviceResponseFormatEither.right().value());
1633 final ServiceRelations serviceRelations = new ForwardingPathUtils().convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1634 return Either.left(serviceRelations);
1639 public ResponseFormat deleteService(String serviceId, User user) {
1640 ResponseFormat responseFormat;
1641 String ecompErrorContext = "delete service";
1643 validateUserExists(user, ecompErrorContext, false);
1644 Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1645 if (serviceStatus.isRight()) {
1646 log.debug("failed to get service {}", serviceId);
1647 return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1650 Service service = serviceStatus.left().value();
1652 StorageOperationStatus result = StorageOperationStatus.OK;
1653 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1654 if (lockResult.isRight()) {
1655 return lockResult.right().value();
1658 result = markComponentToDelete(service);
1659 if (result.equals(StorageOperationStatus.OK)) {
1660 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1662 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1663 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1665 return responseFormat;
1667 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1668 log.warn("operation failed. do rollback");
1669 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1670 titanDao.rollback();
1672 log.debug("operation success. do commit");
1675 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1679 public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1680 ResponseFormat responseFormat;
1681 String ecompErrorContext = "delete service";
1682 validateUserNotEmpty(user, ecompErrorContext);
1683 user = validateUserExists(user, ecompErrorContext, false);
1685 Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1686 if (getResult.isRight()) {
1687 return getResult.right().value();
1689 Service service = getResult.left().value();
1691 StorageOperationStatus result = StorageOperationStatus.OK;
1692 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1693 if (lockResult.isRight()) {
1694 result = StorageOperationStatus.GENERAL_ERROR;
1695 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1699 result = markComponentToDelete(service);
1700 if (result.equals(StorageOperationStatus.OK)) {
1701 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1703 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1704 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1706 return responseFormat;
1709 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1710 log.warn("operation failed. do rollback");
1711 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1712 titanDao.rollback();
1714 log.debug("operation success. do commit");
1717 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1721 public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1722 String ecompErrorContext = "Get service";
1723 validateUserNotEmpty(user, ecompErrorContext);
1724 validateUserExists(user, ecompErrorContext, false);
1726 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1727 if (storageStatus.isRight()) {
1728 log.debug("failed to get service by id {}", serviceId);
1729 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1732 if(!(storageStatus.left().value() instanceof Service)){
1733 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1735 Service service = storageStatus.left().value();
1736 return Either.left(service);
1743 public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1744 validateUserExists(userId, "get Service By Name And Version", false);
1745 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1746 if (storageStatus.isRight()) {
1747 log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1748 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceName));
1750 Service service = storageStatus.left().value();
1751 return Either.left(service);
1754 @SuppressWarnings("unchecked")
1755 private void createMandatoryArtifactsData(Service service, User user) {
1756 // create mandatory artifacts
1758 // TODO it must be removed after that artifact uniqueId creation will be
1759 // moved to ArtifactOperation
1760 String serviceUniqueId = service.getUniqueId();
1761 Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1762 if (artifactMap == null)
1763 artifactMap = new HashMap<>();
1765 Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalServiceArtifacts();
1766 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1768 String category = service.getCategories().get(0).getName();
1769 boolean isCreateArtifact = true;
1770 if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1771 for (String exlude : exludeServiceCategory) {
1772 if (exlude.equalsIgnoreCase(category)) {
1773 isCreateArtifact = false;
1780 if (informationalServiceArtifacts != null && isCreateArtifact) {
1781 Set<String> keys = informationalServiceArtifacts.keySet();
1782 for (String informationalServiceArtifactName : keys) {
1783 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1784 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap, user, false);
1785 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1789 service.setArtifacts(artifactMap);
1793 private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user, Boolean isServiceApi) {
1795 ArtifactDefinition artifactInfo = artifactsBusinessLogic.createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1798 artifactInfo.setMandatory(false);
1799 artifactInfo.setServiceApi(true);
1801 return artifactInfo;
1804 private Either<DistributionTransitionEnum, ResponseFormat> validateTransitionEnum(String distributionTransition) {
1805 DistributionTransitionEnum transitionEnum = null;
1807 transitionEnum = DistributionTransitionEnum.getFromDisplayName(distributionTransition);
1808 if (transitionEnum == null) {
1809 BeEcompErrorManager.getInstance().logBeSystemError(CHANGE_SERVICE_DISTRIBUTION);
1810 log.info("state operation is not valid. operations allowed are: {}", DistributionTransitionEnum.valuesAsString());
1811 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1812 return Either.right(error);
1815 return Either.left(transitionEnum);
1818 private Either<String, ResponseFormat> validateComment(LifecycleChangeInfoWithAction comment) {
1819 String data = comment.getUserRemarks();
1821 if (data == null || data.trim().isEmpty()) {
1822 BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1823 log.debug("user comment cannot be empty or null.");
1824 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1826 data = ValidationUtils.removeNoneUtf8Chars(data);
1827 data = ValidationUtils.removeHtmlTags(data);
1828 data = ValidationUtils.normaliseWhitespace(data);
1829 data = ValidationUtils.stripOctets(data);
1831 if (!ValidationUtils.validateLength(data, ValidationUtils.COMMENT_MAX_LENGTH)) {
1832 BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1833 log.debug("user comment exceeds limit.");
1834 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, "comment", String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH)));
1836 if (!ValidationUtils.validateIsEnglish(data)) {
1837 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1839 return Either.left(data);
1842 private Either<Service, ResponseFormat> validateServiceDistributionChange(User user, String serviceId, AuditingActionEnum auditAction, String comment) {
1843 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1844 if (storageStatus.isRight()) {
1845 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId);
1846 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1847 componentsUtils.auditComponent(responseFormat, user, auditAction, new ResourceCommonInfo(serviceId, ComponentTypeEnum.SERVICE.getValue()), comment);
1848 return Either.right(responseFormat);
1850 Service service = storageStatus.left().value();
1852 if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1853 log.info("service {} is not available for distribution. Should be in certified state", service.getUniqueId());
1854 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1855 createAudit(user, auditAction, comment, service, responseFormat);
1856 return Either.right(responseFormat);
1858 return Either.left(service);
1861 private Either<User, ResponseFormat> validateUserDistributionChange(User user, Service service, AuditingActionEnum auditAction, String comment) {
1862 log.debug("get user from DB");
1865 user = validateUser(user, "Activate Distribution", service, auditAction, false);
1866 // validate user role
1867 List<Role> roles = new ArrayList<>();
1868 roles.add(Role.ADMIN);
1869 roles.add(Role.GOVERNOR);
1870 roles.add(Role.OPS);
1871 validateUserRole(user, service, roles, auditAction, comment);
1872 return Either.left(user);
1875 private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat) {
1876 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1877 componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1878 ResourceVersionInfo.newBuilder()
1879 .state(component.getLifecycleState().name())
1880 .version(component.getVersion())
1885 private String getEnvNameFromConfiguration() {
1886 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1887 log.trace("Update environment name to be {}", configuredEnvName);
1888 return configuredEnvName;
1891 public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier, ServiceDistributionReqInfo data) {
1893 Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation.validateActivateServiceRequest(serviceId, envId, modifier, data);
1894 if (activationRequestInformationEither.isRight()) {
1895 return Either.right(activationRequestInformationEither.right().value());
1898 ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1900 Either<String, ResponseFormat> result = null;
1901 String did = ThreadLocalsHolder.getUuid();
1902 Service service = activationRequestInformation.getServiceToActivate();
1903 result = buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1907 public Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext, User modifier) {
1908 String envName = getEnvNameFromConfiguration();
1909 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1910 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1911 if (notifyServiceResponse == ActionStatus.OK) {
1912 return Either.left(did);
1914 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1915 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1916 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1917 return Either.right(error);
1921 public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1923 User user = validateUserExists(modifier.getUserId(), "activate Distribution", false);
1924 Either<Service, ResponseFormat> result = null;
1925 ResponseFormat response = null;
1926 Service updatedService = null;
1927 String did = ThreadLocalsHolder.getUuid();
1929 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1930 if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1931 log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1932 envName = configuredEnvName;
1936 ServletContext servletContext = request.getSession().getServletContext();
1937 boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1938 if (!isDistributionEngineUp) {
1939 BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1940 log.debug("Distribution Engine is DOWN");
1941 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1942 return Either.right(response);
1945 Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1946 if (serviceRes.isRight()) {
1947 log.debug("failed retrieving service");
1948 response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1949 componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1950 new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1951 ResourceVersionInfo.newBuilder()
1954 return Either.right(response);
1956 Service service = serviceRes.left().value();
1957 String dcurrStatus = service.getDistributionStatus().name();
1958 String updatedStatus = dcurrStatus;
1959 StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1960 if (readyForDistribution.equals(StorageOperationStatus.OK)) {
1961 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1962 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1963 if (notifyServiceResponse == ActionStatus.OK) {
1964 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED);
1965 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1966 updatedService = updateStateRes.left().value();
1967 updatedStatus = updatedService.getDistributionStatus().name();
1969 // The response is not relevant
1970 updatedService = service;
1972 ASDCKpiApi.countActivatedDistribution();
1973 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1974 result = Either.left(updatedService);
1976 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1977 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1978 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1979 result = Either.right(response);
1982 response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution), envName);
1983 result = Either.right(response);
1985 componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1986 new ResourceCommonInfo(service.getName(),ComponentTypeEnum.SERVICE.getValue()),
1987 ResourceVersionInfo.newBuilder()
1988 .distributionStatus(dcurrStatus)
1990 ResourceVersionInfo.newBuilder()
1991 .distributionStatus(updatedStatus)
1997 // convert to private after deletion of temp url
1998 public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
2000 validateUserExists(user.getUserId(), "update Distribution Status For Activation", false);
2002 String serviceId = service.getUniqueId();
2003 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "updateDistributionStatusForActivation");
2004 if (lockResult.isRight()) {
2005 return Either.right(lockResult.right().value());
2008 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
2009 if (result.isRight()) {
2010 titanDao.rollback();
2011 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
2012 log.debug("service {} change distribution status failed", serviceId);
2013 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2016 return Either.left(result.left().value());
2018 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
2022 public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
2024 validateUserExists(user.getUserId(), "mark Distribution As Deployed", false);
2025 log.debug("mark distribution deployed");
2027 AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
2028 Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
2029 if (getServiceResponse.isRight()) {
2030 BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
2031 log.debug("service {} not found", serviceId);
2032 ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
2034 return Either.right(responseFormat);
2037 Service service = getServiceResponse.left().value();
2038 user = validateRoleForDeploy(did, user, auditAction, service);
2039 return checkDistributionAndDeploy(did, user, auditAction, service);
2043 public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2044 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
2045 // Only one VF Module Artifact per instance - add it to a list of one
2046 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
2048 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2052 private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock, boolean inTransaction, ComponentInstance ri) {
2053 List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
2055 if (ri.getOriginType() == OriginTypeEnum.VF) {
2056 asList = Arrays.asList(new VfModuleArtifactGenerator(modifier, ri, service, shouldLock, inTransaction));
2061 private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
2062 Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
2063 if(currVF.getGroupInstances() != null){
2064 currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
2066 return currVF.getGroupInstances();
2069 private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) {
2070 ArtifactDefinition vfModuleAertifact = null;
2071 if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
2072 Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.name())).findAny();
2073 if (optionalVfModuleArtifact.isPresent()) {
2074 vfModuleAertifact = optionalVfModuleArtifact.get();
2077 if (vfModuleAertifact == null) {
2078 Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service, payloadWrapper.getInnerElement());
2079 if (createVfModuleArtifact.isLeft()) {
2080 vfModuleAertifact = createVfModuleArtifact.left().value();
2082 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
2085 return vfModuleAertifact;
2088 private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
2089 List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
2090 if (groupsForCurrVF != null) {
2091 for (GroupInstance groupInstance : groupsForCurrVF) {
2092 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
2093 vfModulePayloads.add(modulePayload);
2095 vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
2097 final Gson gson = new GsonBuilder().setPrettyPrinting().create();
2099 String vfModulePayloadString = gson.toJson(vfModulePayloads);
2100 payloadWrapper.setInnerElement(vfModulePayloadString);
2105 private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock, boolean inTransaction) {
2106 ArtifactDefinition vfModuleArtifact = null;
2107 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
2108 Wrapper<String> payloadWrapper = new Wrapper<>();
2109 List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
2110 if (responseWrapper.isEmpty()) {
2111 fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
2113 if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
2114 vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
2116 if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
2117 vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper, responseWrapper, service);
2120 Either<ArtifactDefinition, ResponseFormat> result;
2121 if (responseWrapper.isEmpty()) {
2122 result = Either.left(vfModuleArtifact);
2124 result = Either.right(responseWrapper.getInnerElement());
2130 private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper, Service service) {
2131 ArtifactDefinition result = null;
2132 Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, inTransaction, System::currentTimeMillis,
2133 () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), currVF.getUniqueId());
2134 if (eitherPayload.isLeft()) {
2135 result = eitherPayload.left().value();
2137 responseWrapper.setInnerElement(eitherPayload.right().value());
2139 if (result == null) {
2140 result = vfModuleArtifact;
2146 private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service, String vfModulePayloadString) {
2148 ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
2149 String newCheckSum = null;
2151 vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
2152 vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
2153 vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
2154 vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
2155 vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
2156 vfModuleArtifactDefinition.setTimeout(0);
2157 vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
2158 vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
2159 if (vfModulePayloadString != null) {
2160 newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
2162 vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
2164 Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent = artifactToscaOperation.addArifactToComponent(vfModuleArtifactDefinition, service.getUniqueId(), NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
2166 Either<ArtifactDefinition, ResponseFormat> result;
2167 if (addArifactToComponent.isLeft()) {
2168 result = Either.left(addArifactToComponent.left().value());
2170 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArifactToComponent.right().value())));
2176 public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2178 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
2179 // Get All Deployment Artifacts
2180 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
2181 // Filter in Only Heat Env
2182 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
2183 // Create ArtifactGenerator from those Artifacts
2184 map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction, resourceInstance.getUniqueId())).collect(Collectors.toList());
2186 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2190 private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
2192 // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
2194 if (service.getComponentInstances() != null) {
2195 List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
2196 if (artifactGenList != null && !artifactGenList.isEmpty()) {
2197 for (ArtifactGenerator<CallVal> entry : artifactGenList) {
2198 Either<CallVal, ResponseFormat> callRes;
2200 callRes = entry.call();
2201 if (callRes.isRight()) {
2202 log.debug("Failed to generate artifact error : {}", callRes.right().value());
2203 return Either.right(callRes.right().value());
2205 } catch (Exception e) {
2206 log.debug("Failed to generate artifact exception : {}", e);
2207 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2212 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
2213 if (storageStatus.isRight()) {
2214 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2217 Service currentService = storageStatus.left().value();
2219 return Either.left(currentService);
2223 abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
2227 class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2228 ArtifactDefinition artifactDefinition;
2230 String resourceInstanceName;
2234 boolean inTransaction;
2236 HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock, boolean inTransaction, String instanceId) {
2237 this.artifactDefinition = artifactDefinition;
2238 this.service = service;
2239 this.resourceInstanceName = resourceInstanceName;
2240 this.modifier = modifier;
2241 this.shouldLock = shouldLock;
2242 this.instanceId = instanceId;
2243 this.inTransaction = inTransaction;
2247 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2248 return artifactsBusinessLogic.forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier, shouldLock, inTransaction, instanceId);
2251 public ArtifactDefinition getArtifactDefinition() {
2252 return artifactDefinition;
2257 class VfModuleArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2259 private ComponentInstance componentInstance;
2260 private Service service;
2262 boolean inTransaction;
2265 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2266 return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
2269 private VfModuleArtifactGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock, boolean inTransaction) {
2272 this.componentInstance = componentInstance;
2273 this.service = service;
2274 this.shouldLock = shouldLock;
2275 this.inTransaction = inTransaction;
2280 private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction, Service service) {
2281 boolean isDeployed = isDistributionDeployed(distributionId);
2283 return Either.left(service);
2285 Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
2286 if (distributionSuccess.isRight()) {
2287 return Either.right(distributionSuccess.right().value());
2290 log.debug("mark distribution {} as deployed - success", distributionId);
2291 componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK", user);
2292 return Either.left(service);
2295 private boolean isDistributionDeployed(String distributionId) {
2296 Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
2298 boolean isDeployed = false;
2299 if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
2301 log.debug("distribution {} is already deployed", distributionId);
2307 protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
2309 log.trace("checkDistributionSuccess");
2310 // get all "DRequest" records for this distribution
2312 Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
2313 if (distRequestsResponse.isRight()) {
2314 ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
2315 return Either.right(error);
2318 List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
2319 if (distributionRequests.isEmpty()) {
2320 BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
2321 log.info("distribution {} is not found", did);
2322 ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
2323 return Either.right(error);
2325 boolean isRequestSucceeded = false;
2326 for (ResourceAdminEvent event : distributionRequests) {
2327 String eventStatus = event.getStatus();
2328 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2329 isRequestSucceeded = true;
2334 // get all "DNotify" records for this distribution
2335 Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
2336 if (distNotificationsResponse.isRight()) {
2337 ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
2338 return Either.right(error);
2341 List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
2342 boolean isNotificationsSucceeded = false;
2343 for (DistributionNotificationEvent event : distributionNotifications) {
2344 String eventStatus = event.getStatus();
2345 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2346 isNotificationsSucceeded = true;
2351 // if request failed OR there are notifications that failed
2352 if (!(isRequestSucceeded && isNotificationsSucceeded)) {
2354 log.info("distribution {} has failed", did);
2355 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2356 auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2357 return Either.right(error);
2359 return Either.left(true);
2362 private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) {
2364 ResponseFormat error = componentsUtils.getResponseFormat(status, params);
2365 String message = "";
2366 if (error.getMessageId() != null) {
2367 message = error.getMessageId() + ": ";
2369 message += error.getFormattedMessage();
2371 if (service != null) {
2372 componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user);
2374 componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
2379 private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
2380 Either<User, ActionStatus> eitherCreator = userAdmin.getUser(user.getUserId(), false);
2381 if (eitherCreator.isRight() || eitherCreator.left().value() == null) {
2382 BeEcompErrorManager.getInstance().logBeUserMissingError("Deploy Service", user.getUserId());
2383 log.debug("validateRoleForDeploy method - user is not listed. userId= {}", user.getUserId());
2384 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, user.getUserId());
2385 auditDeployError(did, user, auditAction, service, ActionStatus.USER_NOT_FOUND);
2386 throw new ComponentException(ActionStatus.USER_NOT_FOUND, user.getUserId());
2388 user = eitherCreator.left().value();
2389 log.debug("validate user role");
2390 List<Role> roles = new ArrayList<>();
2391 roles.add(Role.ADMIN);
2392 roles.add(Role.OPS);
2394 validateUserRole(user, service, roles, auditAction, null);
2395 } catch (ComponentException e){
2396 log.info("role {} is not allowed to perform this action", user.getRole());
2397 auditDeployError(did, user, auditAction, service, e.getActionStatus());
2404 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
2405 Service service = (Service) component;
2406 Map<String, ArtifactDefinition> artifactMap = service.getDeploymentArtifacts();
2407 if (artifactMap == null) {
2408 artifactMap = new HashMap<>();
2410 service.setDeploymentArtifacts(artifactMap);
2414 public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
2415 return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
2418 private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
2419 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
2420 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
2421 return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
2425 public ComponentInstanceBusinessLogic getComponentInstanceBL() {
2426 return componentInstanceBusinessLogic;
2430 public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
2432 validateUserExists(userId, "Get Component Instances", false);
2433 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2434 if (getComponentRes.isRight()) {
2435 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
2436 return Either.right(responseFormat);
2439 List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
2441 return Either.left(componentInstances);
2444 public ICacheMangerOperation getCacheManagerOperation() {
2445 return cacheManagerOperation;
2448 public void setCacheManagerOperation(ICacheMangerOperation cacheManagerOperation) {
2449 this.cacheManagerOperation = cacheManagerOperation;
2452 public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
2453 this.forwardingPathOperation = forwardingPathOperation;
2457 public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
2458 this.toscaOperationFacade = toscaOperationFacade;
2460 * 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
2463 public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2465 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2466 Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
2467 Component component = null;
2468 Either<Boolean, ResponseFormat> lockResult = null;
2469 log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
2471 validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2472 if (validateUserAndComponentRes.isRight()) {
2473 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed. ", groupInstanceId, serviceId);
2474 actionResult = Either.right(validateUserAndComponentRes.right().value());
2476 if (actionResult == null) {
2477 component = validateUserAndComponentRes.left().value().getKey();
2478 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2479 if (lockResult.isRight()) {
2480 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
2481 actionResult = Either.right(lockResult.right().value());
2483 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
2486 if (actionResult == null) {
2487 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId, newProperties);
2488 if (actionResult.isRight()) {
2489 log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ", groupInstanceId, actionResult.right().value().getFormattedMessage());
2492 } catch (Exception e) {
2493 log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2494 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2496 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2497 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2500 return actionResult;
2503 private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2505 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2506 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2507 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2508 ComponentInstance relatedComponentInstance = null;
2509 GroupInstance oldGroupInstance = null;
2510 Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2511 GroupInstance updatedGroupInstance = null;
2512 boolean inTransaction = true;
2513 findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2514 if (findGroupInstanceRes.isRight()) {
2515 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
2516 actionResult = Either.right(findGroupInstanceRes.right().value());
2518 if (actionResult == null) {
2519 oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2520 relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2521 updateGroupInstanceResult = groupBusinessLogic.validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
2522 if (updateGroupInstanceResult.isRight()) {
2523 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ", oldGroupInstance.getName());
2524 actionResult = Either.right(updateGroupInstanceResult.right().value());
2527 if (actionResult == null) {
2528 updatedGroupInstance = updateGroupInstanceResult.left().value();
2529 if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2530 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance, updatedGroupInstance, inTransaction);
2531 if (updateParentsModificationTimeRes.isRight()) {
2532 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ", oldGroupInstance.getName());
2533 actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2537 if (actionResult == null) {
2538 actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2540 return actionResult;
2543 private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance,
2544 boolean inTranscation) {
2546 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2547 Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2548 Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic.updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2549 updatedGroupInstance.getModificationTime(), inTranscation);
2550 if (updateComponentInstanceRes.isRight()) {
2551 log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(), updatedGroupInstance.getName());
2552 actionResult = Either.right(updateComponentInstanceRes.right().value());
2554 serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2555 if (serviceMetadataUpdateResult.isRight()) {
2556 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ", component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2557 actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2559 actionResult = Either.left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2562 return actionResult;
2565 private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2567 Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2568 Either<Component, ResponseFormat> validateComponentExistsRes = null;
2569 User currUser = null;
2570 Component component = null;
2571 Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2572 if (validationUserResult.isRight()) {
2573 log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2574 result = Either.right(validationUserResult.right().value());
2576 if (result == null) {
2577 currUser = validationUserResult.left().value();
2578 validateComponentExistsRes = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2579 if (validateComponentExistsRes.isRight()) {
2580 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2581 result = Either.right(validateComponentExistsRes.right().value());
2584 if (result == null) {
2585 component = validateComponentExistsRes.left().value();
2586 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2587 log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(), component.getCreatorUserId());
2588 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2591 if (result == null) {
2592 result = Either.left(new ImmutablePair<>(component, currUser));
2597 private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component, String componentInstanceId, String groupInstanceId) {
2599 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2600 GroupInstance groupInstance = null;
2601 ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2602 if (foundComponentInstance == null) {
2603 log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2604 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service", component.getName()));
2606 else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2607 groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst().orElse(null);
2608 if (groupInstance == null) {
2609 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2610 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId, foundComponentInstance.getName()));
2613 if (actionResult == null) {
2614 actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2616 return actionResult;
2619 private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2620 ComponentInstance componentInstance = null;
2621 if (isNotEmpty(component.getComponentInstances())) {
2622 componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst().orElse(null);
2624 return componentInstance;
2627 private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2628 User user = validateUser(modifier, ecompErrorContext, null, null, false);
2629 List<Role> roles = new ArrayList<>();
2630 roles.add(Role.ADMIN);
2631 roles.add(Role.DESIGNER);
2632 validateUserRole(user, roles);
2633 return Either.left(user);
2636 public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId, List<String> dataParamsToReturn) {
2638 ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2639 Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2641 if (serviceResultEither.isRight()) {
2642 if(serviceResultEither.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
2643 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2644 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2647 log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2648 return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2651 Service service = serviceResultEither.left().value();
2652 if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
2653 ListUtils.emptyIfNull(service.getInputs())
2654 .forEach(input -> input.setConstraints(setInputConstraint(input)));
2657 UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2658 return Either.left(dataTransfer);
2661 public Either<String, ResponseFormat> deleteIfNotAlreadyDeletedServiceFilter(String serviceId, String resourceId, String userId, boolean lock) {
2662 Service serviceToDelete = initServiceToDeleteServiceFilter(serviceId);
2663 User user = validateUserExists(userId, "Create service Filter", false);
2666 validateUser(user, "deleteIfNotAlreadyDeletedServiceFilter", serviceToDelete, null, false);
2668 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
2669 if (storageStatus.isRight()) {
2670 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2672 Service service = storageStatus.left().value();
2674 Either<Boolean, ResponseFormat> response = serviceFilterValidator.validateComponentInstanceExist(service, resourceId);
2675 if (storageStatus.isRight()) {
2676 return Either.right(response.right().value());
2678 final Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(resourceId);
2679 if (!optionalComponentInstance.isPresent() ){
2680 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2682 CINodeFilterDataDefinition nodeFilter = optionalComponentInstance.get().getNodeFilter();
2683 if (nodeFilter == null){
2684 return Either.left(resourceId);
2687 Either<String, StorageOperationStatus> result;
2689 Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Service Filter from service");
2690 if (lockResult.isRight()) {
2691 titanDao.rollback();
2692 return Either.right(componentsUtils.getResponseFormat(componentsUtils
2693 .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2697 result = serviceFilterOperation.deleteNodeFilter(service , resourceId);
2698 if (result.isRight()) {
2699 log.debug("Failed to delete node filter in service {}. Response is {}. ", service.getName(), result.right().value());
2700 titanDao.rollback();
2701 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
2704 log.debug("Node filter successfully changed in service {} . ", service.getSystemName());
2706 } catch (Exception e){
2707 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
2708 titanDao.rollback();
2709 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2711 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2713 return Either.left(result.left().value());
2717 private Service initServiceToDeleteServiceFilter(String serviceId) {
2718 Service serviceToDelete = new Service();
2719 serviceToDelete.setUniqueId(serviceId);
2720 return serviceToDelete;
2724 public Either<CINodeFilterDataDefinition, ResponseFormat> createIfNotAlreadyExistServiceFilter(String serviceId, String componentInstanceId, String userId, boolean lock) {
2725 String errorContext = "createIfNotAlreadyExistServiceFilter";
2726 User user = validateUserExists(userId, "Create service Filter", false);
2728 Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
2729 if (serviceEither.isRight()) {
2730 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceEither.right().value(), ComponentTypeEnum.SERVICE), ""));
2732 final Service service = serviceEither.left().value();
2733 validateUserAndRole(service, user, errorContext);
2735 Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(componentInstanceId);
2736 if (!optionalComponentInstance.isPresent()){
2737 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2739 ComponentInstance componentInstance = optionalComponentInstance.get();
2740 CINodeFilterDataDefinition serviceFilter = componentInstance.getNodeFilter();
2741 if (serviceFilter != null){
2742 return Either.left(serviceFilter);
2745 Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2747 Either<Boolean, ResponseFormat> lockResult = null;
2750 lockComponent(service.getUniqueId(), service, "Create Service Filter");
2751 if (lockResult.isRight()) {
2752 log.debug("Failed to lock service {}. Response is {}. ", service.getName(),
2753 lockResult.right().value().getFormattedMessage());
2754 return Either.right(lockResult.right().value());
2756 log.debug("The service with system name {} locked. ", service.getSystemName());
2759 CINodeFilterDataDefinition serviceFilterResult;
2761 result = serviceFilterOperation.createNodeFilter(serviceId, componentInstanceId);
2762 if (result.isRight()) {
2763 titanDao.rollback();
2764 return Either.right(componentsUtils.getResponseFormat(
2765 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2768 serviceFilterResult = result.left().value();
2772 } catch (Exception e) {
2773 titanDao.rollback();
2774 log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2776 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2779 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2780 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2783 return Either.left(serviceFilterResult);
2787 public Either<CINodeFilterDataDefinition, ResponseFormat> updateServiceFilter(String serviceId, String componentInstanceId,
2788 List<String> constraints, User inUser, boolean lock) {
2789 String errorContext = "createIfNotAlreadyExistServiceFilter";
2790 User user = validateUserExists(inUser, errorContext, true);
2791 validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2792 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2794 if(serviceStorageOperationStatusEither.isRight()){
2795 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2796 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2797 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2799 Service storedService = serviceStorageOperationStatusEither.left().value();
2801 Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2802 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId, constraints,
2803 NodeFilterConstraintAction.UPDATE);
2804 if(booleanResponseFormatEither.isRight()){
2805 return Either.right(booleanResponseFormatEither.right().value());
2809 Either<Boolean, ResponseFormat> lockResult = null;
2812 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2813 if (lockResult.isRight()) {
2814 log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
2815 lockResult.right().value().getFormattedMessage());
2816 return Either.right(lockResult.right().value());
2818 log.debug("The service with system name {} locked. ", storedService.getSystemName());
2821 Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2822 if (!componentInstanceOptional.isPresent()){
2823 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2825 CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2826 if(serviceFilter == null){
2827 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2829 CINodeFilterDataDefinition serviceFilterResult;
2831 List<RequirementNodeFilterPropertyDataDefinition> properties = constraints.stream().map(this::getRequirementNodeFilterPropertyDataDefinition).collect(Collectors.toList());
2832 Either<CINodeFilterDataDefinition, StorageOperationStatus> result = serviceFilterOperation.updateProperties(serviceId, componentInstanceId, serviceFilter ,properties);
2834 if (result.isRight()) {
2835 titanDao.rollback();
2836 return Either.right(componentsUtils.getResponseFormat(
2837 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2840 serviceFilterResult = result.left().value();
2844 } catch (Exception e) {
2845 titanDao.rollback();
2846 log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2848 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2851 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2852 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2855 return Either.left(serviceFilterResult);
2858 private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition(String constraint){
2859 RequirementNodeFilterPropertyDataDefinition pdd = new RequirementNodeFilterPropertyDataDefinition();
2860 pdd.setConstraints(Arrays.asList(constraint));
2864 public Either<CINodeFilterDataDefinition, ResponseFormat> addOrDeleteServiceFilter(String serviceId, String componentInstanceId,
2865 NodeFilterConstraintAction action, String constraint, int position, User inUser, boolean lock) {
2866 String errorContext = "createIfNotAlreadyExistServiceFilter";
2867 User user = validateUserExists(inUser, errorContext, true);
2868 validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2870 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2872 if(serviceStorageOperationStatusEither.isRight()){
2873 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2874 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2875 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2877 Service storedService = serviceStorageOperationStatusEither.left().value();
2879 Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2880 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId,
2881 Collections.singletonList(constraint), action);
2882 if(booleanResponseFormatEither.isRight()){
2883 return Either.right(booleanResponseFormatEither.right().value());
2886 Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2888 Either<Boolean, ResponseFormat> lockResult = null;
2889 CINodeFilterDataDefinition serviceFilterResult = null;
2893 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2894 if (lockResult.isRight()) {
2895 log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
2896 lockResult.right().value().getFormattedMessage());
2897 return Either.right(lockResult.right().value());
2899 log.debug("The service with system name {} locked. ", storedService.getSystemName());
2903 Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2904 if (!componentInstanceOptional.isPresent()){
2905 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2907 CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2908 if(serviceFilter == null){
2909 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2915 RequirementNodeFilterPropertyDataDefinition newProperty = new RequirementNodeFilterPropertyDataDefinition();
2916 newProperty.setConstraints(Collections.singletonList(constraint));
2917 result = serviceFilterOperation.addNewProperty(serviceId, componentInstanceId,serviceFilter,newProperty);
2920 result = serviceFilterOperation.deleteConstraint(serviceId, componentInstanceId, serviceFilter, position);
2923 log.error("Unsupported operation "+action);
2924 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2928 if (result.isRight()) {
2929 titanDao.rollback();
2930 return Either.right(componentsUtils.getResponseFormat(
2931 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2934 serviceFilterResult = result.left().value();
2938 } catch (Exception e) {
2939 titanDao.rollback();
2940 log.error("Exception occurred during add or update node filter property values: {}", e.getMessage(),
2942 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2945 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2946 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2949 return Either.left(serviceFilterResult);