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 return handleConsumptionStaticValue(consumptionValue, type, operation,
479 operationInputDefinition);
482 if (Objects.isNull(sourceValue)) {
483 List<PropertyDefinition> propertyDefinitions;
484 String componentName;
485 List<OperationOutputDefinition> outputs = null;
486 if (source.equals(containerService.getUniqueId())) {
487 Either<Service, StorageOperationStatus> serviceToTakePropEither =
488 toscaOperationFacade.getToscaElement(source);
489 if (serviceToTakePropEither.isRight()) {
490 return Either.right(componentsUtils.getResponseFormat(serviceToTakePropEither.right().value()));
492 Service service = serviceToTakePropEither.left().value();
493 operationInputDefinition.setSource(service.getUniqueId());
494 sourceValue = SERVICE_INPUT;
495 propertyDefinitions = service.getProperties();
496 componentName = service.getName();
497 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier,
498 service.getInterfaces()).getListToscaDataDefinition();
500 Optional<ComponentInstance> getComponentInstance = containerService.getComponentInstanceById(source);
501 if(!getComponentInstance.isPresent()){
502 return Either.right(componentsUtils.getResponseFormat(
503 ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, source));
505 ComponentInstance componentInstance = getComponentInstance.get();
506 operationInputDefinition.setSource(componentInstance.getUniqueId());
507 propertyDefinitions = componentInstance.getProperties();
508 componentName = source.equals(serviceInstanceId) ? SELF : componentInstance.getName();
509 if (MapUtils.isNotEmpty(componentInstance.getInterfaces())) {
510 Map<String, InterfaceDataDefinition> componentInstanceInterfaces =
511 componentInstance.getInterfaces().entrySet().stream()
512 .collect(Collectors.toMap((Map.Entry::getKey),
513 (interfaceEntry -> (InterfaceDataDefinition) interfaceEntry.getValue())));
514 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier,
515 componentInstanceInterfaces).getListToscaDataDefinition();
519 if(sourceValue == ServiceConsumptionSource.SERVICE_INPUT) {
520 //The operation input in service consumption has been mapped to an input in the parent service
521 return handleConsumptionInputValue(consumptionValue, containerService, operation,
522 operationInputDefinition);
524 return handleConsumptionPropertyValue(operation, operationInputDefinition,
525 serviceConsumptionData, propertyDefinitions, outputs, consumptionValue, componentName);
528 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.SOURCE, source);
529 operationInputDefinition.setSource(source);
531 return Either.left(operation);
534 private Optional<OperationInputDefinition> getOperationInputByInputId(ServiceConsumptionData serviceConsumptionData,
535 ListDataDefinition<OperationInputDefinition> inputs) {
537 if(CollectionUtils.isEmpty(inputs.getListToscaDataDefinition())) {
538 return Optional.empty();
541 return inputs.getListToscaDataDefinition().stream().filter(operationInput -> operationInput.getInputId().equals
542 (serviceConsumptionData.getInputId()))
546 private Either<Operation, ResponseFormat> handleConsumptionPropertyValue(
547 Operation operation, OperationInputDefinition operationInputDefinition,
548 ServiceConsumptionData serviceConsumptionData, List<PropertyDefinition> properties,
549 List<OperationOutputDefinition> outputs, String consumptionValue, String componentName) {
551 if (CollectionUtils.isEmpty(properties) && CollectionUtils.isEmpty(outputs)) {
552 return Either.left(operation);
555 if (CollectionUtils.isNotEmpty(outputs)
556 && isOperationInputMappedToOtherOperationOutput(getOperationOutputName(consumptionValue), outputs)) {
557 return handleConsumptionInputMappedToOperationOutput(operation, operationInputDefinition, outputs,
558 consumptionValue, componentName);
561 if (CollectionUtils.isNotEmpty(properties)) {
562 return handleConsumptionInputMappedToProperty(operation, operationInputDefinition, serviceConsumptionData,
563 properties, componentName);
565 return Either.left(operation);
568 private Either<Operation, ResponseFormat> handleConsumptionInputMappedToProperty(Operation operation,
569 OperationInputDefinition operationInputDefinition, ServiceConsumptionData serviceConsumptionData,
570 List<PropertyDefinition> properties, String componentName) {
571 Optional<PropertyDefinition> servicePropertyCandidate =
572 properties.stream().filter(property -> property.getName()
573 .equals(serviceConsumptionData.getValue())).findAny();
575 if (servicePropertyCandidate.isPresent()) {
576 boolean isInputTypeSimilarToOperation =
577 isAssignedValueFromValidType(operationInputDefinition.getType(),
578 servicePropertyCandidate.get());
580 if (!isInputTypeSimilarToOperation) {
581 return Either.right(componentsUtils.getResponseFormat(
582 ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
585 addPropertyToInputValue(componentName, operation, operationInputDefinition,
586 servicePropertyCandidate.get());
588 return Either.left(operation);
591 private Either<Operation, ResponseFormat> handleConsumptionInputMappedToOperationOutput(Operation operation,
592 OperationInputDefinition operationInputDefinition, List<OperationOutputDefinition> outputs,
593 String consumptionValue, String componentName) {
594 String outputName = getOperationOutputName(consumptionValue);
595 Optional<OperationOutputDefinition> servicePropertyOutputCandidate = outputs.stream()
596 .filter(output -> output.getName().equals(outputName)).findAny();
597 if (servicePropertyOutputCandidate.isPresent()) {
598 boolean isInputTypeSimilarToOperation =
599 isAssignedValueFromValidType(operationInputDefinition.getType(),
600 servicePropertyOutputCandidate.get());
601 if (!isInputTypeSimilarToOperation) {
602 return Either.right(componentsUtils.getResponseFormat(
603 ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
605 addOutputToInputValue(componentName, consumptionValue, operation, operationInputDefinition);
607 return Either.left(operation);
610 private void addPropertyToInputValue(String componentName, Operation operation,
611 OperationInputDefinition operationInputDefinition,
612 PropertyDefinition serviceProperty) {
613 Map<String, List<String>> getProperty = new HashMap<>();
614 List<String> getPropertyValues = new ArrayList<>();
615 getPropertyValues.add(componentName);
616 getPropertyValues.add(serviceProperty.getName());
617 getProperty.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), getPropertyValues);
619 operationInputDefinition.setSourceProperty(serviceProperty.getUniqueId());
620 operation.getInputs().delete(operationInputDefinition);
621 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_PROPERTY,
623 operationInputDefinition.setValue((new Gson()).toJson(getProperty));
624 operation.getInputs().add(operationInputDefinition);
627 private void addOutputToInputValue(String componentName, String consumptionValue,
628 Operation operation, OperationInputDefinition operationInputDefinition) {
629 Map<String, List<String>> getOperationOutput =
630 InterfaceOperationUtils.createMappedOutputDefaultValue(componentName, consumptionValue);
631 operation.getInputs().delete(operationInputDefinition);
632 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_OPERATION_OUTPUT,
634 operationInputDefinition.setValue((new Gson()).toJson(getOperationOutput));
635 operation.getInputs().add(operationInputDefinition);
638 public Either<Operation, ResponseFormat> handleConsumptionStaticValue(String value, String type,
640 OperationInputDefinition
641 operationInputDefinition) {
642 boolean isInputTypeSimilarToOperation =
643 isAssignedValueFromValidType(type, value);
645 if(!isInputTypeSimilarToOperation) {
646 return Either.right(componentsUtils.getResponseFormat(
647 ActionStatus.INVALID_CONSUMPTION_TYPE, type));
650 //Validate Constraint and Value
651 Either<Boolean, ResponseFormat> constraintValidationResponse =
652 validateOperationInputConstraint(operationInputDefinition, value, type);
653 if(constraintValidationResponse.isRight()) {
654 return Either.right(constraintValidationResponse.right().value());
657 addStaticValueToInputOperation(value, operation, operationInputDefinition);
659 return Either.left(operation);
662 private Either<Boolean, ResponseFormat> validateOperationInputConstraint(
663 OperationInputDefinition operationInputDefinition, String value, String type) {
665 if (Objects.nonNull(operationInputDefinition.getParentPropertyType())
666 && !operationInputDefinition.getParentPropertyType().equals(operationInputDefinition.getType())) {
667 InputDefinition inputDefinition = new InputDefinition();
668 inputDefinition.setDefaultValue(value);
669 inputDefinition.setInputPath(operationInputDefinition.getSubPropertyInputPath());
670 inputDefinition.setName(operationInputDefinition.getName());
671 inputDefinition.setType(type);
673 ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
674 propertyDefinition.setType(operationInputDefinition.getParentPropertyType());
675 inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
677 return PropertyValueConstraintValidationUtil.getInstance()
678 .validatePropertyConstraints(Collections.singletonList(inputDefinition), applicationDataTypeCache);
680 PropertyDefinition propertyDefinition = new PropertyDefinition();
681 propertyDefinition.setType(operationInputDefinition.getType());
682 propertyDefinition.setValue(value);
683 propertyDefinition.setName(operationInputDefinition.getName());
685 return PropertyValueConstraintValidationUtil.getInstance()
686 .validatePropertyConstraints(Collections.singletonList(propertyDefinition), applicationDataTypeCache);
690 private void addStaticValueToInputOperation(String value, Operation operation,
691 OperationInputDefinition operationInputDefinition) {
692 operation.getInputs().delete(operationInputDefinition);
693 operationInputDefinition.setSource(STATIC.getSource());
694 operationInputDefinition.setSourceProperty(null);
695 operationInputDefinition.setValue(value);
696 operation.getInputs().add(operationInputDefinition);
699 private Either<Operation, ResponseFormat> handleConsumptionInputValue(String inputId,
702 OperationInputDefinition
703 operationInputDefinition) {
704 List<InputDefinition> serviceInputs = service.getInputs();
705 Optional<InputDefinition> inputForValue =
706 serviceInputs.stream().filter(input -> input.getUniqueId().contains(inputId)).findAny();
708 if(inputForValue.isPresent()) {
709 boolean isInputTypeSimilarToOperation =
710 isAssignedValueFromValidType(operationInputDefinition.getType(), inputForValue.get());
712 if(!isInputTypeSimilarToOperation) {
713 return Either.right(componentsUtils.getResponseFormat(
714 ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
716 addGetInputValueToOperationInput(operation, operationInputDefinition, inputForValue.get());
719 return Either.left(operation);
723 private boolean isAssignedValueFromValidType(String operationInputType, Object actualValue) {
724 if (actualValue instanceof String) {
725 // validate static value
726 ToscaPropertyType actualType = ToscaPropertyType.isValidType(operationInputType);
727 PropertyTypeValidator validator = actualType.getValidator();
728 return validator.isValid((String)actualValue, operationInputType);
729 } else if (actualValue instanceof PropertyDefinition) {
730 // validate input / property value
731 String actualType = ((PropertyDefinition) actualValue).getType();
732 return actualType.equalsIgnoreCase(operationInputType);
733 } else if (actualValue instanceof OperationOutputDefinition) {
734 // validate input / output value
735 String actualType = ((OperationOutputDefinition) actualValue).getType();
736 return actualType.equalsIgnoreCase(operationInputType);
741 private void addGetInputValueToOperationInput(Operation operation,
742 OperationInputDefinition operationInputDefinition,
743 InputDefinition inputForValue) {
744 operation.getInputs().delete(operationInputDefinition);
745 Map<String, String> getInputMap = new HashMap<>();
746 getInputMap.put(ToscaFunctions.GET_INPUT.getFunctionName(), inputForValue.getName());
747 operationInputDefinition.setSourceProperty(inputForValue.getUniqueId());
748 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_INPUT, getInputMap);
749 operationInputDefinition.setValue(new Gson().toJson(getInputMap));
750 operation.getInputs().add(operationInputDefinition);
753 private Either<List<Map<String, Object>>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) {
755 Either<List<ResourceAdminEvent>, ActionStatus> eitherprevVerAudit = auditCassandraDao.getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion);
757 if (eitherprevVerAudit.isRight()) {
758 return Either.right(eitherprevVerAudit.right().value());
762 Either<List<ResourceAdminEvent>, ActionStatus> eitherCurrVerAudit = auditCassandraDao.getAuditByServiceIdAndCurrVersion(componentUUID, componentVersion);
763 if (eitherCurrVerAudit.isRight()) {
764 return Either.right(eitherCurrVerAudit.right().value());
768 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveRestoreList = getArchiveRestoreEventList(componentUUID);
769 if (eitherArchiveRestoreList.isRight()) {
770 return Either.right(eitherArchiveRestoreList.right().value());
773 List<Map<String, Object>> prevVerAuditList = getAuditingFieldsList(eitherprevVerAudit.left().value());
774 List<Map<String, Object>> currVerAuditList = getAuditingFieldsList(eitherCurrVerAudit.left().value());
776 List<Map<String, Object>> duplicateElements = new ArrayList<>();
777 duplicateElements.addAll(prevVerAuditList);
778 duplicateElements.retainAll(currVerAuditList);
780 List<Map<String, Object>> joinedNonDuplicatedList = new ArrayList<>();
781 joinedNonDuplicatedList.addAll(prevVerAuditList);
782 joinedNonDuplicatedList.removeAll(duplicateElements);
783 joinedNonDuplicatedList.addAll(currVerAuditList);
784 joinedNonDuplicatedList.addAll(getAuditingFieldsList(eitherArchiveRestoreList.left().value()));
787 return Either.left(joinedNonDuplicatedList);
790 private Either<List<ResourceAdminEvent>, ActionStatus> getArchiveRestoreEventList(String componentUUID) {
792 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveAudit = auditCassandraDao.getArchiveAuditByServiceInstanceId(componentUUID);
793 if (eitherArchiveAudit.isRight()) {
794 return Either.right(eitherArchiveAudit.right().value());
798 Either<List<ResourceAdminEvent>, ActionStatus> eitherRestoreAudit = auditCassandraDao.getRestoreAuditByServiceInstanceId(componentUUID);
799 if (eitherRestoreAudit.isRight()) {
800 return Either.right(eitherRestoreAudit.right().value());
803 List<ResourceAdminEvent> archiveAudit = new ArrayList<>();
804 archiveAudit.addAll(eitherArchiveAudit.left().value());
805 archiveAudit.addAll(eitherRestoreAudit.left().value());
807 return Either.left(archiveAudit);
810 private List<Map<String, Object>> getAuditingFieldsList(List<? extends AuditingGenericEvent> prevVerAuditList) {
812 List<Map<String, Object>> prevVerAudit = new ArrayList<>();
813 for (AuditingGenericEvent auditEvent : prevVerAuditList) {
814 auditEvent.fillFields();
815 prevVerAudit.add(auditEvent.getFields());
826 * - modifier data (userId)
827 * @return Either<Service, responseFormat>
829 public Either<Service, ResponseFormat> createService(Service service, User user) {
832 user = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false);
833 // validate user role
834 validateUserRole(user, service, new ArrayList<>(), AuditingActionEnum.CREATE_RESOURCE, null);
835 service.setCreatorUserId(user.getUserId());
836 // warn on overridden fields
837 checkFieldsForOverideAttampt(service);
839 log.debug("enrich service with version and state");
840 service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
841 service.setVersion(INITIAL_VERSION);
842 service.setConformanceLevel(ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
843 service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED);
845 Either<Service, ResponseFormat> createServiceResponse = validateServiceBeforeCreate(service, user, AuditingActionEnum.CREATE_RESOURCE);
846 if (createServiceResponse.isRight()) {
847 return createServiceResponse;
849 return createServiceByDao(service, AuditingActionEnum.CREATE_RESOURCE, user);
852 private void checkFieldsForOverideAttampt(Service service) {
853 checkComponentFieldsForOverrideAttempt(service);
854 if (service.getDistributionStatus() != null) {
855 log.info("Distribution Status cannot be defined by user. This field will be overridden by the application");
859 private Either<Service, ResponseFormat> createServiceByDao(Service service, AuditingActionEnum actionEnum, User user) {
860 log.debug("send service {} to dao for create", service.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
862 Either<Boolean, ResponseFormat> lockResult = lockComponentByName(service.getSystemName(), service, "Create Service");
863 if (lockResult.isRight()) {
864 ResponseFormat responseFormat = lockResult.right().value();
865 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
866 return Either.right(responseFormat);
869 log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult);
873 createMandatoryArtifactsData(service, user);
874 createServiceApiArtifactsData(service, user);
875 setToscaArtifactsPlaceHolders(service, user);
876 generateAndAddInputsFromGenericTypeProperties(service, fetchAndSetDerivedFromGenericType(service));
878 Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
880 // service created successfully!!!
881 if (dataModelResponse.isLeft()) {
882 log.debug("Service created successfully!!!");
883 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
884 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
885 ASDCKpiApi.countCreatedServicesKPI();
886 return Either.left(dataModelResponse.left().value());
889 ResponseFormat responseFormat = componentsUtils.getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service, ComponentTypeEnum.SERVICE);
890 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
891 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
892 return Either.right(responseFormat);
895 graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service);
899 @SuppressWarnings("unchecked")
900 private void createServiceApiArtifactsData(Service service, User user) {
901 // create mandatory artifacts
903 // TODO it must be removed after that artifact uniqueId creation will be
904 // moved to ArtifactOperation
905 String serviceUniqueId = service.getUniqueId();
906 Map<String, ArtifactDefinition> artifactMap = service.getServiceApiArtifacts();
907 if (artifactMap == null)
908 artifactMap = new HashMap<>();
910 Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts();
911 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
913 List<CategoryDefinition> categories = service.getCategories();
914 boolean isCreateArtifact = true;
915 if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
916 for (String exlude : exludeServiceCategory) {
917 if (exlude.equalsIgnoreCase(categories.get(0).getName())) {
918 isCreateArtifact = false;
925 if (serviceApiArtifacts != null && isCreateArtifact) {
926 Set<String> keys = serviceApiArtifacts.keySet();
927 for (String serviceApiArtifactName : keys) {
928 Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName);
929 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user, true);
930 artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API);
931 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
934 service.setServiceApiArtifacts(artifactMap);
938 private Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) {
940 Either<Boolean, ResponseFormat> validationResponse = validateServiceFieldsBeforeCreate(user, service, actionEnum);
941 if (validationResponse.isRight()) {
942 return Either.right(validationResponse.right().value());
944 service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
945 service.setContactId(service.getContactId().toLowerCase());
947 // Generate invariant UUID - must be here and not in operation since it
948 // should stay constant during clone
949 String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
950 service.setInvariantUUID(invariantUUID);
952 return Either.left(service);
957 private Either<Boolean, ResponseFormat> validateServiceFieldsBeforeCreate(User user, Service service, AuditingActionEnum actionEnum) {
959 validateComponentFieldsBeforeCreate(user, service, actionEnum);
961 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, service, actionEnum);
962 if (serviceNameUniquenessValidation.isRight()) {
963 throw new ComponentException(serviceNameUniquenessValidation.right().value());
965 Either<Boolean, ResponseFormat> categoryValidation = validateServiceCategory(user, service, actionEnum);
966 if (categoryValidation.isRight()) {
967 return categoryValidation;
969 Either<Boolean, ResponseFormat> projectCodeValidation = validateProjectCode(user, service, actionEnum);
970 if (projectCodeValidation.isRight()) {
971 return projectCodeValidation;
973 validateServiceTypeAndCleanup(service);
975 Either<Boolean, ResponseFormat> serviceRoleValidation = validateServiceRoleAndCleanup(user, service, actionEnum);
976 if (serviceRoleValidation.isRight()) {
977 return serviceRoleValidation;
979 return validateInstantiationTypeValue(user, service, actionEnum);
980 } catch (ComponentException exception) {
981 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
982 componentsUtils.auditComponentAdmin(responseFormat, user, service,
983 AuditingActionEnum.CREATE_SERVICE, ComponentTypeEnum.SERVICE);
984 return Either.right(responseFormat);
988 private Either<Boolean, ResponseFormat> validateServiceCategory(User user, Service service, AuditingActionEnum actionEnum) {
989 log.debug("validate Service category");
990 if (isEmpty(service.getCategories())) {
991 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
992 componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
993 return Either.right(errorResponse);
995 Either<Boolean, ResponseFormat> validatCategory = validateServiceCategory(service.getCategories());
996 if (validatCategory.isRight()) {
997 ResponseFormat responseFormat = validatCategory.right().value();
998 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
999 return Either.right(responseFormat);
1001 return Either.left(true);
1004 public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) {
1005 validateUserExists(userId, "validate Service Name Exists", false);
1007 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateComponentNameUniqueness(serviceName, null, ComponentTypeEnum.SERVICE);
1011 if (dataModelResponse.isLeft()) {
1012 Map<String, Boolean> result = new HashMap<>();
1013 result.put("isValid", dataModelResponse.left().value());
1014 log.debug("validation was successfully performed.");
1015 return Either.left(result);
1017 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
1018 return Either.right(responseFormat);
1021 public void setElementDao(IElementOperation elementDao) {
1022 this.elementDao = elementDao;
1025 public void setCassandraAuditingDao(AuditCassandraDao auditingDao) {
1026 this.auditCassandraDao = auditingDao;
1029 public ArtifactsBusinessLogic getArtifactBl() {
1030 return artifactsBusinessLogic;
1033 public void setArtifactBl(ArtifactsBusinessLogic artifactBl) {
1034 this.artifactsBusinessLogic = artifactBl;
1037 public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) {
1038 user = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false);
1039 // validate user role
1040 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1042 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1043 if (storageStatus.isRight()) {
1044 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1047 Service currentService = storageStatus.left().value();
1049 if (!ComponentValidationUtils.canWorkOnComponent(currentService, user.getUserId())) {
1050 log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
1051 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
1054 Either<Service, ResponseFormat> validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate);
1055 if (validationRsponse.isRight()) {
1056 log.info("service update metadata: validations field.");
1057 return validationRsponse;
1059 Service serviceToUpdate = validationRsponse.left().value();
1062 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, currentService, "Update Service Metadata");
1063 if (lockResult.isRight()) {
1064 return Either.right(lockResult.right().value());
1067 Either<Service, StorageOperationStatus> updateResponse = toscaOperationFacade.updateToscaElement(serviceToUpdate);
1068 if (updateResponse.isRight()) {
1069 titanDao.rollback();
1070 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
1071 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
1072 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1075 return Either.left(updateResponse.left().value());
1077 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1081 public Either<Set<String>, ResponseFormat> deleteForwardingPaths(String serviceId, Set<String> pathIdsToDelete, User user, boolean lock) {
1082 Service serviceToDelete = initServiceToDeletePaths(serviceId, pathIdsToDelete);
1083 user = validateUser(user, "deleteForwardingPaths", serviceToDelete, null, false);
1084 // validate user role
1085 validateUserRole(user, serviceToDelete, new ArrayList<>(), null, null);
1086 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1087 if (storageStatus.isRight()) {
1088 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1090 Service service = storageStatus.left().value();
1091 Either<Set<String>, StorageOperationStatus> result = null;
1093 Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Forwarding Path on Service");
1094 if (lockResult.isRight()) {
1095 titanDao.rollback();
1096 return Either.right(componentsUtils.getResponseFormat(componentsUtils
1097 .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1101 result = forwardingPathOperation.deleteForwardingPath(service ,pathIdsToDelete);
1102 if (result.isRight()) {
1103 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, service.getName(), result.right().value());
1104 titanDao.rollback();
1105 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
1108 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, service.getSystemName());
1110 } catch (Exception e){
1111 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
1112 titanDao.rollback();
1113 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1115 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1117 return Either.left(result.left().value());
1120 private Service initServiceToDeletePaths(String serviceId, Collection<String> pathIdsToDelete) {
1121 Service serviceToDelete = new Service();
1122 serviceToDelete.setUniqueId(serviceId);
1123 serviceToDelete.setForwardingPaths(new HashMap<>());
1124 pathIdsToDelete.forEach(pathIdToDelete -> serviceToDelete.getForwardingPaths().put(pathIdToDelete, new ForwardingPathDataDefinition()));
1125 return serviceToDelete;
1128 public Either<Service, ResponseFormat> updateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
1129 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, true,"updateForwardingPath", lock);
1132 public Either<Service, ResponseFormat> createForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
1133 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, false, "createForwardingPath", lock);
1136 private ForwardingPathDataDefinition getTrimmedValues(ForwardingPathDataDefinition path){
1137 ForwardingPathDataDefinition dataDefinition = new ForwardingPathDataDefinition(path.getName());
1138 dataDefinition.setName(Strings.nullToEmpty(path.getName()).trim());
1139 dataDefinition.setProtocol(Strings.nullToEmpty(path.getProtocol()).trim());
1140 dataDefinition.setDestinationPortNumber(Strings.nullToEmpty(path.getDestinationPortNumber()).trim());
1141 dataDefinition.setUniqueId(path.getUniqueId());
1142 dataDefinition.setPathElements(path.getPathElements());
1143 dataDefinition.setDescription(path.getDescription());
1144 dataDefinition.setToscaResourceName(path.getToscaResourceName());
1145 return dataDefinition;
1148 private Either<Service, ResponseFormat> createOrUpdateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean isUpdate, String errorContext, boolean lock) {
1149 validateUserAndRole(serviceUpdate, user, errorContext);
1151 Map<String, ForwardingPathDataDefinition> forwardingPaths = serviceUpdate.getForwardingPaths();
1153 Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths =
1154 forwardingPaths.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
1155 entry -> new ForwardingPathDataDefinition(getTrimmedValues(entry.getValue()))));
1157 Either<Boolean, ResponseFormat> booleanResponseFormatEither = forwardingPathValidator.validateForwardingPaths(trimmedForwardingPaths.values(),
1158 serviceId, isUpdate);
1159 if(booleanResponseFormatEither.isRight()){
1160 return Either.right(booleanResponseFormatEither.right().value());
1163 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
1165 if(serviceStorageOperationStatusEither.isRight()){
1166 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
1167 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
1168 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
1170 Service storedService = serviceStorageOperationStatusEither.left().value();
1172 Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
1173 Either<Component, StorageOperationStatus> forwardingPathOrigin = toscaOperationFacade.getLatestByName(ForwardingPathUtils.FORWARDING_PATH_NODE_NAME);
1174 if (forwardingPathOrigin.isRight()) {
1175 StorageOperationStatus errorStatus = forwardingPathOrigin.right().value();
1176 log.debug("Failed to fetch normative forwarding path resource by tosca name, error {}", errorStatus);
1177 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
1179 Component component = forwardingPathOrigin.left().value();
1180 final String toscaResourceName;
1181 if ( component.getComponentType() == ComponentTypeEnum.RESOURCE) {
1182 toscaResourceName = ((Resource) component).getToscaResourceName();
1184 toscaResourceName = "";
1186 Either<Boolean, ResponseFormat> lockResult = null;
1189 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Forwarding Path on Service");
1190 if (lockResult.isRight()) {
1191 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, storedService.getName(),
1192 lockResult.right().value().getFormattedMessage());
1193 return Either.right(lockResult.right().value());
1195 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, storedService.getSystemName());
1198 Map<String, ForwardingPathDataDefinition> resultMap = new HashMap<>();
1200 trimmedForwardingPaths.values().forEach(fp -> fp.setToscaResourceName(toscaResourceName));
1203 for (ForwardingPathDataDefinition forwardingPathDataDefinition : trimmedForwardingPaths.values()) {
1205 result = forwardingPathOperation.updateForwardingPath(serviceId, forwardingPathDataDefinition);
1207 result = forwardingPathOperation.addForwardingPath(serviceId, forwardingPathDataDefinition);
1209 if (result.isRight()) {
1210 titanDao.rollback();
1211 return Either.right(componentsUtils.getResponseFormat(
1212 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
1215 ForwardingPathDataDefinition fpDataDefinition = result.left().value();
1216 resultMap.put(fpDataDefinition.getUniqueId(), forwardingPathDataDefinition);
1220 } catch (Exception e) {
1221 titanDao.rollback();
1222 log.error("Exception occurred during add or update forwarding path property values: {}", e.getMessage(),
1224 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1228 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
1229 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
1232 Service service = createServiceWithForwardingPathForResponse(serviceId, resultMap);
1233 return Either.left(service);
1236 private Service createServiceWithForwardingPathForResponse(String serviceId, Map<String,ForwardingPathDataDefinition> forwardingPathDataDefinitionMap) {
1237 Service service = new Service();
1238 service.setUniqueId(serviceId);
1239 service.setForwardingPaths(forwardingPathDataDefinitionMap);
1243 private void validateUserAndRole(Service serviceUpdate, User user, String errorContext) {
1244 user = validateUser(user, errorContext, serviceUpdate, null, false);
1245 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1250 Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) {
1253 boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
1254 Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1255 if (response.isRight()) {
1256 ResponseFormat errorResponse = response.right().value();
1257 return Either.right(errorResponse);
1260 verifyValuesAreIdentical(serviceUpdate.getCreatorUserId(), currentService.getCreatorUserId(), "creatorUserId");
1261 verifyValuesAreIdentical(serviceUpdate.getCreatorFullName(), currentService.getCreatorFullName(), "creatorFullName");
1262 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterUserId(), currentService.getLastUpdaterUserId(), "lastUpdaterUserId");
1263 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterFullName(), currentService.getLastUpdaterFullName(), "lastUpdaterFullName");
1265 response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null);
1266 if (response.isRight()) {
1267 return Either.right(response.right().value());
1270 verifyValuesAreIdentical(serviceUpdate.getDistributionStatus(), currentService.getDistributionStatus(), "distributionStatus");
1272 if (serviceUpdate.getProjectCode() != null) {
1273 response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1274 if (response.isRight()) {
1275 return Either.right(response.right().value());
1279 response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1280 if (response.isRight()) {
1281 return Either.right(response.right().value());
1284 verifyValuesAreIdentical(serviceUpdate.getCreationDate(), currentService.getCreationDate(), "creationDate");
1285 verifyValuesAreIdentical(serviceUpdate.getVersion(), currentService.getVersion(), "version");
1287 response = validateAndUpdateDescription(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1288 if (response.isRight()) {
1289 return Either.right(response.right().value());
1292 response = validateAndUpdateTags(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1293 if (response.isRight()) {
1294 return Either.right(response.right().value());
1297 response = validateAndUpdateContactId(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1298 if (response.isRight()) {
1299 return Either.right(response.right().value());
1302 verifyValuesAreIdentical(serviceUpdate.getLastUpdateDate(), currentService.getLastUpdateDate(), "lastUpdateDate");
1303 verifyValuesAreIdentical(serviceUpdate.getLifecycleState(), currentService.getLifecycleState(), "lifecycleState");
1304 verifyValuesAreIdentical(serviceUpdate.isHighestVersion(), currentService.isHighestVersion(), "isHighestVersion");
1305 verifyValuesAreIdentical(serviceUpdate.getUUID(), currentService.getUUID(), "uuid");
1307 validateAndUpdateServiceType(currentService, serviceUpdate);
1309 response = validateAndUpdateServiceRole(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1310 if (response.isRight()) {
1311 return Either.right(response.right().value());
1314 response = validateAndUpdateInstantiationTypeValue(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1315 if (response.isRight()) {
1316 return Either.right(response.right().value());
1319 verifyValuesAreIdentical(serviceUpdate.getInvariantUUID(), currentService.getInvariantUUID(), "invariantUUID");
1321 validateAndUpdateEcompNaming(currentService, serviceUpdate);
1323 currentService.setEnvironmentContext(serviceUpdate.getEnvironmentContext());
1324 return Either.left(currentService);
1326 } catch (ComponentException exception) {
1327 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
1328 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate,
1329 AuditingActionEnum.UPDATE_SERVICE_METADATA, ComponentTypeEnum.SERVICE);
1330 return Either.right(responseFormat);
1334 private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
1335 if (updatedValue != null && !updatedValue.equals(originalValue)) {
1336 log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
1340 private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
1341 Boolean isEcompGeneratedCurr = currentService.isEcompGeneratedNaming();
1342 Boolean isEcompGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
1343 if (isEcompGeneratedUpdate != null && !isEcompGeneratedUpdate.equals(isEcompGeneratedCurr)) {
1344 currentService.setEcompGeneratedNaming(isEcompGeneratedUpdate);
1346 String namingPolicyUpdate = serviceUpdate.getNamingPolicy();
1347 if (currentService.isEcompGeneratedNaming()) {
1348 currentService.setNamingPolicy(namingPolicyUpdate);
1350 if (!StringUtils.isEmpty(namingPolicyUpdate)) {
1351 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
1353 currentService.setNamingPolicy("");
1357 private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1358 String contactIdUpdated = serviceUpdate.getContactId();
1359 String contactIdCurrent = currentService.getContactId();
1360 if (!contactIdCurrent.equals(contactIdUpdated)) {
1361 validateContactId(user, serviceUpdate, audatingAction);
1362 currentService.setContactId(contactIdUpdated.toLowerCase());
1364 return Either.left(true);
1367 private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1368 List<String> tagsUpdated = serviceUpdate.getTags();
1369 List<String> tagsCurrent = currentService.getTags();
1370 if (tagsUpdated == null || tagsUpdated.isEmpty()) {
1371 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
1372 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
1373 return Either.right(responseFormat);
1376 if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
1377 validateTagsListAndRemoveDuplicates(user, serviceUpdate, audatingAction);
1378 currentService.setTags(tagsUpdated);
1380 return Either.left(true);
1383 private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1384 String descriptionUpdated = serviceUpdate.getDescription();
1385 String descriptionCurrent = currentService.getDescription();
1386 if (!descriptionCurrent.equals(descriptionUpdated)) {
1387 validateDescriptionAndCleanup(user, serviceUpdate, audatingAction);
1388 currentService.setDescription(serviceUpdate.getDescription());
1390 return Either.left(true);
1393 private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1394 String projectCodeUpdated = serviceUpdate.getProjectCode();
1395 String projectCodeCurrent = currentService.getProjectCode();
1396 if (!projectCodeCurrent.equals(projectCodeUpdated)) {
1398 Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, serviceUpdate, audatingAction);
1399 if (validatProjectCodeResponse.isRight()) {
1400 ResponseFormat errorRespons = validatProjectCodeResponse.right().value();
1401 return Either.right(errorRespons);
1403 currentService.setProjectCode(projectCodeUpdated);
1406 return Either.left(true);
1409 private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1410 String iconUpdated = serviceUpdate.getIcon();
1411 String iconCurrent = currentService.getIcon();
1412 if (!iconCurrent.equals(iconUpdated)) {
1413 if (!hasBeenCertified) {
1414 validateIcon(user, serviceUpdate, audatingAction);
1415 currentService.setIcon(iconUpdated);
1417 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
1418 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
1419 return Either.right(errorResponse);
1422 return Either.left(true);
1425 private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum auditingAction) {
1426 String serviceNameUpdated = serviceUpdate.getName();
1427 String serviceNameCurrent = currentService.getName();
1428 if (!serviceNameCurrent.equals(serviceNameUpdated)) {
1429 if (!hasBeenCertified) {
1430 validateComponentName(user, serviceUpdate, auditingAction);
1431 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, serviceUpdate, auditingAction);
1432 if (serviceNameUniquenessValidation.isRight()) {
1433 return serviceNameUniquenessValidation;
1435 currentService.setName(serviceNameUpdated);
1436 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
1437 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
1440 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
1441 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
1442 return Either.right(errorResponse);
1445 return Either.left(true);
1448 private void validateAndUpdateServiceType(Service currentService, Service updatedService) {
1449 String updatedServiceType = updatedService.getServiceType();
1450 String currentServiceType = currentService.getServiceType();
1451 if (!currentServiceType.equals(updatedServiceType)) {
1452 validateServiceTypeAndCleanup(updatedService);
1453 currentService.setServiceType(updatedServiceType);
1457 private void validateServiceTypeAndCleanup(Component component) {
1458 log.debug("validate service type");
1459 String serviceType = ((Service)component).getServiceType();
1460 if (serviceType == null) {
1461 log.info("service type is not valid.");
1462 throw new ComponentException(ActionStatus.INVALID_SERVICE_TYPE);
1464 serviceType = cleanUpText(serviceType);
1465 validateServiceType(serviceType);
1469 private void validateServiceType(String serviceType) {
1470 if (serviceType.isEmpty()) {
1473 if (!ValidationUtils.validateServiceTypeLength(serviceType)) {
1474 log.info("service type exceeds limit.");
1475 throw new ComponentException(ActionStatus.SERVICE_TYPE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_TYPE_MAX_LENGTH);
1477 if (!ValidationUtils.validateIsEnglish(serviceType)) {
1478 log.info("service type is not valid.");
1479 throw new ComponentException(ActionStatus.INVALID_SERVICE_TYPE);
1483 private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1484 String updatedServiceRole = updatedService.getServiceRole();
1485 String currentServiceRole = currentService.getServiceRole();
1486 if (!currentServiceRole.equals(updatedServiceRole)) {
1487 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRoleAndCleanup(user, updatedService , auditingAction);
1488 if (validateServiceRole.isRight()) {
1489 ResponseFormat errorResponse = validateServiceRole.right().value();
1490 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1491 return Either.right(errorResponse);
1493 currentService.setServiceRole(updatedServiceRole);
1495 return Either.left(true);
1498 protected Either<Boolean, ResponseFormat> validateServiceRoleAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
1499 log.debug("validate service role");
1500 String serviceRole = ((Service)component).getServiceRole();
1501 if (serviceRole != null){
1502 serviceRole = cleanUpText(serviceRole);
1504 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRole(serviceRole);
1505 if (validateServiceRole.isRight()) {
1506 ResponseFormat responseFormat = validateServiceRole.right().value();
1507 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, ComponentTypeEnum.SERVICE);
1508 return Either.right(responseFormat);
1510 return Either.left(true);
1512 return Either.left(false);
1516 private Either<Boolean, ResponseFormat> validateAndUpdateInstantiationTypeValue(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1517 String updatedInstaType= updatedService.getInstantiationType();
1518 String currentInstaType = currentService.getInstantiationType();
1519 if (!currentInstaType.equals(updatedInstaType)) {
1520 Either<Boolean, ResponseFormat> validateInstantiationType = validateInstantiationTypeValue(user, updatedService , auditingAction);
1521 if (validateInstantiationType.isRight()) {
1522 ResponseFormat errorResponse = validateInstantiationType.right().value();
1523 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1524 return Either.right(errorResponse);
1526 currentService.setInstantiationType(updatedInstaType);
1528 return Either.left(true);
1531 private Either<Boolean, ResponseFormat> validateInstantiationTypeValue(User user, Service service, AuditingActionEnum actionEnum) {
1532 log.debug("validate instantiation type");
1533 String instantiationType = service.getInstantiationType();
1534 if (!InstantiationTypes.containsName(instantiationType) || instantiationType == null){
1535 log.error("Recieved Instantiation type {} is not valid.", instantiationType);
1536 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_INSTANTIATION_TYPE);
1537 componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
1538 return Either.right(errorResponse);
1540 return Either.left(true);
1543 private Either<Boolean, ResponseFormat> validateServiceRole(String serviceRole) {
1544 if (serviceRole.equals("")){
1545 return Either.left(true);
1547 if (!ValidationUtils.validateServiceRoleLength(serviceRole)) {
1548 log.info("service role exceeds limit.");
1549 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ROLE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_ROLE_MAX_LENGTH);
1550 return Either.right(errorResponse);
1553 if (!ValidationUtils.validateIsEnglish(serviceRole)) {
1554 log.info("service role is not valid.");
1555 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_ROLE);
1556 return Either.right(errorResponse);
1558 return Either.left(true);
1562 private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1563 List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1564 List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1565 Either<Boolean, ResponseFormat> validateCategoryResponse = validateServiceCategory(user, serviceUpdate, audatingAction);
1566 if (validateCategoryResponse.isRight()) {
1567 return Either.right(validateCategoryResponse.right().value());
1569 if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1570 if (!hasBeenCertified) {
1571 currentService.setCategories(categoryUpdated);
1573 log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1574 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1575 return Either.right(errorResponse);
1578 return Either.left(true);
1582 private Either<Boolean, ResponseFormat> validateServiceCategory(List<CategoryDefinition> list) {
1584 if (list.size() > 1) {
1585 log.debug("Must be only one category for service");
1586 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.SERVICE.getValue());
1587 return Either.right(responseFormat);
1589 CategoryDefinition category = list.get(0);
1590 if (category.getSubcategories() != null) {
1591 log.debug("Subcategories cannot be defined for service");
1592 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CANNOT_CONTAIN_SUBCATEGORY);
1593 return Either.right(responseFormat);
1595 if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
1596 log.debug("Resource category is empty");
1597 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
1598 return Either.right(responseFormat);
1601 log.debug("validating service category {} against valid categories list", list);
1602 Either<List<CategoryDefinition>, ActionStatus> categorys = elementDao.getAllServiceCategories();
1603 if (categorys.isRight()) {
1604 log.debug("failed to retrieve service categories from Titan");
1605 ResponseFormat responseFormat = componentsUtils.getResponseFormat(categorys.right().value());
1606 return Either.right(responseFormat);
1608 List<CategoryDefinition> categoryList = categorys.left().value();
1609 for (CategoryDefinition value : categoryList) {
1610 if (value.getName().equals(category.getName())) {
1611 return Either.left(true);
1614 log.debug("Category {} is not part of service category group. Service category valid values are {}", list, categoryList);
1615 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.SERVICE.getValue()));
1617 return Either.left(false);
1620 public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1621 Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1622 if (serviceResponseFormatEither.isRight()){
1623 return Either.right(serviceResponseFormatEither.right().value());
1625 final ServiceRelations serviceRelations = new ForwardingPathUtils().convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1626 return Either.left(serviceRelations);
1631 public ResponseFormat deleteService(String serviceId, User user) {
1632 ResponseFormat responseFormat;
1633 String ecompErrorContext = "delete service";
1635 validateUserExists(user, ecompErrorContext, false);
1636 Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1637 if (serviceStatus.isRight()) {
1638 log.debug("failed to get service {}", serviceId);
1639 return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1642 Service service = serviceStatus.left().value();
1644 StorageOperationStatus result = StorageOperationStatus.OK;
1645 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1646 if (lockResult.isRight()) {
1647 return lockResult.right().value();
1650 result = markComponentToDelete(service);
1651 if (result.equals(StorageOperationStatus.OK)) {
1652 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1654 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1655 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1657 return responseFormat;
1659 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1660 log.warn("operation failed. do rollback");
1661 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1662 titanDao.rollback();
1664 log.debug("operation success. do commit");
1667 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1671 public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1672 ResponseFormat responseFormat;
1673 String ecompErrorContext = "delete service";
1674 validateUserNotEmpty(user, ecompErrorContext);
1675 user = validateUserExists(user, ecompErrorContext, false);
1677 Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1678 if (getResult.isRight()) {
1679 return getResult.right().value();
1681 Service service = getResult.left().value();
1683 StorageOperationStatus result = StorageOperationStatus.OK;
1684 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1685 if (lockResult.isRight()) {
1686 result = StorageOperationStatus.GENERAL_ERROR;
1687 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1691 result = markComponentToDelete(service);
1692 if (result.equals(StorageOperationStatus.OK)) {
1693 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1695 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1696 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1698 return responseFormat;
1701 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1702 log.warn("operation failed. do rollback");
1703 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1704 titanDao.rollback();
1706 log.debug("operation success. do commit");
1709 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1713 public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1714 String ecompErrorContext = "Get service";
1715 validateUserNotEmpty(user, ecompErrorContext);
1716 validateUserExists(user, ecompErrorContext, false);
1718 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1719 if (storageStatus.isRight()) {
1720 log.debug("failed to get service by id {}", serviceId);
1721 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1724 if(!(storageStatus.left().value() instanceof Service)){
1725 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1727 Service service = storageStatus.left().value();
1728 return Either.left(service);
1735 public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1736 validateUserExists(userId, "get Service By Name And Version", false);
1737 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1738 if (storageStatus.isRight()) {
1739 log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1740 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceName));
1742 Service service = storageStatus.left().value();
1743 return Either.left(service);
1746 @SuppressWarnings("unchecked")
1747 private void createMandatoryArtifactsData(Service service, User user) {
1748 // create mandatory artifacts
1750 // TODO it must be removed after that artifact uniqueId creation will be
1751 // moved to ArtifactOperation
1752 String serviceUniqueId = service.getUniqueId();
1753 Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1754 if (artifactMap == null)
1755 artifactMap = new HashMap<>();
1757 Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalServiceArtifacts();
1758 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1760 String category = service.getCategories().get(0).getName();
1761 boolean isCreateArtifact = true;
1762 if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1763 for (String exlude : exludeServiceCategory) {
1764 if (exlude.equalsIgnoreCase(category)) {
1765 isCreateArtifact = false;
1772 if (informationalServiceArtifacts != null && isCreateArtifact) {
1773 Set<String> keys = informationalServiceArtifacts.keySet();
1774 for (String informationalServiceArtifactName : keys) {
1775 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1776 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap, user, false);
1777 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1781 service.setArtifacts(artifactMap);
1785 private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user, Boolean isServiceApi) {
1787 ArtifactDefinition artifactInfo = artifactsBusinessLogic.createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1790 artifactInfo.setMandatory(false);
1791 artifactInfo.setServiceApi(true);
1793 return artifactInfo;
1796 private Either<DistributionTransitionEnum, ResponseFormat> validateTransitionEnum(String distributionTransition) {
1797 DistributionTransitionEnum transitionEnum = null;
1799 transitionEnum = DistributionTransitionEnum.getFromDisplayName(distributionTransition);
1800 if (transitionEnum == null) {
1801 BeEcompErrorManager.getInstance().logBeSystemError(CHANGE_SERVICE_DISTRIBUTION);
1802 log.info("state operation is not valid. operations allowed are: {}", DistributionTransitionEnum.valuesAsString());
1803 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1804 return Either.right(error);
1807 return Either.left(transitionEnum);
1810 private Either<String, ResponseFormat> validateComment(LifecycleChangeInfoWithAction comment) {
1811 String data = comment.getUserRemarks();
1813 if (data == null || data.trim().isEmpty()) {
1814 BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1815 log.debug("user comment cannot be empty or null.");
1816 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1818 data = ValidationUtils.removeNoneUtf8Chars(data);
1819 data = ValidationUtils.removeHtmlTags(data);
1820 data = ValidationUtils.normaliseWhitespace(data);
1821 data = ValidationUtils.stripOctets(data);
1823 if (!ValidationUtils.validateLength(data, ValidationUtils.COMMENT_MAX_LENGTH)) {
1824 BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1825 log.debug("user comment exceeds limit.");
1826 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, "comment", String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH)));
1828 if (!ValidationUtils.validateIsEnglish(data)) {
1829 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1831 return Either.left(data);
1834 private Either<Service, ResponseFormat> validateServiceDistributionChange(User user, String serviceId, AuditingActionEnum auditAction, String comment) {
1835 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1836 if (storageStatus.isRight()) {
1837 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId);
1838 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1839 componentsUtils.auditComponent(responseFormat, user, auditAction, new ResourceCommonInfo(serviceId, ComponentTypeEnum.SERVICE.getValue()), comment);
1840 return Either.right(responseFormat);
1842 Service service = storageStatus.left().value();
1844 if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1845 log.info("service {} is not available for distribution. Should be in certified state", service.getUniqueId());
1846 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1847 createAudit(user, auditAction, comment, service, responseFormat);
1848 return Either.right(responseFormat);
1850 return Either.left(service);
1853 private Either<User, ResponseFormat> validateUserDistributionChange(User user, Service service, AuditingActionEnum auditAction, String comment) {
1854 log.debug("get user from DB");
1857 user = validateUser(user, "Activate Distribution", service, auditAction, false);
1858 // validate user role
1859 List<Role> roles = new ArrayList<>();
1860 roles.add(Role.ADMIN);
1861 roles.add(Role.GOVERNOR);
1862 roles.add(Role.OPS);
1863 validateUserRole(user, service, roles, auditAction, comment);
1864 return Either.left(user);
1867 private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat) {
1868 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1869 componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1870 ResourceVersionInfo.newBuilder()
1871 .state(component.getLifecycleState().name())
1872 .version(component.getVersion())
1877 private String getEnvNameFromConfiguration() {
1878 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1879 log.trace("Update environment name to be {}", configuredEnvName);
1880 return configuredEnvName;
1883 public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier, ServiceDistributionReqInfo data) {
1885 Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation.validateActivateServiceRequest(serviceId, envId, modifier, data);
1886 if (activationRequestInformationEither.isRight()) {
1887 return Either.right(activationRequestInformationEither.right().value());
1890 ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1892 Either<String, ResponseFormat> result = null;
1893 String did = ThreadLocalsHolder.getUuid();
1894 Service service = activationRequestInformation.getServiceToActivate();
1895 result = buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1899 public Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext, User modifier) {
1900 String envName = getEnvNameFromConfiguration();
1901 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1902 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1903 if (notifyServiceResponse == ActionStatus.OK) {
1904 return Either.left(did);
1906 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1907 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1908 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1909 return Either.right(error);
1913 public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1915 User user = validateUserExists(modifier.getUserId(), "activate Distribution", false);
1916 Either<Service, ResponseFormat> result = null;
1917 ResponseFormat response = null;
1918 Service updatedService = null;
1919 String did = ThreadLocalsHolder.getUuid();
1921 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1922 if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1923 log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1924 envName = configuredEnvName;
1928 ServletContext servletContext = request.getSession().getServletContext();
1929 boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1930 if (!isDistributionEngineUp) {
1931 BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1932 log.debug("Distribution Engine is DOWN");
1933 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1934 return Either.right(response);
1937 Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1938 if (serviceRes.isRight()) {
1939 log.debug("failed retrieving service");
1940 response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1941 componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1942 new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1943 ResourceVersionInfo.newBuilder()
1946 return Either.right(response);
1948 Service service = serviceRes.left().value();
1949 String dcurrStatus = service.getDistributionStatus().name();
1950 String updatedStatus = dcurrStatus;
1951 StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1952 if (readyForDistribution.equals(StorageOperationStatus.OK)) {
1953 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1954 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1955 if (notifyServiceResponse == ActionStatus.OK) {
1956 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED);
1957 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1958 updatedService = updateStateRes.left().value();
1959 updatedStatus = updatedService.getDistributionStatus().name();
1961 // The response is not relevant
1962 updatedService = service;
1964 ASDCKpiApi.countActivatedDistribution();
1965 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1966 result = Either.left(updatedService);
1968 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1969 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1970 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1971 result = Either.right(response);
1974 response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution), envName);
1975 result = Either.right(response);
1977 componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1978 new ResourceCommonInfo(service.getName(),ComponentTypeEnum.SERVICE.getValue()),
1979 ResourceVersionInfo.newBuilder()
1980 .distributionStatus(dcurrStatus)
1982 ResourceVersionInfo.newBuilder()
1983 .distributionStatus(updatedStatus)
1989 // convert to private after deletion of temp url
1990 public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1992 validateUserExists(user.getUserId(), "update Distribution Status For Activation", false);
1994 String serviceId = service.getUniqueId();
1995 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1996 if (lockResult.isRight()) {
1997 return Either.right(lockResult.right().value());
2000 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
2001 if (result.isRight()) {
2002 titanDao.rollback();
2003 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
2004 log.debug("service {} change distribution status failed", serviceId);
2005 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2008 return Either.left(result.left().value());
2010 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
2014 public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
2016 validateUserExists(user.getUserId(), "mark Distribution As Deployed", false);
2017 log.debug("mark distribution deployed");
2019 AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
2020 Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
2021 if (getServiceResponse.isRight()) {
2022 BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
2023 log.debug("service {} not found", serviceId);
2024 ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
2026 return Either.right(responseFormat);
2029 Service service = getServiceResponse.left().value();
2030 user = validateRoleForDeploy(did, user, auditAction, service);
2031 return checkDistributionAndDeploy(did, user, auditAction, service);
2035 public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2036 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
2037 // Only one VF Module Artifact per instance - add it to a list of one
2038 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
2040 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2044 private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock, boolean inTransaction, ComponentInstance ri) {
2045 List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
2047 if (ri.getOriginType() == OriginTypeEnum.VF) {
2048 asList = Arrays.asList(new VfModuleArtifactGenerator(modifier, ri, service, shouldLock, inTransaction));
2053 private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
2054 Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
2055 if(currVF.getGroupInstances() != null){
2056 currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
2058 return currVF.getGroupInstances();
2061 private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) {
2062 ArtifactDefinition vfModuleAertifact = null;
2063 if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
2064 Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.name())).findAny();
2065 if (optionalVfModuleArtifact.isPresent()) {
2066 vfModuleAertifact = optionalVfModuleArtifact.get();
2069 if (vfModuleAertifact == null) {
2070 Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service, payloadWrapper.getInnerElement());
2071 if (createVfModuleArtifact.isLeft()) {
2072 vfModuleAertifact = createVfModuleArtifact.left().value();
2074 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
2077 return vfModuleAertifact;
2080 private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
2081 List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
2082 if (groupsForCurrVF != null) {
2083 for (GroupInstance groupInstance : groupsForCurrVF) {
2084 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
2085 vfModulePayloads.add(modulePayload);
2087 vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
2089 final Gson gson = new GsonBuilder().setPrettyPrinting().create();
2091 String vfModulePayloadString = gson.toJson(vfModulePayloads);
2092 payloadWrapper.setInnerElement(vfModulePayloadString);
2097 private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock, boolean inTransaction) {
2098 ArtifactDefinition vfModuleArtifact = null;
2099 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
2100 Wrapper<String> payloadWrapper = new Wrapper<>();
2101 List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
2102 if (responseWrapper.isEmpty()) {
2103 fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
2105 if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
2106 vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
2108 if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
2109 vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper, responseWrapper, service);
2112 Either<ArtifactDefinition, ResponseFormat> result;
2113 if (responseWrapper.isEmpty()) {
2114 result = Either.left(vfModuleArtifact);
2116 result = Either.right(responseWrapper.getInnerElement());
2122 private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper, Service service) {
2123 ArtifactDefinition result = null;
2124 Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, inTransaction, System::currentTimeMillis,
2125 () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), currVF.getUniqueId());
2126 if (eitherPayload.isLeft()) {
2127 result = eitherPayload.left().value();
2129 responseWrapper.setInnerElement(eitherPayload.right().value());
2131 if (result == null) {
2132 result = vfModuleArtifact;
2138 private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service, String vfModulePayloadString) {
2140 ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
2141 String newCheckSum = null;
2143 vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
2144 vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
2145 vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
2146 vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
2147 vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
2148 vfModuleArtifactDefinition.setTimeout(0);
2149 vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
2150 vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
2151 if (vfModulePayloadString != null) {
2152 newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
2154 vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
2156 Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent = artifactToscaOperation.addArifactToComponent(vfModuleArtifactDefinition, service.getUniqueId(), NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
2158 Either<ArtifactDefinition, ResponseFormat> result;
2159 if (addArifactToComponent.isLeft()) {
2160 result = Either.left(addArifactToComponent.left().value());
2162 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArifactToComponent.right().value())));
2168 public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2170 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
2171 // Get All Deployment Artifacts
2172 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
2173 // Filter in Only Heat Env
2174 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
2175 // Create ArtifactGenerator from those Artifacts
2176 map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction, resourceInstance.getUniqueId())).collect(Collectors.toList());
2178 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2182 private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
2184 // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
2186 if (service.getComponentInstances() != null) {
2187 List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
2188 if (artifactGenList != null && !artifactGenList.isEmpty()) {
2189 for (ArtifactGenerator<CallVal> entry : artifactGenList) {
2190 Either<CallVal, ResponseFormat> callRes;
2192 callRes = entry.call();
2193 if (callRes.isRight()) {
2194 log.debug("Failed to generate artifact error : {}", callRes.right().value());
2195 return Either.right(callRes.right().value());
2197 } catch (Exception e) {
2198 log.debug("Failed to generate artifact exception : {}", e);
2199 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2204 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
2205 if (storageStatus.isRight()) {
2206 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2209 Service currentService = storageStatus.left().value();
2211 return Either.left(currentService);
2215 abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
2219 class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2220 ArtifactDefinition artifactDefinition;
2222 String resourceInstanceName;
2226 boolean inTransaction;
2228 HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock, boolean inTransaction, String instanceId) {
2229 this.artifactDefinition = artifactDefinition;
2230 this.service = service;
2231 this.resourceInstanceName = resourceInstanceName;
2232 this.modifier = modifier;
2233 this.shouldLock = shouldLock;
2234 this.instanceId = instanceId;
2235 this.inTransaction = inTransaction;
2239 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2240 return artifactsBusinessLogic.forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier, shouldLock, inTransaction, instanceId);
2243 public ArtifactDefinition getArtifactDefinition() {
2244 return artifactDefinition;
2249 class VfModuleArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2251 private ComponentInstance componentInstance;
2252 private Service service;
2254 boolean inTransaction;
2257 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2258 return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
2261 private VfModuleArtifactGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock, boolean inTransaction) {
2264 this.componentInstance = componentInstance;
2265 this.service = service;
2266 this.shouldLock = shouldLock;
2267 this.inTransaction = inTransaction;
2272 private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction, Service service) {
2273 boolean isDeployed = isDistributionDeployed(distributionId);
2275 return Either.left(service);
2277 Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
2278 if (distributionSuccess.isRight()) {
2279 return Either.right(distributionSuccess.right().value());
2282 log.debug("mark distribution {} as deployed - success", distributionId);
2283 componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK", user);
2284 return Either.left(service);
2287 private boolean isDistributionDeployed(String distributionId) {
2288 Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
2290 boolean isDeployed = false;
2291 if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
2293 log.debug("distribution {} is already deployed", distributionId);
2299 protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
2301 log.trace("checkDistributionSuccess");
2302 // get all "DRequest" records for this distribution
2304 Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
2305 if (distRequestsResponse.isRight()) {
2306 ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
2307 return Either.right(error);
2310 List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
2311 if (distributionRequests.isEmpty()) {
2312 BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
2313 log.info("distribution {} is not found", did);
2314 ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
2315 return Either.right(error);
2317 boolean isRequestSucceeded = false;
2318 for (ResourceAdminEvent event : distributionRequests) {
2319 String eventStatus = event.getStatus();
2320 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2321 isRequestSucceeded = true;
2326 // get all "DNotify" records for this distribution
2327 Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
2328 if (distNotificationsResponse.isRight()) {
2329 ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
2330 return Either.right(error);
2333 List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
2334 boolean isNotificationsSucceeded = false;
2335 for (DistributionNotificationEvent event : distributionNotifications) {
2336 String eventStatus = event.getStatus();
2337 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2338 isNotificationsSucceeded = true;
2343 // if request failed OR there are notifications that failed
2344 if (!(isRequestSucceeded && isNotificationsSucceeded)) {
2346 log.info("distribution {} has failed", did);
2347 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2348 auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2349 return Either.right(error);
2351 return Either.left(true);
2354 private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) {
2356 ResponseFormat error = componentsUtils.getResponseFormat(status, params);
2357 String message = "";
2358 if (error.getMessageId() != null) {
2359 message = error.getMessageId() + ": ";
2361 message += error.getFormattedMessage();
2363 if (service != null) {
2364 componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user);
2366 componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
2371 private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
2372 Either<User, ActionStatus> eitherCreator = userAdmin.getUser(user.getUserId(), false);
2373 if (eitherCreator.isRight() || eitherCreator.left().value() == null) {
2374 BeEcompErrorManager.getInstance().logBeUserMissingError("Deploy Service", user.getUserId());
2375 log.debug("validateRoleForDeploy method - user is not listed. userId= {}", user.getUserId());
2376 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, user.getUserId());
2377 auditDeployError(did, user, auditAction, service, ActionStatus.USER_NOT_FOUND);
2378 throw new ComponentException(ActionStatus.USER_NOT_FOUND, user.getUserId());
2380 user = eitherCreator.left().value();
2381 log.debug("validate user role");
2382 List<Role> roles = new ArrayList<>();
2383 roles.add(Role.ADMIN);
2384 roles.add(Role.OPS);
2386 validateUserRole(user, service, roles, auditAction, null);
2387 } catch (ComponentException e){
2388 log.info("role {} is not allowed to perform this action", user.getRole());
2389 auditDeployError(did, user, auditAction, service, e.getActionStatus());
2396 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
2397 Service service = (Service) component;
2398 Map<String, ArtifactDefinition> artifactMap = service.getDeploymentArtifacts();
2399 if (artifactMap == null) {
2400 artifactMap = new HashMap<>();
2402 service.setDeploymentArtifacts(artifactMap);
2406 public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
2407 return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
2410 private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
2411 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
2412 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
2413 return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
2417 public ComponentInstanceBusinessLogic getComponentInstanceBL() {
2418 return componentInstanceBusinessLogic;
2422 public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
2424 validateUserExists(userId, "Get Component Instances", false);
2425 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2426 if (getComponentRes.isRight()) {
2427 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
2428 return Either.right(responseFormat);
2431 List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
2433 return Either.left(componentInstances);
2436 public ICacheMangerOperation getCacheManagerOperation() {
2437 return cacheManagerOperation;
2440 public void setCacheManagerOperation(ICacheMangerOperation cacheManagerOperation) {
2441 this.cacheManagerOperation = cacheManagerOperation;
2444 public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
2445 this.forwardingPathOperation = forwardingPathOperation;
2449 public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
2450 this.toscaOperationFacade = toscaOperationFacade;
2452 * 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
2455 public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2457 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2458 Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
2459 Component component = null;
2460 Either<Boolean, ResponseFormat> lockResult = null;
2461 log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
2463 validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2464 if (validateUserAndComponentRes.isRight()) {
2465 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed. ", groupInstanceId, serviceId);
2466 actionResult = Either.right(validateUserAndComponentRes.right().value());
2468 if (actionResult == null) {
2469 component = validateUserAndComponentRes.left().value().getKey();
2470 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2471 if (lockResult.isRight()) {
2472 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
2473 actionResult = Either.right(lockResult.right().value());
2475 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
2478 if (actionResult == null) {
2479 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId, newProperties);
2480 if (actionResult.isRight()) {
2481 log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ", groupInstanceId, actionResult.right().value().getFormattedMessage());
2484 } catch (Exception e) {
2485 log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2486 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2488 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2489 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2492 return actionResult;
2495 private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2497 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2498 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2499 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2500 ComponentInstance relatedComponentInstance = null;
2501 GroupInstance oldGroupInstance = null;
2502 Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2503 GroupInstance updatedGroupInstance = null;
2504 boolean inTransaction = true;
2505 findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2506 if (findGroupInstanceRes.isRight()) {
2507 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
2508 actionResult = Either.right(findGroupInstanceRes.right().value());
2510 if (actionResult == null) {
2511 oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2512 relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2513 updateGroupInstanceResult = groupBusinessLogic.validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
2514 if (updateGroupInstanceResult.isRight()) {
2515 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ", oldGroupInstance.getName());
2516 actionResult = Either.right(updateGroupInstanceResult.right().value());
2519 if (actionResult == null) {
2520 updatedGroupInstance = updateGroupInstanceResult.left().value();
2521 if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2522 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance, updatedGroupInstance, inTransaction);
2523 if (updateParentsModificationTimeRes.isRight()) {
2524 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ", oldGroupInstance.getName());
2525 actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2529 if (actionResult == null) {
2530 actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2532 return actionResult;
2535 private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance,
2536 boolean inTranscation) {
2538 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2539 Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2540 Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic.updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2541 updatedGroupInstance.getModificationTime(), inTranscation);
2542 if (updateComponentInstanceRes.isRight()) {
2543 log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(), updatedGroupInstance.getName());
2544 actionResult = Either.right(updateComponentInstanceRes.right().value());
2546 serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2547 if (serviceMetadataUpdateResult.isRight()) {
2548 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ", component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2549 actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2551 actionResult = Either.left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2554 return actionResult;
2557 private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2559 Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2560 Either<Component, ResponseFormat> validateComponentExistsRes = null;
2561 User currUser = null;
2562 Component component = null;
2563 Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2564 if (validationUserResult.isRight()) {
2565 log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2566 result = Either.right(validationUserResult.right().value());
2568 if (result == null) {
2569 currUser = validationUserResult.left().value();
2570 validateComponentExistsRes = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2571 if (validateComponentExistsRes.isRight()) {
2572 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2573 result = Either.right(validateComponentExistsRes.right().value());
2576 if (result == null) {
2577 component = validateComponentExistsRes.left().value();
2578 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2579 log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(), component.getCreatorUserId());
2580 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2583 if (result == null) {
2584 result = Either.left(new ImmutablePair<>(component, currUser));
2589 private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component, String componentInstanceId, String groupInstanceId) {
2591 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2592 GroupInstance groupInstance = null;
2593 ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2594 if (foundComponentInstance == null) {
2595 log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2596 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service", component.getName()));
2598 else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2599 groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst().orElse(null);
2600 if (groupInstance == null) {
2601 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2602 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId, foundComponentInstance.getName()));
2605 if (actionResult == null) {
2606 actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2608 return actionResult;
2611 private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2612 ComponentInstance componentInstance = null;
2613 if (isNotEmpty(component.getComponentInstances())) {
2614 componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst().orElse(null);
2616 return componentInstance;
2619 private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2620 User user = validateUser(modifier, ecompErrorContext, null, null, false);
2621 List<Role> roles = new ArrayList<>();
2622 roles.add(Role.ADMIN);
2623 roles.add(Role.DESIGNER);
2624 validateUserRole(user, roles);
2625 return Either.left(user);
2628 public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId, List<String> dataParamsToReturn) {
2630 ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2631 paramsToReturn.setIgnoreComponentInstancesProperties(false);
2632 Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2634 if (serviceResultEither.isRight()) {
2635 if(serviceResultEither.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
2636 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2637 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2640 log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2641 return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2644 Service service = serviceResultEither.left().value();
2645 if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
2646 ListUtils.emptyIfNull(service.getInputs())
2647 .forEach(input -> input.setConstraints(setInputConstraint(input)));
2650 UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2651 return Either.left(dataTransfer);
2654 public Either<String, ResponseFormat> deleteIfNotAlreadyDeletedServiceFilter(String serviceId, String resourceId, String userId, boolean lock) {
2655 Service serviceToDelete = initServiceToDeleteServiceFilter(serviceId);
2656 User user = validateUserExists(userId, "Create service Filter", false);
2659 validateUser(user, "deleteIfNotAlreadyDeletedServiceFilter", serviceToDelete, null, false);
2661 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
2662 if (storageStatus.isRight()) {
2663 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2665 Service service = storageStatus.left().value();
2667 Either<Boolean, ResponseFormat> response = serviceFilterValidator.validateComponentInstanceExist(service, resourceId);
2668 if (storageStatus.isRight()) {
2669 return Either.right(response.right().value());
2671 final Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(resourceId);
2672 if (!optionalComponentInstance.isPresent() ){
2673 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2675 CINodeFilterDataDefinition nodeFilter = optionalComponentInstance.get().getNodeFilter();
2676 if (nodeFilter == null){
2677 return Either.left(resourceId);
2680 Either<String, StorageOperationStatus> result;
2682 Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Service Filter from service");
2683 if (lockResult.isRight()) {
2684 titanDao.rollback();
2685 return Either.right(componentsUtils.getResponseFormat(componentsUtils
2686 .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2690 result = serviceFilterOperation.deleteNodeFilter(service , resourceId);
2691 if (result.isRight()) {
2692 log.debug("Failed to delete node filter in service {}. Response is {}. ", service.getName(), result.right().value());
2693 titanDao.rollback();
2694 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
2697 log.debug("Node filter successfully changed in service {} . ", service.getSystemName());
2699 } catch (Exception e){
2700 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
2701 titanDao.rollback();
2702 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2704 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2706 return Either.left(result.left().value());
2710 private Service initServiceToDeleteServiceFilter(String serviceId) {
2711 Service serviceToDelete = new Service();
2712 serviceToDelete.setUniqueId(serviceId);
2713 return serviceToDelete;
2717 public Either<CINodeFilterDataDefinition, ResponseFormat> createIfNotAlreadyExistServiceFilter(String serviceId, String componentInstanceId, String userId, boolean lock) {
2718 String errorContext = "createIfNotAlreadyExistServiceFilter";
2719 User user = validateUserExists(userId, "Create service Filter", false);
2721 Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
2722 if (serviceEither.isRight()) {
2723 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceEither.right().value(), ComponentTypeEnum.SERVICE), ""));
2725 final Service service = serviceEither.left().value();
2726 validateUserAndRole(service, user, errorContext);
2728 Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(componentInstanceId);
2729 if (!optionalComponentInstance.isPresent()){
2730 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2732 ComponentInstance componentInstance = optionalComponentInstance.get();
2733 CINodeFilterDataDefinition serviceFilter = componentInstance.getNodeFilter();
2734 if (serviceFilter != null){
2735 return Either.left(serviceFilter);
2738 Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2740 Either<Boolean, ResponseFormat> lockResult = null;
2743 lockComponent(service.getUniqueId(), service, "Create Service Filter");
2744 if (lockResult.isRight()) {
2745 log.debug("Failed to lock service {}. Response is {}. ", service.getName(),
2746 lockResult.right().value().getFormattedMessage());
2747 return Either.right(lockResult.right().value());
2749 log.debug("The service with system name {} locked. ", service.getSystemName());
2752 CINodeFilterDataDefinition serviceFilterResult;
2754 result = serviceFilterOperation.createNodeFilter(serviceId, componentInstanceId);
2755 if (result.isRight()) {
2756 titanDao.rollback();
2757 return Either.right(componentsUtils.getResponseFormat(
2758 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2761 serviceFilterResult = result.left().value();
2765 } catch (Exception e) {
2766 titanDao.rollback();
2767 log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2769 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2772 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2773 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2776 return Either.left(serviceFilterResult);
2780 public Either<CINodeFilterDataDefinition, ResponseFormat> updateServiceFilter(String serviceId, String componentInstanceId,
2781 List<String> constraints, User inUser, boolean lock) {
2782 String errorContext = "createIfNotAlreadyExistServiceFilter";
2783 User user = validateUserExists(inUser, errorContext, true);
2784 validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2785 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2787 if(serviceStorageOperationStatusEither.isRight()){
2788 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2789 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2790 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2792 Service storedService = serviceStorageOperationStatusEither.left().value();
2794 Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2795 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId, constraints,
2796 NodeFilterConstraintAction.UPDATE);
2797 if(booleanResponseFormatEither.isRight()){
2798 return Either.right(booleanResponseFormatEither.right().value());
2802 Either<Boolean, ResponseFormat> lockResult = null;
2805 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2806 if (lockResult.isRight()) {
2807 log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
2808 lockResult.right().value().getFormattedMessage());
2809 return Either.right(lockResult.right().value());
2811 log.debug("The service with system name {} locked. ", storedService.getSystemName());
2814 Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2815 if (!componentInstanceOptional.isPresent()){
2816 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2818 CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2819 if(serviceFilter == null){
2820 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2822 CINodeFilterDataDefinition serviceFilterResult;
2824 List<RequirementNodeFilterPropertyDataDefinition> properties = constraints.stream().map(this::getRequirementNodeFilterPropertyDataDefinition).collect(Collectors.toList());
2825 Either<CINodeFilterDataDefinition, StorageOperationStatus> result = serviceFilterOperation.updateProperties(serviceId, componentInstanceId, serviceFilter ,properties);
2827 if (result.isRight()) {
2828 titanDao.rollback();
2829 return Either.right(componentsUtils.getResponseFormat(
2830 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2833 serviceFilterResult = result.left().value();
2837 } catch (Exception e) {
2838 titanDao.rollback();
2839 log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2841 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2844 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2845 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2848 return Either.left(serviceFilterResult);
2851 private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition(String constraint){
2852 RequirementNodeFilterPropertyDataDefinition pdd = new RequirementNodeFilterPropertyDataDefinition();
2853 pdd.setConstraints(Arrays.asList(constraint));
2857 public Either<CINodeFilterDataDefinition, ResponseFormat> addOrDeleteServiceFilter(String serviceId, String componentInstanceId,
2858 NodeFilterConstraintAction action, String constraint, int position, User inUser, boolean lock) {
2859 String errorContext = "createIfNotAlreadyExistServiceFilter";
2860 User user = validateUserExists(inUser, errorContext, true);
2861 validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2863 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2865 if(serviceStorageOperationStatusEither.isRight()){
2866 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2867 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2868 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2870 Service storedService = serviceStorageOperationStatusEither.left().value();
2872 Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2873 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId,
2874 Collections.singletonList(constraint), action);
2875 if(booleanResponseFormatEither.isRight()){
2876 return Either.right(booleanResponseFormatEither.right().value());
2879 Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2881 Either<Boolean, ResponseFormat> lockResult = null;
2882 CINodeFilterDataDefinition serviceFilterResult = null;
2886 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2887 if (lockResult.isRight()) {
2888 log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
2889 lockResult.right().value().getFormattedMessage());
2890 return Either.right(lockResult.right().value());
2892 log.debug("The service with system name {} locked. ", storedService.getSystemName());
2896 Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2897 if (!componentInstanceOptional.isPresent()){
2898 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2900 CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2901 if(serviceFilter == null){
2902 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2908 RequirementNodeFilterPropertyDataDefinition newProperty = new RequirementNodeFilterPropertyDataDefinition();
2909 newProperty.setConstraints(Collections.singletonList(constraint));
2910 result = serviceFilterOperation.addNewProperty(serviceId, componentInstanceId,serviceFilter,newProperty);
2913 result = serviceFilterOperation.deleteConstraint(serviceId, componentInstanceId, serviceFilter, position);
2916 log.error("Unsupported operation "+action);
2917 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2921 if (result.isRight()) {
2922 titanDao.rollback();
2923 return Either.right(componentsUtils.getResponseFormat(
2924 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2927 serviceFilterResult = result.left().value();
2931 } catch (Exception e) {
2932 titanDao.rollback();
2933 log.error("Exception occurred during add or update node filter property values: {}", e.getMessage(),
2935 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2938 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2939 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2942 return Either.left(serviceFilterResult);