2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.be.components.impl;
23 import static org.apache.commons.collections.CollectionUtils.isEmpty;
24 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
25 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getOperationOutputName;
26 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToOtherOperationOutput;
27 import static org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum.UPDATE_SERVICE_METADATA;
28 import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.SELF;
29 import static org.openecomp.sdc.be.types.ServiceConsumptionSource.SERVICE_INPUT;
30 import static org.openecomp.sdc.be.types.ServiceConsumptionSource.STATIC;
32 import com.google.common.annotations.VisibleForTesting;
33 import com.google.common.base.Strings;
34 import com.google.gson.Gson;
35 import com.google.gson.GsonBuilder;
37 import java.nio.charset.StandardCharsets;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.Collection;
41 import java.util.Collections;
42 import java.util.HashMap;
43 import java.util.List;
45 import java.util.Objects;
46 import java.util.Optional;
48 import java.util.concurrent.Callable;
49 import java.util.function.Function;
50 import java.util.stream.Collectors;
52 import fj.data.Either;
53 import org.apache.commons.collections.CollectionUtils;
54 import org.apache.commons.collections.MapUtils;
55 import org.apache.commons.collections4.ListUtils;
56 import org.apache.commons.lang3.StringUtils;
57 import org.apache.commons.lang3.tuple.ImmutablePair;
58 import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine;
59 import org.openecomp.sdc.be.components.distribution.engine.INotificationData;
60 import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload;
61 import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic;
62 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
63 import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
64 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
65 import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
66 import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
67 import org.openecomp.sdc.be.components.validation.NodeFilterValidator;
68 import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
69 import org.openecomp.sdc.be.config.BeEcompErrorManager;
70 import org.openecomp.sdc.be.config.ConfigurationManager;
71 import org.openecomp.sdc.be.dao.api.ActionStatus;
72 import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
73 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
74 import org.openecomp.sdc.be.datamodel.ServiceRelations;
75 import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil;
76 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
77 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
78 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
79 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
80 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
81 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
82 import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition;
83 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
84 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
85 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
86 import org.openecomp.sdc.be.datatypes.enums.InstantiationTypes;
87 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
88 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
89 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
90 import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo;
91 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
92 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
93 import org.openecomp.sdc.be.model.ArtifactDefinition;
94 import org.openecomp.sdc.be.model.Component;
95 import org.openecomp.sdc.be.model.ComponentInstance;
96 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
97 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
98 import org.openecomp.sdc.be.model.ComponentParametersView;
99 import org.openecomp.sdc.be.model.DistributionStatusEnum;
100 import org.openecomp.sdc.be.model.DistributionTransitionEnum;
101 import org.openecomp.sdc.be.model.GroupInstance;
102 import org.openecomp.sdc.be.model.GroupInstanceProperty;
103 import org.openecomp.sdc.be.model.InputDefinition;
104 import org.openecomp.sdc.be.model.InterfaceDefinition;
105 import org.openecomp.sdc.be.model.LifecycleStateEnum;
106 import org.openecomp.sdc.be.model.Operation;
107 import org.openecomp.sdc.be.model.PropertyDefinition;
108 import org.openecomp.sdc.be.model.Resource;
109 import org.openecomp.sdc.be.model.Service;
110 import org.openecomp.sdc.be.model.User;
111 import org.openecomp.sdc.be.model.category.CategoryDefinition;
112 import org.openecomp.sdc.be.model.jsontitan.operations.ForwardingPathOperation;
113 import org.openecomp.sdc.be.model.jsontitan.operations.NodeFilterOperation;
114 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
115 import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation;
116 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
117 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
118 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
119 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
120 import org.openecomp.sdc.be.model.tosca.ToscaFunctions;
121 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
122 import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
123 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
124 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
125 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
126 import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent;
127 import org.openecomp.sdc.be.resources.data.auditing.DistributionDeployEvent;
128 import org.openecomp.sdc.be.resources.data.auditing.DistributionNotificationEvent;
129 import org.openecomp.sdc.be.resources.data.auditing.ResourceAdminEvent;
130 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
131 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
132 import org.openecomp.sdc.be.types.ServiceConsumptionData;
133 import org.openecomp.sdc.be.types.ServiceConsumptionSource;
134 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
135 import org.openecomp.sdc.be.user.Role;
136 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
137 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
138 import org.openecomp.sdc.common.api.Constants;
139 import org.openecomp.sdc.common.datastructure.Wrapper;
140 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
141 import org.openecomp.sdc.common.log.wrappers.Logger;
142 import org.openecomp.sdc.common.util.GeneralUtility;
143 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
144 import org.openecomp.sdc.common.util.ValidationUtils;
145 import org.openecomp.sdc.exception.ResponseFormat;
146 import org.springframework.beans.factory.annotation.Autowired;
147 import org.springframework.http.HttpStatus;
148 import org.springframework.web.context.WebApplicationContext;
150 import javax.servlet.ServletContext;
151 import javax.servlet.http.HttpServletRequest;
153 @org.springframework.stereotype.Component("serviceBusinessLogic")
154 public class ServiceBusinessLogic extends ComponentBusinessLogic {
156 private static final String CHANGE_SERVICE_DISTRIBUTION = "Change Service Distribution";
157 private static final String THE_SERVICE_WITH_SYSTEM_NAME_LOCKED = "The service with system name {} locked. ";
158 private static final String FAILED_TO_LOCK_SERVICE_RESPONSE_IS = "Failed to lock service {}. Response is {}. ";
159 private static final String AUDIT_BEFORE_SENDING_RESPONSE = "audit before sending response";
160 private static final Logger log = Logger.getLogger(ServiceBusinessLogic.class);
161 private static final String INITIAL_VERSION = "0.1";
162 private static final String STATUS_SUCCESS_200 = "200";
163 private static final String STATUS_DEPLOYED = "DEPLOYED";
165 private IDistributionEngine distributionEngine;
167 private AuditCassandraDao auditCassandraDao;
169 private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
171 private ICacheMangerOperation cacheManagerOperation;
173 private ServiceDistributionValidation serviceDistributionValidation;
176 private ForwardingPathOperation forwardingPathOperation;
178 private ForwardingPathValidator forwardingPathValidator;
180 private UiComponentDataConverter uiComponentDataConverter;
182 private NodeFilterOperation serviceFilterOperation;
184 private NodeFilterValidator serviceFilterValidator;
186 public Either<Service, ResponseFormat> changeServiceDistributionState(String serviceId, String state, LifecycleChangeInfoWithAction commentObj, User user) {
188 validateUserExists(user.getUserId(), "change Service Distribution State", false);
190 log.debug("check request state");
191 Either<DistributionTransitionEnum, ResponseFormat> validateEnum = validateTransitionEnum(state);
192 if (validateEnum.isRight()) {
193 return Either.right(validateEnum.right().value());
195 DistributionTransitionEnum distributionTransition = validateEnum.left().value();
196 AuditingActionEnum auditAction = distributionTransition == DistributionTransitionEnum.APPROVE ? AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_APPROV : AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REJECT;
197 Either<String, ResponseFormat> commentResponse = validateComment(commentObj);
198 if (commentResponse.isRight()) {
199 return Either.right(commentResponse.right().value());
201 String comment = commentResponse.left().value();
203 Either<Service, ResponseFormat> validateService = validateServiceDistributionChange(user, serviceId, auditAction, comment);
204 if (validateService.isRight()) {
205 return Either.right(validateService.right().value());
207 Service service = validateService.left().value();
208 Either<User, ResponseFormat> validateUser = validateUserDistributionChange(user, service, auditAction, comment);
209 if (validateUser.isRight()) {
210 return Either.right(validateUser.right().value());
212 user = validateUser.left().value();
216 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "ChangeServiceDistributionState");
217 if (lockResult.isRight()) {
218 ResponseFormat responseFormat = lockResult.right().value();
219 createAudit(user, auditAction, comment, service, responseFormat);
220 return Either.right(responseFormat);
225 DistributionStatusEnum newState;
226 if (distributionTransition == DistributionTransitionEnum.APPROVE) {
227 newState = DistributionStatusEnum.DISTRIBUTION_APPROVED;
229 newState = DistributionStatusEnum.DISTRIBUTION_REJECTED;
231 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, newState);
232 if (result.isRight()) {
234 BeEcompErrorManager.getInstance().logBeSystemError("ChangeServiceDistributionState");
235 log.debug("service {} is change destribuation status failed", service.getUniqueId());
236 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, service.getVersion(), service.getName());
237 createAudit(user, auditAction, comment, service, responseFormat);
238 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
241 Service updatedService = result.left().value();
242 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
243 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
244 componentsUtils.auditComponent(responseFormat, user, updatedService, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()), ResourceVersionInfo.newBuilder().build(), comment);
245 return Either.left(result.left().value());
247 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
252 public Either<List<Map<String, Object>>, ResponseFormat> getComponentAuditRecords(String componentVersion, String componentUUID, String userId) {
253 validateUserExists(userId, "get Component Audit Records", false);
254 Either<List<Map<String, Object>>, ActionStatus> result;
258 if (componentVersion.endsWith(".0")) {
259 Either<List<ResourceAdminEvent>, ActionStatus> eitherAuditingForCertified = auditCassandraDao.getByServiceInstanceId(componentUUID);
260 if (eitherAuditingForCertified.isLeft()) {
261 result = Either.left(getAuditingFieldsList(eitherAuditingForCertified.left().value()));
263 result = Either.right(eitherAuditingForCertified.right().value());
266 // Uncertified Version
268 result = getAuditRecordsForUncertifiedComponent(componentUUID, componentVersion);
270 } catch (Exception e) {
271 log.debug("get Audit Records failed with exception {}", e);
272 result = Either.right(ActionStatus.GENERAL_ERROR);
275 if (result.isRight()) {
276 return Either.right(componentsUtils.getResponseFormat(result.right().value()));
278 return Either.left(result.left().value());
283 public Either<List<Operation>, ResponseFormat> addServiceConsumptionData(String serviceId,
284 String serviceInstanceId,
286 List<ServiceConsumptionData> serviceConsumptionDataList,
288 List<Operation> operationList = new ArrayList<>();
290 Either<Service, StorageOperationStatus> serviceEither =
291 toscaOperationFacade.getToscaElement(serviceId);
292 if(serviceEither.isRight()) {
293 return Either.right(componentsUtils.getResponseFormat
294 (serviceEither.right().value()));
297 Service service = serviceEither.left().value();
300 StorageOperationStatus storageOperationStatus =
301 graphLockOperation.lockComponent(service.getUniqueId(), NodeTypeEnum.Service);
302 if (storageOperationStatus != StorageOperationStatus.OK) {
303 return Either.right(componentsUtils.getResponseFormat(storageOperationStatus));
307 for (ServiceConsumptionData serviceConsumptionData : serviceConsumptionDataList) {
308 Either<Operation, ResponseFormat> operationEither =
309 addPropertyServiceConsumption(serviceId, serviceInstanceId, operationId,
310 userId, serviceConsumptionData);
312 if (operationEither.isRight()) {
313 return Either.right(operationEither.right().value());
316 operationList.add(operationEither.left().value());
320 return Either.left(operationList);
321 } catch (Exception e) {
323 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
326 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
331 public Either <Operation, ResponseFormat> addPropertyServiceConsumption(String serviceId,
332 String serviceInstanceId,
335 ServiceConsumptionData serviceConsumptionData) {
336 validateUserExists(userId, "create Property", false);
338 Either<Service, StorageOperationStatus> serviceEither =
339 toscaOperationFacade.getToscaElement(serviceId);
340 if(serviceEither.isRight()) {
341 return Either.right(componentsUtils.getResponseFormat(serviceEither.right
345 Service parentService = serviceEither.left().value();
347 List<ComponentInstance> componentInstances = parentService.getComponentInstances();
348 if(CollectionUtils.isEmpty(componentInstances)) {
349 return Either.right(componentsUtils.getResponseFormat(ActionStatus
350 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
353 Optional<ComponentInstance> serviceInstanceCandidate =
354 componentInstances.stream().filter(instance -> instance.getUniqueId().equals
355 (serviceInstanceId)).findAny();
357 if(!serviceInstanceCandidate.isPresent()) {
358 return Either.right(componentsUtils.getResponseFormat(ActionStatus
359 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
362 Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaces =
363 parentService.getComponentInstancesInterfaces();
364 if(MapUtils.isEmpty(componentInstancesInterfaces)) {
365 return Either.right(componentsUtils.getResponseFormat(ActionStatus
366 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
369 List<InterfaceDefinition> interfaces = new ArrayList<>();
370 for(ComponentInstanceInterface componentInstanceInterface :
371 componentInstancesInterfaces.get(serviceInstanceId)) {
372 interfaces.add(componentInstanceInterface);
375 ComponentInstance serviceInstance = serviceInstanceCandidate.get();
376 Optional<InterfaceDefinition> interfaceCandidate = InterfaceOperationUtils
377 .getInterfaceDefinitionFromOperationId(interfaces, operationId);
379 if(!interfaceCandidate.isPresent()) {
380 return Either.right(componentsUtils.getResponseFormat(ActionStatus
381 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
384 InterfaceDefinition interfaceDefinition = interfaceCandidate.get();
385 Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
386 if(MapUtils.isEmpty(operations)) {
387 return Either.right(componentsUtils.getResponseFormat(ActionStatus
388 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
391 Operation operation = operations.get(operationId);
392 Either<Operation, ResponseFormat> operationEither = Either.left(operation);
394 ListDataDefinition<OperationInputDefinition> inputs = operation.getInputs();
395 Optional<OperationInputDefinition> inputCandidate =
396 getOperationInputByInputId(serviceConsumptionData, inputs);
398 if(!inputCandidate.isPresent()) {
399 return Either.right(new ResponseFormat(HttpStatus.NOT_FOUND.value()));
402 OperationInputDefinition operationInputDefinition = inputCandidate.get();
403 // add data to operation
405 if(Objects.nonNull(serviceConsumptionData.getValue())) {
407 handleConsumptionValue(parentService, serviceInstanceId, serviceConsumptionData, operation,
408 operationInputDefinition);
411 if(operationEither.isRight()) {
412 return Either.right(operationEither.right().value());
415 Operation updatedOperation = operationEither.left().value();
416 operations.remove(operationId);
417 operations.put(operationId, updatedOperation);
418 interfaceDefinition.setOperationsMap(operations);
420 parentService.getComponentInstances().remove(serviceInstance);
421 if(CollectionUtils.isEmpty(parentService.getComponentInstances())) {
422 parentService.setComponentInstances(new ArrayList<>());
425 Map<String, Object> instanceInterfaces =
426 MapUtils.isEmpty(serviceInstance.getInterfaces())? new HashMap<>() : serviceInstance.getInterfaces();
427 instanceInterfaces.remove(interfaceDefinition.getUniqueId());
428 instanceInterfaces.put(interfaceDefinition.getUniqueId(), interfaceDefinition);
429 serviceInstance.setInterfaces(instanceInterfaces);
431 removeComponentInstanceInterfaceByInterfaceId(interfaceDefinition.getUniqueId(), componentInstancesInterfaces.get(serviceInstanceId));
432 componentInstancesInterfaces.get(serviceInstanceId).add(new ComponentInstanceInterface(interfaceDefinition.getUniqueId(), interfaceDefinition));
434 parentService.getComponentInstances().add(serviceInstance);
436 StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(parentService, serviceInstanceId);
438 if(status != StorageOperationStatus.OK) {
439 return Either.right(componentsUtils.getResponseFormat(ActionStatus
440 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
443 return Either.left(operation);
446 private void removeComponentInstanceInterfaceByInterfaceId(String interfaceIdToRemove,
447 List<ComponentInstanceInterface> instanceInterfaces) {
448 if(CollectionUtils.isEmpty(instanceInterfaces)) {
452 Optional<ComponentInstanceInterface> interfaceToRemove =
453 instanceInterfaces.stream().filter(instInterface -> instInterface.getUniqueId().equals
454 (interfaceIdToRemove)).findAny();
456 if(interfaceToRemove.isPresent()) {
457 instanceInterfaces.remove(interfaceToRemove.get());
462 private Either<Operation, ResponseFormat> handleConsumptionValue(Service containerService,
463 String serviceInstanceId,
464 ServiceConsumptionData serviceConsumptionData,
466 OperationInputDefinition
467 operationInputDefinition) {
468 String source = serviceConsumptionData.getSource();
469 String consumptionValue = serviceConsumptionData.getValue();
470 String type = serviceConsumptionData.getType();
471 String operationIdentifier = consumptionValue.contains(".")
472 ? consumptionValue.substring(0, consumptionValue.lastIndexOf('.'))
475 ServiceConsumptionSource sourceValue = ServiceConsumptionSource.getSourceValue(source);
477 if(STATIC.equals(sourceValue)) {
478 // Validate constraint on input value
479 /*Either<Boolean, ResponseFormat> constraintValidationResult =
480 validateOperationInputConstraint(operationInputDefinition, serviceConsumptionData);
482 if (constraintValidationResult.isRight()) {
483 return Either.right(constraintValidationResult.right().value());
486 return handleConsumptionStaticValue(consumptionValue, type, operation,
487 operationInputDefinition);
490 if (Objects.isNull(sourceValue)) {
491 List<PropertyDefinition> propertyDefinitions;
492 String componentName;
493 List<OperationOutputDefinition> outputs = null;
494 if (source.equals(containerService.getUniqueId())) {
495 Either<Service, StorageOperationStatus> serviceToTakePropEither =
496 toscaOperationFacade.getToscaElement(source);
497 if (serviceToTakePropEither.isRight()) {
498 return Either.right(componentsUtils.getResponseFormat(serviceToTakePropEither.right().value()));
500 Service service = serviceToTakePropEither.left().value();
501 operationInputDefinition.setSource(service.getUniqueId());
502 sourceValue = SERVICE_INPUT;
503 propertyDefinitions = service.getProperties();
504 componentName = service.getName();
505 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier,
506 service.getInterfaces()).getListToscaDataDefinition();
508 Optional<ComponentInstance> getComponentInstance = containerService.getComponentInstanceById(source);
509 if(!getComponentInstance.isPresent()){
510 return Either.right(componentsUtils.getResponseFormat(
511 ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, source));
513 ComponentInstance componentInstance = getComponentInstance.get();
514 operationInputDefinition.setSource(componentInstance.getUniqueId());
515 propertyDefinitions = componentInstance.getProperties();
516 componentName = source.equals(serviceInstanceId) ? SELF : componentInstance.getName();
517 if (MapUtils.isNotEmpty(componentInstance.getInterfaces())) {
518 Map<String, InterfaceDataDefinition> componentInstanceInterfaces =
519 componentInstance.getInterfaces().entrySet().stream()
520 .collect(Collectors.toMap((Map.Entry::getKey),
521 (interfaceEntry -> (InterfaceDataDefinition) interfaceEntry.getValue())));
522 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier,
523 componentInstanceInterfaces).getListToscaDataDefinition();
527 if(sourceValue == ServiceConsumptionSource.SERVICE_INPUT) {
528 //The operation input in service consumption has been mapped to an input in the parent service
529 return handleConsumptionInputValue(consumptionValue, containerService, operation,
530 operationInputDefinition);
532 return handleConsumptionPropertyValue(operation, operationInputDefinition,
533 serviceConsumptionData, propertyDefinitions, outputs, consumptionValue, componentName);
536 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.SOURCE, source);
537 operationInputDefinition.setSource(source);
539 return Either.left(operation);
542 private Optional<OperationInputDefinition> getOperationInputByInputId(ServiceConsumptionData serviceConsumptionData,
543 ListDataDefinition<OperationInputDefinition> inputs) {
545 if(CollectionUtils.isEmpty(inputs.getListToscaDataDefinition())) {
546 return Optional.empty();
549 return inputs.getListToscaDataDefinition().stream().filter(operationInput -> operationInput.getInputId().equals
550 (serviceConsumptionData.getInputId()))
554 private Either<Operation, ResponseFormat> handleConsumptionPropertyValue(
555 Operation operation, OperationInputDefinition operationInputDefinition,
556 ServiceConsumptionData serviceConsumptionData, List<PropertyDefinition> properties,
557 List<OperationOutputDefinition> outputs, String consumptionValue, String componentName) {
559 if (CollectionUtils.isEmpty(properties) && CollectionUtils.isEmpty(outputs)) {
560 return Either.left(operation);
563 if (CollectionUtils.isNotEmpty(outputs)
564 && isOperationInputMappedToOtherOperationOutput(getOperationOutputName(consumptionValue), outputs)) {
565 return handleConsumptionInputMappedToOperationOutput(operation, operationInputDefinition, outputs,
566 consumptionValue, componentName);
569 if (CollectionUtils.isNotEmpty(properties)) {
570 return handleConsumptionInputMappedToProperty(operation, operationInputDefinition, serviceConsumptionData,
571 properties, componentName);
573 return Either.left(operation);
576 private Either<Operation, ResponseFormat> handleConsumptionInputMappedToProperty(Operation operation,
577 OperationInputDefinition operationInputDefinition, ServiceConsumptionData serviceConsumptionData,
578 List<PropertyDefinition> properties, String componentName) {
579 Optional<PropertyDefinition> servicePropertyCandidate =
580 properties.stream().filter(property -> property.getName()
581 .equals(serviceConsumptionData.getValue())).findAny();
583 if (servicePropertyCandidate.isPresent()) {
584 boolean isInputTypeSimilarToOperation =
585 isAssignedValueFromValidType(operationInputDefinition.getType(),
586 servicePropertyCandidate.get());
588 if (!isInputTypeSimilarToOperation) {
589 return Either.right(componentsUtils.getResponseFormat(
590 ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
593 addPropertyToInputValue(componentName, operation, operationInputDefinition,
594 servicePropertyCandidate.get());
596 return Either.left(operation);
599 private Either<Operation, ResponseFormat> handleConsumptionInputMappedToOperationOutput(Operation operation,
600 OperationInputDefinition operationInputDefinition, List<OperationOutputDefinition> outputs,
601 String consumptionValue, String componentName) {
602 String outputName = getOperationOutputName(consumptionValue);
603 Optional<OperationOutputDefinition> servicePropertyOutputCandidate = outputs.stream()
604 .filter(output -> output.getName().equals(outputName)).findAny();
605 if (servicePropertyOutputCandidate.isPresent()) {
606 boolean isInputTypeSimilarToOperation =
607 isAssignedValueFromValidType(operationInputDefinition.getType(),
608 servicePropertyOutputCandidate.get());
609 if (!isInputTypeSimilarToOperation) {
610 return Either.right(componentsUtils.getResponseFormat(
611 ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
613 addOutputToInputValue(componentName, consumptionValue, operation, operationInputDefinition);
615 return Either.left(operation);
618 private void addPropertyToInputValue(String componentName, Operation operation,
619 OperationInputDefinition operationInputDefinition,
620 PropertyDefinition serviceProperty) {
621 Map<String, List<String>> getProperty = new HashMap<>();
622 List<String> getPropertyValues = new ArrayList<>();
623 getPropertyValues.add(componentName);
624 getPropertyValues.add(serviceProperty.getName());
625 getProperty.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), getPropertyValues);
627 operationInputDefinition.setSourceProperty(serviceProperty.getUniqueId());
628 operation.getInputs().delete(operationInputDefinition);
629 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_PROPERTY,
631 operationInputDefinition.setValue((new Gson()).toJson(getProperty));
632 operation.getInputs().add(operationInputDefinition);
635 private void addOutputToInputValue(String componentName, String consumptionValue,
636 Operation operation, OperationInputDefinition operationInputDefinition) {
637 Map<String, List<String>> getOperationOutput =
638 InterfaceOperationUtils.createMappedOutputDefaultValue(componentName, consumptionValue);
639 operation.getInputs().delete(operationInputDefinition);
640 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_OPERATION_OUTPUT,
642 operationInputDefinition.setValue((new Gson()).toJson(getOperationOutput));
643 operation.getInputs().add(operationInputDefinition);
646 public Either<Operation, ResponseFormat> handleConsumptionStaticValue(String value, String type,
648 OperationInputDefinition
649 operationInputDefinition) {
650 boolean isInputTypeSimilarToOperation =
651 isAssignedValueFromValidType(type, value);
653 if(!isInputTypeSimilarToOperation) {
654 return Either.right(componentsUtils.getResponseFormat(
655 ActionStatus.INVALID_CONSUMPTION_TYPE, type));
658 //Validate Constraint and Value
659 Either<Boolean, ResponseFormat> constraintValidationResponse =
660 validateOperationInputConstraint(operationInputDefinition, value, type);
661 if(constraintValidationResponse.isRight()) {
662 return Either.right(constraintValidationResponse.right().value());
665 addStaticValueToInputOperation(value, operation, operationInputDefinition);
667 return Either.left(operation);
670 private Either<Boolean, ResponseFormat> validateOperationInputConstraint(
671 OperationInputDefinition operationInputDefinition, String value, String type) {
672 ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
673 propertyDefinition.setType(operationInputDefinition.getParentPropertyType());
675 InputDefinition inputDefinition = new InputDefinition();
676 inputDefinition.setDefaultValue(value);
677 inputDefinition.setInputPath(operationInputDefinition.getSubPropertyInputPath());
678 inputDefinition.setType(type);
679 if (Objects.nonNull(operationInputDefinition.getParentPropertyType())) {
680 inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
683 return PropertyValueConstraintValidationUtil.getInstance()
684 .validatePropertyConstraints(Collections.singletonList(inputDefinition), applicationDataTypeCache);
687 private void addStaticValueToInputOperation(String value, Operation operation,
688 OperationInputDefinition operationInputDefinition) {
689 operation.getInputs().delete(operationInputDefinition);
690 operationInputDefinition.setSource(STATIC.getSource());
691 operationInputDefinition.setSourceProperty(null);
692 operationInputDefinition.setValue(value);
693 operation.getInputs().add(operationInputDefinition);
696 private Either<Operation, ResponseFormat> handleConsumptionInputValue(String inputId,
699 OperationInputDefinition
700 operationInputDefinition) {
701 List<InputDefinition> serviceInputs = service.getInputs();
702 Optional<InputDefinition> inputForValue =
703 serviceInputs.stream().filter(input -> input.getUniqueId().contains(inputId)).findAny();
705 if(inputForValue.isPresent()) {
706 boolean isInputTypeSimilarToOperation =
707 isAssignedValueFromValidType(operationInputDefinition.getType(), inputForValue.get());
709 if(!isInputTypeSimilarToOperation) {
710 return Either.right(componentsUtils.getResponseFormat(
711 ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
713 addGetInputValueToOperationInput(operation, operationInputDefinition, inputForValue.get());
716 return Either.left(operation);
720 private boolean isAssignedValueFromValidType(String operationInputType, Object actualValue) {
721 if (actualValue instanceof String) {
722 // validate static value
723 ToscaPropertyType actualType = ToscaPropertyType.isValidType(operationInputType);
724 PropertyTypeValidator validator = actualType.getValidator();
725 return validator.isValid((String)actualValue, operationInputType);
726 } else if (actualValue instanceof PropertyDefinition) {
727 // validate input / property value
728 String actualType = ((PropertyDefinition) actualValue).getType();
729 return actualType.equalsIgnoreCase(operationInputType);
730 } else if (actualValue instanceof OperationOutputDefinition) {
731 // validate input / output value
732 String actualType = ((OperationOutputDefinition) actualValue).getType();
733 return actualType.equalsIgnoreCase(operationInputType);
738 private void addGetInputValueToOperationInput(Operation operation,
739 OperationInputDefinition operationInputDefinition,
740 InputDefinition inputForValue) {
741 operation.getInputs().delete(operationInputDefinition);
742 Map<String, String> getInputMap = new HashMap<>();
743 getInputMap.put(ToscaFunctions.GET_INPUT.getFunctionName(), inputForValue.getName());
744 operationInputDefinition.setSourceProperty(inputForValue.getUniqueId());
745 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_INPUT, getInputMap);
746 operationInputDefinition.setValue(new Gson().toJson(getInputMap));
747 operation.getInputs().add(operationInputDefinition);
750 private Either<List<Map<String, Object>>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) {
752 Either<List<ResourceAdminEvent>, ActionStatus> eitherprevVerAudit = auditCassandraDao.getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion);
754 if (eitherprevVerAudit.isRight()) {
755 return Either.right(eitherprevVerAudit.right().value());
759 Either<List<ResourceAdminEvent>, ActionStatus> eitherCurrVerAudit = auditCassandraDao.getAuditByServiceIdAndCurrVersion(componentUUID, componentVersion);
760 if (eitherCurrVerAudit.isRight()) {
761 return Either.right(eitherCurrVerAudit.right().value());
765 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveRestoreList = getArchiveRestoreEventList(componentUUID);
766 if (eitherArchiveRestoreList.isRight()) {
767 return Either.right(eitherArchiveRestoreList.right().value());
770 List<Map<String, Object>> prevVerAuditList = getAuditingFieldsList(eitherprevVerAudit.left().value());
771 List<Map<String, Object>> currVerAuditList = getAuditingFieldsList(eitherCurrVerAudit.left().value());
773 List<Map<String, Object>> duplicateElements = new ArrayList<>();
774 duplicateElements.addAll(prevVerAuditList);
775 duplicateElements.retainAll(currVerAuditList);
777 List<Map<String, Object>> joinedNonDuplicatedList = new ArrayList<>();
778 joinedNonDuplicatedList.addAll(prevVerAuditList);
779 joinedNonDuplicatedList.removeAll(duplicateElements);
780 joinedNonDuplicatedList.addAll(currVerAuditList);
781 joinedNonDuplicatedList.addAll(getAuditingFieldsList(eitherArchiveRestoreList.left().value()));
784 return Either.left(joinedNonDuplicatedList);
787 private Either<List<ResourceAdminEvent>, ActionStatus> getArchiveRestoreEventList(String componentUUID) {
789 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveAudit = auditCassandraDao.getArchiveAuditByServiceInstanceId(componentUUID);
790 if (eitherArchiveAudit.isRight()) {
791 return Either.right(eitherArchiveAudit.right().value());
795 Either<List<ResourceAdminEvent>, ActionStatus> eitherRestoreAudit = auditCassandraDao.getRestoreAuditByServiceInstanceId(componentUUID);
796 if (eitherRestoreAudit.isRight()) {
797 return Either.right(eitherRestoreAudit.right().value());
800 List<ResourceAdminEvent> archiveAudit = new ArrayList<>();
801 archiveAudit.addAll(eitherArchiveAudit.left().value());
802 archiveAudit.addAll(eitherRestoreAudit.left().value());
804 return Either.left(archiveAudit);
807 private List<Map<String, Object>> getAuditingFieldsList(List<? extends AuditingGenericEvent> prevVerAuditList) {
809 List<Map<String, Object>> prevVerAudit = new ArrayList<>();
810 for (AuditingGenericEvent auditEvent : prevVerAuditList) {
811 auditEvent.fillFields();
812 prevVerAudit.add(auditEvent.getFields());
823 * - modifier data (userId)
824 * @return Either<Service, responseFormat>
826 public Either<Service, ResponseFormat> createService(Service service, User user) {
829 user = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false);
830 // validate user role
831 validateUserRole(user, service, new ArrayList<>(), AuditingActionEnum.CREATE_RESOURCE, null);
832 service.setCreatorUserId(user.getUserId());
833 // warn on overridden fields
834 checkFieldsForOverideAttampt(service);
836 log.debug("enrich service with version and state");
837 service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
838 service.setVersion(INITIAL_VERSION);
839 service.setConformanceLevel(ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
840 service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED);
842 Either<Service, ResponseFormat> createServiceResponse = validateServiceBeforeCreate(service, user, AuditingActionEnum.CREATE_RESOURCE);
843 if (createServiceResponse.isRight()) {
844 return createServiceResponse;
846 return createServiceByDao(service, AuditingActionEnum.CREATE_RESOURCE, user);
849 private void checkFieldsForOverideAttampt(Service service) {
850 checkComponentFieldsForOverrideAttempt(service);
851 if (service.getDistributionStatus() != null) {
852 log.info("Distribution Status cannot be defined by user. This field will be overridden by the application");
856 private Either<Service, ResponseFormat> createServiceByDao(Service service, AuditingActionEnum actionEnum, User user) {
857 log.debug("send service {} to dao for create", service.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
859 Either<Boolean, ResponseFormat> lockResult = lockComponentByName(service.getSystemName(), service, "Create Service");
860 if (lockResult.isRight()) {
861 ResponseFormat responseFormat = lockResult.right().value();
862 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
863 return Either.right(responseFormat);
866 log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult);
870 createMandatoryArtifactsData(service, user);
871 createServiceApiArtifactsData(service, user);
872 setToscaArtifactsPlaceHolders(service, user);
873 generateAndAddInputsFromGenericTypeProperties(service, fetchAndSetDerivedFromGenericType(service));
875 Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
877 // service created successfully!!!
878 if (dataModelResponse.isLeft()) {
879 log.debug("Service created successfully!!!");
880 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
881 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
882 ASDCKpiApi.countCreatedServicesKPI();
883 return Either.left(dataModelResponse.left().value());
886 ResponseFormat responseFormat = componentsUtils.getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service, ComponentTypeEnum.SERVICE);
887 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
888 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
889 return Either.right(responseFormat);
892 graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service);
896 @SuppressWarnings("unchecked")
897 private void createServiceApiArtifactsData(Service service, User user) {
898 // create mandatory artifacts
900 // TODO it must be removed after that artifact uniqueId creation will be
901 // moved to ArtifactOperation
902 String serviceUniqueId = service.getUniqueId();
903 Map<String, ArtifactDefinition> artifactMap = service.getServiceApiArtifacts();
904 if (artifactMap == null)
905 artifactMap = new HashMap<>();
907 Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts();
908 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
910 List<CategoryDefinition> categories = service.getCategories();
911 boolean isCreateArtifact = true;
912 if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
913 for (String exlude : exludeServiceCategory) {
914 if (exlude.equalsIgnoreCase(categories.get(0).getName())) {
915 isCreateArtifact = false;
922 if (serviceApiArtifacts != null && isCreateArtifact) {
923 Set<String> keys = serviceApiArtifacts.keySet();
924 for (String serviceApiArtifactName : keys) {
925 Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName);
926 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user, true);
927 artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API);
928 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
931 service.setServiceApiArtifacts(artifactMap);
935 private Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) {
937 Either<Boolean, ResponseFormat> validationResponse = validateServiceFieldsBeforeCreate(user, service, actionEnum);
938 if (validationResponse.isRight()) {
939 return Either.right(validationResponse.right().value());
941 service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
942 service.setContactId(service.getContactId().toLowerCase());
944 // Generate invariant UUID - must be here and not in operation since it
945 // should stay constant during clone
946 String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
947 service.setInvariantUUID(invariantUUID);
949 return Either.left(service);
954 private Either<Boolean, ResponseFormat> validateServiceFieldsBeforeCreate(User user, Service service, AuditingActionEnum actionEnum) {
956 validateComponentFieldsBeforeCreate(user, service, actionEnum);
958 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, service, actionEnum);
959 if (serviceNameUniquenessValidation.isRight()) {
960 throw new ComponentException(serviceNameUniquenessValidation.right().value());
962 Either<Boolean, ResponseFormat> categoryValidation = validateServiceCategory(user, service, actionEnum);
963 if (categoryValidation.isRight()) {
964 return categoryValidation;
966 Either<Boolean, ResponseFormat> projectCodeValidation = validateProjectCode(user, service, actionEnum);
967 if (projectCodeValidation.isRight()) {
968 return projectCodeValidation;
970 validateServiceTypeAndCleanup(service);
972 Either<Boolean, ResponseFormat> serviceRoleValidation = validateServiceRoleAndCleanup(user, service, actionEnum);
973 if (serviceRoleValidation.isRight()) {
974 return serviceRoleValidation;
976 return validateInstantiationTypeValue(user, service, actionEnum);
977 } catch (ComponentException exception) {
978 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
979 componentsUtils.auditComponentAdmin(responseFormat, user, service,
980 AuditingActionEnum.CREATE_SERVICE, ComponentTypeEnum.SERVICE);
981 return Either.right(responseFormat);
985 private Either<Boolean, ResponseFormat> validateServiceCategory(User user, Service service, AuditingActionEnum actionEnum) {
986 log.debug("validate Service category");
987 if (isEmpty(service.getCategories())) {
988 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
989 componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
990 return Either.right(errorResponse);
992 Either<Boolean, ResponseFormat> validatCategory = validateServiceCategory(service.getCategories());
993 if (validatCategory.isRight()) {
994 ResponseFormat responseFormat = validatCategory.right().value();
995 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
996 return Either.right(responseFormat);
998 return Either.left(true);
1001 public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) {
1002 validateUserExists(userId, "validate Service Name Exists", false);
1004 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateComponentNameUniqueness(serviceName, null, ComponentTypeEnum.SERVICE);
1008 if (dataModelResponse.isLeft()) {
1009 Map<String, Boolean> result = new HashMap<>();
1010 result.put("isValid", dataModelResponse.left().value());
1011 log.debug("validation was successfully performed.");
1012 return Either.left(result);
1014 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
1015 return Either.right(responseFormat);
1018 public void setElementDao(IElementOperation elementDao) {
1019 this.elementDao = elementDao;
1022 public void setCassandraAuditingDao(AuditCassandraDao auditingDao) {
1023 this.auditCassandraDao = auditingDao;
1026 public ArtifactsBusinessLogic getArtifactBl() {
1027 return artifactsBusinessLogic;
1030 public void setArtifactBl(ArtifactsBusinessLogic artifactBl) {
1031 this.artifactsBusinessLogic = artifactBl;
1034 public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) {
1035 user = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false);
1036 // validate user role
1037 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1039 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1040 if (storageStatus.isRight()) {
1041 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1044 Service currentService = storageStatus.left().value();
1046 if (!ComponentValidationUtils.canWorkOnComponent(currentService, user.getUserId())) {
1047 log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
1048 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
1051 Either<Service, ResponseFormat> validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate);
1052 if (validationRsponse.isRight()) {
1053 log.info("service update metadata: validations field.");
1054 return validationRsponse;
1056 Service serviceToUpdate = validationRsponse.left().value();
1059 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, currentService, "Update Service Metadata");
1060 if (lockResult.isRight()) {
1061 return Either.right(lockResult.right().value());
1064 Either<Service, StorageOperationStatus> updateResponse = toscaOperationFacade.updateToscaElement(serviceToUpdate);
1065 if (updateResponse.isRight()) {
1066 titanDao.rollback();
1067 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
1068 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
1069 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1072 return Either.left(updateResponse.left().value());
1074 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1078 public Either<Set<String>, ResponseFormat> deleteForwardingPaths(String serviceId, Set<String> pathIdsToDelete, User user, boolean lock) {
1079 Service serviceToDelete = initServiceToDeletePaths(serviceId, pathIdsToDelete);
1080 user = validateUser(user, "deleteForwardingPaths", serviceToDelete, null, false);
1081 // validate user role
1082 validateUserRole(user, serviceToDelete, new ArrayList<>(), null, null);
1083 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1084 if (storageStatus.isRight()) {
1085 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1087 Service service = storageStatus.left().value();
1088 Either<Set<String>, StorageOperationStatus> result = null;
1090 Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Forwarding Path on Service");
1091 if (lockResult.isRight()) {
1092 titanDao.rollback();
1093 return Either.right(componentsUtils.getResponseFormat(componentsUtils
1094 .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1098 result = forwardingPathOperation.deleteForwardingPath(service ,pathIdsToDelete);
1099 if (result.isRight()) {
1100 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, service.getName(), result.right().value());
1101 titanDao.rollback();
1102 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
1105 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, service.getSystemName());
1107 } catch (Exception e){
1108 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
1109 titanDao.rollback();
1110 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1112 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1114 return Either.left(result.left().value());
1117 private Service initServiceToDeletePaths(String serviceId, Collection<String> pathIdsToDelete) {
1118 Service serviceToDelete = new Service();
1119 serviceToDelete.setUniqueId(serviceId);
1120 serviceToDelete.setForwardingPaths(new HashMap<>());
1121 pathIdsToDelete.forEach(pathIdToDelete -> serviceToDelete.getForwardingPaths().put(pathIdToDelete, new ForwardingPathDataDefinition()));
1122 return serviceToDelete;
1125 public Either<Service, ResponseFormat> updateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
1126 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, true,"updateForwardingPath", lock);
1129 public Either<Service, ResponseFormat> createForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
1130 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, false, "createForwardingPath", lock);
1133 private ForwardingPathDataDefinition getTrimmedValues(ForwardingPathDataDefinition path){
1134 ForwardingPathDataDefinition dataDefinition = new ForwardingPathDataDefinition(path.getName());
1135 dataDefinition.setName(Strings.nullToEmpty(path.getName()).trim());
1136 dataDefinition.setProtocol(Strings.nullToEmpty(path.getProtocol()).trim());
1137 dataDefinition.setDestinationPortNumber(Strings.nullToEmpty(path.getDestinationPortNumber()).trim());
1138 dataDefinition.setUniqueId(path.getUniqueId());
1139 dataDefinition.setPathElements(path.getPathElements());
1140 dataDefinition.setDescription(path.getDescription());
1141 dataDefinition.setToscaResourceName(path.getToscaResourceName());
1142 return dataDefinition;
1145 private Either<Service, ResponseFormat> createOrUpdateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean isUpdate, String errorContext, boolean lock) {
1146 validateUserAndRole(serviceUpdate, user, errorContext);
1148 Map<String, ForwardingPathDataDefinition> forwardingPaths = serviceUpdate.getForwardingPaths();
1150 Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths =
1151 forwardingPaths.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
1152 entry -> new ForwardingPathDataDefinition(getTrimmedValues(entry.getValue()))));
1154 Either<Boolean, ResponseFormat> booleanResponseFormatEither = forwardingPathValidator.validateForwardingPaths(trimmedForwardingPaths.values(),
1155 serviceId, isUpdate);
1156 if(booleanResponseFormatEither.isRight()){
1157 return Either.right(booleanResponseFormatEither.right().value());
1160 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
1162 if(serviceStorageOperationStatusEither.isRight()){
1163 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
1164 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
1165 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
1167 Service storedService = serviceStorageOperationStatusEither.left().value();
1169 Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
1170 Either<Component, StorageOperationStatus> forwardingPathOrigin = toscaOperationFacade.getLatestByName(ForwardingPathUtils.FORWARDING_PATH_NODE_NAME);
1171 if (forwardingPathOrigin.isRight()) {
1172 StorageOperationStatus errorStatus = forwardingPathOrigin.right().value();
1173 log.debug("Failed to fetch normative forwarding path resource by tosca name, error {}", errorStatus);
1174 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
1176 Component component = forwardingPathOrigin.left().value();
1177 final String toscaResourceName;
1178 if ( component.getComponentType() == ComponentTypeEnum.RESOURCE) {
1179 toscaResourceName = ((Resource) component).getToscaResourceName();
1181 toscaResourceName = "";
1183 Either<Boolean, ResponseFormat> lockResult = null;
1186 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Forwarding Path on Service");
1187 if (lockResult.isRight()) {
1188 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, storedService.getName(),
1189 lockResult.right().value().getFormattedMessage());
1190 return Either.right(lockResult.right().value());
1192 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, storedService.getSystemName());
1195 Map<String, ForwardingPathDataDefinition> resultMap = new HashMap<>();
1197 trimmedForwardingPaths.values().forEach(fp -> fp.setToscaResourceName(toscaResourceName));
1200 for (ForwardingPathDataDefinition forwardingPathDataDefinition : trimmedForwardingPaths.values()) {
1202 result = forwardingPathOperation.updateForwardingPath(serviceId, forwardingPathDataDefinition);
1204 result = forwardingPathOperation.addForwardingPath(serviceId, forwardingPathDataDefinition);
1206 if (result.isRight()) {
1207 titanDao.rollback();
1208 return Either.right(componentsUtils.getResponseFormat(
1209 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
1212 ForwardingPathDataDefinition fpDataDefinition = result.left().value();
1213 resultMap.put(fpDataDefinition.getUniqueId(), forwardingPathDataDefinition);
1217 } catch (Exception e) {
1218 titanDao.rollback();
1219 log.error("Exception occurred during add or update forwarding path property values: {}", e.getMessage(),
1221 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1225 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
1226 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
1229 Service service = createServiceWithForwardingPathForResponse(serviceId, resultMap);
1230 return Either.left(service);
1233 private Service createServiceWithForwardingPathForResponse(String serviceId, Map<String,ForwardingPathDataDefinition> forwardingPathDataDefinitionMap) {
1234 Service service = new Service();
1235 service.setUniqueId(serviceId);
1236 service.setForwardingPaths(forwardingPathDataDefinitionMap);
1240 private void validateUserAndRole(Service serviceUpdate, User user, String errorContext) {
1241 user = validateUser(user, errorContext, serviceUpdate, null, false);
1242 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1247 Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) {
1250 boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
1251 Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1252 if (response.isRight()) {
1253 ResponseFormat errorResponse = response.right().value();
1254 return Either.right(errorResponse);
1257 verifyValuesAreIdentical(serviceUpdate.getCreatorUserId(), currentService.getCreatorUserId(), "creatorUserId");
1258 verifyValuesAreIdentical(serviceUpdate.getCreatorFullName(), currentService.getCreatorFullName(), "creatorFullName");
1259 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterUserId(), currentService.getLastUpdaterUserId(), "lastUpdaterUserId");
1260 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterFullName(), currentService.getLastUpdaterFullName(), "lastUpdaterFullName");
1262 response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null);
1263 if (response.isRight()) {
1264 return Either.right(response.right().value());
1267 verifyValuesAreIdentical(serviceUpdate.getDistributionStatus(), currentService.getDistributionStatus(), "distributionStatus");
1269 if (serviceUpdate.getProjectCode() != null) {
1270 response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1271 if (response.isRight()) {
1272 return Either.right(response.right().value());
1276 response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1277 if (response.isRight()) {
1278 return Either.right(response.right().value());
1281 verifyValuesAreIdentical(serviceUpdate.getCreationDate(), currentService.getCreationDate(), "creationDate");
1282 verifyValuesAreIdentical(serviceUpdate.getVersion(), currentService.getVersion(), "version");
1284 response = validateAndUpdateDescription(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1285 if (response.isRight()) {
1286 return Either.right(response.right().value());
1289 response = validateAndUpdateTags(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1290 if (response.isRight()) {
1291 return Either.right(response.right().value());
1294 response = validateAndUpdateContactId(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1295 if (response.isRight()) {
1296 return Either.right(response.right().value());
1299 verifyValuesAreIdentical(serviceUpdate.getLastUpdateDate(), currentService.getLastUpdateDate(), "lastUpdateDate");
1300 verifyValuesAreIdentical(serviceUpdate.getLifecycleState(), currentService.getLifecycleState(), "lifecycleState");
1301 verifyValuesAreIdentical(serviceUpdate.isHighestVersion(), currentService.isHighestVersion(), "isHighestVersion");
1302 verifyValuesAreIdentical(serviceUpdate.getUUID(), currentService.getUUID(), "uuid");
1304 validateAndUpdateServiceType(currentService, serviceUpdate);
1306 response = validateAndUpdateServiceRole(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1307 if (response.isRight()) {
1308 return Either.right(response.right().value());
1311 response = validateAndUpdateInstantiationTypeValue(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1312 if (response.isRight()) {
1313 return Either.right(response.right().value());
1316 verifyValuesAreIdentical(serviceUpdate.getInvariantUUID(), currentService.getInvariantUUID(), "invariantUUID");
1318 validateAndUpdateEcompNaming(currentService, serviceUpdate);
1320 currentService.setEnvironmentContext(serviceUpdate.getEnvironmentContext());
1321 return Either.left(currentService);
1323 } catch (ComponentException exception) {
1324 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
1325 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate,
1326 AuditingActionEnum.UPDATE_SERVICE_METADATA, ComponentTypeEnum.SERVICE);
1327 return Either.right(responseFormat);
1331 private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
1332 if (updatedValue != null && !updatedValue.equals(originalValue)) {
1333 log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
1337 private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
1338 Boolean isEcompGeneratedCurr = currentService.isEcompGeneratedNaming();
1339 Boolean isEcompGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
1340 if (isEcompGeneratedUpdate != null && !isEcompGeneratedUpdate.equals(isEcompGeneratedCurr)) {
1341 currentService.setEcompGeneratedNaming(isEcompGeneratedUpdate);
1343 String namingPolicyUpdate = serviceUpdate.getNamingPolicy();
1344 if (currentService.isEcompGeneratedNaming()) {
1345 currentService.setNamingPolicy(namingPolicyUpdate);
1347 if (!StringUtils.isEmpty(namingPolicyUpdate)) {
1348 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
1350 currentService.setNamingPolicy("");
1354 private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1355 String contactIdUpdated = serviceUpdate.getContactId();
1356 String contactIdCurrent = currentService.getContactId();
1357 if (!contactIdCurrent.equals(contactIdUpdated)) {
1358 validateContactId(user, serviceUpdate, audatingAction);
1359 currentService.setContactId(contactIdUpdated.toLowerCase());
1361 return Either.left(true);
1364 private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1365 List<String> tagsUpdated = serviceUpdate.getTags();
1366 List<String> tagsCurrent = currentService.getTags();
1367 if (tagsUpdated == null || tagsUpdated.isEmpty()) {
1368 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
1369 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
1370 return Either.right(responseFormat);
1373 if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
1374 validateTagsListAndRemoveDuplicates(user, serviceUpdate, audatingAction);
1375 currentService.setTags(tagsUpdated);
1377 return Either.left(true);
1380 private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1381 String descriptionUpdated = serviceUpdate.getDescription();
1382 String descriptionCurrent = currentService.getDescription();
1383 if (!descriptionCurrent.equals(descriptionUpdated)) {
1384 validateDescriptionAndCleanup(user, serviceUpdate, audatingAction);
1385 currentService.setDescription(serviceUpdate.getDescription());
1387 return Either.left(true);
1390 private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1391 String projectCodeUpdated = serviceUpdate.getProjectCode();
1392 String projectCodeCurrent = currentService.getProjectCode();
1393 if (!projectCodeCurrent.equals(projectCodeUpdated)) {
1395 Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, serviceUpdate, audatingAction);
1396 if (validatProjectCodeResponse.isRight()) {
1397 ResponseFormat errorRespons = validatProjectCodeResponse.right().value();
1398 return Either.right(errorRespons);
1400 currentService.setProjectCode(projectCodeUpdated);
1403 return Either.left(true);
1406 private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1407 String iconUpdated = serviceUpdate.getIcon();
1408 String iconCurrent = currentService.getIcon();
1409 if (!iconCurrent.equals(iconUpdated)) {
1410 if (!hasBeenCertified) {
1411 validateIcon(user, serviceUpdate, audatingAction);
1412 currentService.setIcon(iconUpdated);
1414 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
1415 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
1416 return Either.right(errorResponse);
1419 return Either.left(true);
1422 private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum auditingAction) {
1423 String serviceNameUpdated = serviceUpdate.getName();
1424 String serviceNameCurrent = currentService.getName();
1425 if (!serviceNameCurrent.equals(serviceNameUpdated)) {
1426 if (!hasBeenCertified) {
1427 validateComponentName(user, serviceUpdate, auditingAction);
1428 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, serviceUpdate, auditingAction);
1429 if (serviceNameUniquenessValidation.isRight()) {
1430 return serviceNameUniquenessValidation;
1432 currentService.setName(serviceNameUpdated);
1433 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
1434 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
1437 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
1438 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
1439 return Either.right(errorResponse);
1442 return Either.left(true);
1445 private void validateAndUpdateServiceType(Service currentService, Service updatedService) {
1446 String updatedServiceType = updatedService.getServiceType();
1447 String currentServiceType = currentService.getServiceType();
1448 if (!currentServiceType.equals(updatedServiceType)) {
1449 validateServiceTypeAndCleanup(updatedService);
1450 currentService.setServiceType(updatedServiceType);
1454 private void validateServiceTypeAndCleanup(Component component) {
1455 log.debug("validate service type");
1456 String serviceType = ((Service)component).getServiceType();
1457 if (serviceType == null) {
1458 log.info("service type is not valid.");
1459 throw new ComponentException(ActionStatus.INVALID_SERVICE_TYPE);
1461 serviceType = cleanUpText(serviceType);
1462 validateServiceType(serviceType);
1466 private void validateServiceType(String serviceType) {
1467 if (serviceType.isEmpty()) {
1470 if (!ValidationUtils.validateServiceTypeLength(serviceType)) {
1471 log.info("service type exceeds limit.");
1472 throw new ComponentException(ActionStatus.SERVICE_TYPE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_TYPE_MAX_LENGTH);
1474 if (!ValidationUtils.validateIsEnglish(serviceType)) {
1475 log.info("service type is not valid.");
1476 throw new ComponentException(ActionStatus.INVALID_SERVICE_TYPE);
1480 private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1481 String updatedServiceRole = updatedService.getServiceRole();
1482 String currentServiceRole = currentService.getServiceRole();
1483 if (!currentServiceRole.equals(updatedServiceRole)) {
1484 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRoleAndCleanup(user, updatedService , auditingAction);
1485 if (validateServiceRole.isRight()) {
1486 ResponseFormat errorResponse = validateServiceRole.right().value();
1487 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1488 return Either.right(errorResponse);
1490 currentService.setServiceRole(updatedServiceRole);
1492 return Either.left(true);
1495 protected Either<Boolean, ResponseFormat> validateServiceRoleAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
1496 log.debug("validate service role");
1497 String serviceRole = ((Service)component).getServiceRole();
1498 if (serviceRole != null){
1499 serviceRole = cleanUpText(serviceRole);
1501 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRole(serviceRole);
1502 if (validateServiceRole.isRight()) {
1503 ResponseFormat responseFormat = validateServiceRole.right().value();
1504 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, ComponentTypeEnum.SERVICE);
1505 return Either.right(responseFormat);
1507 return Either.left(true);
1509 return Either.left(false);
1513 private Either<Boolean, ResponseFormat> validateAndUpdateInstantiationTypeValue(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1514 String updatedInstaType= updatedService.getInstantiationType();
1515 String currentInstaType = currentService.getInstantiationType();
1516 if (!currentInstaType.equals(updatedInstaType)) {
1517 Either<Boolean, ResponseFormat> validateInstantiationType = validateInstantiationTypeValue(user, updatedService , auditingAction);
1518 if (validateInstantiationType.isRight()) {
1519 ResponseFormat errorResponse = validateInstantiationType.right().value();
1520 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1521 return Either.right(errorResponse);
1523 currentService.setInstantiationType(updatedInstaType);
1525 return Either.left(true);
1528 private Either<Boolean, ResponseFormat> validateInstantiationTypeValue(User user, Service service, AuditingActionEnum actionEnum) {
1529 log.debug("validate instantiation type");
1530 String instantiationType = service.getInstantiationType();
1531 if (!InstantiationTypes.containsName(instantiationType) || instantiationType == null){
1532 log.error("Recieved Instantiation type {} is not valid.", instantiationType);
1533 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_INSTANTIATION_TYPE);
1534 componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
1535 return Either.right(errorResponse);
1537 return Either.left(true);
1540 private Either<Boolean, ResponseFormat> validateServiceRole(String serviceRole) {
1541 if (serviceRole.equals("")){
1542 return Either.left(true);
1544 if (!ValidationUtils.validateServiceRoleLength(serviceRole)) {
1545 log.info("service role exceeds limit.");
1546 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ROLE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_ROLE_MAX_LENGTH);
1547 return Either.right(errorResponse);
1550 if (!ValidationUtils.validateIsEnglish(serviceRole)) {
1551 log.info("service role is not valid.");
1552 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_ROLE);
1553 return Either.right(errorResponse);
1555 return Either.left(true);
1559 private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1560 List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1561 List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1562 Either<Boolean, ResponseFormat> validateCategoryResponse = validateServiceCategory(user, serviceUpdate, audatingAction);
1563 if (validateCategoryResponse.isRight()) {
1564 return Either.right(validateCategoryResponse.right().value());
1566 if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1567 if (!hasBeenCertified) {
1568 currentService.setCategories(categoryUpdated);
1570 log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1571 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1572 return Either.right(errorResponse);
1575 return Either.left(true);
1579 private Either<Boolean, ResponseFormat> validateServiceCategory(List<CategoryDefinition> list) {
1581 if (list.size() > 1) {
1582 log.debug("Must be only one category for service");
1583 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.SERVICE.getValue());
1584 return Either.right(responseFormat);
1586 CategoryDefinition category = list.get(0);
1587 if (category.getSubcategories() != null) {
1588 log.debug("Subcategories cannot be defined for service");
1589 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CANNOT_CONTAIN_SUBCATEGORY);
1590 return Either.right(responseFormat);
1592 if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
1593 log.debug("Resource category is empty");
1594 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
1595 return Either.right(responseFormat);
1598 log.debug("validating service category {} against valid categories list", list);
1599 Either<List<CategoryDefinition>, ActionStatus> categorys = elementDao.getAllServiceCategories();
1600 if (categorys.isRight()) {
1601 log.debug("failed to retrieve service categories from Titan");
1602 ResponseFormat responseFormat = componentsUtils.getResponseFormat(categorys.right().value());
1603 return Either.right(responseFormat);
1605 List<CategoryDefinition> categoryList = categorys.left().value();
1606 for (CategoryDefinition value : categoryList) {
1607 if (value.getName().equals(category.getName())) {
1608 return Either.left(true);
1611 log.debug("Category {} is not part of service category group. Service category valid values are {}", list, categoryList);
1612 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.SERVICE.getValue()));
1614 return Either.left(false);
1617 public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1618 Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1619 if (serviceResponseFormatEither.isRight()){
1620 return Either.right(serviceResponseFormatEither.right().value());
1622 final ServiceRelations serviceRelations = new ForwardingPathUtils().convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1623 return Either.left(serviceRelations);
1628 public ResponseFormat deleteService(String serviceId, User user) {
1629 ResponseFormat responseFormat;
1630 String ecompErrorContext = "delete service";
1632 validateUserExists(user, ecompErrorContext, false);
1633 Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1634 if (serviceStatus.isRight()) {
1635 log.debug("failed to get service {}", serviceId);
1636 return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1639 Service service = serviceStatus.left().value();
1641 StorageOperationStatus result = StorageOperationStatus.OK;
1642 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1643 if (lockResult.isRight()) {
1644 return lockResult.right().value();
1647 result = markComponentToDelete(service);
1648 if (result.equals(StorageOperationStatus.OK)) {
1649 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1651 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1652 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1654 return responseFormat;
1656 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1657 log.warn("operation failed. do rollback");
1658 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1659 titanDao.rollback();
1661 log.debug("operation success. do commit");
1664 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1668 public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1669 ResponseFormat responseFormat;
1670 String ecompErrorContext = "delete service";
1671 validateUserNotEmpty(user, ecompErrorContext);
1672 user = validateUserExists(user, ecompErrorContext, false);
1674 Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1675 if (getResult.isRight()) {
1676 return getResult.right().value();
1678 Service service = getResult.left().value();
1680 StorageOperationStatus result = StorageOperationStatus.OK;
1681 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1682 if (lockResult.isRight()) {
1683 result = StorageOperationStatus.GENERAL_ERROR;
1684 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1688 result = markComponentToDelete(service);
1689 if (result.equals(StorageOperationStatus.OK)) {
1690 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1692 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1693 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1695 return responseFormat;
1698 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1699 log.warn("operation failed. do rollback");
1700 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1701 titanDao.rollback();
1703 log.debug("operation success. do commit");
1706 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1710 public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1711 String ecompErrorContext = "Get service";
1712 validateUserNotEmpty(user, ecompErrorContext);
1713 validateUserExists(user, ecompErrorContext, false);
1715 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1716 if (storageStatus.isRight()) {
1717 log.debug("failed to get service by id {}", serviceId);
1718 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1721 if(!(storageStatus.left().value() instanceof Service)){
1722 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1724 Service service = storageStatus.left().value();
1725 return Either.left(service);
1732 public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1733 validateUserExists(userId, "get Service By Name And Version", false);
1734 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1735 if (storageStatus.isRight()) {
1736 log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1737 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceName));
1739 Service service = storageStatus.left().value();
1740 return Either.left(service);
1743 @SuppressWarnings("unchecked")
1744 private void createMandatoryArtifactsData(Service service, User user) {
1745 // create mandatory artifacts
1747 // TODO it must be removed after that artifact uniqueId creation will be
1748 // moved to ArtifactOperation
1749 String serviceUniqueId = service.getUniqueId();
1750 Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1751 if (artifactMap == null)
1752 artifactMap = new HashMap<>();
1754 Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalServiceArtifacts();
1755 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1757 String category = service.getCategories().get(0).getName();
1758 boolean isCreateArtifact = true;
1759 if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1760 for (String exlude : exludeServiceCategory) {
1761 if (exlude.equalsIgnoreCase(category)) {
1762 isCreateArtifact = false;
1769 if (informationalServiceArtifacts != null && isCreateArtifact) {
1770 Set<String> keys = informationalServiceArtifacts.keySet();
1771 for (String informationalServiceArtifactName : keys) {
1772 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1773 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap, user, false);
1774 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1778 service.setArtifacts(artifactMap);
1782 private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user, Boolean isServiceApi) {
1784 ArtifactDefinition artifactInfo = artifactsBusinessLogic.createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1787 artifactInfo.setMandatory(false);
1788 artifactInfo.setServiceApi(true);
1790 return artifactInfo;
1793 private Either<DistributionTransitionEnum, ResponseFormat> validateTransitionEnum(String distributionTransition) {
1794 DistributionTransitionEnum transitionEnum = null;
1796 transitionEnum = DistributionTransitionEnum.getFromDisplayName(distributionTransition);
1797 if (transitionEnum == null) {
1798 BeEcompErrorManager.getInstance().logBeSystemError(CHANGE_SERVICE_DISTRIBUTION);
1799 log.info("state operation is not valid. operations allowed are: {}", DistributionTransitionEnum.valuesAsString());
1800 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1801 return Either.right(error);
1804 return Either.left(transitionEnum);
1807 private Either<String, ResponseFormat> validateComment(LifecycleChangeInfoWithAction comment) {
1808 String data = comment.getUserRemarks();
1810 if (data == null || data.trim().isEmpty()) {
1811 BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1812 log.debug("user comment cannot be empty or null.");
1813 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1815 data = ValidationUtils.removeNoneUtf8Chars(data);
1816 data = ValidationUtils.removeHtmlTags(data);
1817 data = ValidationUtils.normaliseWhitespace(data);
1818 data = ValidationUtils.stripOctets(data);
1820 if (!ValidationUtils.validateLength(data, ValidationUtils.COMMENT_MAX_LENGTH)) {
1821 BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1822 log.debug("user comment exceeds limit.");
1823 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, "comment", String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH)));
1825 if (!ValidationUtils.validateIsEnglish(data)) {
1826 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1828 return Either.left(data);
1831 private Either<Service, ResponseFormat> validateServiceDistributionChange(User user, String serviceId, AuditingActionEnum auditAction, String comment) {
1832 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1833 if (storageStatus.isRight()) {
1834 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId);
1835 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1836 componentsUtils.auditComponent(responseFormat, user, auditAction, new ResourceCommonInfo(serviceId, ComponentTypeEnum.SERVICE.getValue()), comment);
1837 return Either.right(responseFormat);
1839 Service service = storageStatus.left().value();
1841 if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1842 log.info("service {} is not available for distribution. Should be in certified state", service.getUniqueId());
1843 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1844 createAudit(user, auditAction, comment, service, responseFormat);
1845 return Either.right(responseFormat);
1847 return Either.left(service);
1850 private Either<User, ResponseFormat> validateUserDistributionChange(User user, Service service, AuditingActionEnum auditAction, String comment) {
1851 log.debug("get user from DB");
1854 user = validateUser(user, "Activate Distribution", service, auditAction, false);
1855 // validate user role
1856 List<Role> roles = new ArrayList<>();
1857 roles.add(Role.ADMIN);
1858 roles.add(Role.GOVERNOR);
1859 roles.add(Role.OPS);
1860 validateUserRole(user, service, roles, auditAction, comment);
1861 return Either.left(user);
1864 private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat) {
1865 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1866 componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1867 ResourceVersionInfo.newBuilder()
1868 .state(component.getLifecycleState().name())
1869 .version(component.getVersion())
1874 private String getEnvNameFromConfiguration() {
1875 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1876 log.trace("Update environment name to be {}", configuredEnvName);
1877 return configuredEnvName;
1880 public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier, ServiceDistributionReqInfo data) {
1882 Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation.validateActivateServiceRequest(serviceId, envId, modifier, data);
1883 if (activationRequestInformationEither.isRight()) {
1884 return Either.right(activationRequestInformationEither.right().value());
1887 ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1889 Either<String, ResponseFormat> result = null;
1890 String did = ThreadLocalsHolder.getUuid();
1891 Service service = activationRequestInformation.getServiceToActivate();
1892 result = buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1896 public Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext, User modifier) {
1897 String envName = getEnvNameFromConfiguration();
1898 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1899 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1900 if (notifyServiceResponse == ActionStatus.OK) {
1901 return Either.left(did);
1903 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1904 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1905 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1906 return Either.right(error);
1910 public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1912 User user = validateUserExists(modifier.getUserId(), "activate Distribution", false);
1913 Either<Service, ResponseFormat> result = null;
1914 ResponseFormat response = null;
1915 Service updatedService = null;
1916 String did = ThreadLocalsHolder.getUuid();
1918 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1919 if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1920 log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1921 envName = configuredEnvName;
1925 ServletContext servletContext = request.getSession().getServletContext();
1926 boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1927 if (!isDistributionEngineUp) {
1928 BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1929 log.debug("Distribution Engine is DOWN");
1930 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1931 return Either.right(response);
1934 Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1935 if (serviceRes.isRight()) {
1936 log.debug("failed retrieving service");
1937 response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1938 componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1939 new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1940 ResourceVersionInfo.newBuilder()
1943 return Either.right(response);
1945 Service service = serviceRes.left().value();
1946 String dcurrStatus = service.getDistributionStatus().name();
1947 String updatedStatus = dcurrStatus;
1948 StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1949 if (readyForDistribution.equals(StorageOperationStatus.OK)) {
1950 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1951 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1952 if (notifyServiceResponse == ActionStatus.OK) {
1953 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED);
1954 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1955 updatedService = updateStateRes.left().value();
1956 updatedStatus = updatedService.getDistributionStatus().name();
1958 // The response is not relevant
1959 updatedService = service;
1961 ASDCKpiApi.countActivatedDistribution();
1962 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1963 result = Either.left(updatedService);
1965 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1966 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1967 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1968 result = Either.right(response);
1971 response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution), envName);
1972 result = Either.right(response);
1974 componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1975 new ResourceCommonInfo(service.getName(),ComponentTypeEnum.SERVICE.getValue()),
1976 ResourceVersionInfo.newBuilder()
1977 .distributionStatus(dcurrStatus)
1979 ResourceVersionInfo.newBuilder()
1980 .distributionStatus(updatedStatus)
1986 // convert to private after deletion of temp url
1987 public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1989 validateUserExists(user.getUserId(), "update Distribution Status For Activation", false);
1991 String serviceId = service.getUniqueId();
1992 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1993 if (lockResult.isRight()) {
1994 return Either.right(lockResult.right().value());
1997 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
1998 if (result.isRight()) {
1999 titanDao.rollback();
2000 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
2001 log.debug("service {} change distribution status failed", serviceId);
2002 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2005 return Either.left(result.left().value());
2007 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
2011 public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
2013 validateUserExists(user.getUserId(), "mark Distribution As Deployed", false);
2014 log.debug("mark distribution deployed");
2016 AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
2017 Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
2018 if (getServiceResponse.isRight()) {
2019 BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
2020 log.debug("service {} not found", serviceId);
2021 ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
2023 return Either.right(responseFormat);
2026 Service service = getServiceResponse.left().value();
2027 user = validateRoleForDeploy(did, user, auditAction, service);
2028 return checkDistributionAndDeploy(did, user, auditAction, service);
2032 public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2033 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
2034 // Only one VF Module Artifact per instance - add it to a list of one
2035 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
2037 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2041 private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock, boolean inTransaction, ComponentInstance ri) {
2042 List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
2044 if (ri.getOriginType() == OriginTypeEnum.VF) {
2045 asList = Arrays.asList(new VfModuleArtifactGenerator(modifier, ri, service, shouldLock, inTransaction));
2050 private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
2051 Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
2052 if(currVF.getGroupInstances() != null){
2053 currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
2055 return currVF.getGroupInstances();
2058 private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) {
2059 ArtifactDefinition vfModuleAertifact = null;
2060 if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
2061 Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.name())).findAny();
2062 if (optionalVfModuleArtifact.isPresent()) {
2063 vfModuleAertifact = optionalVfModuleArtifact.get();
2066 if (vfModuleAertifact == null) {
2067 Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service, payloadWrapper.getInnerElement());
2068 if (createVfModuleArtifact.isLeft()) {
2069 vfModuleAertifact = createVfModuleArtifact.left().value();
2071 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
2074 return vfModuleAertifact;
2077 private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
2078 List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
2079 if (groupsForCurrVF != null) {
2080 for (GroupInstance groupInstance : groupsForCurrVF) {
2081 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
2082 vfModulePayloads.add(modulePayload);
2084 vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
2086 final Gson gson = new GsonBuilder().setPrettyPrinting().create();
2088 String vfModulePayloadString = gson.toJson(vfModulePayloads);
2089 payloadWrapper.setInnerElement(vfModulePayloadString);
2094 private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock, boolean inTransaction) {
2095 ArtifactDefinition vfModuleArtifact = null;
2096 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
2097 Wrapper<String> payloadWrapper = new Wrapper<>();
2098 List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
2099 if (responseWrapper.isEmpty()) {
2100 fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
2102 if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
2103 vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
2105 if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
2106 vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper, responseWrapper, service);
2109 Either<ArtifactDefinition, ResponseFormat> result;
2110 if (responseWrapper.isEmpty()) {
2111 result = Either.left(vfModuleArtifact);
2113 result = Either.right(responseWrapper.getInnerElement());
2119 private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper, Service service) {
2120 ArtifactDefinition result = null;
2121 Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, inTransaction, System::currentTimeMillis,
2122 () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), currVF.getUniqueId());
2123 if (eitherPayload.isLeft()) {
2124 result = eitherPayload.left().value();
2126 responseWrapper.setInnerElement(eitherPayload.right().value());
2128 if (result == null) {
2129 result = vfModuleArtifact;
2135 private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service, String vfModulePayloadString) {
2137 ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
2138 String newCheckSum = null;
2140 vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
2141 vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
2142 vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
2143 vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
2144 vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
2145 vfModuleArtifactDefinition.setTimeout(0);
2146 vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
2147 vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
2148 if (vfModulePayloadString != null) {
2149 newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
2151 vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
2153 Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent = artifactToscaOperation.addArifactToComponent(vfModuleArtifactDefinition, service.getUniqueId(), NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
2155 Either<ArtifactDefinition, ResponseFormat> result;
2156 if (addArifactToComponent.isLeft()) {
2157 result = Either.left(addArifactToComponent.left().value());
2159 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArifactToComponent.right().value())));
2165 public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2167 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
2168 // Get All Deployment Artifacts
2169 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
2170 // Filter in Only Heat Env
2171 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
2172 // Create ArtifactGenerator from those Artifacts
2173 map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction, resourceInstance.getUniqueId())).collect(Collectors.toList());
2175 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2179 private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
2181 // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
2183 if (service.getComponentInstances() != null) {
2184 List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
2185 if (artifactGenList != null && !artifactGenList.isEmpty()) {
2186 for (ArtifactGenerator<CallVal> entry : artifactGenList) {
2187 Either<CallVal, ResponseFormat> callRes;
2189 callRes = entry.call();
2190 if (callRes.isRight()) {
2191 log.debug("Failed to generate artifact error : {}", callRes.right().value());
2192 return Either.right(callRes.right().value());
2194 } catch (Exception e) {
2195 log.debug("Failed to generate artifact exception : {}", e);
2196 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2201 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
2202 if (storageStatus.isRight()) {
2203 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2206 Service currentService = storageStatus.left().value();
2208 return Either.left(currentService);
2212 abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
2216 class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2217 ArtifactDefinition artifactDefinition;
2219 String resourceInstanceName;
2223 boolean inTransaction;
2225 HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock, boolean inTransaction, String instanceId) {
2226 this.artifactDefinition = artifactDefinition;
2227 this.service = service;
2228 this.resourceInstanceName = resourceInstanceName;
2229 this.modifier = modifier;
2230 this.shouldLock = shouldLock;
2231 this.instanceId = instanceId;
2232 this.inTransaction = inTransaction;
2236 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2237 return artifactsBusinessLogic.forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier, shouldLock, inTransaction, instanceId);
2240 public ArtifactDefinition getArtifactDefinition() {
2241 return artifactDefinition;
2246 class VfModuleArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2248 private ComponentInstance componentInstance;
2249 private Service service;
2251 boolean inTransaction;
2254 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2255 return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
2258 private VfModuleArtifactGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock, boolean inTransaction) {
2261 this.componentInstance = componentInstance;
2262 this.service = service;
2263 this.shouldLock = shouldLock;
2264 this.inTransaction = inTransaction;
2269 private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction, Service service) {
2270 boolean isDeployed = isDistributionDeployed(distributionId);
2272 return Either.left(service);
2274 Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
2275 if (distributionSuccess.isRight()) {
2276 return Either.right(distributionSuccess.right().value());
2279 log.debug("mark distribution {} as deployed - success", distributionId);
2280 componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK", user);
2281 return Either.left(service);
2284 private boolean isDistributionDeployed(String distributionId) {
2285 Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
2287 boolean isDeployed = false;
2288 if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
2290 log.debug("distribution {} is already deployed", distributionId);
2296 protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
2298 log.trace("checkDistributionSuccess");
2299 // get all "DRequest" records for this distribution
2301 Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
2302 if (distRequestsResponse.isRight()) {
2303 ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
2304 return Either.right(error);
2307 List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
2308 if (distributionRequests.isEmpty()) {
2309 BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
2310 log.info("distribution {} is not found", did);
2311 ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
2312 return Either.right(error);
2314 boolean isRequestSucceeded = false;
2315 for (ResourceAdminEvent event : distributionRequests) {
2316 String eventStatus = event.getStatus();
2317 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2318 isRequestSucceeded = true;
2323 // get all "DNotify" records for this distribution
2324 Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
2325 if (distNotificationsResponse.isRight()) {
2326 ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
2327 return Either.right(error);
2330 List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
2331 boolean isNotificationsSucceeded = false;
2332 for (DistributionNotificationEvent event : distributionNotifications) {
2333 String eventStatus = event.getStatus();
2334 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2335 isNotificationsSucceeded = true;
2340 // if request failed OR there are notifications that failed
2341 if (!(isRequestSucceeded && isNotificationsSucceeded)) {
2343 log.info("distribution {} has failed", did);
2344 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2345 auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2346 return Either.right(error);
2348 return Either.left(true);
2351 private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) {
2353 ResponseFormat error = componentsUtils.getResponseFormat(status, params);
2354 String message = "";
2355 if (error.getMessageId() != null) {
2356 message = error.getMessageId() + ": ";
2358 message += error.getFormattedMessage();
2360 if (service != null) {
2361 componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user);
2363 componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
2368 private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
2369 Either<User, ActionStatus> eitherCreator = userAdmin.getUser(user.getUserId(), false);
2370 if (eitherCreator.isRight() || eitherCreator.left().value() == null) {
2371 BeEcompErrorManager.getInstance().logBeUserMissingError("Deploy Service", user.getUserId());
2372 log.debug("validateRoleForDeploy method - user is not listed. userId= {}", user.getUserId());
2373 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, user.getUserId());
2374 auditDeployError(did, user, auditAction, service, ActionStatus.USER_NOT_FOUND);
2375 throw new ComponentException(ActionStatus.USER_NOT_FOUND, user.getUserId());
2377 user = eitherCreator.left().value();
2378 log.debug("validate user role");
2379 List<Role> roles = new ArrayList<>();
2380 roles.add(Role.ADMIN);
2381 roles.add(Role.OPS);
2383 validateUserRole(user, service, roles, auditAction, null);
2384 } catch (ComponentException e){
2385 log.info("role {} is not allowed to perform this action", user.getRole());
2386 auditDeployError(did, user, auditAction, service, e.getActionStatus());
2393 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
2394 Service service = (Service) component;
2395 Map<String, ArtifactDefinition> artifactMap = service.getDeploymentArtifacts();
2396 if (artifactMap == null) {
2397 artifactMap = new HashMap<>();
2399 service.setDeploymentArtifacts(artifactMap);
2403 public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
2404 return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
2407 private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
2408 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
2409 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
2410 return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
2414 public ComponentInstanceBusinessLogic getComponentInstanceBL() {
2415 return componentInstanceBusinessLogic;
2419 public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
2421 validateUserExists(userId, "Get Component Instances", false);
2422 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2423 if (getComponentRes.isRight()) {
2424 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
2425 return Either.right(responseFormat);
2428 List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
2430 return Either.left(componentInstances);
2433 public ICacheMangerOperation getCacheManagerOperation() {
2434 return cacheManagerOperation;
2437 public void setCacheManagerOperation(ICacheMangerOperation cacheManagerOperation) {
2438 this.cacheManagerOperation = cacheManagerOperation;
2441 public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
2442 this.forwardingPathOperation = forwardingPathOperation;
2446 public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
2447 this.toscaOperationFacade = toscaOperationFacade;
2449 * 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
2452 public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2454 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2455 Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
2456 Component component = null;
2457 Either<Boolean, ResponseFormat> lockResult = null;
2458 log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
2460 validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2461 if (validateUserAndComponentRes.isRight()) {
2462 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed. ", groupInstanceId, serviceId);
2463 actionResult = Either.right(validateUserAndComponentRes.right().value());
2465 if (actionResult == null) {
2466 component = validateUserAndComponentRes.left().value().getKey();
2467 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2468 if (lockResult.isRight()) {
2469 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
2470 actionResult = Either.right(lockResult.right().value());
2472 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
2475 if (actionResult == null) {
2476 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId, newProperties);
2477 if (actionResult.isRight()) {
2478 log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ", groupInstanceId, actionResult.right().value().getFormattedMessage());
2481 } catch (Exception e) {
2482 log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2483 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2485 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2486 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2489 return actionResult;
2492 private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2494 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2495 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2496 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2497 ComponentInstance relatedComponentInstance = null;
2498 GroupInstance oldGroupInstance = null;
2499 Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2500 GroupInstance updatedGroupInstance = null;
2501 boolean inTransaction = true;
2502 findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2503 if (findGroupInstanceRes.isRight()) {
2504 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
2505 actionResult = Either.right(findGroupInstanceRes.right().value());
2507 if (actionResult == null) {
2508 oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2509 relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2510 updateGroupInstanceResult = groupBusinessLogic.validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
2511 if (updateGroupInstanceResult.isRight()) {
2512 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ", oldGroupInstance.getName());
2513 actionResult = Either.right(updateGroupInstanceResult.right().value());
2516 if (actionResult == null) {
2517 updatedGroupInstance = updateGroupInstanceResult.left().value();
2518 if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2519 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance, updatedGroupInstance, inTransaction);
2520 if (updateParentsModificationTimeRes.isRight()) {
2521 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ", oldGroupInstance.getName());
2522 actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2526 if (actionResult == null) {
2527 actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2529 return actionResult;
2532 private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance,
2533 boolean inTranscation) {
2535 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2536 Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2537 Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic.updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2538 updatedGroupInstance.getModificationTime(), inTranscation);
2539 if (updateComponentInstanceRes.isRight()) {
2540 log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(), updatedGroupInstance.getName());
2541 actionResult = Either.right(updateComponentInstanceRes.right().value());
2543 serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2544 if (serviceMetadataUpdateResult.isRight()) {
2545 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ", component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2546 actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2548 actionResult = Either.left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2551 return actionResult;
2554 private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2556 Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2557 Either<Component, ResponseFormat> validateComponentExistsRes = null;
2558 User currUser = null;
2559 Component component = null;
2560 Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2561 if (validationUserResult.isRight()) {
2562 log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2563 result = Either.right(validationUserResult.right().value());
2565 if (result == null) {
2566 currUser = validationUserResult.left().value();
2567 validateComponentExistsRes = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2568 if (validateComponentExistsRes.isRight()) {
2569 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2570 result = Either.right(validateComponentExistsRes.right().value());
2573 if (result == null) {
2574 component = validateComponentExistsRes.left().value();
2575 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2576 log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(), component.getCreatorUserId());
2577 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2580 if (result == null) {
2581 result = Either.left(new ImmutablePair<>(component, currUser));
2586 private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component, String componentInstanceId, String groupInstanceId) {
2588 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2589 GroupInstance groupInstance = null;
2590 ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2591 if (foundComponentInstance == null) {
2592 log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2593 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service", component.getName()));
2595 else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2596 groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst().orElse(null);
2597 if (groupInstance == null) {
2598 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2599 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId, foundComponentInstance.getName()));
2602 if (actionResult == null) {
2603 actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2605 return actionResult;
2608 private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2609 ComponentInstance componentInstance = null;
2610 if (isNotEmpty(component.getComponentInstances())) {
2611 componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst().orElse(null);
2613 return componentInstance;
2616 private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2617 User user = validateUser(modifier, ecompErrorContext, null, null, false);
2618 List<Role> roles = new ArrayList<>();
2619 roles.add(Role.ADMIN);
2620 roles.add(Role.DESIGNER);
2621 validateUserRole(user, roles);
2622 return Either.left(user);
2625 public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId, List<String> dataParamsToReturn) {
2627 ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2628 Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2630 if (serviceResultEither.isRight()) {
2631 if(serviceResultEither.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
2632 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2633 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2636 log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2637 return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2640 Service service = serviceResultEither.left().value();
2641 if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
2642 ListUtils.emptyIfNull(service.getInputs())
2643 .forEach(input -> input.setConstraints(setInputConstraint(input)));
2646 UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2647 return Either.left(dataTransfer);
2650 public Either<String, ResponseFormat> deleteIfNotAlreadyDeletedServiceFilter(String serviceId, String resourceId, String userId, boolean lock) {
2651 Service serviceToDelete = initServiceToDeleteServiceFilter(serviceId);
2652 User user = validateUserExists(userId, "Create service Filter", false);
2655 validateUser(user, "deleteIfNotAlreadyDeletedServiceFilter", serviceToDelete, null, false);
2657 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
2658 if (storageStatus.isRight()) {
2659 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2661 Service service = storageStatus.left().value();
2663 Either<Boolean, ResponseFormat> response = serviceFilterValidator.validateComponentInstanceExist(service, resourceId);
2664 if (storageStatus.isRight()) {
2665 return Either.right(response.right().value());
2667 final Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(resourceId);
2668 if (!optionalComponentInstance.isPresent() ){
2669 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2671 CINodeFilterDataDefinition nodeFilter = optionalComponentInstance.get().getNodeFilter();
2672 if (nodeFilter == null){
2673 return Either.left(resourceId);
2676 Either<String, StorageOperationStatus> result;
2678 Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Service Filter from service");
2679 if (lockResult.isRight()) {
2680 titanDao.rollback();
2681 return Either.right(componentsUtils.getResponseFormat(componentsUtils
2682 .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2686 result = serviceFilterOperation.deleteNodeFilter(service , resourceId);
2687 if (result.isRight()) {
2688 log.debug("Failed to delete node filter in service {}. Response is {}. ", service.getName(), result.right().value());
2689 titanDao.rollback();
2690 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
2693 log.debug("Node filter successfully changed in service {} . ", service.getSystemName());
2695 } catch (Exception e){
2696 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
2697 titanDao.rollback();
2698 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2700 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2702 return Either.left(result.left().value());
2706 private Service initServiceToDeleteServiceFilter(String serviceId) {
2707 Service serviceToDelete = new Service();
2708 serviceToDelete.setUniqueId(serviceId);
2709 return serviceToDelete;
2713 public Either<CINodeFilterDataDefinition, ResponseFormat> createIfNotAlreadyExistServiceFilter(String serviceId, String componentInstanceId, String userId, boolean lock) {
2714 String errorContext = "createIfNotAlreadyExistServiceFilter";
2715 User user = validateUserExists(userId, "Create service Filter", false);
2717 Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
2718 if (serviceEither.isRight()) {
2719 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceEither.right().value(), ComponentTypeEnum.SERVICE), ""));
2721 final Service service = serviceEither.left().value();
2722 validateUserAndRole(service, user, errorContext);
2724 Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(componentInstanceId);
2725 if (!optionalComponentInstance.isPresent()){
2726 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2728 ComponentInstance componentInstance = optionalComponentInstance.get();
2729 CINodeFilterDataDefinition serviceFilter = componentInstance.getNodeFilter();
2730 if (serviceFilter != null){
2731 return Either.left(serviceFilter);
2734 Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2736 Either<Boolean, ResponseFormat> lockResult = null;
2739 lockComponent(service.getUniqueId(), service, "Create Service Filter");
2740 if (lockResult.isRight()) {
2741 log.debug("Failed to lock service {}. Response is {}. ", service.getName(),
2742 lockResult.right().value().getFormattedMessage());
2743 return Either.right(lockResult.right().value());
2745 log.debug("The service with system name {} locked. ", service.getSystemName());
2748 CINodeFilterDataDefinition serviceFilterResult;
2750 result = serviceFilterOperation.createNodeFilter(serviceId, componentInstanceId);
2751 if (result.isRight()) {
2752 titanDao.rollback();
2753 return Either.right(componentsUtils.getResponseFormat(
2754 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2757 serviceFilterResult = result.left().value();
2761 } catch (Exception e) {
2762 titanDao.rollback();
2763 log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2765 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2768 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2769 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2772 return Either.left(serviceFilterResult);
2776 public Either<CINodeFilterDataDefinition, ResponseFormat> updateServiceFilter(String serviceId, String componentInstanceId,
2777 List<String> constraints, User inUser, boolean lock) {
2778 String errorContext = "createIfNotAlreadyExistServiceFilter";
2779 User user = validateUserExists(inUser, errorContext, true);
2780 validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2781 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2783 if(serviceStorageOperationStatusEither.isRight()){
2784 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2785 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2786 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2788 Service storedService = serviceStorageOperationStatusEither.left().value();
2790 Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2791 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId, constraints,
2792 NodeFilterConstraintAction.UPDATE);
2793 if(booleanResponseFormatEither.isRight()){
2794 return Either.right(booleanResponseFormatEither.right().value());
2798 Either<Boolean, ResponseFormat> lockResult = null;
2801 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2802 if (lockResult.isRight()) {
2803 log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
2804 lockResult.right().value().getFormattedMessage());
2805 return Either.right(lockResult.right().value());
2807 log.debug("The service with system name {} locked. ", storedService.getSystemName());
2810 Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2811 if (!componentInstanceOptional.isPresent()){
2812 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2814 CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2815 if(serviceFilter == null){
2816 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2818 CINodeFilterDataDefinition serviceFilterResult;
2820 List<RequirementNodeFilterPropertyDataDefinition> properties = constraints.stream().map(this::getRequirementNodeFilterPropertyDataDefinition).collect(Collectors.toList());
2821 Either<CINodeFilterDataDefinition, StorageOperationStatus> result = serviceFilterOperation.updateProperties(serviceId, componentInstanceId, serviceFilter ,properties);
2823 if (result.isRight()) {
2824 titanDao.rollback();
2825 return Either.right(componentsUtils.getResponseFormat(
2826 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2829 serviceFilterResult = result.left().value();
2833 } catch (Exception e) {
2834 titanDao.rollback();
2835 log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2837 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2840 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2841 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2844 return Either.left(serviceFilterResult);
2847 private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition(String constraint){
2848 RequirementNodeFilterPropertyDataDefinition pdd = new RequirementNodeFilterPropertyDataDefinition();
2849 pdd.setConstraints(Arrays.asList(constraint));
2853 public Either<CINodeFilterDataDefinition, ResponseFormat> addOrDeleteServiceFilter(String serviceId, String componentInstanceId,
2854 NodeFilterConstraintAction action, String constraint, int position, User inUser, boolean lock) {
2855 String errorContext = "createIfNotAlreadyExistServiceFilter";
2856 User user = validateUserExists(inUser, errorContext, true);
2857 validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2859 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2861 if(serviceStorageOperationStatusEither.isRight()){
2862 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2863 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2864 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2866 Service storedService = serviceStorageOperationStatusEither.left().value();
2868 Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2869 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId,
2870 Collections.singletonList(constraint), action);
2871 if(booleanResponseFormatEither.isRight()){
2872 return Either.right(booleanResponseFormatEither.right().value());
2875 Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2877 Either<Boolean, ResponseFormat> lockResult = null;
2878 CINodeFilterDataDefinition serviceFilterResult = null;
2882 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2883 if (lockResult.isRight()) {
2884 log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
2885 lockResult.right().value().getFormattedMessage());
2886 return Either.right(lockResult.right().value());
2888 log.debug("The service with system name {} locked. ", storedService.getSystemName());
2892 Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2893 if (!componentInstanceOptional.isPresent()){
2894 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2896 CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2897 if(serviceFilter == null){
2898 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2904 RequirementNodeFilterPropertyDataDefinition newProperty = new RequirementNodeFilterPropertyDataDefinition();
2905 newProperty.setConstraints(Collections.singletonList(constraint));
2906 result = serviceFilterOperation.addNewProperty(serviceId, componentInstanceId,serviceFilter,newProperty);
2909 result = serviceFilterOperation.deleteConstraint(serviceId, componentInstanceId, serviceFilter, position);
2912 log.error("Unsupported operation "+action);
2913 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2917 if (result.isRight()) {
2918 titanDao.rollback();
2919 return Either.right(componentsUtils.getResponseFormat(
2920 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2923 serviceFilterResult = result.left().value();
2927 } catch (Exception e) {
2928 titanDao.rollback();
2929 log.error("Exception occurred during add or update node filter property values: {}", e.getMessage(),
2931 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2934 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2935 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2938 return Either.left(serviceFilterResult);