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;
59 import lombok.AccessLevel;
60 import lombok.AllArgsConstructor;
62 import org.apache.commons.collections.CollectionUtils;
63 import org.apache.commons.collections.MapUtils;
64 import org.apache.commons.collections4.ListUtils;
65 import org.apache.commons.lang3.StringUtils;
66 import org.apache.commons.lang3.tuple.ImmutablePair;
67 import org.openecomp.sdc.be.catalog.enums.ChangeTypeEnum;
68 import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine;
69 import org.openecomp.sdc.be.components.distribution.engine.INotificationData;
70 import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload;
71 import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic;
72 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
73 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
74 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
75 import org.openecomp.sdc.be.components.kafka.KafkaHandler;
76 import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
77 import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
78 import org.openecomp.sdc.be.components.utils.PropertiesUtils;
79 import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
80 import org.openecomp.sdc.be.components.validation.component.ComponentContactIdValidator;
81 import org.openecomp.sdc.be.components.validation.component.ComponentDescriptionValidator;
82 import org.openecomp.sdc.be.components.validation.component.ComponentIconValidator;
83 import org.openecomp.sdc.be.components.validation.component.ComponentNameValidator;
84 import org.openecomp.sdc.be.components.validation.component.ComponentProjectCodeValidator;
85 import org.openecomp.sdc.be.components.validation.component.ComponentTagsValidator;
86 import org.openecomp.sdc.be.components.validation.component.ComponentValidator;
87 import org.openecomp.sdc.be.components.validation.service.ServiceCategoryValidator;
88 import org.openecomp.sdc.be.components.validation.service.ServiceFunctionValidator;
89 import org.openecomp.sdc.be.components.validation.service.ServiceInstantiationTypeValidator;
90 import org.openecomp.sdc.be.components.validation.service.ServiceRoleValidator;
91 import org.openecomp.sdc.be.components.validation.service.ServiceTypeValidator;
92 import org.openecomp.sdc.be.components.validation.service.ServiceValidator;
93 import org.openecomp.sdc.be.config.BeEcompErrorManager;
94 import org.openecomp.sdc.be.config.ConfigurationManager;
95 import org.openecomp.sdc.be.dao.api.ActionStatus;
96 import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
97 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
98 import org.openecomp.sdc.be.datamodel.ServiceRelations;
99 import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil;
100 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
101 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
102 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
103 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
104 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
105 import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition;
106 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
107 import org.openecomp.sdc.be.datatypes.elements.ToscaFunction;
108 import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType;
109 import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
110 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
111 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
112 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
113 import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum;
114 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
115 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
116 import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo;
117 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
118 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
119 import org.openecomp.sdc.be.model.ArtifactDefinition;
120 import org.openecomp.sdc.be.model.CapabilityDefinition;
121 import org.openecomp.sdc.be.model.Component;
122 import org.openecomp.sdc.be.model.ComponentInstance;
123 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
124 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
125 import org.openecomp.sdc.be.model.ComponentParametersView;
126 import org.openecomp.sdc.be.model.DistributionStatusEnum;
127 import org.openecomp.sdc.be.model.GroupInstance;
128 import org.openecomp.sdc.be.model.GroupInstanceProperty;
129 import org.openecomp.sdc.be.model.InputDefinition;
130 import org.openecomp.sdc.be.model.InterfaceDefinition;
131 import org.openecomp.sdc.be.model.LifecycleStateEnum;
132 import org.openecomp.sdc.be.model.Model;
133 import org.openecomp.sdc.be.model.Operation;
134 import org.openecomp.sdc.be.model.PropertyDefinition;
135 import org.openecomp.sdc.be.model.Resource;
136 import org.openecomp.sdc.be.model.Service;
137 import org.openecomp.sdc.be.model.User;
138 import org.openecomp.sdc.be.model.category.CategoryDefinition;
139 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
140 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ForwardingPathOperation;
141 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
142 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
143 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
144 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
145 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
146 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
147 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
148 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
149 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
150 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
151 import org.openecomp.sdc.be.plugins.ServiceCreationPlugin;
152 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
153 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
154 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
155 import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent;
156 import org.openecomp.sdc.be.resources.data.auditing.DistributionDeployEvent;
157 import org.openecomp.sdc.be.resources.data.auditing.DistributionNotificationEvent;
158 import org.openecomp.sdc.be.resources.data.auditing.ResourceAdminEvent;
159 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
160 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
161 import org.openecomp.sdc.be.types.ServiceConsumptionData;
162 import org.openecomp.sdc.be.types.ServiceConsumptionSource;
163 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
164 import org.openecomp.sdc.be.user.Role;
165 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
166 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
167 import org.openecomp.sdc.common.api.Constants;
168 import org.openecomp.sdc.common.datastructure.Wrapper;
169 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
170 import org.openecomp.sdc.common.log.wrappers.Logger;
171 import org.openecomp.sdc.common.util.GeneralUtility;
172 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
173 import org.openecomp.sdc.common.util.ValidationUtils;
174 import org.openecomp.sdc.exception.ResponseFormat;
175 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
176 import org.springframework.beans.factory.annotation.Autowired;
177 import org.springframework.http.HttpStatus;
178 import org.springframework.web.context.WebApplicationContext;
180 @org.springframework.stereotype.Component("serviceBusinessLogic")
181 public class ServiceBusinessLogic extends ComponentBusinessLogic {
183 private static final String IS_VALID = "isValid";
184 private static final String THE_SERVICE_WITH_SYSTEM_NAME_LOCKED = "The service with system name {} locked. ";
185 private static final String FAILED_TO_LOCK_SERVICE_RESPONSE_IS = "Failed to lock service {}. Response is {}. ";
186 private static final String AUDIT_BEFORE_SENDING_RESPONSE = "audit before sending response";
187 private static final Logger log = Logger.getLogger(ServiceBusinessLogic.class);
188 private static final String INITIAL_VERSION = "0.1";
189 private static final String STATUS_SUCCESS_200 = "200";
190 private static final String STATUS_DEPLOYED = "DEPLOYED";
191 private static final String PLACE_HOLDER_RESOURCE_TYPES = "validForResourceTypes";
192 private final IDistributionEngine distributionEngine;
193 private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
194 private final ServiceDistributionValidation serviceDistributionValidation;
195 private final ForwardingPathValidator forwardingPathValidator;
196 private final UiComponentDataConverter uiComponentDataConverter;
197 private final ModelOperation modelOperation;
198 private final ServiceRoleValidator serviceRoleValidator;
199 private final ServiceInstantiationTypeValidator serviceInstantiationTypeValidator;
200 private final ServiceCategoryValidator serviceCategoryValidator;
201 private final ServiceValidator serviceValidator;
202 private final GroupBusinessLogic groupBusinessLogic;
203 private final KafkaHandler kafkaHandler;
204 private ForwardingPathOperation forwardingPathOperation;
205 private AuditCassandraDao auditCassandraDao;
206 private ServiceTypeValidator serviceTypeValidator;
207 private List<ServiceCreationPlugin> serviceCreationPluginList;
208 private ServiceFunctionValidator serviceFunctionValidator;
210 public ServiceBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation,
211 IGroupTypeOperation groupTypeOperation, GroupBusinessLogic groupBusinessLogic, InterfaceOperation interfaceOperation,
212 InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactsBusinessLogic artifactsBusinessLogic,
213 IDistributionEngine distributionEngine, ComponentInstanceBusinessLogic componentInstanceBusinessLogic,
214 ServiceDistributionValidation serviceDistributionValidation, ForwardingPathValidator forwardingPathValidator,
215 UiComponentDataConverter uiComponentDataConverter, ArtifactsOperations artifactToscaOperation,
216 ComponentContactIdValidator componentContactIdValidator, ComponentNameValidator componentNameValidator,
217 ComponentTagsValidator componentTagsValidator, ComponentValidator componentValidator,
218 ComponentIconValidator componentIconValidator, ComponentProjectCodeValidator componentProjectCodeValidator,
219 ComponentDescriptionValidator componentDescriptionValidator, ModelOperation modelOperation,
220 final ServiceRoleValidator serviceRoleValidator,
221 final ServiceInstantiationTypeValidator serviceInstantiationTypeValidator,
222 final ServiceCategoryValidator serviceCategoryValidator, final ServiceValidator serviceValidator, 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 service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
804 service.setContactId(service.getContactId().toLowerCase());
805 // Generate invariant UUID - must be here and not in operation since it
807 // should stay constant during clone
808 String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
809 service.setInvariantUUID(invariantUUID);
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().collect(Collectors.toMap(prop -> prop.getName(), prop -> prop));
1288 Map<String, PropertyDefinition> mapOfPropsInUpdatedVersion = propsInUpdatedVersion.stream().collect(Collectors.toMap(prop -> prop.getName(), prop -> prop));
1290 List<PropertyDefinition> propsToBeAdded = new ArrayList<>();
1291 for (Entry<String, PropertyDefinition> propertyInUpdatedVersion: mapOfPropsInUpdatedVersion.entrySet()) {
1292 if (mapOfPropsInCurrentVersion.containsKey(propertyInUpdatedVersion.getKey())) {
1293 if (!haveSameType(mapOfPropsInCurrentVersion.get(propertyInUpdatedVersion.getKey()), propertyInUpdatedVersion.getValue())) {
1294 propsToBeAdded.add(propertyInUpdatedVersion.getValue());
1297 propsToBeAdded.add(propertyInUpdatedVersion.getValue());
1301 return propsToBeAdded;
1305 private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
1306 if (updatedValue != null && !updatedValue.equals(originalValue)) {
1307 log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
1311 private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
1312 Boolean isEcompGeneratedCurr = currentService.isEcompGeneratedNaming();
1313 Boolean isEcompGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
1314 if (isEcompGeneratedUpdate != null && !isEcompGeneratedUpdate.equals(isEcompGeneratedCurr)) {
1315 currentService.setEcompGeneratedNaming(isEcompGeneratedUpdate);
1317 String namingPolicyUpdate = serviceUpdate.getNamingPolicy();
1318 if (currentService.isEcompGeneratedNaming() != null && currentService.isEcompGeneratedNaming()) {
1319 currentService.setNamingPolicy(namingPolicyUpdate);
1321 if (!StringUtils.isEmpty(namingPolicyUpdate)) {
1322 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
1324 currentService.setNamingPolicy("");
1328 private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate,
1329 AuditingActionEnum audatingAction) {
1330 String contactIdUpdated = serviceUpdate.getContactId();
1331 String contactIdCurrent = currentService.getContactId();
1332 if (!contactIdCurrent.equals(contactIdUpdated)) {
1333 componentContactIdValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1334 currentService.setContactId(contactIdUpdated.toLowerCase());
1336 return Either.left(true);
1339 private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate,
1340 AuditingActionEnum audatingAction) {
1341 List<String> tagsUpdated = serviceUpdate.getTags();
1342 List<String> tagsCurrent = currentService.getTags();
1343 if (tagsUpdated == null || tagsUpdated.isEmpty()) {
1344 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
1345 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
1346 return Either.right(responseFormat);
1348 if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
1349 componentTagsValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1350 currentService.setTags(tagsUpdated);
1352 return Either.left(true);
1355 private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate,
1356 AuditingActionEnum audatingAction) {
1357 String descriptionUpdated = serviceUpdate.getDescription();
1358 String descriptionCurrent = currentService.getDescription();
1359 if (!descriptionCurrent.equals(descriptionUpdated)) {
1360 componentDescriptionValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1361 currentService.setDescription(serviceUpdate.getDescription());
1363 return Either.left(true);
1366 private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate,
1367 AuditingActionEnum audatingAction) {
1368 String projectCodeUpdated = serviceUpdate.getProjectCode();
1369 String projectCodeCurrent = currentService.getProjectCode();
1370 if (StringUtils.isEmpty(projectCodeCurrent) || !projectCodeCurrent.equals(projectCodeUpdated)) {
1372 componentProjectCodeValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1373 } catch (ComponentException exp) {
1374 ResponseFormat errorRespons = exp.getResponseFormat();
1375 return Either.right(errorRespons);
1377 currentService.setProjectCode(projectCodeUpdated);
1379 return Either.left(true);
1382 private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified,
1383 AuditingActionEnum audatingAction) {
1384 String iconUpdated = serviceUpdate.getIcon();
1385 String iconCurrent = currentService.getIcon();
1386 if (!iconCurrent.equals(iconUpdated)) {
1387 if (!hasBeenCertified) {
1388 componentIconValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1389 currentService.setIcon(iconUpdated);
1391 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
1392 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
1393 return Either.right(errorResponse);
1396 return Either.left(true);
1399 private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate,
1400 boolean hasBeenCertified, AuditingActionEnum auditingAction) {
1401 String serviceNameUpdated = serviceUpdate.getName();
1402 String serviceNameCurrent = currentService.getName();
1403 if (!serviceNameCurrent.equals(serviceNameUpdated)) {
1404 if (!hasBeenCertified) {
1405 componentNameValidator.validateAndCorrectField(user, serviceUpdate, auditingAction);
1407 componentNameValidator.validateComponentNameUnique(user, serviceUpdate, auditingAction);
1408 } catch (ComponentException exp) {
1409 return Either.right(exp.getResponseFormat());
1411 currentService.setName(serviceNameUpdated);
1412 currentService.getComponentMetadataDefinition().getMetadataDataDefinition()
1413 .setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
1414 currentService.getComponentMetadataDefinition().getMetadataDataDefinition()
1415 .setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
1417 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
1418 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
1419 return Either.right(errorResponse);
1422 return Either.left(true);
1425 private void validateAndUpdateServiceType(Service currentService, Service updatedService) {
1426 String updatedServiceType = updatedService.getServiceType();
1427 String currentServiceType = currentService.getServiceType();
1428 if (!currentServiceType.equals(updatedServiceType)) {
1429 serviceTypeValidator.validateAndCorrectField(null, updatedService, null);
1430 currentService.setServiceType(updatedServiceType);
1434 private void validateAndUpdateServiceFunction(Service currentService, Service updatedService) {
1435 String updatedServiceFunction = updatedService.getServiceFunction();
1436 String currentServiceFunction = currentService.getServiceFunction();
1437 if (!currentServiceFunction.equals(updatedServiceFunction)) {
1438 serviceFunctionValidator.validateAndCorrectField(null, updatedService, null);
1439 currentService.setServiceFunction(updatedService.getServiceFunction());
1443 private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService,
1444 AuditingActionEnum auditingAction) {
1445 String updatedServiceRole = updatedService.getServiceRole();
1446 String currentServiceRole = currentService.getServiceRole();
1447 if (!currentServiceRole.equals(updatedServiceRole)) {
1449 serviceRoleValidator.validateAndCorrectField(user, updatedService, auditingAction);
1450 } catch (ComponentException exp) {
1451 ResponseFormat errorResponse = exp.getResponseFormat();
1452 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1453 return Either.right(errorResponse);
1455 currentService.setServiceRole(updatedServiceRole);
1457 return Either.left(true);
1460 private Either<Boolean, ResponseFormat> validateAndUpdateInstantiationTypeValue(User user, Service currentService, Service updatedService,
1461 AuditingActionEnum auditingAction) {
1462 String updatedInstaType = updatedService.getInstantiationType();
1463 String currentInstaType = currentService.getInstantiationType();
1464 if (!currentInstaType.equals(updatedInstaType)) {
1466 serviceInstantiationTypeValidator.validateAndCorrectField(user, updatedService, auditingAction);
1467 } catch (ComponentException exp) {
1468 ResponseFormat errorResponse = exp.getResponseFormat();
1469 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1470 return Either.right(errorResponse);
1472 currentService.setInstantiationType(updatedInstaType);
1474 return Either.left(true);
1477 private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate,
1478 boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1480 List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1481 List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1482 serviceCategoryValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1483 if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1484 if (!hasBeenCertified) {
1485 currentService.setCategories(categoryUpdated);
1487 log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1488 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1489 return Either.right(errorResponse);
1492 } catch (ComponentException exp) {
1493 return Either.right(exp.getResponseFormat());
1495 return Either.left(true);
1498 public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1499 Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1500 if (serviceResponseFormatEither.isRight()) {
1501 return Either.right(serviceResponseFormatEither.right().value());
1503 final ServiceRelations serviceRelations = new ForwardingPathUtils()
1504 .convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1505 return Either.left(serviceRelations);
1508 public void deleteServiceAllVersions(String serviceId, User user) {
1509 validateUserExists(user);
1510 Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1511 if (serviceStatus.isRight()) {
1512 log.debug("Failed to get service {}", serviceId);
1513 componentException(serviceStatus.right().value());
1515 Service service = serviceStatus.left().value();
1516 if (Boolean.FALSE.equals(service.isArchived())) {
1517 log.debug("The service, {}, requested for delete has not been archived.", serviceId);
1518 throw new ComponentException(ActionStatus.COMPONENT_NOT_ARCHIVED, serviceId);
1520 List<String> deletedServiceList = new ArrayList<>();
1522 String model = service.getModel();
1523 final Optional<Model> modelOptional = modelOperation.findModelByName(model);
1524 deletedServiceList = toscaOperationFacade.deleteService(service.getInvariantUUID(), true);
1525 if (log.isDebugEnabled()) {
1526 deletedServiceList.forEach(deletedS -> log.debug("Component {} was deleted.", deletedS));
1528 if (modelOptional.isPresent() && modelOptional.get().getModelType() == ModelTypeEnum.NORMATIVE_EXTENSION) {
1529 modelOperation.deleteModel(modelOptional.get(), false);
1531 toscaOperationFacade.commitAndCheck(service.getUniqueId());
1532 updateCatalog(service, ChangeTypeEnum.DELETE);
1533 } catch (ComponentException exception) {
1534 log.debug("Failed to delete service, {}, in ServiceServlet", serviceId);
1535 janusGraphDao.rollback();
1540 public ResponseFormat markServiceForDeletion(String serviceId, User user) {
1541 ResponseFormat responseFormat;
1542 validateUserExists(user);
1543 Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1544 if (serviceStatus.isRight()) {
1545 log.debug("failed to get service {}", serviceId);
1546 return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1548 Service service = serviceStatus.left().value();
1549 StorageOperationStatus result = StorageOperationStatus.OK;
1551 lockComponent(service, "Mark service to delete");
1552 result = markComponentToDelete(service);
1553 if (result == StorageOperationStatus.OK) {
1554 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1556 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1557 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1559 return responseFormat;
1560 } catch (ComponentException e) {
1561 return e.getResponseFormat();
1563 if (result == null || result != StorageOperationStatus.OK) {
1564 log.warn("operation failed. do rollback");
1565 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1566 janusGraphDao.rollback();
1568 log.debug("operation success. do commit");
1569 janusGraphDao.commit();
1571 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1575 public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1576 ResponseFormat responseFormat;
1577 String ecompErrorContext = "delete service";
1578 validateUserNotEmpty(user, ecompErrorContext);
1579 user = validateUserExists(user);
1580 Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1581 if (getResult.isRight()) {
1582 return getResult.right().value();
1584 Service service = getResult.left().value();
1585 StorageOperationStatus result = StorageOperationStatus.OK;
1587 lockComponent(service, "Mark service to delete");
1588 result = markComponentToDelete(service);
1589 if (result == StorageOperationStatus.OK) {
1590 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1592 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1593 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1595 return responseFormat;
1596 } catch (ComponentException e) {
1597 result = StorageOperationStatus.GENERAL_ERROR;
1598 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1600 if (result == null || result != StorageOperationStatus.OK) {
1601 log.warn("operation failed. do rollback");
1602 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1603 janusGraphDao.rollback();
1605 log.debug("operation success. do commit");
1606 janusGraphDao.commit();
1608 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1612 public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1613 String ecompErrorContext = "Get service";
1614 validateUserNotEmpty(user, ecompErrorContext);
1615 validateUserExists(user);
1616 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1617 if (storageStatus.isRight()) {
1618 log.debug("failed to get service by id {}", serviceId);
1619 return Either.right(componentsUtils
1620 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1622 if (!(storageStatus.left().value() instanceof Service)) {
1624 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1626 Service service = storageStatus.left().value();
1627 return Either.left(service);
1630 public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1631 validateUserExists(userId);
1632 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade
1633 .getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1634 if (storageStatus.isRight()) {
1635 log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1636 return Either.right(componentsUtils
1637 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE),
1640 Service service = storageStatus.left().value();
1641 return Either.left(service);
1644 @SuppressWarnings("unchecked")
1645 private void createMandatoryArtifactsData(Service service, User user) {
1646 // create mandatory artifacts
1648 // TODO it must be removed after that artifact uniqueId creation will be
1650 // moved to ArtifactOperation
1651 String serviceUniqueId = service.getUniqueId();
1652 Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1653 if (artifactMap == null) {
1654 artifactMap = new HashMap<>();
1656 Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
1657 .getInformationalServiceArtifacts();
1658 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1659 String category = service.getCategories().get(0).getName();
1660 boolean isCreateArtifact = true;
1661 if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1662 for (String exlude : exludeServiceCategory) {
1663 if (exlude.equalsIgnoreCase(category)) {
1664 isCreateArtifact = false;
1669 if (informationalServiceArtifacts != null && isCreateArtifact) {
1670 Set<String> keys = informationalServiceArtifacts.keySet();
1671 for (String informationalServiceArtifactName : keys) {
1672 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1673 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap,
1675 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1677 service.setArtifacts(artifactMap);
1681 private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user,
1682 Boolean isServiceApi) {
1683 ArtifactDefinition artifactInfo = artifactsBusinessLogic
1684 .createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1685 if (Boolean.TRUE.equals(isServiceApi)) {
1686 artifactInfo.setMandatory(false);
1687 artifactInfo.setServiceApi(true);
1689 return artifactInfo;
1692 private String getEnvNameFromConfiguration() {
1693 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1694 log.trace("Update environment name to be {}", configuredEnvName);
1695 return configuredEnvName;
1698 public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier,
1699 ServiceDistributionReqInfo data) {
1700 Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation
1701 .validateActivateServiceRequest(serviceId, envId, modifier, data);
1702 if (activationRequestInformationEither.isRight()) {
1703 return Either.right(activationRequestInformationEither.right().value());
1705 ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1706 String did = ThreadLocalsHolder.getUuid();
1707 Service service = activationRequestInformation.getServiceToActivate();
1708 return buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1711 private Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext,
1713 String envName = getEnvNameFromConfiguration();
1714 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1715 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1716 if (notifyServiceResponse == ActionStatus.OK) {
1717 return Either.left(did);
1719 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1720 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1721 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1722 return Either.right(error);
1726 public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1727 User user = validateUserExists(modifier.getUserId());
1728 validateUserRole(user, Collections.singletonList(Role.DESIGNER));
1729 Either<Service, ResponseFormat> result;
1730 ResponseFormat response;
1731 Service updatedService;
1732 String did = ThreadLocalsHolder.getUuid();
1734 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1735 if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1736 log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1737 envName = configuredEnvName;
1739 if (!kafkaHandler.isKafkaActive()) {
1741 ServletContext servletContext = request.getSession().getServletContext();
1742 boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1743 if (!isDistributionEngineUp) {
1744 BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1745 log.debug("Distribution Engine is DOWN");
1746 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1747 return Either.right(response);
1750 Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1751 if (serviceRes.isRight()) {
1752 log.debug("failed retrieving service");
1753 response = componentsUtils
1754 .getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1755 componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1756 new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()), ResourceVersionInfo.newBuilder().build(), did);
1757 return Either.right(response);
1759 Service service = serviceRes.left().value();
1760 if (Boolean.TRUE.equals(service.isArchived())) {
1761 log.info("Component is archived. Component id: {}", serviceId);
1762 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, service.getName()));
1764 if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1765 log.info("service {} is not available for distribution. Should be in certified state", service.getUniqueId());
1766 ResponseFormat responseFormat = componentsUtils
1767 .getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1768 return Either.right(responseFormat);
1770 String dcurrStatus = service.getDistributionStatus().name();
1771 String updatedStatus = dcurrStatus;
1772 StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1773 if (readyForDistribution == StorageOperationStatus.OK) {
1774 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1775 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1776 if (notifyServiceResponse == ActionStatus.OK) {
1777 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user,
1778 DistributionStatusEnum.DISTRIBUTED);
1779 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1780 updatedService = updateStateRes.left().value();
1781 updatedStatus = updatedService.getDistributionStatus().name();
1783 // The response is not relevant
1784 updatedService = service;
1786 ASDCKpiApi.countActivatedDistribution();
1787 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1788 result = Either.left(updatedService);
1790 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1791 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1792 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1793 result = Either.right(response);
1796 response = componentsUtils
1797 .getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution, ComponentTypeEnum.SERVICE), envName);
1798 result = Either.right(response);
1800 componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1801 new ResourceCommonInfo(service.getName(), ComponentTypeEnum.SERVICE.getValue()),
1802 ResourceVersionInfo.newBuilder().distributionStatus(dcurrStatus).build(),
1803 ResourceVersionInfo.newBuilder().distributionStatus(updatedStatus).build(), null, null, did);
1807 // convert to private after deletion of temp url
1808 public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1809 validateUserExists(user.getUserId());
1810 String serviceId = service.getUniqueId();
1811 lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1813 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
1814 if (result.isRight()) {
1815 janusGraphDao.rollback();
1816 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
1817 log.debug("service {} change distribution status failed", serviceId);
1818 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1820 janusGraphDao.commit();
1821 updateCatalog(service, ChangeTypeEnum.LIFECYCLE);
1822 return Either.left(result.left().value());
1824 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1828 public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
1829 validateUserExists(user.getUserId());
1830 log.debug("mark distribution deployed");
1831 AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
1832 Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
1833 if (getServiceResponse.isRight()) {
1834 BeEcompErrorManager.getInstance()
1835 .logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
1836 log.debug("service {} not found", serviceId);
1837 ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null,
1838 componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
1839 return Either.right(responseFormat);
1841 Service service = getServiceResponse.left().value();
1842 user = validateRoleForDeploy(did, user, auditAction, service);
1843 return checkDistributionAndDeploy(did, user, auditAction, service);
1846 public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1847 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
1848 // Only one VF Module Artifact per instance - add it to a list of one
1849 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
1850 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1853 private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock,
1854 boolean inTransaction, ComponentInstance ri) {
1855 List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
1856 if (ri.getOriginType() == OriginTypeEnum.VF) {
1857 asList = Arrays.asList(new VfModuleArtifactGenerator(modifier, ri, service, shouldLock, inTransaction));
1862 public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1863 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
1864 // Get All Deployment Artifacts
1865 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance)
1866 .filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
1867 // Filter in Only Heat Env
1868 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
1869 // Create ArtifactGenerator from those Artifacts
1871 depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction,
1872 resourceInstance.getUniqueId())).collect(Collectors.toList());
1873 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1876 private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service,
1877 Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
1878 // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
1881 if (service.getComponentInstances() != null) {
1882 List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream()
1883 .flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
1884 if (artifactGenList != null && !artifactGenList.isEmpty()) {
1885 Either<Service, ResponseFormat> callRes = checkDeploymentArtifact(artifactGenList);
1886 if (callRes != null) {
1891 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
1892 if (storageStatus.isRight()) {
1893 return Either.right(componentsUtils
1894 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1896 Service currentService = storageStatus.left().value();
1897 return Either.left(currentService);
1900 private <CallVal> Either<Service, ResponseFormat> checkDeploymentArtifact(List<ArtifactGenerator<CallVal>> artifactGenList) {
1901 for (ArtifactGenerator<CallVal> entry : artifactGenList) {
1902 Either<CallVal, ResponseFormat> callRes;
1904 callRes = entry.call();
1905 if (callRes.isRight()) {
1906 log.debug("Failed to generate artifact error : {}", callRes.right().value());
1907 return Either.right(callRes.right().value());
1909 } catch (Exception e) {
1910 log.debug("Failed to generate artifact exception : {}", e);
1911 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1917 private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction,
1919 boolean isDeployed = isDistributionDeployed(distributionId);
1921 return Either.left(service);
1923 Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
1924 if (distributionSuccess.isRight()) {
1925 return Either.right(distributionSuccess.right().value());
1927 log.debug("mark distribution {} as deployed - success", distributionId);
1929 .auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK",
1931 return Either.left(service);
1934 private boolean isDistributionDeployed(String distributionId) {
1935 Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao
1936 .getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
1937 boolean isDeployed = false;
1938 if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
1940 log.debug("distribution {} is already deployed", distributionId);
1946 protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
1947 log.trace("checkDistributionSuccess");
1948 // get all "DRequest" records for this distribution
1949 Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao
1950 .getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
1951 if (distRequestsResponse.isRight()) {
1952 ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
1953 return Either.right(error);
1955 List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
1956 if (distributionRequests.isEmpty()) {
1957 BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
1958 log.info("distribution {} is not found", did);
1959 ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
1960 return Either.right(error);
1962 boolean isRequestSucceeded = false;
1963 for (ResourceAdminEvent event : distributionRequests) {
1964 String eventStatus = event.getStatus();
1965 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1966 isRequestSucceeded = true;
1970 // get all "DNotify" records for this distribution
1971 Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao
1972 .getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
1973 if (distNotificationsResponse.isRight()) {
1974 ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
1975 return Either.right(error);
1977 List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
1978 boolean isNotificationsSucceeded = false;
1979 for (DistributionNotificationEvent event : distributionNotifications) {
1980 String eventStatus = event.getStatus();
1981 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1982 isNotificationsSucceeded = true;
1986 // if request failed OR there are notifications that failed
1987 if (!(isRequestSucceeded && isNotificationsSucceeded)) {
1988 log.info("distribution {} has failed", did);
1989 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1990 auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1991 return Either.right(error);
1993 return Either.left(true);
1996 private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status,
1998 ResponseFormat error = componentsUtils.getResponseFormat(status, params);
1999 String message = "";
2000 if (error.getMessageId() != null) {
2001 message = error.getMessageId() + ": ";
2003 message += error.getFormattedMessage();
2004 if (service != null) {
2006 .auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(),
2009 componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
2014 private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
2015 user = userAdmin.getUser(user.getUserId());
2016 log.debug("validate user role");
2017 List<Role> roles = new ArrayList<>();
2018 roles.add(Role.ADMIN);
2019 roles.add(Role.DESIGNER);
2021 validateUserRole(user, service, roles, auditAction, null);
2022 } catch (ByActionStatusComponentException e) {
2023 log.info("role {} is not allowed to perform this action", user.getRole());
2024 auditDeployError(did, user, auditAction, service, e.getActionStatus());
2031 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
2032 if (component instanceof Service) {
2033 Service service = (Service) component;
2034 Map<String, ArtifactDefinition> artifactMap = service.getDeploymentArtifacts();
2035 if (artifactMap == null) {
2036 artifactMap = new HashMap<>();
2038 service.setDeploymentArtifacts(artifactMap);
2039 } else if (component instanceof Resource) {
2040 Resource resource = (Resource) component;
2041 Map<String, ArtifactDefinition> artifactMap = resource.getDeploymentArtifacts();
2042 if (artifactMap == null) {
2043 artifactMap = new HashMap<>();
2045 Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
2046 .getDeploymentResourceArtifacts();
2047 if (deploymentResourceArtifacts != null) {
2048 Map<String, ArtifactDefinition> finalArtifactMap = artifactMap;
2049 deploymentResourceArtifacts.forEach((k, v) -> processDeploymentResourceArtifacts(user, resource, finalArtifactMap, k, v));
2051 resource.setDeploymentArtifacts(artifactMap);
2055 private void processDeploymentResourceArtifacts(User user, Resource resource, Map<String, ArtifactDefinition> artifactMap, String k, Object v) {
2056 Map<String, Object> artifactDetails = (Map<String, Object>) v;
2057 Object object = artifactDetails.get(PLACE_HOLDER_RESOURCE_TYPES);
2058 if (object != null) {
2059 List<String> artifactTypes = (List<String>) object;
2060 if (!artifactTypes.contains(resource.getResourceType().name())) {
2064 log.info("resource types for artifact placeholder {} were not defined. default is all resources", k);
2066 if (artifactsBusinessLogic != null) {
2067 ArtifactDefinition artifactDefinition = artifactsBusinessLogic
2068 .createArtifactPlaceHolderInfo(resource.getUniqueId(), k, (Map<String, Object>) v, user, ArtifactGroupTypeEnum.DEPLOYMENT);
2069 if (artifactDefinition != null && !artifactMap.containsKey(artifactDefinition.getArtifactLabel())) {
2070 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
2076 public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
2077 return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
2080 private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
2081 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context
2082 .getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
2083 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
2084 return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
2088 public ComponentInstanceBusinessLogic getComponentInstanceBL() {
2089 return componentInstanceBusinessLogic;
2093 public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
2094 validateUserExists(userId);
2095 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2096 if (getComponentRes.isRight()) {
2097 ResponseFormat responseFormat = componentsUtils
2098 .getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
2099 return Either.right(responseFormat);
2101 List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
2102 return Either.left(componentInstances);
2106 public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
2107 this.forwardingPathOperation = forwardingPathOperation;
2111 * updates group instance with new property values in case of successful update of group instance related component instance will be updated with
2112 * new modification time and related service will be updated with new last update date
2114 public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId,
2115 String componentInstanceId, String groupInstanceId,
2116 List<GroupInstanceProperty> newProperties) {
2117 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2118 Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
2119 Component component = null;
2120 Either<Boolean, ResponseFormat> lockResult = null;
2121 log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
2123 validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2124 if (validateUserAndComponentRes.isRight()) {
2125 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed. ", groupInstanceId, serviceId);
2126 actionResult = Either.right(validateUserAndComponentRes.right().value());
2128 if (actionResult == null) {
2129 component = validateUserAndComponentRes.left().value().getKey();
2130 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2131 if (lockResult.isRight()) {
2132 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
2133 actionResult = Either.right(lockResult.right().value());
2135 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
2138 if (actionResult == null) {
2139 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId,
2141 if (actionResult.isRight()) {
2142 log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ",
2143 groupInstanceId, actionResult.right().value().getFormattedMessage());
2146 } catch (Exception e) {
2147 log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2148 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2150 if (lockResult != null && lockResult.isLeft() && Boolean.TRUE.equals(lockResult.left().value())) {
2151 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2154 return actionResult;
2157 private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component,
2158 String componentInstanceId,
2159 String groupInstanceId,
2160 List<GroupInstanceProperty> newProperties) {
2161 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2162 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2163 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2164 ComponentInstance relatedComponentInstance = null;
2165 GroupInstance oldGroupInstance = null;
2166 Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2167 GroupInstance updatedGroupInstance = null;
2168 boolean inTransaction = true;
2169 findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2170 if (findGroupInstanceRes.isRight()) {
2171 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
2172 actionResult = Either.right(findGroupInstanceRes.right().value());
2174 if (actionResult == null) {
2175 oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2176 relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2177 updateGroupInstanceResult = groupBusinessLogic
2178 .validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
2179 if (updateGroupInstanceResult.isRight()) {
2180 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ",
2181 oldGroupInstance.getName());
2182 actionResult = Either.right(updateGroupInstanceResult.right().value());
2185 if (actionResult == null) {
2186 updatedGroupInstance = updateGroupInstanceResult.left().value();
2187 if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2188 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance,
2189 updatedGroupInstance, inTransaction);
2190 if (updateParentsModificationTimeRes.isRight()) {
2192 "#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ",
2193 oldGroupInstance.getName());
2194 actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2198 if (actionResult == null) {
2199 actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2201 return actionResult;
2204 private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(
2205 Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance, boolean inTranscation) {
2206 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2207 Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2208 Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic
2209 .updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2210 updatedGroupInstance.getModificationTime(), inTranscation);
2211 if (updateComponentInstanceRes.isRight()) {
2212 log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(),
2213 updatedGroupInstance.getName());
2214 actionResult = Either.right(updateComponentInstanceRes.right().value());
2216 serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2217 if (serviceMetadataUpdateResult.isRight()) {
2218 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ",
2219 component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2220 actionResult = Either.right(
2221 componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2223 actionResult = Either
2224 .left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2227 return actionResult;
2230 private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2231 Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2232 User currUser = null;
2233 Component component = null;
2234 Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2235 if (validationUserResult.isRight()) {
2236 log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2237 result = Either.right(validationUserResult.right().value());
2239 if (result == null) {
2240 currUser = validationUserResult.left().value();
2242 component = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2243 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2244 log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(),
2245 component.getCreatorUserId());
2246 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2248 } catch (ComponentException e) {
2249 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2250 result = Either.right(e.getResponseFormat());
2253 if (result == null) {
2254 result = Either.left(new ImmutablePair<>(component, currUser));
2259 private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component,
2260 String componentInstanceId,
2261 String groupInstanceId) {
2262 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2263 GroupInstance groupInstance = null;
2264 ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2265 if (foundComponentInstance == null) {
2266 log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2267 actionResult = Either.right(componentsUtils
2268 .getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service",
2269 component.getName()));
2270 } else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2271 groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst()
2273 if (groupInstance == null) {
2274 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2275 actionResult = Either.right(componentsUtils
2276 .getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId,
2277 foundComponentInstance.getName()));
2280 if (actionResult == null) {
2281 actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2283 return actionResult;
2286 private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2287 ComponentInstance componentInstance = null;
2288 if (isNotEmpty(component.getComponentInstances())) {
2289 componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst()
2292 return componentInstance;
2295 private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2296 User user = validateUser(modifier, ecompErrorContext, null, null, false);
2297 List<Role> roles = new ArrayList<>();
2298 roles.add(Role.ADMIN);
2299 roles.add(Role.DESIGNER);
2300 validateUserRole(user, roles);
2301 return Either.left(user);
2304 public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId,
2305 List<String> dataParamsToReturn) {
2306 ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2307 paramsToReturn.setIgnoreComponentInstancesProperties(false);
2308 Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2309 if (serviceResultEither.isRight()) {
2310 if (serviceResultEither.right().value() == StorageOperationStatus.NOT_FOUND) {
2311 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2312 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2314 log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2315 return Either.right(
2316 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2318 Service service = serviceResultEither.left().value();
2319 if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
2320 ListUtils.emptyIfNull(service.getInputs()).stream().filter(input -> CollectionUtils.isEmpty(input.getConstraints()))
2321 .forEach(input -> input.setConstraints(setInputConstraint(input)));
2323 UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2324 return Either.left(dataTransfer);
2327 @Autowired(required = false)
2328 public void setServiceCreationPluginList(List<ServiceCreationPlugin> serviceCreationPluginList) {
2329 this.serviceCreationPluginList = serviceCreationPluginList;
2332 public boolean isServiceExist(String serviceName) {
2333 return toscaOperationFacade.getLatestByServiceName(serviceName).isLeft();
2336 public void updateService(Service service, Map<String, Object> map) {
2339 interface ArtifactGenerator<CallVal> extends Callable<Either<CallVal, ResponseFormat>> {
2344 @AllArgsConstructor(access = AccessLevel.PRIVATE)
2345 class HeatEnvArtifactGenerator implements ArtifactGenerator<ArtifactDefinition> {
2347 private ArtifactDefinition artifactDefinition;
2348 private Service service;
2349 private String resourceInstanceName;
2350 private User modifier;
2351 private boolean shouldLock;
2352 private boolean inTransaction;
2353 private String instanceId;
2356 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2357 return artifactsBusinessLogic
2358 .forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier,
2359 shouldLock, inTransaction, instanceId);
2363 @AllArgsConstructor(access = AccessLevel.PRIVATE)
2364 class VfModuleArtifactGenerator implements ArtifactGenerator<ArtifactDefinition> {
2367 private ComponentInstance componentInstance;
2368 private Service service;
2369 private boolean shouldLock;
2370 private boolean inTransaction;
2372 private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance,
2373 Service service, boolean shouldLock,
2374 boolean inTransaction) {
2375 ArtifactDefinition vfModuleArtifact = null;
2376 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
2377 Wrapper<String> payloadWrapper = new Wrapper<>();
2378 List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
2379 if (responseWrapper.isEmpty()) {
2380 fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
2382 if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
2383 vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
2385 if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
2386 vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper,
2387 responseWrapper, service);
2389 if (responseWrapper.isEmpty()) {
2390 return Either.left(vfModuleArtifact);
2392 return Either.right(responseWrapper.getInnerElement());
2396 private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
2397 List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
2398 if (groupsForCurrVF != null) {
2399 for (GroupInstance groupInstance : groupsForCurrVF) {
2400 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
2401 vfModulePayloads.add(modulePayload);
2403 vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
2404 final Gson gson = new GsonBuilder().setPrettyPrinting().create();
2405 String vfModulePayloadString = gson.toJson(vfModulePayloads);
2406 payloadWrapper.setInnerElement(vfModulePayloadString);
2410 private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper,
2411 Wrapper<ResponseFormat> responseWrapper) {
2412 ArtifactDefinition vfModuleAertifact = null;
2413 if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
2414 final Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream()
2415 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.getType())).findAny();
2416 if (optionalVfModuleArtifact.isPresent()) {
2417 vfModuleAertifact = optionalVfModuleArtifact.get();
2420 if (vfModuleAertifact == null) {
2421 Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service,
2422 payloadWrapper.getInnerElement());
2423 if (createVfModuleArtifact.isLeft()) {
2424 vfModuleAertifact = createVfModuleArtifact.left().value();
2426 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
2429 return vfModuleAertifact;
2432 private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
2433 if (currVF.getGroupInstances() != null) {
2434 currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(currVF.getDeploymentArtifacts()));
2436 return currVF.getGroupInstances();
2439 private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service,
2440 String vfModulePayloadString) {
2441 ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
2442 String newCheckSum = null;
2443 vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
2444 vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
2445 vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
2446 vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
2447 vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
2448 vfModuleArtifactDefinition.setTimeout(0);
2449 vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
2450 vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
2451 if (vfModulePayloadString != null) {
2452 newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
2454 vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
2455 Either<ArtifactDefinition, StorageOperationStatus> addArtifactToComponent = artifactToscaOperation
2456 .addArtifactToComponent(vfModuleArtifactDefinition, service, NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
2457 if (addArtifactToComponent.isLeft()) {
2458 return Either.left(addArtifactToComponent.left().value());
2461 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArtifactToComponent.right().value())));
2465 private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact,
2467 boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper,
2469 ArtifactDefinition result = null;
2470 Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic
2471 .generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock,
2472 inTransaction, System::currentTimeMillis, () -> Either.left(
2473 artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact,
2474 payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))),
2475 currVF.getUniqueId());
2476 if (eitherPayload.isLeft()) {
2477 result = eitherPayload.left().value();
2479 responseWrapper.setInnerElement(eitherPayload.right().value());
2481 if (result == null) {
2482 result = vfModuleArtifact;
2488 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2489 return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);