2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
19 * Modifications copyright (c) 2019 Nokia
20 * ================================================================================
23 package org.openecomp.sdc.be.components.impl;
25 import static org.apache.commons.collections.CollectionUtils.isEmpty;
26 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
27 import static org.openecomp.sdc.be.components.utils.ConsumptionUtils.handleConsumptionInputMappedToCapabilityProperty;
28 import static org.openecomp.sdc.be.components.utils.ConsumptionUtils.isAssignedValueFromValidType;
29 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getOperationOutputName;
30 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToOtherOperationOutput;
31 import static org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum.UPDATE_SERVICE_METADATA;
32 import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.SELF;
33 import static org.openecomp.sdc.be.types.ServiceConsumptionSource.SERVICE_INPUT;
34 import static org.openecomp.sdc.be.types.ServiceConsumptionSource.STATIC;
36 import com.google.common.annotations.VisibleForTesting;
37 import com.google.common.base.Strings;
38 import com.google.gson.Gson;
39 import com.google.gson.GsonBuilder;
41 import java.nio.charset.StandardCharsets;
42 import java.util.ArrayList;
43 import java.util.Arrays;
44 import java.util.Collection;
45 import java.util.Collections;
46 import java.util.HashMap;
47 import java.util.List;
49 import java.util.Objects;
50 import java.util.Optional;
52 import java.util.concurrent.Callable;
53 import java.util.function.Function;
54 import java.util.stream.Collectors;
56 import fj.data.Either;
57 import org.apache.commons.collections.CollectionUtils;
58 import org.apache.commons.collections.MapUtils;
59 import org.apache.commons.collections4.ListUtils;
60 import org.apache.commons.lang3.StringUtils;
61 import org.apache.commons.lang3.tuple.ImmutablePair;
62 import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine;
63 import org.openecomp.sdc.be.components.distribution.engine.INotificationData;
64 import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload;
65 import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic;
66 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
67 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
68 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
69 import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
70 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
71 import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
72 import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
73 import org.openecomp.sdc.be.components.utils.PropertiesUtils;
74 import org.openecomp.sdc.be.components.validation.NodeFilterValidator;
75 import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
76 import org.openecomp.sdc.be.config.BeEcompErrorManager;
77 import org.openecomp.sdc.be.config.ConfigurationManager;
78 import org.openecomp.sdc.be.dao.api.ActionStatus;
79 import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
80 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
81 import org.openecomp.sdc.be.datamodel.ServiceRelations;
82 import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil;
83 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
84 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
85 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
86 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
87 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
88 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
89 import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition;
90 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
91 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
92 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
93 import org.openecomp.sdc.be.datatypes.enums.InstantiationTypes;
94 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
95 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
96 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
97 import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo;
98 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
99 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
100 import org.openecomp.sdc.be.model.ArtifactDefinition;
101 import org.openecomp.sdc.be.model.CapabilityDefinition;
102 import org.openecomp.sdc.be.model.Component;
103 import org.openecomp.sdc.be.model.ComponentInstance;
104 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
105 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
106 import org.openecomp.sdc.be.model.ComponentParametersView;
107 import org.openecomp.sdc.be.model.DistributionStatusEnum;
108 import org.openecomp.sdc.be.model.DistributionTransitionEnum;
109 import org.openecomp.sdc.be.model.GroupInstance;
110 import org.openecomp.sdc.be.model.GroupInstanceProperty;
111 import org.openecomp.sdc.be.model.InputDefinition;
112 import org.openecomp.sdc.be.model.InterfaceDefinition;
113 import org.openecomp.sdc.be.model.LifecycleStateEnum;
114 import org.openecomp.sdc.be.model.Operation;
115 import org.openecomp.sdc.be.model.PropertyDefinition;
116 import org.openecomp.sdc.be.model.Resource;
117 import org.openecomp.sdc.be.model.Service;
118 import org.openecomp.sdc.be.model.User;
119 import org.openecomp.sdc.be.model.category.CategoryDefinition;
120 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ForwardingPathOperation;
121 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeFilterOperation;
122 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
123 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
124 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
125 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
126 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
127 import org.openecomp.sdc.be.model.tosca.ToscaFunctions;
128 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
129 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
130 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
131 import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent;
132 import org.openecomp.sdc.be.resources.data.auditing.DistributionDeployEvent;
133 import org.openecomp.sdc.be.resources.data.auditing.DistributionNotificationEvent;
134 import org.openecomp.sdc.be.resources.data.auditing.ResourceAdminEvent;
135 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
136 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
137 import org.openecomp.sdc.be.types.ServiceConsumptionData;
138 import org.openecomp.sdc.be.types.ServiceConsumptionSource;
139 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
140 import org.openecomp.sdc.be.user.Role;
141 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
142 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
143 import org.openecomp.sdc.common.api.Constants;
144 import org.openecomp.sdc.common.datastructure.Wrapper;
145 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
146 import org.openecomp.sdc.common.log.wrappers.Logger;
147 import org.openecomp.sdc.common.util.GeneralUtility;
148 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
149 import org.openecomp.sdc.common.util.ValidationUtils;
150 import org.openecomp.sdc.exception.ResponseFormat;
151 import org.springframework.beans.factory.annotation.Autowired;
152 import org.springframework.http.HttpStatus;
153 import org.springframework.web.context.WebApplicationContext;
155 import javax.servlet.ServletContext;
156 import javax.servlet.http.HttpServletRequest;
158 @org.springframework.stereotype.Component("serviceBusinessLogic")
159 public class ServiceBusinessLogic extends ComponentBusinessLogic {
161 private static final String CHANGE_SERVICE_DISTRIBUTION = "Change Service Distribution";
162 private static final String THE_SERVICE_WITH_SYSTEM_NAME_LOCKED = "The service with system name {} locked. ";
163 private static final String FAILED_TO_LOCK_SERVICE_RESPONSE_IS = "Failed to lock service {}. Response is {}. ";
164 private static final String AUDIT_BEFORE_SENDING_RESPONSE = "audit before sending response";
165 private static final Logger log = Logger.getLogger(ServiceBusinessLogic.class);
166 private static final String INITIAL_VERSION = "0.1";
167 private static final String STATUS_SUCCESS_200 = "200";
168 private static final String STATUS_DEPLOYED = "DEPLOYED";
171 private IDistributionEngine distributionEngine;
173 private AuditCassandraDao auditCassandraDao;
175 private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
177 private ServiceDistributionValidation serviceDistributionValidation;
180 private ForwardingPathOperation forwardingPathOperation;
182 private ForwardingPathValidator forwardingPathValidator;
184 private UiComponentDataConverter uiComponentDataConverter;
186 private NodeFilterOperation serviceFilterOperation;
188 private NodeFilterValidator serviceFilterValidator;
190 public Either<Service, ResponseFormat> changeServiceDistributionState(String serviceId, String state, LifecycleChangeInfoWithAction commentObj, User user) {
192 validateUserExists(user.getUserId(), "change Service Distribution State", false);
194 log.debug("check request state");
195 Either<DistributionTransitionEnum, ResponseFormat> validateEnum = validateTransitionEnum(state);
196 if (validateEnum.isRight()) {
197 return Either.right(validateEnum.right().value());
199 DistributionTransitionEnum distributionTransition = validateEnum.left().value();
200 AuditingActionEnum auditAction = distributionTransition == DistributionTransitionEnum.APPROVE ? AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_APPROV : AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REJECT;
201 Either<String, ResponseFormat> commentResponse = validateComment(commentObj);
202 if (commentResponse.isRight()) {
203 return Either.right(commentResponse.right().value());
205 String comment = commentResponse.left().value();
207 Either<Service, ResponseFormat> validateService = validateServiceDistributionChange(user, serviceId, auditAction, comment);
208 if (validateService.isRight()) {
209 return Either.right(validateService.right().value());
211 Service service = validateService.left().value();
212 Either<User, ResponseFormat> validateUser = validateUserDistributionChange(user, service, auditAction, comment);
213 if (validateUser.isRight()) {
214 return Either.right(validateUser.right().value());
216 user = validateUser.left().value();
220 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "ChangeServiceDistributionState");
221 if (lockResult.isRight()) {
222 ResponseFormat responseFormat = lockResult.right().value();
223 createAudit(user, auditAction, comment, service, responseFormat);
224 return Either.right(responseFormat);
229 DistributionStatusEnum newState;
230 if (distributionTransition == DistributionTransitionEnum.APPROVE) {
231 newState = DistributionStatusEnum.DISTRIBUTION_APPROVED;
233 newState = DistributionStatusEnum.DISTRIBUTION_REJECTED;
235 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, newState);
236 if (result.isRight()) {
237 janusGraphDao.rollback();
238 BeEcompErrorManager.getInstance().logBeSystemError("ChangeServiceDistributionState");
239 log.debug("service {} is change destribuation status failed", service.getUniqueId());
240 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, service.getVersion(), service.getName());
241 createAudit(user, auditAction, comment, service, responseFormat);
242 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
244 janusGraphDao.commit();
245 Service updatedService = result.left().value();
246 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
247 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
248 componentsUtils.auditComponent(responseFormat, user, updatedService, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()), ResourceVersionInfo.newBuilder().build(), comment);
249 return Either.left(result.left().value());
251 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
256 public Either<List<Map<String, Object>>, ResponseFormat> getComponentAuditRecords(String componentVersion, String componentUUID, String userId) {
257 validateUserExists(userId, "get Component Audit Records", false);
258 Either<List<Map<String, Object>>, ActionStatus> result;
262 if (componentVersion.endsWith(".0")) {
263 Either<List<ResourceAdminEvent>, ActionStatus> eitherAuditingForCertified = auditCassandraDao.getByServiceInstanceId(componentUUID);
264 if (eitherAuditingForCertified.isLeft()) {
265 result = Either.left(getAuditingFieldsList(eitherAuditingForCertified.left().value()));
267 result = Either.right(eitherAuditingForCertified.right().value());
270 // Uncertified Version
272 result = getAuditRecordsForUncertifiedComponent(componentUUID, componentVersion);
274 } catch (Exception e) {
275 log.debug("get Audit Records failed with exception {}", e);
276 result = Either.right(ActionStatus.GENERAL_ERROR);
279 if (result.isRight()) {
280 return Either.right(componentsUtils.getResponseFormat(result.right().value()));
282 return Either.left(result.left().value());
287 public Either<List<Operation>, ResponseFormat> addServiceConsumptionData(String serviceId,
288 String serviceInstanceId,
290 List<ServiceConsumptionData> serviceConsumptionDataList,
292 List<Operation> operationList = new ArrayList<>();
294 Either<Service, StorageOperationStatus> serviceEither =
295 toscaOperationFacade.getToscaElement(serviceId);
296 if(serviceEither.isRight()) {
297 return Either.right(componentsUtils.getResponseFormat
298 (serviceEither.right().value()));
301 Service service = serviceEither.left().value();
304 StorageOperationStatus storageOperationStatus =
305 graphLockOperation.lockComponent(service.getUniqueId(), NodeTypeEnum.Service);
306 if (storageOperationStatus != StorageOperationStatus.OK) {
307 return Either.right(componentsUtils.getResponseFormat(storageOperationStatus));
311 for (ServiceConsumptionData serviceConsumptionData : serviceConsumptionDataList) {
312 Either<Operation, ResponseFormat> operationEither =
313 addPropertyServiceConsumption(serviceId, serviceInstanceId, operationId,
314 userId, serviceConsumptionData);
316 if (operationEither.isRight()) {
317 return Either.right(operationEither.right().value());
320 operationList.add(operationEither.left().value());
323 janusGraphDao.commit();
324 return Either.left(operationList);
325 } catch (Exception e) {
326 janusGraphDao.rollback();
327 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
330 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
335 public Either <Operation, ResponseFormat> addPropertyServiceConsumption(String serviceId,
336 String serviceInstanceId,
339 ServiceConsumptionData serviceConsumptionData) {
340 validateUserExists(userId, "create Property", false);
342 Either<Service, StorageOperationStatus> serviceEither =
343 toscaOperationFacade.getToscaElement(serviceId);
344 if(serviceEither.isRight()) {
345 return Either.right(componentsUtils.getResponseFormat(serviceEither.right
349 Service parentService = serviceEither.left().value();
351 List<ComponentInstance> componentInstances = parentService.getComponentInstances();
352 if(CollectionUtils.isEmpty(componentInstances)) {
353 return Either.right(componentsUtils.getResponseFormat(ActionStatus
354 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
357 Optional<ComponentInstance> serviceInstanceCandidate =
358 componentInstances.stream().filter(instance -> instance.getUniqueId().equals
359 (serviceInstanceId)).findAny();
361 if(!serviceInstanceCandidate.isPresent()) {
362 return Either.right(componentsUtils.getResponseFormat(ActionStatus
363 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
366 Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaces =
367 parentService.getComponentInstancesInterfaces();
368 if(MapUtils.isEmpty(componentInstancesInterfaces)) {
369 return Either.right(componentsUtils.getResponseFormat(ActionStatus
370 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
373 List<InterfaceDefinition> interfaces = new ArrayList<>();
374 for(ComponentInstanceInterface componentInstanceInterface :
375 componentInstancesInterfaces.get(serviceInstanceId)) {
376 interfaces.add(componentInstanceInterface);
379 ComponentInstance serviceInstance = serviceInstanceCandidate.get();
380 Optional<InterfaceDefinition> interfaceCandidate = InterfaceOperationUtils
381 .getInterfaceDefinitionFromOperationId(interfaces, operationId);
383 if(!interfaceCandidate.isPresent()) {
384 return Either.right(componentsUtils.getResponseFormat(ActionStatus
385 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
388 InterfaceDefinition interfaceDefinition = interfaceCandidate.get();
389 Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
390 if(MapUtils.isEmpty(operations)) {
391 return Either.right(componentsUtils.getResponseFormat(ActionStatus
392 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
395 Operation operation = operations.get(operationId);
396 Either<Operation, ResponseFormat> operationEither = Either.left(operation);
398 ListDataDefinition<OperationInputDefinition> inputs = operation.getInputs();
399 Optional<OperationInputDefinition> inputCandidate =
400 getOperationInputByInputId(serviceConsumptionData, inputs);
402 if(!inputCandidate.isPresent()) {
403 return Either.right(new ResponseFormat(HttpStatus.NOT_FOUND.value()));
406 OperationInputDefinition operationInputDefinition = inputCandidate.get();
407 // add data to operation
409 if(Objects.nonNull(serviceConsumptionData.getValue())) {
411 handleConsumptionValue(parentService, serviceInstanceId, serviceConsumptionData, operation,
412 operationInputDefinition);
415 if(operationEither.isRight()) {
416 return Either.right(operationEither.right().value());
419 Operation updatedOperation = operationEither.left().value();
420 operations.remove(operationId);
421 operations.put(operationId, updatedOperation);
422 interfaceDefinition.setOperationsMap(operations);
424 parentService.getComponentInstances().remove(serviceInstance);
425 if(CollectionUtils.isEmpty(parentService.getComponentInstances())) {
426 parentService.setComponentInstances(new ArrayList<>());
429 Map<String, Object> instanceInterfaces =
430 MapUtils.isEmpty(serviceInstance.getInterfaces())? new HashMap<>() : serviceInstance.getInterfaces();
431 instanceInterfaces.remove(interfaceDefinition.getUniqueId());
432 instanceInterfaces.put(interfaceDefinition.getUniqueId(), interfaceDefinition);
433 serviceInstance.setInterfaces(instanceInterfaces);
435 removeComponentInstanceInterfaceByInterfaceId(interfaceDefinition.getUniqueId(), componentInstancesInterfaces.get(serviceInstanceId));
436 componentInstancesInterfaces.get(serviceInstanceId).add(new ComponentInstanceInterface(interfaceDefinition.getUniqueId(), interfaceDefinition));
438 parentService.getComponentInstances().add(serviceInstance);
440 StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(parentService, serviceInstanceId);
442 if(status != StorageOperationStatus.OK) {
443 return Either.right(componentsUtils.getResponseFormat(ActionStatus
444 .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
447 return Either.left(operation);
450 private void removeComponentInstanceInterfaceByInterfaceId(String interfaceIdToRemove,
451 List<ComponentInstanceInterface> instanceInterfaces) {
452 if(CollectionUtils.isEmpty(instanceInterfaces)) {
456 Optional<ComponentInstanceInterface> interfaceToRemove =
457 instanceInterfaces.stream().filter(instInterface -> instInterface.getUniqueId().equals
458 (interfaceIdToRemove)).findAny();
460 if(interfaceToRemove.isPresent()) {
461 instanceInterfaces.remove(interfaceToRemove.get());
466 private Either<Operation, ResponseFormat> handleConsumptionValue(Service containerService,
467 String serviceInstanceId,
468 ServiceConsumptionData serviceConsumptionData,
470 OperationInputDefinition
471 operationInputDefinition) {
472 String source = serviceConsumptionData.getSource();
473 String consumptionValue = serviceConsumptionData.getValue();
474 String type = serviceConsumptionData.getType();
475 String operationIdentifier = consumptionValue.contains(".")
476 ? consumptionValue.substring(0, consumptionValue.lastIndexOf('.'))
479 ServiceConsumptionSource sourceValue = ServiceConsumptionSource.getSourceValue(source);
481 if(STATIC.equals(sourceValue)) {
482 // Validate constraint on input value
483 Either<Boolean, ResponseFormat> constraintValidationResult =
484 validateOperationInputConstraint(operationInputDefinition, consumptionValue, type);
486 if (constraintValidationResult.isRight()) {
487 return Either.right(constraintValidationResult.right().value());
489 return handleConsumptionStaticValue(consumptionValue, type, operation,
490 operationInputDefinition);
493 if (Objects.isNull(sourceValue)) {
494 List<PropertyDefinition> propertyDefinitions;
495 Map<String, List<CapabilityDefinition>> capabilities = null;
496 String componentName;
497 List<OperationOutputDefinition> outputs = null;
498 if (source.equals(containerService.getUniqueId())) {
499 Either<Service, StorageOperationStatus> serviceToTakePropEither =
500 toscaOperationFacade.getToscaElement(source);
501 if (serviceToTakePropEither.isRight()) {
502 return Either.right(componentsUtils.getResponseFormat(serviceToTakePropEither.right().value()));
504 Service service = serviceToTakePropEither.left().value();
505 operationInputDefinition.setSource(service.getUniqueId());
506 sourceValue = SERVICE_INPUT;
507 propertyDefinitions = service.getProperties();
508 componentName = service.getName();
509 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier,
510 service.getInterfaces()).getListToscaDataDefinition();
512 Optional<ComponentInstance> getComponentInstance = containerService.getComponentInstanceById(source);
513 if(!getComponentInstance.isPresent()){
514 return Either.right(componentsUtils.getResponseFormat(
515 ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, source));
517 ComponentInstance componentInstance = getComponentInstance.get();
518 operationInputDefinition.setSource(componentInstance.getUniqueId());
519 propertyDefinitions = componentInstance.getProperties();
520 capabilities = componentInstance.getCapabilities();
521 componentName = source.equals(serviceInstanceId) ? SELF : componentInstance.getName();
522 if (MapUtils.isNotEmpty(componentInstance.getInterfaces())) {
523 Map<String, InterfaceDataDefinition> componentInstanceInterfaces =
524 componentInstance.getInterfaces().entrySet().stream()
525 .collect(Collectors.toMap((Map.Entry::getKey),
526 (interfaceEntry -> (InterfaceDataDefinition) interfaceEntry.getValue())));
527 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier,
528 componentInstanceInterfaces).getListToscaDataDefinition();
532 if(sourceValue == ServiceConsumptionSource.SERVICE_INPUT) {
533 //The operation input in service consumption has been mapped to an input in the parent service
534 return handleConsumptionInputValue(consumptionValue, containerService, operation,
535 operationInputDefinition);
537 return handleConsumptionPropertyValue(operation, operationInputDefinition,
538 serviceConsumptionData, propertyDefinitions, capabilities, outputs, componentName);
541 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.SOURCE, source);
542 operationInputDefinition.setSource(source);
544 return Either.left(operation);
547 private Optional<OperationInputDefinition> getOperationInputByInputId(ServiceConsumptionData serviceConsumptionData,
548 ListDataDefinition<OperationInputDefinition> inputs) {
550 if(CollectionUtils.isEmpty(inputs.getListToscaDataDefinition())) {
551 return Optional.empty();
554 return inputs.getListToscaDataDefinition().stream().filter(operationInput -> operationInput.getInputId().equals
555 (serviceConsumptionData.getInputId()))
559 private Either<Operation, ResponseFormat> handleConsumptionPropertyValue(
560 Operation operation, OperationInputDefinition operationInputDefinition,
561 ServiceConsumptionData serviceConsumptionData, List<PropertyDefinition> properties,Map<String,
562 List<CapabilityDefinition>> capabilities,
563 List<OperationOutputDefinition> outputs, String componentName) {
565 if (CollectionUtils.isEmpty(properties) && CollectionUtils.isEmpty(outputs)) {
566 return Either.left(operation);
568 String consumptionValue = serviceConsumptionData.getValue();
570 if (CollectionUtils.isNotEmpty(outputs)
571 && isOperationInputMappedToOtherOperationOutput(getOperationOutputName(consumptionValue), outputs)) {
572 return handleConsumptionInputMappedToOperationOutput(operation, operationInputDefinition, outputs,
573 consumptionValue, componentName);
576 if (CollectionUtils.isNotEmpty(properties) && PropertiesUtils.isNodeProperty(consumptionValue, properties)) {
577 return handleConsumptionInputMappedToProperty(operation, operationInputDefinition, serviceConsumptionData,
578 properties, componentName);
581 if (MapUtils.isNotEmpty(capabilities)) {
582 return handleConsumptionInputMappedToCapabilityProperty(operation, operationInputDefinition,
583 serviceConsumptionData, capabilities, componentName);
586 return Either.left(operation);
589 private Either<Operation, ResponseFormat> handleConsumptionInputMappedToProperty(Operation operation,
590 OperationInputDefinition operationInputDefinition, ServiceConsumptionData serviceConsumptionData,
591 List<PropertyDefinition> properties, String componentName) {
592 Optional<PropertyDefinition> servicePropertyCandidate =
593 properties.stream().filter(property -> property.getName()
594 .equals(serviceConsumptionData.getValue())).findAny();
596 if (servicePropertyCandidate.isPresent()) {
597 boolean isInputTypeSimilarToOperation =
598 isAssignedValueFromValidType(operationInputDefinition.getType(),
599 servicePropertyCandidate.get());
601 if (!isInputTypeSimilarToOperation) {
602 return Either.right(componentsUtils.getResponseFormat(
603 ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
606 addPropertyToInputValue(componentName, operation, operationInputDefinition,
607 servicePropertyCandidate.get());
609 return Either.left(operation);
612 private Either<Operation, ResponseFormat> handleConsumptionInputMappedToOperationOutput(Operation operation,
613 OperationInputDefinition operationInputDefinition, List<OperationOutputDefinition> outputs,
614 String consumptionValue, String componentName) {
615 String outputName = getOperationOutputName(consumptionValue);
616 Optional<OperationOutputDefinition> servicePropertyOutputCandidate = outputs.stream()
617 .filter(output -> output.getName().equals(outputName)).findAny();
618 if (servicePropertyOutputCandidate.isPresent()) {
619 boolean isInputTypeSimilarToOperation =
620 isAssignedValueFromValidType(operationInputDefinition.getType(),
621 servicePropertyOutputCandidate.get());
622 if (!isInputTypeSimilarToOperation) {
623 return Either.right(componentsUtils.getResponseFormat(
624 ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
626 addOutputToInputValue(componentName, consumptionValue, operation, operationInputDefinition);
628 return Either.left(operation);
631 private void addPropertyToInputValue(String componentName, Operation operation,
632 OperationInputDefinition operationInputDefinition,
633 PropertyDefinition serviceProperty) {
634 Map<String, List<String>> getProperty = new HashMap<>();
635 List<String> getPropertyValues = new ArrayList<>();
636 getPropertyValues.add(componentName);
637 getPropertyValues.add(serviceProperty.getName());
638 getProperty.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), getPropertyValues);
640 operationInputDefinition.setSourceProperty(serviceProperty.getUniqueId());
641 operation.getInputs().delete(operationInputDefinition);
642 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_PROPERTY,
644 operationInputDefinition.setValue((new Gson()).toJson(getProperty));
645 operation.getInputs().add(operationInputDefinition);
648 private void addOutputToInputValue(String componentName, String consumptionValue,
649 Operation operation, OperationInputDefinition operationInputDefinition) {
650 Map<String, List<String>> getOperationOutput =
651 InterfaceOperationUtils.createMappedOutputDefaultValue(componentName, consumptionValue);
652 operation.getInputs().delete(operationInputDefinition);
653 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_OPERATION_OUTPUT,
655 operationInputDefinition.setValue((new Gson()).toJson(getOperationOutput));
656 operation.getInputs().add(operationInputDefinition);
659 public Either<Operation, ResponseFormat> handleConsumptionStaticValue(String value, String type,
661 OperationInputDefinition
662 operationInputDefinition) {
663 boolean isInputTypeSimilarToOperation =
664 isAssignedValueFromValidType(type, value);
666 if(!isInputTypeSimilarToOperation) {
667 return Either.right(componentsUtils.getResponseFormat(
668 ActionStatus.INVALID_CONSUMPTION_TYPE, type));
671 //Validate Constraint and Value
672 Either<Boolean, ResponseFormat> constraintValidationResponse =
673 validateOperationInputConstraint(operationInputDefinition, value, type);
674 if(constraintValidationResponse.isRight()) {
675 return Either.right(constraintValidationResponse.right().value());
678 addStaticValueToInputOperation(value, operation, operationInputDefinition);
680 return Either.left(operation);
683 private Either<Boolean, ResponseFormat> validateOperationInputConstraint(
684 OperationInputDefinition operationInputDefinition, String value, String type) {
686 if (Objects.nonNull(operationInputDefinition.getParentPropertyType())
687 && !operationInputDefinition.getParentPropertyType().equals(operationInputDefinition.getType())) {
688 InputDefinition inputDefinition = new InputDefinition();
689 inputDefinition.setDefaultValue(value);
690 inputDefinition.setInputPath(operationInputDefinition.getSubPropertyInputPath());
691 inputDefinition.setName(operationInputDefinition.getName());
692 inputDefinition.setType(type);
694 ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
695 propertyDefinition.setType(operationInputDefinition.getParentPropertyType());
696 if (operationInputDefinition.getParentPropertyType() != null) {
697 inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
700 return PropertyValueConstraintValidationUtil.getInstance()
701 .validatePropertyConstraints(Collections.singletonList(inputDefinition), applicationDataTypeCache);
703 PropertyDefinition propertyDefinition = new PropertyDefinition();
704 propertyDefinition.setType(operationInputDefinition.getType());
705 propertyDefinition.setSchema(operationInputDefinition.getSchema());
706 propertyDefinition.setValue(value);
707 propertyDefinition.setName(operationInputDefinition.getName());
709 return PropertyValueConstraintValidationUtil.getInstance()
710 .validatePropertyConstraints(Collections.singletonList(propertyDefinition), applicationDataTypeCache);
714 private void addStaticValueToInputOperation(String value, Operation operation,
715 OperationInputDefinition operationInputDefinition) {
716 operation.getInputs().delete(operationInputDefinition);
717 operationInputDefinition.setSource(STATIC.getSource());
718 operationInputDefinition.setSourceProperty(null);
719 operationInputDefinition.setValue(value);
720 operation.getInputs().add(operationInputDefinition);
723 private Either<Operation, ResponseFormat> handleConsumptionInputValue(String inputId,
726 OperationInputDefinition
727 operationInputDefinition) {
728 List<InputDefinition> serviceInputs = service.getInputs();
729 Optional<InputDefinition> inputForValue =
730 serviceInputs.stream().filter(input -> input.getUniqueId().contains(inputId)).findAny();
732 if(inputForValue.isPresent()) {
733 boolean isInputTypeSimilarToOperation =
734 isAssignedValueFromValidType(operationInputDefinition.getType(), inputForValue.get());
736 if(!isInputTypeSimilarToOperation) {
737 return Either.right(componentsUtils.getResponseFormat(
738 ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
740 addGetInputValueToOperationInput(operation, operationInputDefinition, inputForValue.get());
743 return Either.left(operation);
746 private void addGetInputValueToOperationInput(Operation operation,
747 OperationInputDefinition operationInputDefinition,
748 InputDefinition inputForValue) {
749 operation.getInputs().delete(operationInputDefinition);
750 Map<String, String> getInputMap = new HashMap<>();
751 getInputMap.put(ToscaFunctions.GET_INPUT.getFunctionName(), inputForValue.getName());
752 operationInputDefinition.setSourceProperty(inputForValue.getUniqueId());
753 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_INPUT, getInputMap);
754 operationInputDefinition.setValue(new Gson().toJson(getInputMap));
755 operation.getInputs().add(operationInputDefinition);
758 private Either<List<Map<String, Object>>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) {
760 Either<List<ResourceAdminEvent>, ActionStatus> eitherprevVerAudit = auditCassandraDao.getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion);
762 if (eitherprevVerAudit.isRight()) {
763 return Either.right(eitherprevVerAudit.right().value());
767 Either<List<ResourceAdminEvent>, ActionStatus> eitherCurrVerAudit = auditCassandraDao.getAuditByServiceIdAndCurrVersion(componentUUID, componentVersion);
768 if (eitherCurrVerAudit.isRight()) {
769 return Either.right(eitherCurrVerAudit.right().value());
773 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveRestoreList = getArchiveRestoreEventList(componentUUID);
774 if (eitherArchiveRestoreList.isRight()) {
775 return Either.right(eitherArchiveRestoreList.right().value());
778 List<Map<String, Object>> prevVerAuditList = getAuditingFieldsList(eitherprevVerAudit.left().value());
779 List<Map<String, Object>> currVerAuditList = getAuditingFieldsList(eitherCurrVerAudit.left().value());
781 List<Map<String, Object>> duplicateElements = new ArrayList<>();
782 duplicateElements.addAll(prevVerAuditList);
783 duplicateElements.retainAll(currVerAuditList);
785 List<Map<String, Object>> joinedNonDuplicatedList = new ArrayList<>();
786 joinedNonDuplicatedList.addAll(prevVerAuditList);
787 joinedNonDuplicatedList.removeAll(duplicateElements);
788 joinedNonDuplicatedList.addAll(currVerAuditList);
789 joinedNonDuplicatedList.addAll(getAuditingFieldsList(eitherArchiveRestoreList.left().value()));
792 return Either.left(joinedNonDuplicatedList);
795 private Either<List<ResourceAdminEvent>, ActionStatus> getArchiveRestoreEventList(String componentUUID) {
797 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveAudit = auditCassandraDao.getArchiveAuditByServiceInstanceId(componentUUID);
798 if (eitherArchiveAudit.isRight()) {
799 return Either.right(eitherArchiveAudit.right().value());
803 Either<List<ResourceAdminEvent>, ActionStatus> eitherRestoreAudit = auditCassandraDao.getRestoreAuditByServiceInstanceId(componentUUID);
804 if (eitherRestoreAudit.isRight()) {
805 return Either.right(eitherRestoreAudit.right().value());
808 List<ResourceAdminEvent> archiveAudit = new ArrayList<>();
809 archiveAudit.addAll(eitherArchiveAudit.left().value());
810 archiveAudit.addAll(eitherRestoreAudit.left().value());
812 return Either.left(archiveAudit);
815 private List<Map<String, Object>> getAuditingFieldsList(List<? extends AuditingGenericEvent> prevVerAuditList) {
817 List<Map<String, Object>> prevVerAudit = new ArrayList<>();
818 for (AuditingGenericEvent auditEvent : prevVerAuditList) {
819 auditEvent.fillFields();
820 prevVerAudit.add(auditEvent.getFields());
831 * - modifier data (userId)
832 * @return Either<Service, responseFormat>
834 public Either<Service, ResponseFormat> createService(Service service, User user) {
837 user = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false);
838 // validate user role
839 validateUserRole(user, service, new ArrayList<>(), AuditingActionEnum.CREATE_RESOURCE, null);
840 service.setCreatorUserId(user.getUserId());
841 // warn on overridden fields
842 checkFieldsForOverideAttampt(service);
844 log.debug("enrich service with version and state");
845 service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
846 service.setVersion(INITIAL_VERSION);
847 service.setConformanceLevel(ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
848 service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED);
850 Either<Service, ResponseFormat> createServiceResponse = validateServiceBeforeCreate(service, user, AuditingActionEnum.CREATE_RESOURCE);
851 if (createServiceResponse.isRight()) {
852 return createServiceResponse;
854 return createServiceByDao(service, AuditingActionEnum.CREATE_RESOURCE, user);
857 private void checkFieldsForOverideAttampt(Service service) {
858 checkComponentFieldsForOverrideAttempt(service);
859 if (service.getDistributionStatus() != null) {
860 log.info("Distribution Status cannot be defined by user. This field will be overridden by the application");
864 private Either<Service, ResponseFormat> createServiceByDao(Service service, AuditingActionEnum actionEnum, User user) {
865 log.debug("send service {} to dao for create", service.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
867 Either<Boolean, ResponseFormat> lockResult = lockComponentByName(service.getSystemName(), service, "Create Service");
868 if (lockResult.isRight()) {
869 ResponseFormat responseFormat = lockResult.right().value();
870 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
871 return Either.right(responseFormat);
874 log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult);
878 createMandatoryArtifactsData(service, user);
879 createServiceApiArtifactsData(service, user);
880 setToscaArtifactsPlaceHolders(service, user);
881 generateAndAddInputsFromGenericTypeProperties(service, fetchAndSetDerivedFromGenericType(service));
883 Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
885 // service created successfully!!!
886 if (dataModelResponse.isLeft()) {
887 log.debug("Service created successfully!!!");
888 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
889 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
890 ASDCKpiApi.countCreatedServicesKPI();
891 return Either.left(dataModelResponse.left().value());
894 ResponseFormat responseFormat = componentsUtils.getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service, ComponentTypeEnum.SERVICE);
895 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
896 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
897 return Either.right(responseFormat);
900 graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service);
904 @SuppressWarnings("unchecked")
905 private void createServiceApiArtifactsData(Service service, User user) {
906 // create mandatory artifacts
908 // TODO it must be removed after that artifact uniqueId creation will be
909 // moved to ArtifactOperation
910 String serviceUniqueId = service.getUniqueId();
911 Map<String, ArtifactDefinition> artifactMap = service.getServiceApiArtifacts();
912 if (artifactMap == null)
913 artifactMap = new HashMap<>();
915 Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts();
916 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
918 List<CategoryDefinition> categories = service.getCategories();
919 boolean isCreateArtifact = true;
920 if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
921 for (String exlude : exludeServiceCategory) {
922 if (exlude.equalsIgnoreCase(categories.get(0).getName())) {
923 isCreateArtifact = false;
930 if (serviceApiArtifacts != null && isCreateArtifact) {
931 Set<String> keys = serviceApiArtifacts.keySet();
932 for (String serviceApiArtifactName : keys) {
933 Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName);
934 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user, true);
935 artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API);
936 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
939 service.setServiceApiArtifacts(artifactMap);
943 private Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) {
945 Either<Boolean, ResponseFormat> validationResponse = validateServiceFieldsBeforeCreate(user, service, actionEnum);
946 if (validationResponse.isRight()) {
947 return Either.right(validationResponse.right().value());
949 service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
950 service.setContactId(service.getContactId().toLowerCase());
952 // Generate invariant UUID - must be here and not in operation since it
953 // should stay constant during clone
954 String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
955 service.setInvariantUUID(invariantUUID);
957 return Either.left(service);
962 private Either<Boolean, ResponseFormat> validateServiceFieldsBeforeCreate(User user, Service service, AuditingActionEnum actionEnum) {
964 validateComponentFieldsBeforeCreate(user, service, actionEnum);
966 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, service, actionEnum);
967 if (serviceNameUniquenessValidation.isRight()) {
968 throw new ByResponseFormatComponentException(serviceNameUniquenessValidation.right().value());
970 Either<Boolean, ResponseFormat> categoryValidation = validateServiceCategory(user, service, actionEnum);
971 if (categoryValidation.isRight()) {
972 return categoryValidation;
974 Either<Boolean, ResponseFormat> projectCodeValidation = validateProjectCode(user, service, actionEnum);
975 if (projectCodeValidation.isRight()) {
976 return projectCodeValidation;
978 validateServiceTypeAndCleanup(service);
980 Either<Boolean, ResponseFormat> serviceRoleValidation = validateServiceRoleAndCleanup(user, service, actionEnum);
981 if (serviceRoleValidation.isRight()) {
982 return serviceRoleValidation;
984 return validateInstantiationTypeValue(user, service, actionEnum);
985 } catch (ComponentException exception) {
986 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
987 componentsUtils.auditComponentAdmin(responseFormat, user, service,
988 AuditingActionEnum.CREATE_SERVICE, ComponentTypeEnum.SERVICE);
989 return Either.right(responseFormat);
993 private Either<Boolean, ResponseFormat> validateServiceCategory(User user, Service service, AuditingActionEnum actionEnum) {
994 log.debug("validate Service category");
995 if (isEmpty(service.getCategories())) {
996 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
997 componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
998 return Either.right(errorResponse);
1000 Either<Boolean, ResponseFormat> validatCategory = validateServiceCategory(service.getCategories());
1001 if (validatCategory.isRight()) {
1002 ResponseFormat responseFormat = validatCategory.right().value();
1003 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
1004 return Either.right(responseFormat);
1006 return Either.left(true);
1009 public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) {
1010 validateUserExists(userId, "validate Service Name Exists", false);
1012 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateComponentNameUniqueness(serviceName, null, ComponentTypeEnum.SERVICE);
1014 janusGraphDao.commit();
1016 if (dataModelResponse.isLeft()) {
1017 Map<String, Boolean> result = new HashMap<>();
1018 result.put("isValid", dataModelResponse.left().value());
1019 log.debug("validation was successfully performed.");
1020 return Either.left(result);
1022 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
1023 return Either.right(responseFormat);
1026 public void setElementDao(IElementOperation elementDao) {
1027 this.elementDao = elementDao;
1030 public void setCassandraAuditingDao(AuditCassandraDao auditingDao) {
1031 this.auditCassandraDao = auditingDao;
1034 public ArtifactsBusinessLogic getArtifactBl() {
1035 return artifactsBusinessLogic;
1038 public void setArtifactBl(ArtifactsBusinessLogic artifactBl) {
1039 this.artifactsBusinessLogic = artifactBl;
1042 public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) {
1043 user = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false);
1044 // validate user role
1045 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1047 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1048 if (storageStatus.isRight()) {
1049 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1052 Service currentService = storageStatus.left().value();
1054 if (!ComponentValidationUtils.canWorkOnComponent(currentService, user.getUserId())) {
1055 log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
1056 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
1059 Either<Service, ResponseFormat> validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate);
1060 if (validationRsponse.isRight()) {
1061 log.info("service update metadata: validations field.");
1062 return validationRsponse;
1064 Service serviceToUpdate = validationRsponse.left().value();
1067 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, currentService, "Update Service Metadata");
1068 if (lockResult.isRight()) {
1069 return Either.right(lockResult.right().value());
1072 Either<Service, StorageOperationStatus> updateResponse = toscaOperationFacade.updateToscaElement(serviceToUpdate);
1073 if (updateResponse.isRight()) {
1074 janusGraphDao.rollback();
1075 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
1076 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
1077 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1079 janusGraphDao.commit();
1080 return Either.left(updateResponse.left().value());
1082 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1086 public Either<Set<String>, ResponseFormat> deleteForwardingPaths(String serviceId, Set<String> pathIdsToDelete, User user, boolean lock) {
1087 Service serviceToDelete = initServiceToDeletePaths(serviceId, pathIdsToDelete);
1088 user = validateUser(user, "deleteForwardingPaths", serviceToDelete, null, false);
1089 // validate user role
1090 validateUserRole(user, serviceToDelete, new ArrayList<>(), null, null);
1091 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1092 if (storageStatus.isRight()) {
1093 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1095 Service service = storageStatus.left().value();
1096 Either<Set<String>, StorageOperationStatus> result = null;
1098 Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Forwarding Path on Service");
1099 if (lockResult.isRight()) {
1100 janusGraphDao.rollback();
1101 return Either.right(componentsUtils.getResponseFormat(componentsUtils
1102 .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1106 result = forwardingPathOperation.deleteForwardingPath(service ,pathIdsToDelete);
1107 if (result.isRight()) {
1108 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, service.getName(), result.right().value());
1109 janusGraphDao.rollback();
1110 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
1112 janusGraphDao.commit();
1113 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, service.getSystemName());
1115 } catch (Exception e){
1116 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
1117 janusGraphDao.rollback();
1118 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1120 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1122 return Either.left(result.left().value());
1125 private Service initServiceToDeletePaths(String serviceId, Collection<String> pathIdsToDelete) {
1126 Service serviceToDelete = new Service();
1127 serviceToDelete.setUniqueId(serviceId);
1128 serviceToDelete.setForwardingPaths(new HashMap<>());
1129 pathIdsToDelete.forEach(pathIdToDelete -> serviceToDelete.getForwardingPaths().put(pathIdToDelete, new ForwardingPathDataDefinition()));
1130 return serviceToDelete;
1133 public Either<Service, ResponseFormat> updateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
1134 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, true,"updateForwardingPath", lock);
1137 public Either<Service, ResponseFormat> createForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
1138 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, false, "createForwardingPath", lock);
1141 private ForwardingPathDataDefinition getTrimmedValues(ForwardingPathDataDefinition path){
1142 ForwardingPathDataDefinition dataDefinition = new ForwardingPathDataDefinition(path.getName());
1143 dataDefinition.setName(Strings.nullToEmpty(path.getName()).trim());
1144 dataDefinition.setProtocol(Strings.nullToEmpty(path.getProtocol()).trim());
1145 dataDefinition.setDestinationPortNumber(Strings.nullToEmpty(path.getDestinationPortNumber()).trim());
1146 dataDefinition.setUniqueId(path.getUniqueId());
1147 dataDefinition.setPathElements(path.getPathElements());
1148 dataDefinition.setDescription(path.getDescription());
1149 dataDefinition.setToscaResourceName(path.getToscaResourceName());
1150 return dataDefinition;
1153 private Either<Service, ResponseFormat> createOrUpdateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean isUpdate, String errorContext, boolean lock) {
1154 validateUserAndRole(serviceUpdate, user, errorContext);
1156 Map<String, ForwardingPathDataDefinition> forwardingPaths = serviceUpdate.getForwardingPaths();
1158 Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths =
1159 forwardingPaths.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
1160 entry -> new ForwardingPathDataDefinition(getTrimmedValues(entry.getValue()))));
1162 Either<Boolean, ResponseFormat> booleanResponseFormatEither = forwardingPathValidator.validateForwardingPaths(trimmedForwardingPaths.values(),
1163 serviceId, isUpdate);
1164 if(booleanResponseFormatEither.isRight()){
1165 return Either.right(booleanResponseFormatEither.right().value());
1168 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
1170 if(serviceStorageOperationStatusEither.isRight()){
1171 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
1172 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
1173 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
1175 Service storedService = serviceStorageOperationStatusEither.left().value();
1177 Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
1178 Either<Component, StorageOperationStatus> forwardingPathOrigin = toscaOperationFacade.getLatestByName(ForwardingPathUtils.FORWARDING_PATH_NODE_NAME);
1179 if (forwardingPathOrigin.isRight()) {
1180 StorageOperationStatus errorStatus = forwardingPathOrigin.right().value();
1181 log.debug("Failed to fetch normative forwarding path resource by tosca name, error {}", errorStatus);
1182 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
1184 Component component = forwardingPathOrigin.left().value();
1185 final String toscaResourceName;
1186 if ( component.getComponentType() == ComponentTypeEnum.RESOURCE) {
1187 toscaResourceName = ((Resource) component).getToscaResourceName();
1189 toscaResourceName = "";
1191 Either<Boolean, ResponseFormat> lockResult = null;
1194 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Forwarding Path on Service");
1195 if (lockResult.isRight()) {
1196 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, storedService.getName(),
1197 lockResult.right().value().getFormattedMessage());
1198 return Either.right(lockResult.right().value());
1200 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, storedService.getSystemName());
1203 Map<String, ForwardingPathDataDefinition> resultMap = new HashMap<>();
1205 trimmedForwardingPaths.values().forEach(fp -> fp.setToscaResourceName(toscaResourceName));
1208 for (ForwardingPathDataDefinition forwardingPathDataDefinition : trimmedForwardingPaths.values()) {
1210 result = forwardingPathOperation.updateForwardingPath(serviceId, forwardingPathDataDefinition);
1212 result = forwardingPathOperation.addForwardingPath(serviceId, forwardingPathDataDefinition);
1214 if (result.isRight()) {
1215 janusGraphDao.rollback();
1216 return Either.right(componentsUtils.getResponseFormat(
1217 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
1220 ForwardingPathDataDefinition fpDataDefinition = result.left().value();
1221 resultMap.put(fpDataDefinition.getUniqueId(), forwardingPathDataDefinition);
1225 } catch (Exception e) {
1226 janusGraphDao.rollback();
1227 log.error("Exception occurred during add or update forwarding path property values: {}", e.getMessage(),
1229 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1231 janusGraphDao.commit();
1233 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
1234 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
1237 Service service = createServiceWithForwardingPathForResponse(serviceId, resultMap);
1238 return Either.left(service);
1241 private Service createServiceWithForwardingPathForResponse(String serviceId, Map<String,ForwardingPathDataDefinition> forwardingPathDataDefinitionMap) {
1242 Service service = new Service();
1243 service.setUniqueId(serviceId);
1244 service.setForwardingPaths(forwardingPathDataDefinitionMap);
1248 private void validateUserAndRole(Service serviceUpdate, User user, String errorContext) {
1249 user = validateUser(user, errorContext, serviceUpdate, null, false);
1250 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1255 Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) {
1258 boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
1259 Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1260 if (response.isRight()) {
1261 ResponseFormat errorResponse = response.right().value();
1262 return Either.right(errorResponse);
1265 verifyValuesAreIdentical(serviceUpdate.getCreatorUserId(), currentService.getCreatorUserId(), "creatorUserId");
1266 verifyValuesAreIdentical(serviceUpdate.getCreatorFullName(), currentService.getCreatorFullName(), "creatorFullName");
1267 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterUserId(), currentService.getLastUpdaterUserId(), "lastUpdaterUserId");
1268 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterFullName(), currentService.getLastUpdaterFullName(), "lastUpdaterFullName");
1270 response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null);
1271 if (response.isRight()) {
1272 return Either.right(response.right().value());
1275 verifyValuesAreIdentical(serviceUpdate.getDistributionStatus(), currentService.getDistributionStatus(), "distributionStatus");
1277 if (serviceUpdate.getProjectCode() != null) {
1278 response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1279 if (response.isRight()) {
1280 return Either.right(response.right().value());
1284 response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1285 if (response.isRight()) {
1286 return Either.right(response.right().value());
1289 verifyValuesAreIdentical(serviceUpdate.getCreationDate(), currentService.getCreationDate(), "creationDate");
1290 verifyValuesAreIdentical(serviceUpdate.getVersion(), currentService.getVersion(), "version");
1292 response = validateAndUpdateDescription(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1293 if (response.isRight()) {
1294 return Either.right(response.right().value());
1297 response = validateAndUpdateTags(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1298 if (response.isRight()) {
1299 return Either.right(response.right().value());
1302 response = validateAndUpdateContactId(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1303 if (response.isRight()) {
1304 return Either.right(response.right().value());
1307 verifyValuesAreIdentical(serviceUpdate.getLastUpdateDate(), currentService.getLastUpdateDate(), "lastUpdateDate");
1308 verifyValuesAreIdentical(serviceUpdate.getLifecycleState(), currentService.getLifecycleState(), "lifecycleState");
1309 verifyValuesAreIdentical(serviceUpdate.isHighestVersion(), currentService.isHighestVersion(), "isHighestVersion");
1310 verifyValuesAreIdentical(serviceUpdate.getUUID(), currentService.getUUID(), "uuid");
1312 validateAndUpdateServiceType(currentService, serviceUpdate);
1314 response = validateAndUpdateServiceRole(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1315 if (response.isRight()) {
1316 return Either.right(response.right().value());
1319 response = validateAndUpdateInstantiationTypeValue(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1320 if (response.isRight()) {
1321 return Either.right(response.right().value());
1324 verifyValuesAreIdentical(serviceUpdate.getInvariantUUID(), currentService.getInvariantUUID(), "invariantUUID");
1326 validateAndUpdateEcompNaming(currentService, serviceUpdate);
1328 currentService.setEnvironmentContext(serviceUpdate.getEnvironmentContext());
1329 return Either.left(currentService);
1331 } catch (ComponentException exception) {
1332 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
1333 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate,
1334 AuditingActionEnum.UPDATE_SERVICE_METADATA, ComponentTypeEnum.SERVICE);
1335 return Either.right(responseFormat);
1339 private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
1340 if (updatedValue != null && !updatedValue.equals(originalValue)) {
1341 log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
1345 private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
1346 Boolean isEcompGeneratedCurr = currentService.isEcompGeneratedNaming();
1347 Boolean isEcompGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
1348 if (isEcompGeneratedUpdate != null && !isEcompGeneratedUpdate.equals(isEcompGeneratedCurr)) {
1349 currentService.setEcompGeneratedNaming(isEcompGeneratedUpdate);
1351 String namingPolicyUpdate = serviceUpdate.getNamingPolicy();
1352 if (currentService.isEcompGeneratedNaming()) {
1353 currentService.setNamingPolicy(namingPolicyUpdate);
1355 if (!StringUtils.isEmpty(namingPolicyUpdate)) {
1356 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
1358 currentService.setNamingPolicy("");
1362 private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1363 String contactIdUpdated = serviceUpdate.getContactId();
1364 String contactIdCurrent = currentService.getContactId();
1365 if (!contactIdCurrent.equals(contactIdUpdated)) {
1366 validateContactId(user, serviceUpdate, audatingAction);
1367 currentService.setContactId(contactIdUpdated.toLowerCase());
1369 return Either.left(true);
1372 private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1373 List<String> tagsUpdated = serviceUpdate.getTags();
1374 List<String> tagsCurrent = currentService.getTags();
1375 if (tagsUpdated == null || tagsUpdated.isEmpty()) {
1376 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
1377 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
1378 return Either.right(responseFormat);
1381 if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
1382 validateTagsListAndRemoveDuplicates(user, serviceUpdate, audatingAction);
1383 currentService.setTags(tagsUpdated);
1385 return Either.left(true);
1388 private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1389 String descriptionUpdated = serviceUpdate.getDescription();
1390 String descriptionCurrent = currentService.getDescription();
1391 if (!descriptionCurrent.equals(descriptionUpdated)) {
1392 validateDescriptionAndCleanup(user, serviceUpdate, audatingAction);
1393 currentService.setDescription(serviceUpdate.getDescription());
1395 return Either.left(true);
1398 private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1399 String projectCodeUpdated = serviceUpdate.getProjectCode();
1400 String projectCodeCurrent = currentService.getProjectCode();
1401 if (!projectCodeCurrent.equals(projectCodeUpdated)) {
1403 Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, serviceUpdate, audatingAction);
1404 if (validatProjectCodeResponse.isRight()) {
1405 ResponseFormat errorRespons = validatProjectCodeResponse.right().value();
1406 return Either.right(errorRespons);
1408 currentService.setProjectCode(projectCodeUpdated);
1411 return Either.left(true);
1414 private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1415 String iconUpdated = serviceUpdate.getIcon();
1416 String iconCurrent = currentService.getIcon();
1417 if (!iconCurrent.equals(iconUpdated)) {
1418 if (!hasBeenCertified) {
1419 validateIcon(user, serviceUpdate, audatingAction);
1420 currentService.setIcon(iconUpdated);
1422 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
1423 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
1424 return Either.right(errorResponse);
1427 return Either.left(true);
1430 private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum auditingAction) {
1431 String serviceNameUpdated = serviceUpdate.getName();
1432 String serviceNameCurrent = currentService.getName();
1433 if (!serviceNameCurrent.equals(serviceNameUpdated)) {
1434 if (!hasBeenCertified) {
1435 validateComponentName(user, serviceUpdate, auditingAction);
1436 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, serviceUpdate, auditingAction);
1437 if (serviceNameUniquenessValidation.isRight()) {
1438 return serviceNameUniquenessValidation;
1440 currentService.setName(serviceNameUpdated);
1441 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
1442 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
1445 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
1446 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
1447 return Either.right(errorResponse);
1450 return Either.left(true);
1453 private void validateAndUpdateServiceType(Service currentService, Service updatedService) {
1454 String updatedServiceType = updatedService.getServiceType();
1455 String currentServiceType = currentService.getServiceType();
1456 if (!currentServiceType.equals(updatedServiceType)) {
1457 validateServiceTypeAndCleanup(updatedService);
1458 currentService.setServiceType(updatedServiceType);
1462 private void validateServiceTypeAndCleanup(Component component) {
1463 log.debug("validate service type");
1464 String serviceType = ((Service)component).getServiceType();
1465 if (serviceType == null) {
1466 log.info("service type is not valid.");
1467 throw new ByActionStatusComponentException(ActionStatus.INVALID_SERVICE_TYPE);
1469 serviceType = cleanUpText(serviceType);
1470 validateServiceType(serviceType);
1474 private void validateServiceType(String serviceType) {
1475 if (serviceType.isEmpty()) {
1478 if (!ValidationUtils.validateServiceTypeLength(serviceType)) {
1479 log.info("service type exceeds limit.");
1480 throw new ByActionStatusComponentException(ActionStatus.SERVICE_TYPE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_TYPE_MAX_LENGTH);
1482 if (!ValidationUtils.validateIsEnglish(serviceType)) {
1483 log.info("service type is not valid.");
1484 throw new ByActionStatusComponentException(ActionStatus.INVALID_SERVICE_TYPE);
1488 private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1489 String updatedServiceRole = updatedService.getServiceRole();
1490 String currentServiceRole = currentService.getServiceRole();
1491 if (!currentServiceRole.equals(updatedServiceRole)) {
1492 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRoleAndCleanup(user, updatedService , auditingAction);
1493 if (validateServiceRole.isRight()) {
1494 ResponseFormat errorResponse = validateServiceRole.right().value();
1495 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1496 return Either.right(errorResponse);
1498 currentService.setServiceRole(updatedServiceRole);
1500 return Either.left(true);
1503 protected Either<Boolean, ResponseFormat> validateServiceRoleAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
1504 log.debug("validate service role");
1505 String serviceRole = ((Service)component).getServiceRole();
1506 if (serviceRole != null){
1507 serviceRole = cleanUpText(serviceRole);
1509 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRole(serviceRole);
1510 if (validateServiceRole.isRight()) {
1511 ResponseFormat responseFormat = validateServiceRole.right().value();
1512 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, ComponentTypeEnum.SERVICE);
1513 return Either.right(responseFormat);
1515 return Either.left(true);
1517 return Either.left(false);
1521 private Either<Boolean, ResponseFormat> validateAndUpdateInstantiationTypeValue(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1522 String updatedInstaType= updatedService.getInstantiationType();
1523 String currentInstaType = currentService.getInstantiationType();
1524 if (!currentInstaType.equals(updatedInstaType)) {
1525 Either<Boolean, ResponseFormat> validateInstantiationType = validateInstantiationTypeValue(user, updatedService , auditingAction);
1526 if (validateInstantiationType.isRight()) {
1527 ResponseFormat errorResponse = validateInstantiationType.right().value();
1528 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1529 return Either.right(errorResponse);
1531 currentService.setInstantiationType(updatedInstaType);
1533 return Either.left(true);
1536 private Either<Boolean, ResponseFormat> validateInstantiationTypeValue(User user, Service service, AuditingActionEnum actionEnum) {
1537 log.debug("validate instantiation type");
1538 String instantiationType = service.getInstantiationType();
1539 if (!InstantiationTypes.containsName(instantiationType) || instantiationType == null){
1540 log.error("Recieved Instantiation type {} is not valid.", instantiationType);
1541 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_INSTANTIATION_TYPE);
1542 componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
1543 return Either.right(errorResponse);
1545 return Either.left(true);
1548 private Either<Boolean, ResponseFormat> validateServiceRole(String serviceRole) {
1549 if (serviceRole.equals("")){
1550 return Either.left(true);
1552 if (!ValidationUtils.validateServiceRoleLength(serviceRole)) {
1553 log.info("service role exceeds limit.");
1554 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ROLE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_ROLE_MAX_LENGTH);
1555 return Either.right(errorResponse);
1558 if (!ValidationUtils.validateIsEnglish(serviceRole)) {
1559 log.info("service role is not valid.");
1560 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_ROLE);
1561 return Either.right(errorResponse);
1563 return Either.left(true);
1567 private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1568 List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1569 List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1570 Either<Boolean, ResponseFormat> validateCategoryResponse = validateServiceCategory(user, serviceUpdate, audatingAction);
1571 if (validateCategoryResponse.isRight()) {
1572 return Either.right(validateCategoryResponse.right().value());
1574 if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1575 if (!hasBeenCertified) {
1576 currentService.setCategories(categoryUpdated);
1578 log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1579 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1580 return Either.right(errorResponse);
1583 return Either.left(true);
1587 private Either<Boolean, ResponseFormat> validateServiceCategory(List<CategoryDefinition> list) {
1589 if (list.size() > 1) {
1590 log.debug("Must be only one category for service");
1591 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.SERVICE.getValue());
1592 return Either.right(responseFormat);
1594 CategoryDefinition category = list.get(0);
1595 if (category.getSubcategories() != null) {
1596 log.debug("Subcategories cannot be defined for service");
1597 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CANNOT_CONTAIN_SUBCATEGORY);
1598 return Either.right(responseFormat);
1600 if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
1601 log.debug("Resource category is empty");
1602 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
1603 return Either.right(responseFormat);
1606 log.debug("validating service category {} against valid categories list", list);
1607 Either<List<CategoryDefinition>, ActionStatus> categorys = elementDao.getAllServiceCategories();
1608 if (categorys.isRight()) {
1609 log.debug("failed to retrieve service categories from JanusGraph");
1610 ResponseFormat responseFormat = componentsUtils.getResponseFormat(categorys.right().value());
1611 return Either.right(responseFormat);
1613 List<CategoryDefinition> categoryList = categorys.left().value();
1614 for (CategoryDefinition value : categoryList) {
1615 if (value.getName().equals(category.getName())) {
1616 return Either.left(true);
1619 log.debug("Category {} is not part of service category group. Service category valid values are {}", list, categoryList);
1620 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.SERVICE.getValue()));
1622 return Either.left(false);
1625 public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1626 Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1627 if (serviceResponseFormatEither.isRight()){
1628 return Either.right(serviceResponseFormatEither.right().value());
1630 final ServiceRelations serviceRelations = new ForwardingPathUtils().convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1631 return Either.left(serviceRelations);
1636 public ResponseFormat deleteService(String serviceId, User user) {
1637 ResponseFormat responseFormat;
1638 String ecompErrorContext = "delete service";
1640 validateUserExists(user, ecompErrorContext, false);
1641 Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1642 if (serviceStatus.isRight()) {
1643 log.debug("failed to get service {}", serviceId);
1644 return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1647 Service service = serviceStatus.left().value();
1649 StorageOperationStatus result = StorageOperationStatus.OK;
1650 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1651 if (lockResult.isRight()) {
1652 return lockResult.right().value();
1655 result = markComponentToDelete(service);
1656 if (result.equals(StorageOperationStatus.OK)) {
1657 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1659 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1660 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1662 return responseFormat;
1664 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1665 log.warn("operation failed. do rollback");
1666 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1667 janusGraphDao.rollback();
1669 log.debug("operation success. do commit");
1670 janusGraphDao.commit();
1672 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1676 public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1677 ResponseFormat responseFormat;
1678 String ecompErrorContext = "delete service";
1679 validateUserNotEmpty(user, ecompErrorContext);
1680 user = validateUserExists(user, ecompErrorContext, false);
1682 Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1683 if (getResult.isRight()) {
1684 return getResult.right().value();
1686 Service service = getResult.left().value();
1688 StorageOperationStatus result = StorageOperationStatus.OK;
1689 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1690 if (lockResult.isRight()) {
1691 result = StorageOperationStatus.GENERAL_ERROR;
1692 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1696 result = markComponentToDelete(service);
1697 if (result.equals(StorageOperationStatus.OK)) {
1698 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1700 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1701 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1703 return responseFormat;
1706 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1707 log.warn("operation failed. do rollback");
1708 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1709 janusGraphDao.rollback();
1711 log.debug("operation success. do commit");
1712 janusGraphDao.commit();
1714 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1718 public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1719 String ecompErrorContext = "Get service";
1720 validateUserNotEmpty(user, ecompErrorContext);
1721 validateUserExists(user, ecompErrorContext, false);
1723 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1724 if (storageStatus.isRight()) {
1725 log.debug("failed to get service by id {}", serviceId);
1726 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1729 if(!(storageStatus.left().value() instanceof Service)){
1730 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1732 Service service = storageStatus.left().value();
1733 return Either.left(service);
1740 public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1741 validateUserExists(userId, "get Service By Name And Version", false);
1742 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1743 if (storageStatus.isRight()) {
1744 log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1745 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceName));
1747 Service service = storageStatus.left().value();
1748 return Either.left(service);
1751 @SuppressWarnings("unchecked")
1752 private void createMandatoryArtifactsData(Service service, User user) {
1753 // create mandatory artifacts
1755 // TODO it must be removed after that artifact uniqueId creation will be
1756 // moved to ArtifactOperation
1757 String serviceUniqueId = service.getUniqueId();
1758 Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1759 if (artifactMap == null)
1760 artifactMap = new HashMap<>();
1762 Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalServiceArtifacts();
1763 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1765 String category = service.getCategories().get(0).getName();
1766 boolean isCreateArtifact = true;
1767 if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1768 for (String exlude : exludeServiceCategory) {
1769 if (exlude.equalsIgnoreCase(category)) {
1770 isCreateArtifact = false;
1777 if (informationalServiceArtifacts != null && isCreateArtifact) {
1778 Set<String> keys = informationalServiceArtifacts.keySet();
1779 for (String informationalServiceArtifactName : keys) {
1780 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1781 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap, user, false);
1782 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1786 service.setArtifacts(artifactMap);
1790 private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user, Boolean isServiceApi) {
1792 ArtifactDefinition artifactInfo = artifactsBusinessLogic.createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1795 artifactInfo.setMandatory(false);
1796 artifactInfo.setServiceApi(true);
1798 return artifactInfo;
1801 private Either<DistributionTransitionEnum, ResponseFormat> validateTransitionEnum(String distributionTransition) {
1802 DistributionTransitionEnum transitionEnum = null;
1804 transitionEnum = DistributionTransitionEnum.getFromDisplayName(distributionTransition);
1805 if (transitionEnum == null) {
1806 BeEcompErrorManager.getInstance().logBeSystemError(CHANGE_SERVICE_DISTRIBUTION);
1807 log.info("state operation is not valid. operations allowed are: {}", DistributionTransitionEnum.valuesAsString());
1808 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1809 return Either.right(error);
1812 return Either.left(transitionEnum);
1815 private Either<String, ResponseFormat> validateComment(LifecycleChangeInfoWithAction comment) {
1816 String data = comment.getUserRemarks();
1818 if (data == null || data.trim().isEmpty()) {
1819 BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1820 log.debug("user comment cannot be empty or null.");
1821 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1823 data = ValidationUtils.removeNoneUtf8Chars(data);
1824 data = ValidationUtils.removeHtmlTags(data);
1825 data = ValidationUtils.normaliseWhitespace(data);
1826 data = ValidationUtils.stripOctets(data);
1828 if (!ValidationUtils.validateLength(data, ValidationUtils.COMMENT_MAX_LENGTH)) {
1829 BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1830 log.debug("user comment exceeds limit.");
1831 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, "comment", String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH)));
1833 if (!ValidationUtils.validateIsEnglish(data)) {
1834 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1836 return Either.left(data);
1839 private Either<Service, ResponseFormat> validateServiceDistributionChange(User user, String serviceId, AuditingActionEnum auditAction, String comment) {
1840 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1841 if (storageStatus.isRight()) {
1842 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId);
1843 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1844 componentsUtils.auditComponent(responseFormat, user, auditAction, new ResourceCommonInfo(serviceId, ComponentTypeEnum.SERVICE.getValue()), comment);
1845 return Either.right(responseFormat);
1847 Service service = storageStatus.left().value();
1849 if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1850 log.info("service {} is not available for distribution. Should be in certified state", service.getUniqueId());
1851 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1852 createAudit(user, auditAction, comment, service, responseFormat);
1853 return Either.right(responseFormat);
1855 return Either.left(service);
1858 private Either<User, ResponseFormat> validateUserDistributionChange(User user, Service service, AuditingActionEnum auditAction, String comment) {
1859 log.debug("get user from DB");
1862 user = validateUser(user, "Activate Distribution", service, auditAction, false);
1863 // validate user role
1864 List<Role> roles = new ArrayList<>();
1865 roles.add(Role.ADMIN);
1866 roles.add(Role.GOVERNOR);
1867 roles.add(Role.OPS);
1868 validateUserRole(user, service, roles, auditAction, comment);
1869 return Either.left(user);
1872 private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat) {
1873 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1874 componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1875 ResourceVersionInfo.newBuilder()
1876 .state(component.getLifecycleState().name())
1877 .version(component.getVersion())
1882 private String getEnvNameFromConfiguration() {
1883 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1884 log.trace("Update environment name to be {}", configuredEnvName);
1885 return configuredEnvName;
1888 public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier, ServiceDistributionReqInfo data) {
1890 Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation.validateActivateServiceRequest(serviceId, envId, modifier, data);
1891 if (activationRequestInformationEither.isRight()) {
1892 return Either.right(activationRequestInformationEither.right().value());
1895 ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1897 Either<String, ResponseFormat> result = null;
1898 String did = ThreadLocalsHolder.getUuid();
1899 Service service = activationRequestInformation.getServiceToActivate();
1900 result = buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1904 public Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext, User modifier) {
1905 String envName = getEnvNameFromConfiguration();
1906 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1907 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1908 if (notifyServiceResponse == ActionStatus.OK) {
1909 return Either.left(did);
1911 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1912 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1913 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1914 return Either.right(error);
1918 public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1920 User user = validateUserExists(modifier.getUserId(), "activate Distribution", false);
1921 Either<Service, ResponseFormat> result = null;
1922 ResponseFormat response = null;
1923 Service updatedService = null;
1924 String did = ThreadLocalsHolder.getUuid();
1926 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1927 if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1928 log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1929 envName = configuredEnvName;
1933 ServletContext servletContext = request.getSession().getServletContext();
1934 boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1935 if (!isDistributionEngineUp) {
1936 BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1937 log.debug("Distribution Engine is DOWN");
1938 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1939 return Either.right(response);
1942 Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1943 if (serviceRes.isRight()) {
1944 log.debug("failed retrieving service");
1945 response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1946 componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1947 new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1948 ResourceVersionInfo.newBuilder()
1951 return Either.right(response);
1953 Service service = serviceRes.left().value();
1954 String dcurrStatus = service.getDistributionStatus().name();
1955 String updatedStatus = dcurrStatus;
1956 StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1957 if (readyForDistribution.equals(StorageOperationStatus.OK)) {
1958 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1959 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1960 if (notifyServiceResponse == ActionStatus.OK) {
1961 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED);
1962 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1963 updatedService = updateStateRes.left().value();
1964 updatedStatus = updatedService.getDistributionStatus().name();
1966 // The response is not relevant
1967 updatedService = service;
1969 ASDCKpiApi.countActivatedDistribution();
1970 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1971 result = Either.left(updatedService);
1973 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1974 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1975 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1976 result = Either.right(response);
1979 response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution), envName);
1980 result = Either.right(response);
1982 componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1983 new ResourceCommonInfo(service.getName(),ComponentTypeEnum.SERVICE.getValue()),
1984 ResourceVersionInfo.newBuilder()
1985 .distributionStatus(dcurrStatus)
1987 ResourceVersionInfo.newBuilder()
1988 .distributionStatus(updatedStatus)
1994 // convert to private after deletion of temp url
1995 public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1997 validateUserExists(user.getUserId(), "update Distribution Status For Activation", false);
1999 String serviceId = service.getUniqueId();
2000 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "updateDistributionStatusForActivation");
2001 if (lockResult.isRight()) {
2002 return Either.right(lockResult.right().value());
2005 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
2006 if (result.isRight()) {
2007 janusGraphDao.rollback();
2008 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
2009 log.debug("service {} change distribution status failed", serviceId);
2010 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2012 janusGraphDao.commit();
2013 return Either.left(result.left().value());
2015 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
2019 public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
2021 validateUserExists(user.getUserId(), "mark Distribution As Deployed", false);
2022 log.debug("mark distribution deployed");
2024 AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
2025 Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
2026 if (getServiceResponse.isRight()) {
2027 BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
2028 log.debug("service {} not found", serviceId);
2029 ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
2031 return Either.right(responseFormat);
2034 Service service = getServiceResponse.left().value();
2035 user = validateRoleForDeploy(did, user, auditAction, service);
2036 return checkDistributionAndDeploy(did, user, auditAction, service);
2040 public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2041 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
2042 // Only one VF Module Artifact per instance - add it to a list of one
2043 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
2045 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2049 private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock, boolean inTransaction, ComponentInstance ri) {
2050 List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
2052 if (ri.getOriginType() == OriginTypeEnum.VF) {
2053 asList = Arrays.asList(new VfModuleArtifactGenerator(modifier, ri, service, shouldLock, inTransaction));
2058 private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
2059 Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
2060 if(currVF.getGroupInstances() != null){
2061 currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
2063 return currVF.getGroupInstances();
2066 private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) {
2067 ArtifactDefinition vfModuleAertifact = null;
2068 if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
2069 Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.name())).findAny();
2070 if (optionalVfModuleArtifact.isPresent()) {
2071 vfModuleAertifact = optionalVfModuleArtifact.get();
2074 if (vfModuleAertifact == null) {
2075 Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service, payloadWrapper.getInnerElement());
2076 if (createVfModuleArtifact.isLeft()) {
2077 vfModuleAertifact = createVfModuleArtifact.left().value();
2079 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
2082 return vfModuleAertifact;
2085 private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
2086 List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
2087 if (groupsForCurrVF != null) {
2088 for (GroupInstance groupInstance : groupsForCurrVF) {
2089 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
2090 vfModulePayloads.add(modulePayload);
2092 vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
2094 final Gson gson = new GsonBuilder().setPrettyPrinting().create();
2096 String vfModulePayloadString = gson.toJson(vfModulePayloads);
2097 payloadWrapper.setInnerElement(vfModulePayloadString);
2102 private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock, boolean inTransaction) {
2103 ArtifactDefinition vfModuleArtifact = null;
2104 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
2105 Wrapper<String> payloadWrapper = new Wrapper<>();
2106 List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
2107 if (responseWrapper.isEmpty()) {
2108 fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
2110 if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
2111 vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
2113 if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
2114 vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper, responseWrapper, service);
2117 Either<ArtifactDefinition, ResponseFormat> result;
2118 if (responseWrapper.isEmpty()) {
2119 result = Either.left(vfModuleArtifact);
2121 result = Either.right(responseWrapper.getInnerElement());
2127 private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper, Service service) {
2128 ArtifactDefinition result = null;
2129 Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, inTransaction, System::currentTimeMillis,
2130 () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), currVF.getUniqueId());
2131 if (eitherPayload.isLeft()) {
2132 result = eitherPayload.left().value();
2134 responseWrapper.setInnerElement(eitherPayload.right().value());
2136 if (result == null) {
2137 result = vfModuleArtifact;
2143 private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service, String vfModulePayloadString) {
2145 ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
2146 String newCheckSum = null;
2148 vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
2149 vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
2150 vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
2151 vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
2152 vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
2153 vfModuleArtifactDefinition.setTimeout(0);
2154 vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
2155 vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
2156 if (vfModulePayloadString != null) {
2157 newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
2159 vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
2161 Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent = artifactToscaOperation.addArifactToComponent(vfModuleArtifactDefinition, service.getUniqueId(), NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
2163 Either<ArtifactDefinition, ResponseFormat> result;
2164 if (addArifactToComponent.isLeft()) {
2165 result = Either.left(addArifactToComponent.left().value());
2167 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArifactToComponent.right().value())));
2173 public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2175 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
2176 // Get All Deployment Artifacts
2177 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
2178 // Filter in Only Heat Env
2179 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
2180 // Create ArtifactGenerator from those Artifacts
2181 map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction, resourceInstance.getUniqueId())).collect(Collectors.toList());
2183 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2187 private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
2189 // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
2191 if (service.getComponentInstances() != null) {
2192 List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
2193 if (artifactGenList != null && !artifactGenList.isEmpty()) {
2194 for (ArtifactGenerator<CallVal> entry : artifactGenList) {
2195 Either<CallVal, ResponseFormat> callRes;
2197 callRes = entry.call();
2198 if (callRes.isRight()) {
2199 log.debug("Failed to generate artifact error : {}", callRes.right().value());
2200 return Either.right(callRes.right().value());
2202 } catch (Exception e) {
2203 log.debug("Failed to generate artifact exception : {}", e);
2204 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2209 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
2210 if (storageStatus.isRight()) {
2211 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2214 Service currentService = storageStatus.left().value();
2216 return Either.left(currentService);
2220 abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
2224 class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2225 ArtifactDefinition artifactDefinition;
2227 String resourceInstanceName;
2231 boolean inTransaction;
2233 HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock, boolean inTransaction, String instanceId) {
2234 this.artifactDefinition = artifactDefinition;
2235 this.service = service;
2236 this.resourceInstanceName = resourceInstanceName;
2237 this.modifier = modifier;
2238 this.shouldLock = shouldLock;
2239 this.instanceId = instanceId;
2240 this.inTransaction = inTransaction;
2244 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2245 return artifactsBusinessLogic.forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier, shouldLock, inTransaction, instanceId);
2248 public ArtifactDefinition getArtifactDefinition() {
2249 return artifactDefinition;
2254 class VfModuleArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2256 private ComponentInstance componentInstance;
2257 private Service service;
2259 boolean inTransaction;
2262 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2263 return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
2266 private VfModuleArtifactGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock, boolean inTransaction) {
2269 this.componentInstance = componentInstance;
2270 this.service = service;
2271 this.shouldLock = shouldLock;
2272 this.inTransaction = inTransaction;
2277 private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction, Service service) {
2278 boolean isDeployed = isDistributionDeployed(distributionId);
2280 return Either.left(service);
2282 Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
2283 if (distributionSuccess.isRight()) {
2284 return Either.right(distributionSuccess.right().value());
2287 log.debug("mark distribution {} as deployed - success", distributionId);
2288 componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK", user);
2289 return Either.left(service);
2292 private boolean isDistributionDeployed(String distributionId) {
2293 Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
2295 boolean isDeployed = false;
2296 if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
2298 log.debug("distribution {} is already deployed", distributionId);
2304 protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
2306 log.trace("checkDistributionSuccess");
2307 // get all "DRequest" records for this distribution
2309 Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
2310 if (distRequestsResponse.isRight()) {
2311 ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
2312 return Either.right(error);
2315 List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
2316 if (distributionRequests.isEmpty()) {
2317 BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
2318 log.info("distribution {} is not found", did);
2319 ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
2320 return Either.right(error);
2322 boolean isRequestSucceeded = false;
2323 for (ResourceAdminEvent event : distributionRequests) {
2324 String eventStatus = event.getStatus();
2325 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2326 isRequestSucceeded = true;
2331 // get all "DNotify" records for this distribution
2332 Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
2333 if (distNotificationsResponse.isRight()) {
2334 ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
2335 return Either.right(error);
2338 List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
2339 boolean isNotificationsSucceeded = false;
2340 for (DistributionNotificationEvent event : distributionNotifications) {
2341 String eventStatus = event.getStatus();
2342 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2343 isNotificationsSucceeded = true;
2348 // if request failed OR there are notifications that failed
2349 if (!(isRequestSucceeded && isNotificationsSucceeded)) {
2351 log.info("distribution {} has failed", did);
2352 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2353 auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2354 return Either.right(error);
2356 return Either.left(true);
2359 private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) {
2361 ResponseFormat error = componentsUtils.getResponseFormat(status, params);
2362 String message = "";
2363 if (error.getMessageId() != null) {
2364 message = error.getMessageId() + ": ";
2366 message += error.getFormattedMessage();
2368 if (service != null) {
2369 componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user);
2371 componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
2376 private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
2377 Either<User, ActionStatus> eitherCreator = userAdmin.getUser(user.getUserId(), false);
2378 if (eitherCreator.isRight() || eitherCreator.left().value() == null) {
2379 BeEcompErrorManager.getInstance().logBeUserMissingError("Deploy Service", user.getUserId());
2380 log.debug("validateRoleForDeploy method - user is not listed. userId= {}", user.getUserId());
2381 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, user.getUserId());
2382 auditDeployError(did, user, auditAction, service, ActionStatus.USER_NOT_FOUND);
2383 throw new ByActionStatusComponentException(ActionStatus.USER_NOT_FOUND, user.getUserId());
2385 user = eitherCreator.left().value();
2386 log.debug("validate user role");
2387 List<Role> roles = new ArrayList<>();
2388 roles.add(Role.ADMIN);
2389 roles.add(Role.OPS);
2391 validateUserRole(user, service, roles, auditAction, null);
2392 } catch (ByActionStatusComponentException e){
2393 log.info("role {} is not allowed to perform this action", user.getRole());
2394 auditDeployError(did, user, auditAction, service, e.getActionStatus());
2401 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
2402 Service service = (Service) component;
2403 Map<String, ArtifactDefinition> artifactMap = service.getDeploymentArtifacts();
2404 if (artifactMap == null) {
2405 artifactMap = new HashMap<>();
2407 service.setDeploymentArtifacts(artifactMap);
2411 public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
2412 return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
2415 private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
2416 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
2417 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
2418 return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
2422 public ComponentInstanceBusinessLogic getComponentInstanceBL() {
2423 return componentInstanceBusinessLogic;
2427 public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
2429 validateUserExists(userId, "Get Component Instances", false);
2430 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2431 if (getComponentRes.isRight()) {
2432 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
2433 return Either.right(responseFormat);
2436 List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
2438 return Either.left(componentInstances);
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 paramsToReturn.setIgnoreComponentInstancesProperties(false);
2629 Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2631 if (serviceResultEither.isRight()) {
2632 if(serviceResultEither.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
2633 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2634 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2637 log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2638 return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2641 Service service = serviceResultEither.left().value();
2642 if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
2643 ListUtils.emptyIfNull(service.getInputs())
2644 .forEach(input -> input.setConstraints(setInputConstraint(input)));
2647 UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2648 return Either.left(dataTransfer);
2651 public Either<String, ResponseFormat> deleteIfNotAlreadyDeletedServiceFilter(String serviceId, String resourceId, String userId, boolean lock) {
2652 Service serviceToDelete = initServiceToDeleteServiceFilter(serviceId);
2653 User user = validateUserExists(userId, "Create service Filter", false);
2656 validateUser(user, "deleteIfNotAlreadyDeletedServiceFilter", serviceToDelete, null, false);
2658 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
2659 if (storageStatus.isRight()) {
2660 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2662 Service service = storageStatus.left().value();
2664 Either<Boolean, ResponseFormat> response = serviceFilterValidator.validateComponentInstanceExist(service, resourceId);
2665 if (storageStatus.isRight()) {
2666 return Either.right(response.right().value());
2668 final Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(resourceId);
2669 if (!optionalComponentInstance.isPresent() ){
2670 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2672 CINodeFilterDataDefinition nodeFilter = optionalComponentInstance.get().getNodeFilter();
2673 if (nodeFilter == null){
2674 return Either.left(resourceId);
2677 Either<String, StorageOperationStatus> result;
2679 Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Service Filter from service");
2680 if (lockResult.isRight()) {
2681 janusGraphDao.rollback();
2682 return Either.right(componentsUtils.getResponseFormat(componentsUtils
2683 .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2687 result = serviceFilterOperation.deleteNodeFilter(service , resourceId);
2688 if (result.isRight()) {
2689 log.debug("Failed to delete node filter in service {}. Response is {}. ", service.getName(), result.right().value());
2690 janusGraphDao.rollback();
2691 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
2693 janusGraphDao.commit();
2694 log.debug("Node filter successfully changed in service {} . ", service.getSystemName());
2696 } catch (Exception e){
2697 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
2698 janusGraphDao.rollback();
2699 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2701 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2703 return Either.left(result.left().value());
2707 private Service initServiceToDeleteServiceFilter(String serviceId) {
2708 Service serviceToDelete = new Service();
2709 serviceToDelete.setUniqueId(serviceId);
2710 return serviceToDelete;
2714 public Either<CINodeFilterDataDefinition, ResponseFormat> createIfNotAlreadyExistServiceFilter(String serviceId, String componentInstanceId, String userId, boolean lock) {
2715 String errorContext = "createIfNotAlreadyExistServiceFilter";
2716 User user = validateUserExists(userId, "Create service Filter", false);
2718 Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
2719 if (serviceEither.isRight()) {
2720 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceEither.right().value(), ComponentTypeEnum.SERVICE), ""));
2722 final Service service = serviceEither.left().value();
2723 validateUserAndRole(service, user, errorContext);
2725 Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(componentInstanceId);
2726 if (!optionalComponentInstance.isPresent()){
2727 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2729 ComponentInstance componentInstance = optionalComponentInstance.get();
2730 CINodeFilterDataDefinition serviceFilter = componentInstance.getNodeFilter();
2731 if (serviceFilter != null){
2732 return Either.left(serviceFilter);
2735 Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2737 Either<Boolean, ResponseFormat> lockResult = null;
2740 lockComponent(service.getUniqueId(), service, "Create Service Filter");
2741 if (lockResult.isRight()) {
2742 log.debug("Failed to lock service {}. Response is {}. ", service.getName(),
2743 lockResult.right().value().getFormattedMessage());
2744 return Either.right(lockResult.right().value());
2746 log.debug("The service with system name {} locked. ", service.getSystemName());
2749 CINodeFilterDataDefinition serviceFilterResult;
2751 result = serviceFilterOperation.createNodeFilter(serviceId, componentInstanceId);
2752 if (result.isRight()) {
2753 janusGraphDao.rollback();
2754 return Either.right(componentsUtils.getResponseFormat(
2755 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2758 serviceFilterResult = result.left().value();
2760 janusGraphDao.commit();
2762 } catch (Exception e) {
2763 janusGraphDao.rollback();
2764 log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2766 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2769 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2770 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2773 return Either.left(serviceFilterResult);
2777 public Either<CINodeFilterDataDefinition, ResponseFormat> updateServiceFilter(String serviceId, String componentInstanceId,
2778 List<String> constraints, User inUser, boolean lock) {
2779 String errorContext = "createIfNotAlreadyExistServiceFilter";
2780 User user = validateUserExists(inUser, errorContext, true);
2781 validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2782 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2784 if(serviceStorageOperationStatusEither.isRight()){
2785 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2786 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2787 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2789 Service storedService = serviceStorageOperationStatusEither.left().value();
2791 Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2792 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId, constraints,
2793 NodeFilterConstraintAction.UPDATE);
2794 if(booleanResponseFormatEither.isRight()){
2795 return Either.right(booleanResponseFormatEither.right().value());
2799 Either<Boolean, ResponseFormat> lockResult = null;
2802 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2803 if (lockResult.isRight()) {
2804 log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
2805 lockResult.right().value().getFormattedMessage());
2806 return Either.right(lockResult.right().value());
2808 log.debug("The service with system name {} locked. ", storedService.getSystemName());
2811 Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2812 if (!componentInstanceOptional.isPresent()){
2813 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2815 CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2816 if(serviceFilter == null){
2817 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2819 CINodeFilterDataDefinition serviceFilterResult;
2821 List<RequirementNodeFilterPropertyDataDefinition> properties = constraints.stream().map(this::getRequirementNodeFilterPropertyDataDefinition).collect(Collectors.toList());
2822 Either<CINodeFilterDataDefinition, StorageOperationStatus> result = serviceFilterOperation.updateProperties(serviceId, componentInstanceId, serviceFilter ,properties);
2824 if (result.isRight()) {
2825 janusGraphDao.rollback();
2826 return Either.right(componentsUtils.getResponseFormat(
2827 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2830 serviceFilterResult = result.left().value();
2832 janusGraphDao.commit();
2834 } catch (Exception e) {
2835 janusGraphDao.rollback();
2836 log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2838 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2841 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2842 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2845 return Either.left(serviceFilterResult);
2848 private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition(String constraint){
2849 RequirementNodeFilterPropertyDataDefinition pdd = new RequirementNodeFilterPropertyDataDefinition();
2850 pdd.setConstraints(Arrays.asList(constraint));
2854 public Either<CINodeFilterDataDefinition, ResponseFormat> addOrDeleteServiceFilter(String serviceId, String componentInstanceId,
2855 NodeFilterConstraintAction action, String propertyName, String constraint, int position, User inUser, boolean lock) {
2856 String errorContext = "createIfNotAlreadyExistServiceFilter";
2857 User user = validateUserExists(inUser, errorContext, true);
2858 validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2860 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2862 if(serviceStorageOperationStatusEither.isRight()){
2863 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2864 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2865 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2867 Service storedService = serviceStorageOperationStatusEither.left().value();
2869 Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2870 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId,
2871 Collections.singletonList(constraint), action);
2872 if(booleanResponseFormatEither.isRight()){
2873 return Either.right(booleanResponseFormatEither.right().value());
2876 Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2878 Either<Boolean, ResponseFormat> lockResult = null;
2879 CINodeFilterDataDefinition serviceFilterResult = null;
2883 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2884 if (lockResult.isRight()) {
2885 log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
2886 lockResult.right().value().getFormattedMessage());
2887 return Either.right(lockResult.right().value());
2889 log.debug("The service with system name {} locked. ", storedService.getSystemName());
2893 Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2894 if (!componentInstanceOptional.isPresent()){
2895 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2897 CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2898 if(serviceFilter == null){
2899 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2905 RequirementNodeFilterPropertyDataDefinition newProperty = new RequirementNodeFilterPropertyDataDefinition();
2906 newProperty.setName(propertyName);
2907 newProperty.setConstraints(Collections.singletonList(constraint));
2908 result = serviceFilterOperation.addNewProperty(serviceId, componentInstanceId,serviceFilter,newProperty);
2911 result = serviceFilterOperation.deleteConstraint(serviceId, componentInstanceId, serviceFilter, position);
2914 log.error("Unsupported operation "+action);
2915 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2919 if (result.isRight()) {
2920 janusGraphDao.rollback();
2921 return Either.right(componentsUtils.getResponseFormat(
2922 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2925 serviceFilterResult = result.left().value();
2927 janusGraphDao.commit();
2929 } catch (Exception e) {
2930 janusGraphDao.rollback();
2931 log.error("Exception occurred during add or update node filter property values: {}", e.getMessage(),
2933 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2936 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2937 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2940 return Either.left(serviceFilterResult);