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.isNotEmpty;
26 import static org.openecomp.sdc.be.components.utils.ConsumptionUtils.handleConsumptionInputMappedToCapabilityProperty;
27 import static org.openecomp.sdc.be.components.utils.ConsumptionUtils.isAssignedValueFromValidType;
28 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getOperationOutputName;
29 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToOtherOperationOutput;
30 import static org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum.UPDATE_SERVICE_METADATA;
31 import static org.openecomp.sdc.be.tosca.InterfacesOperationsConverter.SELF;
32 import static org.openecomp.sdc.be.types.ServiceConsumptionSource.SERVICE_INPUT;
33 import static org.openecomp.sdc.be.types.ServiceConsumptionSource.STATIC;
35 import com.google.common.annotations.VisibleForTesting;
36 import com.google.common.base.Strings;
37 import com.google.gson.Gson;
38 import com.google.gson.GsonBuilder;
39 import fj.data.Either;
40 import java.nio.charset.StandardCharsets;
41 import java.util.ArrayList;
42 import java.util.Arrays;
43 import java.util.Collection;
44 import java.util.Collections;
45 import java.util.Comparator;
46 import java.util.HashMap;
47 import java.util.List;
49 import java.util.Map.Entry;
50 import java.util.Objects;
51 import java.util.Optional;
53 import java.util.concurrent.Callable;
54 import java.util.function.Function;
55 import java.util.stream.Collectors;
56 import javax.servlet.ServletContext;
57 import javax.servlet.http.HttpServletRequest;
58 import lombok.AccessLevel;
59 import lombok.AllArgsConstructor;
61 import org.apache.commons.collections.CollectionUtils;
62 import org.apache.commons.collections.MapUtils;
63 import org.apache.commons.collections4.ListUtils;
64 import org.apache.commons.lang3.StringUtils;
65 import org.apache.commons.lang3.tuple.ImmutablePair;
66 import org.openecomp.sdc.be.catalog.enums.ChangeTypeEnum;
67 import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine;
68 import org.openecomp.sdc.be.components.distribution.engine.INotificationData;
69 import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload;
70 import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic;
71 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
72 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
73 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
74 import org.openecomp.sdc.be.components.kafka.KafkaHandler;
75 import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
76 import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
77 import org.openecomp.sdc.be.components.utils.PropertiesUtils;
78 import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
79 import org.openecomp.sdc.be.components.validation.component.ComponentContactIdValidator;
80 import org.openecomp.sdc.be.components.validation.component.ComponentDescriptionValidator;
81 import org.openecomp.sdc.be.components.validation.component.ComponentIconValidator;
82 import org.openecomp.sdc.be.components.validation.component.ComponentNameValidator;
83 import org.openecomp.sdc.be.components.validation.component.ComponentProjectCodeValidator;
84 import org.openecomp.sdc.be.components.validation.component.ComponentTagsValidator;
85 import org.openecomp.sdc.be.components.validation.component.ComponentValidator;
86 import org.openecomp.sdc.be.components.validation.service.ServiceCategoryValidator;
87 import org.openecomp.sdc.be.components.validation.service.ServiceFunctionValidator;
88 import org.openecomp.sdc.be.components.validation.service.ServiceInstantiationTypeValidator;
89 import org.openecomp.sdc.be.components.validation.service.ServiceRoleValidator;
90 import org.openecomp.sdc.be.components.validation.service.ServiceTypeValidator;
91 import org.openecomp.sdc.be.components.validation.service.ServiceValidator;
92 import org.openecomp.sdc.be.config.BeEcompErrorManager;
93 import org.openecomp.sdc.be.config.ConfigurationManager;
94 import org.openecomp.sdc.be.dao.api.ActionStatus;
95 import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
96 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
97 import org.openecomp.sdc.be.datamodel.ServiceRelations;
98 import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil;
99 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
100 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
101 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
102 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
103 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
104 import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition;
105 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
106 import org.openecomp.sdc.be.datatypes.elements.ToscaFunction;
107 import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType;
108 import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
109 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
110 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
111 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
112 import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum;
113 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
114 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
115 import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo;
116 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
117 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
118 import org.openecomp.sdc.be.model.ArtifactDefinition;
119 import org.openecomp.sdc.be.model.CapabilityDefinition;
120 import org.openecomp.sdc.be.model.Component;
121 import org.openecomp.sdc.be.model.ComponentInstance;
122 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
123 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
124 import org.openecomp.sdc.be.model.ComponentParametersView;
125 import org.openecomp.sdc.be.model.DistributionStatusEnum;
126 import org.openecomp.sdc.be.model.GroupInstance;
127 import org.openecomp.sdc.be.model.GroupInstanceProperty;
128 import org.openecomp.sdc.be.model.InputDefinition;
129 import org.openecomp.sdc.be.model.InterfaceDefinition;
130 import org.openecomp.sdc.be.model.LifecycleStateEnum;
131 import org.openecomp.sdc.be.model.Model;
132 import org.openecomp.sdc.be.model.Operation;
133 import org.openecomp.sdc.be.model.PropertyDefinition;
134 import org.openecomp.sdc.be.model.Resource;
135 import org.openecomp.sdc.be.model.Service;
136 import org.openecomp.sdc.be.model.User;
137 import org.openecomp.sdc.be.model.category.CategoryDefinition;
138 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
139 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ForwardingPathOperation;
140 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
141 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
142 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
143 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
144 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
145 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
146 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
147 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
148 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
149 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
150 import org.openecomp.sdc.be.plugins.ServiceCreationPlugin;
151 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
152 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
153 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
154 import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent;
155 import org.openecomp.sdc.be.resources.data.auditing.DistributionDeployEvent;
156 import org.openecomp.sdc.be.resources.data.auditing.DistributionNotificationEvent;
157 import org.openecomp.sdc.be.resources.data.auditing.ResourceAdminEvent;
158 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
159 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
160 import org.openecomp.sdc.be.types.ServiceConsumptionData;
161 import org.openecomp.sdc.be.types.ServiceConsumptionSource;
162 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
163 import org.openecomp.sdc.be.user.Role;
164 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
165 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
166 import org.openecomp.sdc.common.api.Constants;
167 import org.openecomp.sdc.common.datastructure.Wrapper;
168 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
169 import org.openecomp.sdc.common.log.wrappers.Logger;
170 import org.openecomp.sdc.common.util.GeneralUtility;
171 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
172 import org.openecomp.sdc.common.util.ValidationUtils;
173 import org.openecomp.sdc.exception.ResponseFormat;
174 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
175 import org.springframework.beans.factory.annotation.Autowired;
176 import org.springframework.http.HttpStatus;
177 import org.springframework.web.context.WebApplicationContext;
179 @org.springframework.stereotype.Component("serviceBusinessLogic")
180 public class ServiceBusinessLogic extends ComponentBusinessLogic {
182 private static final String IS_VALID = "isValid";
183 private static final String THE_SERVICE_WITH_SYSTEM_NAME_LOCKED = "The service with system name {} locked. ";
184 private static final String FAILED_TO_LOCK_SERVICE_RESPONSE_IS = "Failed to lock service {}. Response is {}. ";
185 private static final String AUDIT_BEFORE_SENDING_RESPONSE = "audit before sending response";
186 private static final Logger log = Logger.getLogger(ServiceBusinessLogic.class);
187 private static final String INITIAL_VERSION = "0.1";
188 private static final String STATUS_SUCCESS_200 = "200";
189 private static final String STATUS_DEPLOYED = "DEPLOYED";
190 private static final String PLACE_HOLDER_RESOURCE_TYPES = "validForResourceTypes";
191 private final IDistributionEngine distributionEngine;
192 private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
193 private final ServiceDistributionValidation serviceDistributionValidation;
194 private final ForwardingPathValidator forwardingPathValidator;
195 private final UiComponentDataConverter uiComponentDataConverter;
196 private final ModelOperation modelOperation;
197 private final ServiceRoleValidator serviceRoleValidator;
198 private final ServiceInstantiationTypeValidator serviceInstantiationTypeValidator;
199 private final ServiceCategoryValidator serviceCategoryValidator;
200 private final ServiceValidator serviceValidator;
201 private final GroupBusinessLogic groupBusinessLogic;
202 private final KafkaHandler kafkaHandler;
203 private ForwardingPathOperation forwardingPathOperation;
204 private AuditCassandraDao auditCassandraDao;
205 private ServiceTypeValidator serviceTypeValidator;
206 private List<ServiceCreationPlugin> serviceCreationPluginList;
207 private ServiceFunctionValidator serviceFunctionValidator;
209 public ServiceBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation,
210 IGroupTypeOperation groupTypeOperation, GroupBusinessLogic groupBusinessLogic, InterfaceOperation interfaceOperation,
211 InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactsBusinessLogic artifactsBusinessLogic,
212 IDistributionEngine distributionEngine, ComponentInstanceBusinessLogic componentInstanceBusinessLogic,
213 ServiceDistributionValidation serviceDistributionValidation, ForwardingPathValidator forwardingPathValidator,
214 UiComponentDataConverter uiComponentDataConverter, ArtifactsOperations artifactToscaOperation,
215 ComponentContactIdValidator componentContactIdValidator, ComponentNameValidator componentNameValidator,
216 ComponentTagsValidator componentTagsValidator, ComponentValidator componentValidator,
217 ComponentIconValidator componentIconValidator, ComponentProjectCodeValidator componentProjectCodeValidator,
218 ComponentDescriptionValidator componentDescriptionValidator, ModelOperation modelOperation,
219 final ServiceRoleValidator serviceRoleValidator,
220 final ServiceInstantiationTypeValidator serviceInstantiationTypeValidator,
221 final ServiceCategoryValidator serviceCategoryValidator, final ServiceValidator serviceValidator,
222 KafkaHandler kafkaHandler) {
223 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation,
224 interfaceLifecycleTypeOperation, artifactsBusinessLogic, artifactToscaOperation, componentContactIdValidator, componentNameValidator,
225 componentTagsValidator, componentValidator, componentIconValidator, componentProjectCodeValidator, componentDescriptionValidator);
226 this.distributionEngine = distributionEngine;
227 this.componentInstanceBusinessLogic = componentInstanceBusinessLogic;
228 this.serviceDistributionValidation = serviceDistributionValidation;
229 this.forwardingPathValidator = forwardingPathValidator;
230 this.uiComponentDataConverter = uiComponentDataConverter;
231 this.modelOperation = modelOperation;
232 this.serviceRoleValidator = serviceRoleValidator;
233 this.serviceInstantiationTypeValidator = serviceInstantiationTypeValidator;
234 this.serviceCategoryValidator = serviceCategoryValidator;
235 this.serviceValidator = serviceValidator;
236 this.groupBusinessLogic = groupBusinessLogic;
237 this.kafkaHandler = kafkaHandler;
241 public void setServiceTypeValidator(ServiceTypeValidator serviceTypeValidator) {
242 this.serviceTypeValidator = serviceTypeValidator;
246 public void setServiceFunctionValidator(ServiceFunctionValidator serviceFunctionValidator) {
247 this.serviceFunctionValidator = serviceFunctionValidator;
250 public Either<List<Map<String, Object>>, ResponseFormat> getComponentAuditRecords(String componentVersion, String componentUUID, String userId) {
251 validateUserExists(userId);
252 Either<List<Map<String, Object>>, ActionStatus> result;
255 if (componentVersion.endsWith(".0")) {
256 Either<List<ResourceAdminEvent>, ActionStatus> eitherAuditingForCertified = auditCassandraDao.getByServiceInstanceId(componentUUID);
257 if (eitherAuditingForCertified.isLeft()) {
258 result = Either.left(getAuditingFieldsList(eitherAuditingForCertified.left().value()));
260 result = Either.right(eitherAuditingForCertified.right().value());
263 // Uncertified Version
265 result = getAuditRecordsForUncertifiedComponent(componentUUID, componentVersion);
267 } catch (Exception e) {
268 log.debug("get Audit Records failed with exception {}", e);
269 result = Either.right(ActionStatus.GENERAL_ERROR);
271 if (result.isRight()) {
272 return Either.right(componentsUtils.getResponseFormat(result.right().value()));
274 return Either.left(result.left().value());
278 public Either<List<Operation>, ResponseFormat> addServiceConsumptionData(String serviceId, String serviceInstanceId, String operationId,
279 List<ServiceConsumptionData> serviceConsumptionDataList, String userId) {
280 List<Operation> operationList = new ArrayList<>();
281 Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
282 if (serviceEither.isRight()) {
283 return Either.right(componentsUtils.getResponseFormat(serviceEither.right().value()));
285 Service service = serviceEither.left().value();
286 StorageOperationStatus storageOperationStatus = graphLockOperation.lockComponent(service.getUniqueId(), NodeTypeEnum.Service);
287 if (storageOperationStatus != StorageOperationStatus.OK) {
288 return Either.right(componentsUtils.getResponseFormat(storageOperationStatus));
291 for (ServiceConsumptionData serviceConsumptionData : serviceConsumptionDataList) {
292 Either<Operation, ResponseFormat> operationEither = addPropertyServiceConsumption(serviceId, serviceInstanceId, operationId, userId,
293 serviceConsumptionData);
294 if (operationEither.isRight()) {
295 return Either.right(operationEither.right().value());
297 operationList.add(operationEither.left().value());
299 janusGraphDao.commit();
300 return Either.left(operationList);
301 } catch (Exception e) {
302 janusGraphDao.rollback();
303 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
305 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
309 public Either<Operation, ResponseFormat> addPropertyServiceConsumption(String serviceId, String serviceInstanceId, String operationId,
310 String userId, ServiceConsumptionData serviceConsumptionData) {
311 validateUserExists(userId);
312 Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
313 if (serviceEither.isRight()) {
314 return Either.right(componentsUtils.getResponseFormat(serviceEither.right().value()));
316 Service parentService = serviceEither.left().value();
317 List<ComponentInstance> componentInstances = parentService.getComponentInstances();
318 if (CollectionUtils.isEmpty(componentInstances)) {
319 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
321 Optional<ComponentInstance> serviceInstanceCandidate = componentInstances.stream()
322 .filter(instance -> instance.getUniqueId().equals(serviceInstanceId)).findAny();
323 if (!serviceInstanceCandidate.isPresent()) {
324 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
326 Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaces = parentService.getComponentInstancesInterfaces();
327 if (MapUtils.isEmpty(componentInstancesInterfaces)) {
328 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
330 List<InterfaceDefinition> interfaces = new ArrayList<>();
331 for (ComponentInstanceInterface componentInstanceInterface : componentInstancesInterfaces.get(serviceInstanceId)) {
332 interfaces.add(componentInstanceInterface);
334 ComponentInstance serviceInstance = serviceInstanceCandidate.get();
335 Optional<InterfaceDefinition> interfaceCandidate = InterfaceOperationUtils.getInterfaceDefinitionFromOperationId(interfaces, operationId);
336 if (!interfaceCandidate.isPresent()) {
337 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
339 InterfaceDefinition interfaceDefinition = interfaceCandidate.get();
340 Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
341 if (MapUtils.isEmpty(operations)) {
342 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
344 Operation operation = operations.get(operationId);
345 Either<Operation, ResponseFormat> operationEither = Either.left(operation);
346 ListDataDefinition<OperationInputDefinition> inputs = operation.getInputs();
347 Optional<OperationInputDefinition> inputCandidate = getOperationInputByInputId(serviceConsumptionData, inputs);
348 if (!inputCandidate.isPresent()) {
349 return Either.right(new ResponseFormat(HttpStatus.NOT_FOUND.value()));
351 OperationInputDefinition operationInputDefinition = inputCandidate.get();
352 // add data to operation
353 if (Objects.nonNull(serviceConsumptionData.getValue())) {
354 operationEither = handleConsumptionValue(parentService, serviceInstanceId, serviceConsumptionData, operation, operationInputDefinition);
356 if (operationEither.isRight()) {
357 return Either.right(operationEither.right().value());
359 Operation updatedOperation = operationEither.left().value();
360 operations.remove(operationId);
361 operations.put(operationId, updatedOperation);
362 interfaceDefinition.setOperationsMap(operations);
363 parentService.getComponentInstances().remove(serviceInstance);
364 if (CollectionUtils.isEmpty(parentService.getComponentInstances())) {
365 parentService.setComponentInstances(new ArrayList<>());
367 Map<String, Object> instanceInterfaces =
368 MapUtils.isEmpty(serviceInstance.getInterfaces()) ? new HashMap<>() : serviceInstance.getInterfaces();
369 instanceInterfaces.remove(interfaceDefinition.getUniqueId());
370 instanceInterfaces.put(interfaceDefinition.getUniqueId(), interfaceDefinition);
371 serviceInstance.setInterfaces(instanceInterfaces);
372 removeComponentInstanceInterfaceByInterfaceId(interfaceDefinition.getUniqueId(), componentInstancesInterfaces.get(serviceInstanceId));
373 componentInstancesInterfaces.get(serviceInstanceId)
374 .add(new ComponentInstanceInterface(interfaceDefinition.getUniqueId(), interfaceDefinition));
375 parentService.getComponentInstances().add(serviceInstance);
376 StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(parentService, serviceInstanceId);
377 if (status != StorageOperationStatus.OK) {
378 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
380 return Either.left(operation);
383 private void removeComponentInstanceInterfaceByInterfaceId(String interfaceIdToRemove, List<ComponentInstanceInterface> instanceInterfaces) {
384 if (CollectionUtils.isEmpty(instanceInterfaces)) {
387 Optional<ComponentInstanceInterface> interfaceToRemove = instanceInterfaces.stream()
388 .filter(instInterface -> instInterface.getUniqueId().equals(interfaceIdToRemove)).findAny();
389 if (interfaceToRemove.isPresent()) {
390 instanceInterfaces.remove(interfaceToRemove.get());
394 private Either<Operation, ResponseFormat> handleConsumptionValue(Service containerService, String serviceInstanceId,
395 ServiceConsumptionData serviceConsumptionData, Operation operation,
396 OperationInputDefinition operationInputDefinition) {
397 String source = serviceConsumptionData.getSource();
398 String consumptionValue = serviceConsumptionData.getValue();
399 String type = serviceConsumptionData.getType();
400 String operationIdentifier =
401 consumptionValue.contains(".") ? consumptionValue.substring(0, consumptionValue.lastIndexOf('.')) : consumptionValue;
402 ServiceConsumptionSource sourceValue = ServiceConsumptionSource.getSourceValue(source);
403 if (STATIC.equals(sourceValue)) {
404 // Validate constraint on input value
405 Either<Boolean, ResponseFormat> constraintValidationResult = validateOperationInputConstraint(operationInputDefinition, consumptionValue,
406 type, containerService.getModel());
407 if (constraintValidationResult.isRight()) {
408 return Either.right(constraintValidationResult.right().value());
410 return handleConsumptionStaticValue(consumptionValue, type, operation, operationInputDefinition, containerService.getModel());
412 if (Objects.isNull(sourceValue)) {
413 List<PropertyDefinition> propertyDefinitions;
414 Map<String, List<CapabilityDefinition>> capabilities = null;
415 String componentName;
416 List<OperationOutputDefinition> outputs = null;
417 if (source.equals(containerService.getUniqueId())) {
418 Either<Service, StorageOperationStatus> serviceToTakePropEither = toscaOperationFacade.getToscaElement(source);
419 if (serviceToTakePropEither.isRight()) {
420 return Either.right(componentsUtils.getResponseFormat(serviceToTakePropEither.right().value()));
422 Service service = serviceToTakePropEither.left().value();
423 operationInputDefinition.setSource(service.getUniqueId());
424 sourceValue = SERVICE_INPUT;
425 propertyDefinitions = service.getProperties();
426 componentName = service.getName();
427 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier, service.getInterfaces())
428 .getListToscaDataDefinition();
430 Optional<ComponentInstance> getComponentInstance = containerService.getComponentInstanceById(source);
431 if (!getComponentInstance.isPresent()) {
432 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, source));
434 ComponentInstance componentInstance = getComponentInstance.get();
435 operationInputDefinition.setSource(componentInstance.getUniqueId());
436 propertyDefinitions = componentInstance.getProperties();
437 capabilities = componentInstance.getCapabilities();
438 componentName = source.equals(serviceInstanceId) ? SELF : componentInstance.getName();
439 if (MapUtils.isNotEmpty(componentInstance.getInterfaces())) {
440 Map<String, InterfaceDataDefinition> componentInstanceInterfaces = componentInstance.getInterfaces().entrySet().stream()
441 .collect(Collectors.toMap((Map.Entry::getKey), (interfaceEntry -> (InterfaceDataDefinition) interfaceEntry.getValue())));
442 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier, componentInstanceInterfaces)
443 .getListToscaDataDefinition();
446 if (sourceValue == ServiceConsumptionSource.SERVICE_INPUT) {
447 //The operation input in service consumption has been mapped to an input in the parent service
448 return handleConsumptionInputValue(consumptionValue, containerService, operation, operationInputDefinition);
450 return handleConsumptionPropertyValue(operation, operationInputDefinition, serviceConsumptionData, propertyDefinitions, capabilities,
451 outputs, componentName);
453 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.SOURCE, source);
454 operationInputDefinition.setSource(source);
455 return Either.left(operation);
458 private Optional<OperationInputDefinition> getOperationInputByInputId(ServiceConsumptionData serviceConsumptionData,
459 ListDataDefinition<OperationInputDefinition> inputs) {
460 if (CollectionUtils.isEmpty(inputs.getListToscaDataDefinition())) {
461 return Optional.empty();
463 return inputs.getListToscaDataDefinition().stream()
464 .filter(operationInput -> operationInput.getInputId().equals(serviceConsumptionData.getInputId())).findAny();
467 private Either<Operation, ResponseFormat> handleConsumptionPropertyValue(Operation operation, OperationInputDefinition operationInputDefinition,
468 ServiceConsumptionData serviceConsumptionData,
469 List<PropertyDefinition> properties,
470 Map<String, List<CapabilityDefinition>> capabilities,
471 List<OperationOutputDefinition> outputs, String componentName) {
472 if (CollectionUtils.isEmpty(properties) && CollectionUtils.isEmpty(outputs)) {
473 return Either.left(operation);
475 String consumptionValue = serviceConsumptionData.getValue();
476 if (CollectionUtils.isNotEmpty(outputs) && isOperationInputMappedToOtherOperationOutput(getOperationOutputName(consumptionValue), outputs)) {
477 return handleConsumptionInputMappedToOperationOutput(operation, operationInputDefinition, outputs, consumptionValue, componentName);
479 if (CollectionUtils.isNotEmpty(properties) && PropertiesUtils.isNodeProperty(consumptionValue, properties)) {
480 return handleConsumptionInputMappedToProperty(operation, operationInputDefinition, serviceConsumptionData, properties, componentName);
482 if (MapUtils.isNotEmpty(capabilities)) {
483 return handleConsumptionInputMappedToCapabilityProperty(operation, operationInputDefinition, serviceConsumptionData, capabilities,
486 return Either.left(operation);
489 private Either<Operation, ResponseFormat> handleConsumptionInputMappedToProperty(Operation operation,
490 OperationInputDefinition operationInputDefinition,
491 ServiceConsumptionData serviceConsumptionData,
492 List<PropertyDefinition> properties, String componentName) {
493 Optional<PropertyDefinition> servicePropertyCandidate = properties.stream()
494 .filter(property -> property.getName().equals(serviceConsumptionData.getValue())).findAny();
495 if (servicePropertyCandidate.isPresent()) {
496 boolean isInputTypeSimilarToOperation = isAssignedValueFromValidType(operationInputDefinition.getType(), servicePropertyCandidate.get());
497 if (!isInputTypeSimilarToOperation) {
498 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
500 addPropertyToInputValue(componentName, operation, operationInputDefinition, servicePropertyCandidate.get());
502 return Either.left(operation);
505 private Either<Operation, ResponseFormat> handleConsumptionInputMappedToOperationOutput(Operation operation,
506 OperationInputDefinition operationInputDefinition,
507 List<OperationOutputDefinition> outputs,
508 String consumptionValue, String componentName) {
509 String outputName = getOperationOutputName(consumptionValue);
510 Optional<OperationOutputDefinition> servicePropertyOutputCandidate = outputs.stream().filter(output -> output.getName().equals(outputName))
512 if (servicePropertyOutputCandidate.isPresent()) {
513 boolean isInputTypeSimilarToOperation = isAssignedValueFromValidType(operationInputDefinition.getType(),
514 servicePropertyOutputCandidate.get());
515 if (!isInputTypeSimilarToOperation) {
516 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
518 addOutputToInputValue(componentName, consumptionValue, operation, operationInputDefinition);
520 return Either.left(operation);
523 private void addPropertyToInputValue(String componentName, Operation operation, OperationInputDefinition operationInputDefinition,
524 PropertyDefinition serviceProperty) {
525 Map<String, List<String>> getProperty = new HashMap<>();
526 List<String> getPropertyValues = new ArrayList<>();
527 getPropertyValues.add(componentName);
528 getPropertyValues.add(serviceProperty.getName());
529 getProperty.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), getPropertyValues);
530 operationInputDefinition.setSourceProperty(serviceProperty.getUniqueId());
531 operation.getInputs().delete(operationInputDefinition);
532 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_PROPERTY, getPropertyValues);
533 operationInputDefinition.setValue((new Gson()).toJson(getProperty));
534 operation.getInputs().add(operationInputDefinition);
537 private void addOutputToInputValue(String componentName, String consumptionValue, Operation operation,
538 OperationInputDefinition operationInputDefinition) {
539 Map<String, List<String>> getOperationOutput = InterfaceOperationUtils.createMappedOutputDefaultValue(componentName, consumptionValue);
540 operation.getInputs().delete(operationInputDefinition);
541 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_OPERATION_OUTPUT, getOperationOutput);
542 operationInputDefinition.setValue((new Gson()).toJson(getOperationOutput));
543 operation.getInputs().add(operationInputDefinition);
546 public Either<Operation, ResponseFormat> handleConsumptionStaticValue(String value, String type, Operation operation,
547 OperationInputDefinition operationInputDefinition, String model) {
548 boolean isInputTypeSimilarToOperation = isAssignedValueFromValidType(type, value);
549 if (!isInputTypeSimilarToOperation) {
550 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONSUMPTION_TYPE, type));
552 //Validate Constraint and Value
553 Either<Boolean, ResponseFormat> constraintValidationResponse = validateOperationInputConstraint(operationInputDefinition, value, type, model);
554 if (constraintValidationResponse.isRight()) {
555 return Either.right(constraintValidationResponse.right().value());
557 addStaticValueToInputOperation(value, operation, operationInputDefinition);
558 return Either.left(operation);
561 private Either<Boolean, ResponseFormat> validateOperationInputConstraint(OperationInputDefinition operationInputDefinition, String value,
562 String type, String model) {
563 ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
564 propertyDefinition.setType(operationInputDefinition.getParentPropertyType());
565 InputDefinition inputDefinition = new InputDefinition();
566 inputDefinition.setDefaultValue(value);
567 inputDefinition.setInputPath(operationInputDefinition.getSubPropertyInputPath());
568 inputDefinition.setType(type);
569 if (Objects.nonNull(operationInputDefinition.getParentPropertyType())) {
570 inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
572 return new PropertyValueConstraintValidationUtil().validatePropertyConstraints(Collections.singletonList(inputDefinition),
573 applicationDataTypeCache, model);
576 private void addStaticValueToInputOperation(String value, Operation operation, OperationInputDefinition operationInputDefinition) {
577 operation.getInputs().delete(operationInputDefinition);
578 operationInputDefinition.setSource(STATIC.getSource());
579 operationInputDefinition.setSourceProperty(null);
580 operationInputDefinition.setValue(value);
581 operation.getInputs().add(operationInputDefinition);
584 private Either<Operation, ResponseFormat> handleConsumptionInputValue(String inputId, Service service, Operation operation,
585 OperationInputDefinition operationInputDefinition) {
586 List<InputDefinition> serviceInputs = service.getInputs();
587 Optional<InputDefinition> inputForValue = serviceInputs.stream().filter(input -> input.getUniqueId().contains(inputId)).findAny();
588 if (inputForValue.isPresent()) {
589 boolean isInputTypeSimilarToOperation = isAssignedValueFromValidType(operationInputDefinition.getType(), inputForValue.get());
590 if (!isInputTypeSimilarToOperation) {
591 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
593 addGetInputValueToOperationInput(operation, operationInputDefinition, inputForValue.get());
595 return Either.left(operation);
598 private void addGetInputValueToOperationInput(Operation operation, OperationInputDefinition operationInputDefinition,
599 InputDefinition inputForValue) {
600 operation.getInputs().delete(operationInputDefinition);
601 Map<String, String> getInputMap = new HashMap<>();
602 getInputMap.put(ToscaFunctions.GET_INPUT.getFunctionName(), inputForValue.getName());
603 operationInputDefinition.setSourceProperty(inputForValue.getUniqueId());
604 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_INPUT, getInputMap);
605 operationInputDefinition.setValue(new Gson().toJson(getInputMap));
606 operation.getInputs().add(operationInputDefinition);
609 private Either<List<Map<String, Object>>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) {
611 Either<List<ResourceAdminEvent>, ActionStatus> eitherprevVerAudit = auditCassandraDao
612 .getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion);
613 if (eitherprevVerAudit.isRight()) {
614 return Either.right(eitherprevVerAudit.right().value());
617 Either<List<ResourceAdminEvent>, ActionStatus> eitherCurrVerAudit = auditCassandraDao
618 .getAuditByServiceIdAndCurrVersion(componentUUID, componentVersion);
619 if (eitherCurrVerAudit.isRight()) {
620 return Either.right(eitherCurrVerAudit.right().value());
622 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveRestoreList = getArchiveRestoreEventList(componentUUID);
623 if (eitherArchiveRestoreList.isRight()) {
624 return Either.right(eitherArchiveRestoreList.right().value());
626 List<Map<String, Object>> prevVerAuditList = getAuditingFieldsList(eitherprevVerAudit.left().value());
627 List<Map<String, Object>> currVerAuditList = getAuditingFieldsList(eitherCurrVerAudit.left().value());
628 List<Map<String, Object>> duplicateElements = new ArrayList<>();
629 duplicateElements.addAll(prevVerAuditList);
630 duplicateElements.retainAll(currVerAuditList);
631 List<Map<String, Object>> joinedNonDuplicatedList = new ArrayList<>();
632 joinedNonDuplicatedList.addAll(prevVerAuditList);
633 joinedNonDuplicatedList.removeAll(duplicateElements);
634 joinedNonDuplicatedList.addAll(currVerAuditList);
635 joinedNonDuplicatedList.addAll(getAuditingFieldsList(eitherArchiveRestoreList.left().value()));
636 return Either.left(joinedNonDuplicatedList);
639 private Either<List<ResourceAdminEvent>, ActionStatus> getArchiveRestoreEventList(String componentUUID) {
641 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveAudit = auditCassandraDao.getArchiveAuditByServiceInstanceId(componentUUID);
642 if (eitherArchiveAudit.isRight()) {
643 return Either.right(eitherArchiveAudit.right().value());
646 Either<List<ResourceAdminEvent>, ActionStatus> eitherRestoreAudit = auditCassandraDao.getRestoreAuditByServiceInstanceId(componentUUID);
647 if (eitherRestoreAudit.isRight()) {
648 return Either.right(eitherRestoreAudit.right().value());
650 List<ResourceAdminEvent> archiveAudit = new ArrayList<>();
651 archiveAudit.addAll(eitherArchiveAudit.left().value());
652 archiveAudit.addAll(eitherRestoreAudit.left().value());
653 return Either.left(archiveAudit);
656 private List<Map<String, Object>> getAuditingFieldsList(List<? extends AuditingGenericEvent> prevVerAuditList) {
657 List<Map<String, Object>> prevVerAudit = new ArrayList<>();
658 for (AuditingGenericEvent auditEvent : prevVerAuditList) {
659 auditEvent.fillFields();
660 prevVerAudit.add(auditEvent.getFields());
668 * @param service - Service
669 * @param user - modifier data (userId)
670 * @return Either<Service, responseFormat>
672 public Either<Service, ResponseFormat> createService(Service service, User user) {
674 user = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false);
675 log.debug("User returned from validation: {}", user);
676 // validate user role
677 validateUserRole(user, service, new ArrayList<>(), AuditingActionEnum.CREATE_RESOURCE, null);
678 service.setCreatorUserId(user.getUserId());
679 // warn on overridden fields
680 checkFieldsForOverideAttempt(service);
682 log.debug("enrich service with version and state");
683 service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
684 service.setVersion(INITIAL_VERSION);
685 service.setConformanceLevel(ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
686 service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED);
687 service.setComponentType(ComponentTypeEnum.SERVICE);
688 Either<Service, ResponseFormat> createServiceResponse = validateServiceBeforeCreate(service, user, AuditingActionEnum.CREATE_RESOURCE);
689 if (createServiceResponse.isRight()) {
690 return createServiceResponse;
692 return createServiceByDao(service, user).left().bind(c -> updateCatalog(c, ChangeTypeEnum.LIFECYCLE).left().map(Service.class::cast));
695 private void checkFieldsForOverideAttempt(Service service) {
696 checkComponentFieldsForOverrideAttempt(service);
697 if (service.getDistributionStatus() != null) {
698 log.info("Distribution Status cannot be defined by user. This field will be overridden by the application");
702 private Either<Service, ResponseFormat> createServiceByDao(final Service service, final User user) {
703 log.debug("send service {} to dao for create", service.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
704 Either<Boolean, ResponseFormat> lockResult = lockComponentByName(service.getSystemName(), service, "Create Service");
705 if (lockResult.isRight()) {
706 ResponseFormat responseFormat = lockResult.right().value();
707 componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
708 return Either.right(responseFormat);
710 log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult);
712 createMandatoryArtifactsData(service, user);
713 createServiceApiArtifactsData(service, user);
714 setToscaArtifactsPlaceHolders(service, user);
716 if (service.isSubstituteCandidate() || genericTypeBusinessLogic.hasMandatorySubstitutionType(service)) {
717 final Resource genericType = fetchAndSetDerivedFromGenericType(service);
718 generatePropertiesFromGenericType(service, genericType);
719 if (Constants.DEFAULT_MODEL_NAME.equals(service.getModel()) || service.getModel() == null) {
720 generateAndAddInputsFromGenericTypeProperties(service, genericType);
723 beforeCreate(service);
724 Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
725 if (dataModelResponse.isLeft()) {
726 log.debug("Service '{}' created successfully", service.getName());
727 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
728 componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
729 ASDCKpiApi.countCreatedServicesKPI();
730 return Either.left(dataModelResponse.left().value());
732 janusGraphDao.rollback();
733 ResponseFormat responseFormat = componentsUtils
734 .getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service,
735 ComponentTypeEnum.SERVICE);
736 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
737 componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
738 return Either.right(responseFormat);
740 graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service);
744 private void beforeCreate(final Service service) {
745 if (CollectionUtils.isEmpty(serviceCreationPluginList)) {
748 serviceCreationPluginList.stream().sorted(Comparator.comparingInt(ServiceCreationPlugin::getOrder)).forEach(serviceCreationPlugin -> {
750 serviceCreationPlugin.beforeCreate(service);
751 } catch (final Exception e) {
752 log.error("An error has occurred while running the serviceCreationPlugin '{}'", serviceCreationPlugin.getClass(), e);
757 @SuppressWarnings("unchecked")
758 private void createServiceApiArtifactsData(Service service, User user) {
759 // create mandatory artifacts
761 // TODO it must be removed after that artifact uniqueId creation will be
763 // moved to ArtifactOperation
764 String serviceUniqueId = service.getUniqueId();
765 Map<String, ArtifactDefinition> artifactMap = service.getServiceApiArtifacts();
766 if (artifactMap == null) {
767 artifactMap = new HashMap<>();
769 Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts();
770 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
771 List<CategoryDefinition> categories = service.getCategories();
772 boolean isCreateArtifact = true;
773 if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
774 for (String exlude : exludeServiceCategory) {
775 if (exlude.equalsIgnoreCase(categories.get(0).getName())) {
776 isCreateArtifact = false;
781 if (serviceApiArtifacts != null && isCreateArtifact) {
782 Set<String> keys = serviceApiArtifacts.keySet();
783 for (String serviceApiArtifactName : keys) {
784 Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName);
785 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user,
787 artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API);
788 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
790 service.setServiceApiArtifacts(artifactMap);
795 protected Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) {
797 serviceValidator.validate(user, service, actionEnum);
798 } catch (ComponentException exp) {
799 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exp);
800 componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_SERVICE, ComponentTypeEnum.SERVICE);
803 if (!AuditingActionEnum.UPDATE_SERVICE_TOSCA_TEMPLATE.equals(actionEnum) &&
804 !AuditingActionEnum.UPDATE_SERVICE_TOSCA_MODEL.equals(actionEnum)) {
805 service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
806 service.setContactId(service.getContactId().toLowerCase());
807 // Generate invariant UUID - must be here and not in operation since it should stay constant during clone
808 service.setInvariantUUID(UniqueIdBuilder.buildInvariantUUID());
810 return Either.left(service);
813 public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) {
814 validateUserExists(userId);
815 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade
816 .validateComponentNameUniqueness(serviceName, null, ComponentTypeEnum.SERVICE);
818 janusGraphDao.commit();
819 if (dataModelResponse.isLeft()) {
820 Map<String, Boolean> result = new HashMap<>();
821 result.put(IS_VALID, dataModelResponse.left().value());
822 log.debug("validation was successfully performed.");
823 return Either.left(result);
825 ResponseFormat responseFormat = componentsUtils
826 .getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
827 return Either.right(responseFormat);
830 public void setElementDao(IElementOperation elementDao) {
831 this.elementDao = elementDao;
835 public void setCassandraAuditingDao(AuditCassandraDao auditingDao) {
836 this.auditCassandraDao = auditingDao;
839 public ArtifactsBusinessLogic getArtifactBl() {
840 return artifactsBusinessLogic;
843 public void setArtifactBl(ArtifactsBusinessLogic artifactBl) {
844 this.artifactsBusinessLogic = artifactBl;
847 public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) {
848 user = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false);
849 // validate user role
850 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
851 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
852 if (storageStatus.isRight()) {
853 return Either.right(componentsUtils
854 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
856 Service currentService = storageStatus.left().value();
857 if (!ComponentValidationUtils.canWorkOnComponent(currentService, user.getUserId())) {
858 log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
859 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
861 List<String> subNodePropsToBeRemoved = getSubstitutionNodePropertiesToBeRemoved(currentService, serviceUpdate);
862 List<PropertyDefinition> subNodePropsToBeAdded = getSubstitutionNodePropertiesToBeAdded(currentService, serviceUpdate);
863 boolean subNodeChanged = isSubstitutionNodeChanged(currentService, serviceUpdate);
864 Either<Service, ResponseFormat> validationResponse =
865 validateAndUpdateServiceMetadata(user, currentService, serviceUpdate, subNodeChanged, ListUtils.emptyIfNull(subNodePropsToBeRemoved));
866 if (validationResponse.isRight()) {
867 log.info("service update metadata: validations field.");
868 return validationResponse;
870 Service serviceToUpdate = validationResponse.left().value();
872 lockComponent(serviceId, currentService, "Update Service Metadata");
874 if (subNodeChanged) {
875 if (!subNodePropsToBeRemoved.isEmpty()) {
876 removePropertiesFromService(currentService, subNodePropsToBeRemoved);
877 removeInputsFromService(currentService, subNodePropsToBeRemoved);
879 if (!subNodePropsToBeAdded.isEmpty()) {
880 addPropertiesToService(currentService, subNodePropsToBeAdded);
881 if (Constants.DEFAULT_MODEL_NAME.equals(currentService.getModel()) || currentService.getModel() == null) {
882 addInputsToService(currentService, subNodePropsToBeAdded);
886 return toscaOperationFacade.updateToscaElement(serviceToUpdate).right().map(rf -> {
887 janusGraphDao.rollback();
888 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
889 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
890 return (componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
891 }).left().bind(this::updateCatalogAndCommit);
892 } catch (ComponentException e) {
893 janusGraphDao.rollback();
894 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
895 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
896 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
898 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
902 private Either<Service, ResponseFormat> updateCatalogAndCommit(Service service) {
903 Either<Service, ResponseFormat> res = updateCatalog(service, ChangeTypeEnum.LIFECYCLE).left().map(Service.class::cast);
904 janusGraphDao.commit();
908 public Set<String> deleteForwardingPaths(String serviceId, Set<String> pathIdsToDelete, User user, boolean lock) {
909 Service serviceToDelete = initServiceToDeletePaths(serviceId, pathIdsToDelete);
910 user = validateUser(user, "deleteForwardingPaths", serviceToDelete, null, false);
911 // validate user role
912 validateUserRole(user, serviceToDelete, new ArrayList<>(), null, null);
913 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
914 if (storageStatus.isRight()) {
915 throw new ByActionStatusComponentException(
916 componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), "");
918 Service service = storageStatus.left().value();
919 Either<Set<String>, StorageOperationStatus> result = null;
922 lockComponent(service.getUniqueId(), service, "Delete Forwarding Path on Service");
923 } catch (ComponentException e) {
924 janusGraphDao.rollback();
925 throw new ByActionStatusComponentException(
926 componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), "");
930 result = forwardingPathOperation.deleteForwardingPath(service, pathIdsToDelete);
931 if (result.isRight()) {
932 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, service.getName(), result.right().value());
933 janusGraphDao.rollback();
934 throw new ByActionStatusComponentException(
935 componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE));
937 janusGraphDao.commit();
938 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, service.getSystemName());
939 } catch (ComponentException e) {
940 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
941 janusGraphDao.rollback();
942 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
944 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
946 return result.left().value();
949 private Service initServiceToDeletePaths(String serviceId, Collection<String> pathIdsToDelete) {
950 Service serviceToDelete = new Service();
951 serviceToDelete.setUniqueId(serviceId);
952 serviceToDelete.setForwardingPaths(new HashMap<>());
953 pathIdsToDelete.forEach(pathIdToDelete -> serviceToDelete.getForwardingPaths().put(pathIdToDelete, new ForwardingPathDataDefinition()));
954 return serviceToDelete;
957 public Service updateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
958 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, true, "updateForwardingPath", lock);
961 public Service createForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
962 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, false, "createForwardingPath", lock);
965 private ForwardingPathDataDefinition getTrimmedValues(ForwardingPathDataDefinition path) {
966 ForwardingPathDataDefinition dataDefinition = new ForwardingPathDataDefinition(path.getName());
967 dataDefinition.setName(Strings.nullToEmpty(path.getName()).trim());
968 dataDefinition.setProtocol(Strings.nullToEmpty(path.getProtocol()).trim());
969 dataDefinition.setDestinationPortNumber(Strings.nullToEmpty(path.getDestinationPortNumber()).trim());
970 dataDefinition.setUniqueId(path.getUniqueId());
971 dataDefinition.setPathElements(path.getPathElements());
972 dataDefinition.setDescription(path.getDescription());
973 dataDefinition.setToscaResourceName(path.getToscaResourceName());
974 return dataDefinition;
977 private Service createOrUpdateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean isUpdate, String errorContext,
979 validateUserAndRole(serviceUpdate, user, errorContext);
980 Map<String, ForwardingPathDataDefinition> forwardingPaths = serviceUpdate.getForwardingPaths();
981 Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths = forwardingPaths.entrySet().stream()
982 .collect(Collectors.toMap(Map.Entry::getKey, entry -> new ForwardingPathDataDefinition(getTrimmedValues(entry.getValue()))));
983 forwardingPathValidator.validateForwardingPaths(trimmedForwardingPaths.values(), serviceId, isUpdate);
984 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
985 if (serviceStorageOperationStatusEither.isRight()) {
986 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
987 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
988 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(errorStatus));
990 Service storedService = serviceStorageOperationStatusEither.left().value();
991 Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
992 Component component = getForwardingPathOriginComponent();
993 final String toscaResourceName;
994 if (component.getComponentType() == ComponentTypeEnum.RESOURCE) {
995 toscaResourceName = ((Resource) component).getToscaResourceName();
997 toscaResourceName = "";
1000 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Forwarding Path on Service");
1001 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, storedService.getSystemName());
1003 Map<String, ForwardingPathDataDefinition> resultMap = new HashMap<>();
1005 trimmedForwardingPaths.values().forEach(fp -> fp.setToscaResourceName(toscaResourceName));
1006 populateForwardingPaths(serviceId, isUpdate, trimmedForwardingPaths, resultMap);
1007 janusGraphDao.commit();
1010 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
1013 return createServiceWithForwardingPathForResponse(serviceId, resultMap);
1016 private Component getForwardingPathOriginComponent() {
1017 Either<Component, StorageOperationStatus> forwardingPathOrigin = toscaOperationFacade
1018 .getLatestByName(ForwardingPathUtils.FORWARDING_PATH_NODE_NAME, null);
1019 if (forwardingPathOrigin.isRight()) {
1020 StorageOperationStatus errorStatus = forwardingPathOrigin.right().value();
1021 log.debug("Failed to fetch normative forwarding path resource by tosca name, error {}", errorStatus);
1022 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(errorStatus));
1024 return forwardingPathOrigin.left().value();
1027 private void populateForwardingPaths(String serviceId, boolean isUpdate, Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths,
1028 Map<String, ForwardingPathDataDefinition> resultMap) {
1029 Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
1031 for (ForwardingPathDataDefinition forwardingPathDataDefinition : trimmedForwardingPaths.values()) {
1033 result = forwardingPathOperation.updateForwardingPath(serviceId, forwardingPathDataDefinition);
1035 result = forwardingPathOperation.addForwardingPath(serviceId, forwardingPathDataDefinition);
1037 if (result.isRight()) {
1038 janusGraphDao.rollback();
1039 throw new ByResponseFormatComponentException(componentsUtils
1040 .getResponseFormat(componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE), ""));
1042 ForwardingPathDataDefinition fpDataDefinition = result.left().value();
1043 resultMap.put(fpDataDefinition.getUniqueId(), forwardingPathDataDefinition);
1046 } catch (ComponentException e) {
1047 janusGraphDao.rollback();
1048 log.error("Exception occurred during add or update forwarding path property values: {}", e.getMessage(), e);
1049 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1053 private Service createServiceWithForwardingPathForResponse(String serviceId,
1054 Map<String, ForwardingPathDataDefinition> forwardingPathDataDefinitionMap) {
1055 Service service = new Service();
1056 service.setUniqueId(serviceId);
1057 service.setForwardingPaths(forwardingPathDataDefinitionMap);
1061 private void validateUserAndRole(Service serviceUpdate, User user, String errorContext) {
1062 user = validateUser(user, errorContext, serviceUpdate, null, false);
1063 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1067 Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate, boolean subNodeChanged,
1068 List<String> subNodePropsToBeRemoved) {
1070 boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
1071 if (subNodeChanged) {
1072 if (!subNodePropsToBeRemoved.isEmpty()) {
1073 areSubstitutionNodePropertiesInUse(currentService, subNodePropsToBeRemoved);
1075 currentService.setDerivedFromGenericVersion(serviceUpdate.getDerivedFromGenericVersion());
1076 currentService.setDerivedFromGenericType(serviceUpdate.getDerivedFromGenericType());
1079 Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified,
1080 UPDATE_SERVICE_METADATA);
1081 if (response.isRight()) {
1082 ResponseFormat errorResponse = response.right().value();
1083 return Either.right(errorResponse);
1085 verifyValuesAreIdentical(serviceUpdate.getCreatorUserId(), currentService.getCreatorUserId(), "creatorUserId");
1086 verifyValuesAreIdentical(serviceUpdate.getCreatorFullName(), currentService.getCreatorFullName(), "creatorFullName");
1087 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterUserId(), currentService.getLastUpdaterUserId(), "lastUpdaterUserId");
1088 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterFullName(), currentService.getLastUpdaterFullName(), "lastUpdaterFullName");
1089 response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null);
1090 if (response.isRight()) {
1091 return Either.right(response.right().value());
1093 verifyValuesAreIdentical(serviceUpdate.getDistributionStatus(), currentService.getDistributionStatus(), "distributionStatus");
1094 if (serviceUpdate.getProjectCode() != null) {
1095 response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1096 if (response.isRight()) {
1097 return Either.right(response.right().value());
1100 response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1101 if (response.isRight()) {
1102 return Either.right(response.right().value());
1104 verifyValuesAreIdentical(serviceUpdate.getCreationDate(), currentService.getCreationDate(), "creationDate");
1105 verifyValuesAreIdentical(serviceUpdate.getVersion(), currentService.getVersion(), "version");
1106 response = validateAndUpdateDescription(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1107 if (response.isRight()) {
1108 return Either.right(response.right().value());
1110 response = validateAndUpdateTags(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1111 if (response.isRight()) {
1112 return Either.right(response.right().value());
1114 response = validateAndUpdateContactId(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1115 if (response.isRight()) {
1116 return Either.right(response.right().value());
1118 verifyValuesAreIdentical(serviceUpdate.getLastUpdateDate(), currentService.getLastUpdateDate(), "lastUpdateDate");
1119 verifyValuesAreIdentical(serviceUpdate.getLifecycleState(), currentService.getLifecycleState(), "lifecycleState");
1120 verifyValuesAreIdentical(serviceUpdate.isHighestVersion(), currentService.isHighestVersion(), "isHighestVersion");
1121 verifyValuesAreIdentical(serviceUpdate.getUUID(), currentService.getUUID(), "uuid");
1122 validateAndUpdateServiceType(currentService, serviceUpdate);
1123 validateAndUpdateServiceFunction(currentService, serviceUpdate);
1124 response = validateAndUpdateServiceRole(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1125 if (response.isRight()) {
1126 return Either.right(response.right().value());
1128 response = validateAndUpdateInstantiationTypeValue(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1129 if (response.isRight()) {
1130 return Either.right(response.right().value());
1132 verifyValuesAreIdentical(serviceUpdate.getInvariantUUID(), currentService.getInvariantUUID(), "invariantUUID");
1133 validateAndUpdateEcompNaming(currentService, serviceUpdate);
1134 currentService.setEnvironmentContext(serviceUpdate.getEnvironmentContext());
1135 currentService.setCategorySpecificMetadata(serviceUpdate.getCategorySpecificMetadata());
1136 return Either.left(currentService);
1137 } catch (ComponentException exception) {
1138 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
1140 .auditComponentAdmin(responseFormat, user, serviceUpdate, AuditingActionEnum.UPDATE_SERVICE_METADATA, ComponentTypeEnum.SERVICE);
1141 return Either.right(responseFormat);
1145 private void addPropertiesToService(Service currentService, List<PropertyDefinition> subNodePropsToBeAdded) {
1146 ListUtils.emptyIfNull(subNodePropsToBeAdded).forEach(prop -> {
1147 Either<PropertyDefinition, StorageOperationStatus> addPropertyEither =
1148 toscaOperationFacade.addPropertyToComponent(prop, currentService);
1149 if (addPropertyEither.isRight()) {
1150 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1155 private void addInputsToService(Service currentService, List<PropertyDefinition> subNodePropsToBeAdded) {
1156 ListUtils.emptyIfNull(subNodePropsToBeAdded).forEach(prop -> {
1157 InputDefinition inputDef = new InputDefinition(prop);
1158 Either<InputDefinition, StorageOperationStatus> status =
1159 toscaOperationFacade.addInputToComponent(prop.getName(), inputDef, currentService);
1160 if (status.isRight()) {
1161 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1166 private void removePropertiesFromService(Service currentService, List<String> subNodePropsToBeRemoved) {
1167 List<PropertyDefinition> props = currentService.getProperties();
1168 List<String> propsUniqueIdsToBeRemoved =
1169 props.stream().filter(prop -> subNodePropsToBeRemoved.contains(prop.getName())).map(PropertyDefinition::getUniqueId)
1170 .collect(Collectors.toList());
1171 ListUtils.emptyIfNull(props).stream().filter(prop -> propsUniqueIdsToBeRemoved.contains(prop.getUniqueId())).forEach(prop -> {
1172 StorageOperationStatus status = toscaOperationFacade.deletePropertyOfComponent(currentService, prop.getName());
1173 if (status != StorageOperationStatus.OK) {
1174 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1179 private void removeInputsFromService(Service currentService, List<String> subNodePropsToBeRemoved) {
1180 List<PropertyDefinition> props = currentService.getProperties();
1181 List<InputDefinition> inputs = currentService.getInputs();
1182 List<String> propsUniqueIdsToBeRemoved =
1183 props.stream().filter(prop -> subNodePropsToBeRemoved.contains(prop.getName())).map(PropertyDefinition::getUniqueId)
1184 .collect(Collectors.toList());
1185 ListUtils.emptyIfNull(inputs).stream().filter(input -> input.isMappedToComponentProperty() &&
1186 (propsUniqueIdsToBeRemoved.contains(input.getPropertyId()) || subNodePropsToBeRemoved.contains(input.getName()))).forEach(input -> {
1187 StorageOperationStatus status = toscaOperationFacade.deleteInputOfResource(currentService, input.getName());
1188 if (status != StorageOperationStatus.OK) {
1189 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1194 private void areSubstitutionNodePropertiesInUse(Service service, List<String> subNodePropsToBeRemoved) {
1195 Map<String, List<ComponentInstanceProperty>> componentInstancesProps = service.getComponentInstancesProperties();
1196 List<String> propsUniqueIdsToBeRemoved =
1197 ListUtils.emptyIfNull(service.getProperties()).stream().filter(prop -> subNodePropsToBeRemoved.contains(prop.getName()))
1198 .map(PropertyDefinition::getUniqueId)
1199 .collect(Collectors.toList());
1200 List<String> inputsUniqueIdsToBeRemoved = ListUtils.emptyIfNull(service.getInputs()).stream()
1201 .filter(input -> propsUniqueIdsToBeRemoved.contains(input.getPropertyId()) || subNodePropsToBeRemoved.contains(input.getName()))
1202 .map(PropertyDefinition::getUniqueId)
1203 .collect(Collectors.toList());
1204 Map<String, List<String>> inUse = new HashMap<>();
1205 if (componentInstancesProps != null && !componentInstancesProps.isEmpty()) {
1206 componentInstancesProps.forEach((compInstanceId, listOfProps) -> {
1207 List<String> propsInUse = new ArrayList<>();
1208 listOfProps.stream()
1209 .filter(PropertyDataDefinition::isToscaFunction)
1210 .filter(compProp -> ToscaFunctionType.isGetFunction(compProp.getToscaFunction().getType()))
1211 .forEach(compProp -> {
1212 ToscaFunction toscaFunction = compProp.getToscaFunction();
1213 ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) toscaFunction;
1214 String propName = toscaGetFunction.getPropertyName();
1215 String propUniqueId = toscaGetFunction.getPropertyUniqueId();
1216 if (inputsUniqueIdsToBeRemoved.contains(propUniqueId) || propsUniqueIdsToBeRemoved.contains(propUniqueId) ||
1217 subNodePropsToBeRemoved.contains(propName)) {
1218 propsInUse.add(compProp.getName());
1221 if (!propsInUse.isEmpty()) {
1222 Optional<ComponentInstance> componentInstance = service.getComponentInstanceById(compInstanceId);
1223 componentInstance.ifPresent(instance -> inUse.put(instance.getName(), propsInUse));
1228 if (!inUse.isEmpty()) {
1229 String propsInUse = inUse.entrySet().stream().map(entry -> {
1230 String properties = entry.getValue().stream().map(Object::toString).collect(Collectors.joining(", "));
1231 return properties + " on " + entry.getKey();
1232 }).collect(Collectors.joining(", properties "));
1233 throw new ByActionStatusComponentException(ActionStatus.SUBSTITUTION_NODE_TYPE_PROPERTY_IN_USE, propsInUse);
1238 private boolean isSubstitutionNodeChanged(Service currentService, Service updatedService) {
1239 String currentServiceType = currentService.getDerivedFromGenericType();
1240 String updatedServiceType = updatedService.getDerivedFromGenericType();
1241 String currentServiceVersion = currentService.getDerivedFromGenericVersion();
1242 String updatedServiceVersion = updatedService.getDerivedFromGenericVersion();
1243 return !(StringUtils.equals(currentServiceType, updatedServiceType) && StringUtils.equals(currentServiceVersion, updatedServiceVersion));
1246 private List<String> getSubstitutionNodePropertiesToBeRemoved(Service currentService, Service serviceUpdate) {
1247 List<PropertyDefinition> currentProps = ListUtils.emptyIfNull(fetchDerivedFromGenericType(currentService, null).getProperties());
1248 List<PropertyDefinition> updatedProps = ListUtils.emptyIfNull(fetchDerivedFromGenericType(serviceUpdate, null).getProperties());
1249 if (!StringUtils.equals(currentService.getDerivedFromGenericType(), serviceUpdate.getDerivedFromGenericType())) {
1250 return currentProps.stream().map(PropertyDefinition::getName).collect(Collectors.toList());
1253 Map<String, PropertyDefinition> currentPropsMap = currentProps.stream().collect(Collectors.toMap(prop -> prop.getName(), prop -> prop));
1254 Map<String, PropertyDefinition> updatedPropsMap = updatedProps.stream().collect(Collectors.toMap(prop -> prop.getName(), prop -> prop));
1256 List<String> propNamesToBeRemoved = new ArrayList<>();
1257 for (String currentPropertyName : currentPropsMap.keySet()) {
1258 if (updatedPropsMap.containsKey(currentPropertyName)) {
1259 if (!haveSameType(currentPropsMap.get(currentPropertyName), updatedPropsMap.get(currentPropertyName))) {
1260 propNamesToBeRemoved.add(currentPropertyName);
1263 propNamesToBeRemoved.add(currentPropertyName);
1267 return propNamesToBeRemoved;
1270 private boolean haveSameType(final PropertyDefinition property1, final PropertyDefinition property2) {
1271 if (property1.getType().equals("list")) {
1272 return property2.getType().equals("list") && property1.getSchema().equals(property2.getSchema());
1274 if (property1.getType().equals("map")) {
1275 return property2.getType().equals("map") && property1.getSchema().equals(property2.getSchema());
1277 return property1.getType().equals(property2.getType());
1280 private List<PropertyDefinition> getSubstitutionNodePropertiesToBeAdded(Service currentService, Service serviceUpdate) {
1281 List<PropertyDefinition> propsInCurrentVersion = ListUtils.emptyIfNull(fetchDerivedFromGenericType(currentService, null).getProperties());
1282 List<PropertyDefinition> propsInUpdatedVersion = ListUtils.emptyIfNull(fetchDerivedFromGenericType(serviceUpdate, null).getProperties());
1283 if (!StringUtils.equals(currentService.getDerivedFromGenericType(), serviceUpdate.getDerivedFromGenericType())) {
1284 return propsInUpdatedVersion;
1287 Map<String, PropertyDefinition> mapOfPropsInCurrentVersion = propsInCurrentVersion.stream()
1288 .collect(Collectors.toMap(prop -> prop.getName(), prop -> prop));
1289 Map<String, PropertyDefinition> mapOfPropsInUpdatedVersion = propsInUpdatedVersion.stream()
1290 .collect(Collectors.toMap(prop -> prop.getName(), prop -> prop));
1292 List<PropertyDefinition> propsToBeAdded = new ArrayList<>();
1293 for (Entry<String, PropertyDefinition> propertyInUpdatedVersion : mapOfPropsInUpdatedVersion.entrySet()) {
1294 if (mapOfPropsInCurrentVersion.containsKey(propertyInUpdatedVersion.getKey())) {
1295 if (!haveSameType(mapOfPropsInCurrentVersion.get(propertyInUpdatedVersion.getKey()), propertyInUpdatedVersion.getValue())) {
1296 propsToBeAdded.add(propertyInUpdatedVersion.getValue());
1299 propsToBeAdded.add(propertyInUpdatedVersion.getValue());
1303 return propsToBeAdded;
1307 private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
1308 if (updatedValue != null && !updatedValue.equals(originalValue)) {
1309 log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
1313 private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
1314 Boolean isEcompGeneratedCurr = currentService.isEcompGeneratedNaming();
1315 Boolean isEcompGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
1316 if (isEcompGeneratedUpdate != null && !isEcompGeneratedUpdate.equals(isEcompGeneratedCurr)) {
1317 currentService.setEcompGeneratedNaming(isEcompGeneratedUpdate);
1319 String namingPolicyUpdate = serviceUpdate.getNamingPolicy();
1320 if (currentService.isEcompGeneratedNaming() != null && currentService.isEcompGeneratedNaming()) {
1321 currentService.setNamingPolicy(namingPolicyUpdate);
1323 if (!StringUtils.isEmpty(namingPolicyUpdate)) {
1324 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
1326 currentService.setNamingPolicy("");
1330 private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate,
1331 AuditingActionEnum audatingAction) {
1332 String contactIdUpdated = serviceUpdate.getContactId();
1333 String contactIdCurrent = currentService.getContactId();
1334 if (!contactIdCurrent.equals(contactIdUpdated)) {
1335 componentContactIdValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1336 currentService.setContactId(contactIdUpdated.toLowerCase());
1338 return Either.left(true);
1341 private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate,
1342 AuditingActionEnum audatingAction) {
1343 List<String> tagsUpdated = serviceUpdate.getTags();
1344 List<String> tagsCurrent = currentService.getTags();
1345 if (tagsUpdated == null || tagsUpdated.isEmpty()) {
1346 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
1347 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
1348 return Either.right(responseFormat);
1350 if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
1351 componentTagsValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1352 currentService.setTags(tagsUpdated);
1354 return Either.left(true);
1357 private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate,
1358 AuditingActionEnum audatingAction) {
1359 String descriptionUpdated = serviceUpdate.getDescription();
1360 String descriptionCurrent = currentService.getDescription();
1361 if (!descriptionCurrent.equals(descriptionUpdated)) {
1362 componentDescriptionValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1363 currentService.setDescription(serviceUpdate.getDescription());
1365 return Either.left(true);
1368 private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate,
1369 AuditingActionEnum audatingAction) {
1370 String projectCodeUpdated = serviceUpdate.getProjectCode();
1371 String projectCodeCurrent = currentService.getProjectCode();
1372 if (StringUtils.isEmpty(projectCodeCurrent) || !projectCodeCurrent.equals(projectCodeUpdated)) {
1374 componentProjectCodeValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1375 } catch (ComponentException exp) {
1376 ResponseFormat errorRespons = exp.getResponseFormat();
1377 return Either.right(errorRespons);
1379 currentService.setProjectCode(projectCodeUpdated);
1381 return Either.left(true);
1384 private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified,
1385 AuditingActionEnum audatingAction) {
1386 String iconUpdated = serviceUpdate.getIcon();
1387 String iconCurrent = currentService.getIcon();
1388 if (!iconCurrent.equals(iconUpdated)) {
1389 if (!hasBeenCertified) {
1390 componentIconValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1391 currentService.setIcon(iconUpdated);
1393 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
1394 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
1395 return Either.right(errorResponse);
1398 return Either.left(true);
1401 private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate,
1402 boolean hasBeenCertified, AuditingActionEnum auditingAction) {
1403 String serviceNameUpdated = serviceUpdate.getName();
1404 String serviceNameCurrent = currentService.getName();
1405 if (!serviceNameCurrent.equals(serviceNameUpdated)) {
1406 if (!hasBeenCertified) {
1407 componentNameValidator.validateAndCorrectField(user, serviceUpdate, auditingAction);
1409 componentNameValidator.validateComponentNameUnique(user, serviceUpdate, auditingAction);
1410 } catch (ComponentException exp) {
1411 return Either.right(exp.getResponseFormat());
1413 currentService.setName(serviceNameUpdated);
1414 currentService.getComponentMetadataDefinition().getMetadataDataDefinition()
1415 .setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
1416 currentService.getComponentMetadataDefinition().getMetadataDataDefinition()
1417 .setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
1419 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
1420 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
1421 return Either.right(errorResponse);
1424 return Either.left(true);
1427 private void validateAndUpdateServiceType(Service currentService, Service updatedService) {
1428 String updatedServiceType = updatedService.getServiceType();
1429 String currentServiceType = currentService.getServiceType();
1430 if (!currentServiceType.equals(updatedServiceType)) {
1431 serviceTypeValidator.validateAndCorrectField(null, updatedService, null);
1432 currentService.setServiceType(updatedServiceType);
1436 private void validateAndUpdateServiceFunction(Service currentService, Service updatedService) {
1437 String updatedServiceFunction = updatedService.getServiceFunction();
1438 String currentServiceFunction = currentService.getServiceFunction();
1439 if (!currentServiceFunction.equals(updatedServiceFunction)) {
1440 serviceFunctionValidator.validateAndCorrectField(null, updatedService, null);
1441 currentService.setServiceFunction(updatedService.getServiceFunction());
1445 private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService,
1446 AuditingActionEnum auditingAction) {
1447 String updatedServiceRole = updatedService.getServiceRole();
1448 String currentServiceRole = currentService.getServiceRole();
1449 if (!currentServiceRole.equals(updatedServiceRole)) {
1451 serviceRoleValidator.validateAndCorrectField(user, updatedService, auditingAction);
1452 } catch (ComponentException exp) {
1453 ResponseFormat errorResponse = exp.getResponseFormat();
1454 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1455 return Either.right(errorResponse);
1457 currentService.setServiceRole(updatedServiceRole);
1459 return Either.left(true);
1462 private Either<Boolean, ResponseFormat> validateAndUpdateInstantiationTypeValue(User user, Service currentService, Service updatedService,
1463 AuditingActionEnum auditingAction) {
1464 String updatedInstaType = updatedService.getInstantiationType();
1465 String currentInstaType = currentService.getInstantiationType();
1466 if (!currentInstaType.equals(updatedInstaType)) {
1468 serviceInstantiationTypeValidator.validateAndCorrectField(user, updatedService, auditingAction);
1469 } catch (ComponentException exp) {
1470 ResponseFormat errorResponse = exp.getResponseFormat();
1471 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1472 return Either.right(errorResponse);
1474 currentService.setInstantiationType(updatedInstaType);
1476 return Either.left(true);
1479 private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate,
1480 boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1482 List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1483 List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1484 serviceCategoryValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1485 if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1486 if (!hasBeenCertified) {
1487 currentService.setCategories(categoryUpdated);
1489 log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1490 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1491 return Either.right(errorResponse);
1494 } catch (ComponentException exp) {
1495 return Either.right(exp.getResponseFormat());
1497 return Either.left(true);
1500 public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1501 Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1502 if (serviceResponseFormatEither.isRight()) {
1503 return Either.right(serviceResponseFormatEither.right().value());
1505 final ServiceRelations serviceRelations = new ForwardingPathUtils()
1506 .convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1507 return Either.left(serviceRelations);
1510 public void deleteServiceAllVersions(String serviceId, User user) {
1511 validateUserExists(user);
1512 Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1513 if (serviceStatus.isRight()) {
1514 log.debug("Failed to get service {}", serviceId);
1515 componentException(serviceStatus.right().value());
1517 Service service = serviceStatus.left().value();
1518 if (Boolean.FALSE.equals(service.isArchived())) {
1519 log.debug("The service, {}, requested for delete has not been archived.", serviceId);
1520 throw new ComponentException(ActionStatus.COMPONENT_NOT_ARCHIVED, serviceId);
1522 List<String> deletedServiceList = new ArrayList<>();
1524 String model = service.getModel();
1525 final Optional<Model> modelOptional = modelOperation.findModelByName(model);
1526 deletedServiceList = toscaOperationFacade.deleteService(service.getInvariantUUID(), true);
1527 if (log.isDebugEnabled()) {
1528 deletedServiceList.forEach(deletedS -> log.debug("Component {} was deleted.", deletedS));
1530 if (modelOptional.isPresent() && modelOptional.get().getModelType() == ModelTypeEnum.NORMATIVE_EXTENSION) {
1531 modelOperation.deleteModel(modelOptional.get(), false);
1533 toscaOperationFacade.commitAndCheck(service.getUniqueId());
1534 updateCatalog(service, ChangeTypeEnum.DELETE);
1535 } catch (ComponentException exception) {
1536 log.debug("Failed to delete service, {}, in ServiceServlet", serviceId);
1537 janusGraphDao.rollback();
1542 public ResponseFormat markServiceForDeletion(String serviceId, User user) {
1543 ResponseFormat responseFormat;
1544 validateUserExists(user);
1545 Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1546 if (serviceStatus.isRight()) {
1547 log.debug("failed to get service {}", serviceId);
1548 return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1550 Service service = serviceStatus.left().value();
1551 StorageOperationStatus result = StorageOperationStatus.OK;
1553 lockComponent(service, "Mark service to delete");
1554 result = markComponentToDelete(service);
1555 if (result == StorageOperationStatus.OK) {
1556 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1558 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1559 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1561 return responseFormat;
1562 } catch (ComponentException e) {
1563 return e.getResponseFormat();
1565 if (result == null || result != StorageOperationStatus.OK) {
1566 log.warn("operation failed. do rollback");
1567 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1568 janusGraphDao.rollback();
1570 log.debug("operation success. do commit");
1571 janusGraphDao.commit();
1573 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1577 public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1578 ResponseFormat responseFormat;
1579 String ecompErrorContext = "delete service";
1580 validateUserNotEmpty(user, ecompErrorContext);
1581 user = validateUserExists(user);
1582 Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1583 if (getResult.isRight()) {
1584 return getResult.right().value();
1586 Service service = getResult.left().value();
1587 StorageOperationStatus result = StorageOperationStatus.OK;
1589 lockComponent(service, "Mark service to delete");
1590 result = markComponentToDelete(service);
1591 if (result == StorageOperationStatus.OK) {
1592 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1594 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1595 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1597 return responseFormat;
1598 } catch (ComponentException e) {
1599 result = StorageOperationStatus.GENERAL_ERROR;
1600 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1602 if (result == null || result != StorageOperationStatus.OK) {
1603 log.warn("operation failed. do rollback");
1604 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1605 janusGraphDao.rollback();
1607 log.debug("operation success. do commit");
1608 janusGraphDao.commit();
1610 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1614 public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1615 String ecompErrorContext = "Get service";
1616 validateUserNotEmpty(user, ecompErrorContext);
1617 validateUserExists(user);
1618 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1619 if (storageStatus.isRight()) {
1620 log.debug("failed to get service by id {}", serviceId);
1621 return Either.right(componentsUtils
1622 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1624 if (!(storageStatus.left().value() instanceof Service)) {
1626 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1628 Service service = storageStatus.left().value();
1629 return Either.left(service);
1632 public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1633 validateUserExists(userId);
1634 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade
1635 .getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1636 if (storageStatus.isRight()) {
1637 log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1638 return Either.right(componentsUtils
1639 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE),
1642 Service service = storageStatus.left().value();
1643 return Either.left(service);
1646 @SuppressWarnings("unchecked")
1647 private void createMandatoryArtifactsData(Service service, User user) {
1648 // create mandatory artifacts
1650 // TODO it must be removed after that artifact uniqueId creation will be
1652 // moved to ArtifactOperation
1653 String serviceUniqueId = service.getUniqueId();
1654 Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1655 if (artifactMap == null) {
1656 artifactMap = new HashMap<>();
1658 Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
1659 .getInformationalServiceArtifacts();
1660 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1661 String category = service.getCategories().get(0).getName();
1662 boolean isCreateArtifact = true;
1663 if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1664 for (String exlude : exludeServiceCategory) {
1665 if (exlude.equalsIgnoreCase(category)) {
1666 isCreateArtifact = false;
1671 if (informationalServiceArtifacts != null && isCreateArtifact) {
1672 Set<String> keys = informationalServiceArtifacts.keySet();
1673 for (String informationalServiceArtifactName : keys) {
1674 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1675 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap,
1677 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1679 service.setArtifacts(artifactMap);
1683 private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user,
1684 Boolean isServiceApi) {
1685 ArtifactDefinition artifactInfo = artifactsBusinessLogic
1686 .createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1687 if (Boolean.TRUE.equals(isServiceApi)) {
1688 artifactInfo.setMandatory(false);
1689 artifactInfo.setServiceApi(true);
1691 return artifactInfo;
1694 private String getEnvNameFromConfiguration() {
1695 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1696 log.trace("Update environment name to be {}", configuredEnvName);
1697 return configuredEnvName;
1700 public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier,
1701 ServiceDistributionReqInfo data) {
1702 Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation
1703 .validateActivateServiceRequest(serviceId, envId, modifier, data);
1704 if (activationRequestInformationEither.isRight()) {
1705 return Either.right(activationRequestInformationEither.right().value());
1707 ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1708 String did = ThreadLocalsHolder.getUuid();
1709 Service service = activationRequestInformation.getServiceToActivate();
1710 return buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1713 private Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext,
1715 String envName = getEnvNameFromConfiguration();
1716 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1717 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1718 if (notifyServiceResponse == ActionStatus.OK) {
1719 return Either.left(did);
1721 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1722 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1723 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1724 return Either.right(error);
1728 public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1729 User user = validateUserExists(modifier.getUserId());
1730 validateUserRole(user, Collections.singletonList(Role.DESIGNER));
1731 Either<Service, ResponseFormat> result;
1732 ResponseFormat response;
1733 Service updatedService;
1734 String did = ThreadLocalsHolder.getUuid();
1736 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1737 if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1738 log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1739 envName = configuredEnvName;
1741 if (!kafkaHandler.isKafkaActive()) {
1743 ServletContext servletContext = request.getSession().getServletContext();
1744 boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1745 if (!isDistributionEngineUp) {
1746 BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1747 log.debug("Distribution Engine is DOWN");
1748 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1749 return Either.right(response);
1752 Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1753 if (serviceRes.isRight()) {
1754 log.debug("failed retrieving service");
1755 response = componentsUtils
1756 .getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1757 componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1758 new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()), ResourceVersionInfo.newBuilder().build(), did);
1759 return Either.right(response);
1761 Service service = serviceRes.left().value();
1762 if (Boolean.TRUE.equals(service.isArchived())) {
1763 log.info("Component is archived. Component id: {}", serviceId);
1764 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, service.getName()));
1766 if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1767 log.info("service {} is not available for distribution. Should be in certified state", service.getUniqueId());
1768 ResponseFormat responseFormat = componentsUtils
1769 .getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1770 return Either.right(responseFormat);
1772 String dcurrStatus = service.getDistributionStatus().name();
1773 String updatedStatus = dcurrStatus;
1774 StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1775 if (readyForDistribution == StorageOperationStatus.OK) {
1776 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1777 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1778 if (notifyServiceResponse == ActionStatus.OK) {
1779 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user,
1780 DistributionStatusEnum.DISTRIBUTED);
1781 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1782 updatedService = updateStateRes.left().value();
1783 updatedStatus = updatedService.getDistributionStatus().name();
1785 // The response is not relevant
1786 updatedService = service;
1788 ASDCKpiApi.countActivatedDistribution();
1789 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1790 result = Either.left(updatedService);
1792 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1793 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1794 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1795 result = Either.right(response);
1798 response = componentsUtils
1799 .getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution, ComponentTypeEnum.SERVICE), envName);
1800 result = Either.right(response);
1802 componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1803 new ResourceCommonInfo(service.getName(), ComponentTypeEnum.SERVICE.getValue()),
1804 ResourceVersionInfo.newBuilder().distributionStatus(dcurrStatus).build(),
1805 ResourceVersionInfo.newBuilder().distributionStatus(updatedStatus).build(), null, null, did);
1809 // convert to private after deletion of temp url
1810 public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1811 validateUserExists(user.getUserId());
1812 String serviceId = service.getUniqueId();
1813 lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1815 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
1816 if (result.isRight()) {
1817 janusGraphDao.rollback();
1818 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
1819 log.debug("service {} change distribution status failed", serviceId);
1820 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1822 janusGraphDao.commit();
1823 updateCatalog(service, ChangeTypeEnum.LIFECYCLE);
1824 return Either.left(result.left().value());
1826 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1830 public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
1831 validateUserExists(user.getUserId());
1832 log.debug("mark distribution deployed");
1833 AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
1834 Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
1835 if (getServiceResponse.isRight()) {
1836 BeEcompErrorManager.getInstance()
1837 .logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
1838 log.debug("service {} not found", serviceId);
1839 ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null,
1840 componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
1841 return Either.right(responseFormat);
1843 Service service = getServiceResponse.left().value();
1844 user = validateRoleForDeploy(did, user, auditAction, service);
1845 return checkDistributionAndDeploy(did, user, auditAction, service);
1848 public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1849 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
1850 // Only one VF Module Artifact per instance - add it to a list of one
1851 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
1852 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1855 private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock,
1856 boolean inTransaction, ComponentInstance ri) {
1857 List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
1858 if (ri.getOriginType() == OriginTypeEnum.VF) {
1859 asList = Arrays.asList(new VfModuleArtifactGenerator(modifier, ri, service, shouldLock, inTransaction));
1864 public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1865 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
1866 // Get All Deployment Artifacts
1867 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance)
1868 .filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
1869 // Filter in Only Heat Env
1870 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
1871 // Create ArtifactGenerator from those Artifacts
1873 depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction,
1874 resourceInstance.getUniqueId())).collect(Collectors.toList());
1875 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1878 private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service,
1879 Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
1880 // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
1883 if (service.getComponentInstances() != null) {
1884 List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream()
1885 .flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
1886 if (artifactGenList != null && !artifactGenList.isEmpty()) {
1887 Either<Service, ResponseFormat> callRes = checkDeploymentArtifact(artifactGenList);
1888 if (callRes != null) {
1893 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
1894 if (storageStatus.isRight()) {
1895 return Either.right(componentsUtils
1896 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1898 Service currentService = storageStatus.left().value();
1899 return Either.left(currentService);
1902 private <CallVal> Either<Service, ResponseFormat> checkDeploymentArtifact(List<ArtifactGenerator<CallVal>> artifactGenList) {
1903 for (ArtifactGenerator<CallVal> entry : artifactGenList) {
1904 Either<CallVal, ResponseFormat> callRes;
1906 callRes = entry.call();
1907 if (callRes.isRight()) {
1908 log.debug("Failed to generate artifact error : {}", callRes.right().value());
1909 return Either.right(callRes.right().value());
1911 } catch (Exception e) {
1912 log.debug("Failed to generate artifact exception : {}", e);
1913 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1919 private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction,
1921 boolean isDeployed = isDistributionDeployed(distributionId);
1923 return Either.left(service);
1925 Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
1926 if (distributionSuccess.isRight()) {
1927 return Either.right(distributionSuccess.right().value());
1929 log.debug("mark distribution {} as deployed - success", distributionId);
1931 .auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK",
1933 return Either.left(service);
1936 private boolean isDistributionDeployed(String distributionId) {
1937 Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao
1938 .getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
1939 boolean isDeployed = false;
1940 if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
1942 log.debug("distribution {} is already deployed", distributionId);
1948 protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
1949 log.trace("checkDistributionSuccess");
1950 // get all "DRequest" records for this distribution
1951 Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao
1952 .getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
1953 if (distRequestsResponse.isRight()) {
1954 ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
1955 return Either.right(error);
1957 List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
1958 if (distributionRequests.isEmpty()) {
1959 BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
1960 log.info("distribution {} is not found", did);
1961 ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
1962 return Either.right(error);
1964 boolean isRequestSucceeded = false;
1965 for (ResourceAdminEvent event : distributionRequests) {
1966 String eventStatus = event.getStatus();
1967 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1968 isRequestSucceeded = true;
1972 // get all "DNotify" records for this distribution
1973 Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao
1974 .getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
1975 if (distNotificationsResponse.isRight()) {
1976 ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
1977 return Either.right(error);
1979 List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
1980 boolean isNotificationsSucceeded = false;
1981 for (DistributionNotificationEvent event : distributionNotifications) {
1982 String eventStatus = event.getStatus();
1983 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1984 isNotificationsSucceeded = true;
1988 // if request failed OR there are notifications that failed
1989 if (!(isRequestSucceeded && isNotificationsSucceeded)) {
1990 log.info("distribution {} has failed", did);
1991 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1992 auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1993 return Either.right(error);
1995 return Either.left(true);
1998 private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status,
2000 ResponseFormat error = componentsUtils.getResponseFormat(status, params);
2001 String message = "";
2002 if (error.getMessageId() != null) {
2003 message = error.getMessageId() + ": ";
2005 message += error.getFormattedMessage();
2006 if (service != null) {
2008 .auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(),
2011 componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
2016 private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
2017 user = userAdmin.getUser(user.getUserId());
2018 log.debug("validate user role");
2019 List<Role> roles = new ArrayList<>();
2020 roles.add(Role.ADMIN);
2021 roles.add(Role.DESIGNER);
2023 validateUserRole(user, service, roles, auditAction, null);
2024 } catch (ByActionStatusComponentException e) {
2025 log.info("role {} is not allowed to perform this action", user.getRole());
2026 auditDeployError(did, user, auditAction, service, e.getActionStatus());
2033 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
2034 if (component instanceof Service) {
2035 Service service = (Service) component;
2036 Map<String, ArtifactDefinition> artifactMap = service.getDeploymentArtifacts();
2037 if (artifactMap == null) {
2038 artifactMap = new HashMap<>();
2040 service.setDeploymentArtifacts(artifactMap);
2041 } else if (component instanceof Resource) {
2042 Resource resource = (Resource) component;
2043 Map<String, ArtifactDefinition> artifactMap = resource.getDeploymentArtifacts();
2044 if (artifactMap == null) {
2045 artifactMap = new HashMap<>();
2047 Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
2048 .getDeploymentResourceArtifacts();
2049 if (deploymentResourceArtifacts != null) {
2050 Map<String, ArtifactDefinition> finalArtifactMap = artifactMap;
2051 deploymentResourceArtifacts.forEach((k, v) -> processDeploymentResourceArtifacts(user, resource, finalArtifactMap, k, v));
2053 resource.setDeploymentArtifacts(artifactMap);
2057 private void processDeploymentResourceArtifacts(User user, Resource resource, Map<String, ArtifactDefinition> artifactMap, String k, Object v) {
2058 Map<String, Object> artifactDetails = (Map<String, Object>) v;
2059 Object object = artifactDetails.get(PLACE_HOLDER_RESOURCE_TYPES);
2060 if (object != null) {
2061 List<String> artifactTypes = (List<String>) object;
2062 if (!artifactTypes.contains(resource.getResourceType().name())) {
2066 log.info("resource types for artifact placeholder {} were not defined. default is all resources", k);
2068 if (artifactsBusinessLogic != null) {
2069 ArtifactDefinition artifactDefinition = artifactsBusinessLogic
2070 .createArtifactPlaceHolderInfo(resource.getUniqueId(), k, (Map<String, Object>) v, user, ArtifactGroupTypeEnum.DEPLOYMENT);
2071 if (artifactDefinition != null && !artifactMap.containsKey(artifactDefinition.getArtifactLabel())) {
2072 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
2078 public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
2079 return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
2082 private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
2083 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context
2084 .getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
2085 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
2086 return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
2090 public ComponentInstanceBusinessLogic getComponentInstanceBL() {
2091 return componentInstanceBusinessLogic;
2095 public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
2096 validateUserExists(userId);
2097 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2098 if (getComponentRes.isRight()) {
2099 ResponseFormat responseFormat = componentsUtils
2100 .getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
2101 return Either.right(responseFormat);
2103 List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
2104 return Either.left(componentInstances);
2108 public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
2109 this.forwardingPathOperation = forwardingPathOperation;
2113 * updates group instance with new property values in case of successful update of group instance related component instance will be updated with
2114 * new modification time and related service will be updated with new last update date
2116 public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId,
2117 String componentInstanceId, String groupInstanceId,
2118 List<GroupInstanceProperty> newProperties) {
2119 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2120 Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
2121 Component component = null;
2122 Either<Boolean, ResponseFormat> lockResult = null;
2123 log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
2125 validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2126 if (validateUserAndComponentRes.isRight()) {
2127 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed. ", groupInstanceId, serviceId);
2128 actionResult = Either.right(validateUserAndComponentRes.right().value());
2130 if (actionResult == null) {
2131 component = validateUserAndComponentRes.left().value().getKey();
2132 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2133 if (lockResult.isRight()) {
2134 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
2135 actionResult = Either.right(lockResult.right().value());
2137 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
2140 if (actionResult == null) {
2141 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId,
2143 if (actionResult.isRight()) {
2144 log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ",
2145 groupInstanceId, actionResult.right().value().getFormattedMessage());
2148 } catch (Exception e) {
2149 log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2150 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2152 if (lockResult != null && lockResult.isLeft() && Boolean.TRUE.equals(lockResult.left().value())) {
2153 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2156 return actionResult;
2159 private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component,
2160 String componentInstanceId,
2161 String groupInstanceId,
2162 List<GroupInstanceProperty> newProperties) {
2163 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2164 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2165 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2166 ComponentInstance relatedComponentInstance = null;
2167 GroupInstance oldGroupInstance = null;
2168 Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2169 GroupInstance updatedGroupInstance = null;
2170 boolean inTransaction = true;
2171 findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2172 if (findGroupInstanceRes.isRight()) {
2173 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
2174 actionResult = Either.right(findGroupInstanceRes.right().value());
2176 if (actionResult == null) {
2177 oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2178 relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2179 updateGroupInstanceResult = groupBusinessLogic
2180 .validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
2181 if (updateGroupInstanceResult.isRight()) {
2182 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ",
2183 oldGroupInstance.getName());
2184 actionResult = Either.right(updateGroupInstanceResult.right().value());
2187 if (actionResult == null) {
2188 updatedGroupInstance = updateGroupInstanceResult.left().value();
2189 if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2190 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance,
2191 updatedGroupInstance, inTransaction);
2192 if (updateParentsModificationTimeRes.isRight()) {
2194 "#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ",
2195 oldGroupInstance.getName());
2196 actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2200 if (actionResult == null) {
2201 actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2203 return actionResult;
2206 private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(
2207 Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance, boolean inTranscation) {
2208 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2209 Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2210 Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic
2211 .updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2212 updatedGroupInstance.getModificationTime(), inTranscation);
2213 if (updateComponentInstanceRes.isRight()) {
2214 log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(),
2215 updatedGroupInstance.getName());
2216 actionResult = Either.right(updateComponentInstanceRes.right().value());
2218 serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2219 if (serviceMetadataUpdateResult.isRight()) {
2220 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ",
2221 component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2222 actionResult = Either.right(
2223 componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2225 actionResult = Either
2226 .left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2229 return actionResult;
2232 private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2233 Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2234 User currUser = null;
2235 Component component = null;
2236 Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2237 if (validationUserResult.isRight()) {
2238 log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2239 result = Either.right(validationUserResult.right().value());
2241 if (result == null) {
2242 currUser = validationUserResult.left().value();
2244 component = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2245 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2246 log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(),
2247 component.getCreatorUserId());
2248 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2250 } catch (ComponentException e) {
2251 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2252 result = Either.right(e.getResponseFormat());
2255 if (result == null) {
2256 result = Either.left(new ImmutablePair<>(component, currUser));
2261 private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component,
2262 String componentInstanceId,
2263 String groupInstanceId) {
2264 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2265 GroupInstance groupInstance = null;
2266 ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2267 if (foundComponentInstance == null) {
2268 log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2269 actionResult = Either.right(componentsUtils
2270 .getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service",
2271 component.getName()));
2272 } else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2273 groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst()
2275 if (groupInstance == null) {
2276 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2277 actionResult = Either.right(componentsUtils
2278 .getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId,
2279 foundComponentInstance.getName()));
2282 if (actionResult == null) {
2283 actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2285 return actionResult;
2288 private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2289 ComponentInstance componentInstance = null;
2290 if (isNotEmpty(component.getComponentInstances())) {
2291 componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst()
2294 return componentInstance;
2297 private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2298 User user = validateUser(modifier, ecompErrorContext, null, null, false);
2299 List<Role> roles = new ArrayList<>();
2300 roles.add(Role.ADMIN);
2301 roles.add(Role.DESIGNER);
2302 validateUserRole(user, roles);
2303 return Either.left(user);
2306 public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId,
2307 List<String> dataParamsToReturn) {
2308 ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2309 paramsToReturn.setIgnoreComponentInstancesProperties(false);
2310 Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2311 if (serviceResultEither.isRight()) {
2312 if (serviceResultEither.right().value() == StorageOperationStatus.NOT_FOUND) {
2313 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2314 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2316 log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2317 return Either.right(
2318 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2320 Service service = serviceResultEither.left().value();
2321 if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
2322 ListUtils.emptyIfNull(service.getInputs()).stream().filter(input -> CollectionUtils.isEmpty(input.getConstraints()))
2323 .forEach(input -> input.setConstraints(setInputConstraint(input)));
2325 UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2326 return Either.left(dataTransfer);
2329 @Autowired(required = false)
2330 public void setServiceCreationPluginList(List<ServiceCreationPlugin> serviceCreationPluginList) {
2331 this.serviceCreationPluginList = serviceCreationPluginList;
2334 public boolean isServiceExist(String serviceName) {
2335 return toscaOperationFacade.getLatestByServiceName(serviceName).isLeft();
2338 interface ArtifactGenerator<CallVal> extends Callable<Either<CallVal, ResponseFormat>> {
2343 @AllArgsConstructor(access = AccessLevel.PRIVATE)
2344 class HeatEnvArtifactGenerator implements ArtifactGenerator<ArtifactDefinition> {
2346 private ArtifactDefinition artifactDefinition;
2347 private Service service;
2348 private String resourceInstanceName;
2349 private User modifier;
2350 private boolean shouldLock;
2351 private boolean inTransaction;
2352 private String instanceId;
2355 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2356 return artifactsBusinessLogic
2357 .forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier,
2358 shouldLock, inTransaction, instanceId);
2362 @AllArgsConstructor(access = AccessLevel.PRIVATE)
2363 class VfModuleArtifactGenerator implements ArtifactGenerator<ArtifactDefinition> {
2366 private ComponentInstance componentInstance;
2367 private Service service;
2368 private boolean shouldLock;
2369 private boolean inTransaction;
2371 private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance,
2372 Service service, boolean shouldLock,
2373 boolean inTransaction) {
2374 ArtifactDefinition vfModuleArtifact = null;
2375 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
2376 Wrapper<String> payloadWrapper = new Wrapper<>();
2377 List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
2378 if (responseWrapper.isEmpty()) {
2379 fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
2381 if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
2382 vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
2384 if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
2385 vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper,
2386 responseWrapper, service);
2388 if (responseWrapper.isEmpty()) {
2389 return Either.left(vfModuleArtifact);
2391 return Either.right(responseWrapper.getInnerElement());
2395 private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
2396 List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
2397 if (groupsForCurrVF != null) {
2398 for (GroupInstance groupInstance : groupsForCurrVF) {
2399 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
2400 vfModulePayloads.add(modulePayload);
2402 vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
2403 final Gson gson = new GsonBuilder().setPrettyPrinting().create();
2404 String vfModulePayloadString = gson.toJson(vfModulePayloads);
2405 payloadWrapper.setInnerElement(vfModulePayloadString);
2409 private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper,
2410 Wrapper<ResponseFormat> responseWrapper) {
2411 ArtifactDefinition vfModuleAertifact = null;
2412 if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
2413 final Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream()
2414 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.getType())).findAny();
2415 if (optionalVfModuleArtifact.isPresent()) {
2416 vfModuleAertifact = optionalVfModuleArtifact.get();
2419 if (vfModuleAertifact == null) {
2420 Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service,
2421 payloadWrapper.getInnerElement());
2422 if (createVfModuleArtifact.isLeft()) {
2423 vfModuleAertifact = createVfModuleArtifact.left().value();
2425 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
2428 return vfModuleAertifact;
2431 private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
2432 if (currVF.getGroupInstances() != null) {
2433 currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(currVF.getDeploymentArtifacts()));
2435 return currVF.getGroupInstances();
2438 private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service,
2439 String vfModulePayloadString) {
2440 ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
2441 String newCheckSum = null;
2442 vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
2443 vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
2444 vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
2445 vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
2446 vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
2447 vfModuleArtifactDefinition.setTimeout(0);
2448 vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
2449 vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
2450 if (vfModulePayloadString != null) {
2451 newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
2453 vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
2454 Either<ArtifactDefinition, StorageOperationStatus> addArtifactToComponent = artifactToscaOperation
2455 .addArtifactToComponent(vfModuleArtifactDefinition, service, NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
2456 if (addArtifactToComponent.isLeft()) {
2457 return Either.left(addArtifactToComponent.left().value());
2460 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArtifactToComponent.right().value())));
2464 private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact,
2466 boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper,
2468 ArtifactDefinition result = null;
2469 Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic
2470 .generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock,
2471 inTransaction, System::currentTimeMillis, () -> Either.left(
2472 artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact,
2473 payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))),
2474 currVF.getUniqueId());
2475 if (eitherPayload.isLeft()) {
2476 result = eitherPayload.left().value();
2478 responseWrapper.setInnerElement(eitherPayload.right().value());
2480 if (result == null) {
2481 result = vfModuleArtifact;
2487 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2488 return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);