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 org.apache.commons.collections.CollectionUtils;
60 import org.apache.commons.collections.MapUtils;
61 import org.apache.commons.collections4.ListUtils;
62 import org.apache.commons.lang3.StringUtils;
63 import org.apache.commons.lang3.tuple.ImmutablePair;
64 import org.openecomp.sdc.be.catalog.enums.ChangeTypeEnum;
65 import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine;
66 import org.openecomp.sdc.be.components.distribution.engine.INotificationData;
67 import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload;
68 import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic;
69 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
70 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
71 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
72 import org.openecomp.sdc.be.components.kafka.KafkaHandler;
73 import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
74 import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
75 import org.openecomp.sdc.be.components.utils.PropertiesUtils;
76 import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
77 import org.openecomp.sdc.be.components.validation.component.ComponentContactIdValidator;
78 import org.openecomp.sdc.be.components.validation.component.ComponentDescriptionValidator;
79 import org.openecomp.sdc.be.components.validation.component.ComponentIconValidator;
80 import org.openecomp.sdc.be.components.validation.component.ComponentNameValidator;
81 import org.openecomp.sdc.be.components.validation.component.ComponentProjectCodeValidator;
82 import org.openecomp.sdc.be.components.validation.component.ComponentTagsValidator;
83 import org.openecomp.sdc.be.components.validation.component.ComponentValidator;
84 import org.openecomp.sdc.be.components.validation.service.ServiceCategoryValidator;
85 import org.openecomp.sdc.be.components.validation.service.ServiceFunctionValidator;
86 import org.openecomp.sdc.be.components.validation.service.ServiceInstantiationTypeValidator;
87 import org.openecomp.sdc.be.components.validation.service.ServiceRoleValidator;
88 import org.openecomp.sdc.be.components.validation.service.ServiceTypeValidator;
89 import org.openecomp.sdc.be.components.validation.service.ServiceValidator;
90 import org.openecomp.sdc.be.config.BeEcompErrorManager;
91 import org.openecomp.sdc.be.config.ConfigurationManager;
92 import org.openecomp.sdc.be.dao.api.ActionStatus;
93 import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
94 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
95 import org.openecomp.sdc.be.datamodel.ServiceRelations;
96 import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil;
97 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
98 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
99 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
100 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
101 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
102 import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition;
103 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
104 import org.openecomp.sdc.be.datatypes.elements.ToscaFunction;
105 import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType;
106 import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
107 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
108 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
109 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
110 import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum;
111 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
112 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
113 import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo;
114 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
115 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
116 import org.openecomp.sdc.be.model.ArtifactDefinition;
117 import org.openecomp.sdc.be.model.CapabilityDefinition;
118 import org.openecomp.sdc.be.model.Component;
119 import org.openecomp.sdc.be.model.ComponentInstance;
120 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
121 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
122 import org.openecomp.sdc.be.model.ComponentParametersView;
123 import org.openecomp.sdc.be.model.DistributionStatusEnum;
124 import org.openecomp.sdc.be.model.GroupInstance;
125 import org.openecomp.sdc.be.model.GroupInstanceProperty;
126 import org.openecomp.sdc.be.model.InputDefinition;
127 import org.openecomp.sdc.be.model.InterfaceDefinition;
128 import org.openecomp.sdc.be.model.LifecycleStateEnum;
129 import org.openecomp.sdc.be.model.Model;
130 import org.openecomp.sdc.be.model.Operation;
131 import org.openecomp.sdc.be.model.PropertyDefinition;
132 import org.openecomp.sdc.be.model.Resource;
133 import org.openecomp.sdc.be.model.Service;
134 import org.openecomp.sdc.be.model.User;
135 import org.openecomp.sdc.be.model.category.CategoryDefinition;
136 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
137 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ForwardingPathOperation;
138 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
139 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
140 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
141 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
142 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
143 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
144 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
145 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
146 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
147 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
148 import org.openecomp.sdc.be.plugins.ServiceCreationPlugin;
149 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
150 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
151 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
152 import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent;
153 import org.openecomp.sdc.be.resources.data.auditing.DistributionDeployEvent;
154 import org.openecomp.sdc.be.resources.data.auditing.DistributionNotificationEvent;
155 import org.openecomp.sdc.be.resources.data.auditing.ResourceAdminEvent;
156 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
157 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
158 import org.openecomp.sdc.be.types.ServiceConsumptionData;
159 import org.openecomp.sdc.be.types.ServiceConsumptionSource;
160 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
161 import org.openecomp.sdc.be.user.Role;
162 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
163 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
164 import org.openecomp.sdc.common.api.Constants;
165 import org.openecomp.sdc.common.datastructure.Wrapper;
166 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
167 import org.openecomp.sdc.common.log.wrappers.Logger;
168 import org.openecomp.sdc.common.util.GeneralUtility;
169 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
170 import org.openecomp.sdc.common.util.ValidationUtils;
171 import org.openecomp.sdc.exception.ResponseFormat;
172 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
173 import org.springframework.beans.factory.annotation.Autowired;
174 import org.springframework.http.HttpStatus;
175 import org.springframework.web.context.WebApplicationContext;
177 @org.springframework.stereotype.Component("serviceBusinessLogic")
178 public class ServiceBusinessLogic extends ComponentBusinessLogic {
180 private static final String IS_VALID = "isValid";
181 private static final String THE_SERVICE_WITH_SYSTEM_NAME_LOCKED = "The service with system name {} locked. ";
182 private static final String FAILED_TO_LOCK_SERVICE_RESPONSE_IS = "Failed to lock service {}. Response is {}. ";
183 private static final String AUDIT_BEFORE_SENDING_RESPONSE = "audit before sending response";
184 private static final Logger log = Logger.getLogger(ServiceBusinessLogic.class);
185 private static final String INITIAL_VERSION = "0.1";
186 private static final String STATUS_SUCCESS_200 = "200";
187 private static final String STATUS_DEPLOYED = "DEPLOYED";
188 private static final String PLACE_HOLDER_RESOURCE_TYPES = "validForResourceTypes";
189 private final IDistributionEngine distributionEngine;
190 private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
191 private final ServiceDistributionValidation serviceDistributionValidation;
192 private final ForwardingPathValidator forwardingPathValidator;
193 private final UiComponentDataConverter uiComponentDataConverter;
194 private final ModelOperation modelOperation;
195 private final ServiceRoleValidator serviceRoleValidator;
196 private final ServiceInstantiationTypeValidator serviceInstantiationTypeValidator;
197 private final ServiceCategoryValidator serviceCategoryValidator;
198 private final ServiceValidator serviceValidator;
199 private final GroupBusinessLogic groupBusinessLogic;
200 private final KafkaHandler kafkaHandler;
201 private ForwardingPathOperation forwardingPathOperation;
202 private AuditCassandraDao auditCassandraDao;
203 private ServiceTypeValidator serviceTypeValidator;
204 private List<ServiceCreationPlugin> serviceCreationPluginList;
205 private ServiceFunctionValidator serviceFunctionValidator;
207 public ServiceBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation,
208 IGroupTypeOperation groupTypeOperation, GroupBusinessLogic groupBusinessLogic, InterfaceOperation interfaceOperation,
209 InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactsBusinessLogic artifactsBusinessLogic,
210 IDistributionEngine distributionEngine, ComponentInstanceBusinessLogic componentInstanceBusinessLogic,
211 ServiceDistributionValidation serviceDistributionValidation, ForwardingPathValidator forwardingPathValidator,
212 UiComponentDataConverter uiComponentDataConverter, ArtifactsOperations artifactToscaOperation,
213 ComponentContactIdValidator componentContactIdValidator, ComponentNameValidator componentNameValidator,
214 ComponentTagsValidator componentTagsValidator, ComponentValidator componentValidator,
215 ComponentIconValidator componentIconValidator, ComponentProjectCodeValidator componentProjectCodeValidator,
216 ComponentDescriptionValidator componentDescriptionValidator, ModelOperation modelOperation,
217 final ServiceRoleValidator serviceRoleValidator,
218 final ServiceInstantiationTypeValidator serviceInstantiationTypeValidator,
219 final ServiceCategoryValidator serviceCategoryValidator, final ServiceValidator serviceValidator, KafkaHandler kafkaHandler) {
220 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation,
221 interfaceLifecycleTypeOperation, artifactsBusinessLogic, artifactToscaOperation, componentContactIdValidator, componentNameValidator,
222 componentTagsValidator, componentValidator, componentIconValidator, componentProjectCodeValidator, componentDescriptionValidator);
223 this.distributionEngine = distributionEngine;
224 this.componentInstanceBusinessLogic = componentInstanceBusinessLogic;
225 this.serviceDistributionValidation = serviceDistributionValidation;
226 this.forwardingPathValidator = forwardingPathValidator;
227 this.uiComponentDataConverter = uiComponentDataConverter;
228 this.modelOperation = modelOperation;
229 this.serviceRoleValidator = serviceRoleValidator;
230 this.serviceInstantiationTypeValidator = serviceInstantiationTypeValidator;
231 this.serviceCategoryValidator = serviceCategoryValidator;
232 this.serviceValidator = serviceValidator;
233 this.groupBusinessLogic = groupBusinessLogic;
234 this.kafkaHandler = kafkaHandler;
238 public void setServiceTypeValidator(ServiceTypeValidator serviceTypeValidator) {
239 this.serviceTypeValidator = serviceTypeValidator;
243 public void setServiceFunctionValidator(ServiceFunctionValidator serviceFunctionValidator) {
244 this.serviceFunctionValidator = serviceFunctionValidator;
247 public Either<List<Map<String, Object>>, ResponseFormat> getComponentAuditRecords(String componentVersion, String componentUUID, String userId) {
248 validateUserExists(userId);
249 Either<List<Map<String, Object>>, ActionStatus> result;
252 if (componentVersion.endsWith(".0")) {
253 Either<List<ResourceAdminEvent>, ActionStatus> eitherAuditingForCertified = auditCassandraDao.getByServiceInstanceId(componentUUID);
254 if (eitherAuditingForCertified.isLeft()) {
255 result = Either.left(getAuditingFieldsList(eitherAuditingForCertified.left().value()));
257 result = Either.right(eitherAuditingForCertified.right().value());
260 // Uncertified Version
262 result = getAuditRecordsForUncertifiedComponent(componentUUID, componentVersion);
264 } catch (Exception e) {
265 log.debug("get Audit Records failed with exception {}", e);
266 result = Either.right(ActionStatus.GENERAL_ERROR);
268 if (result.isRight()) {
269 return Either.right(componentsUtils.getResponseFormat(result.right().value()));
271 return Either.left(result.left().value());
275 public Either<List<Operation>, ResponseFormat> addServiceConsumptionData(String serviceId, String serviceInstanceId, String operationId,
276 List<ServiceConsumptionData> serviceConsumptionDataList, String userId) {
277 List<Operation> operationList = new ArrayList<>();
278 Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
279 if (serviceEither.isRight()) {
280 return Either.right(componentsUtils.getResponseFormat(serviceEither.right().value()));
282 Service service = serviceEither.left().value();
283 StorageOperationStatus storageOperationStatus = graphLockOperation.lockComponent(service.getUniqueId(), NodeTypeEnum.Service);
284 if (storageOperationStatus != StorageOperationStatus.OK) {
285 return Either.right(componentsUtils.getResponseFormat(storageOperationStatus));
288 for (ServiceConsumptionData serviceConsumptionData : serviceConsumptionDataList) {
289 Either<Operation, ResponseFormat> operationEither = addPropertyServiceConsumption(serviceId, serviceInstanceId, operationId, userId,
290 serviceConsumptionData);
291 if (operationEither.isRight()) {
292 return Either.right(operationEither.right().value());
294 operationList.add(operationEither.left().value());
296 janusGraphDao.commit();
297 return Either.left(operationList);
298 } catch (Exception e) {
299 janusGraphDao.rollback();
300 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
302 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
306 public Either<Operation, ResponseFormat> addPropertyServiceConsumption(String serviceId, String serviceInstanceId, String operationId,
307 String userId, ServiceConsumptionData serviceConsumptionData) {
308 validateUserExists(userId);
309 Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
310 if (serviceEither.isRight()) {
311 return Either.right(componentsUtils.getResponseFormat(serviceEither.right().value()));
313 Service parentService = serviceEither.left().value();
314 List<ComponentInstance> componentInstances = parentService.getComponentInstances();
315 if (CollectionUtils.isEmpty(componentInstances)) {
316 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
318 Optional<ComponentInstance> serviceInstanceCandidate = componentInstances.stream()
319 .filter(instance -> instance.getUniqueId().equals(serviceInstanceId)).findAny();
320 if (!serviceInstanceCandidate.isPresent()) {
321 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
323 Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaces = parentService.getComponentInstancesInterfaces();
324 if (MapUtils.isEmpty(componentInstancesInterfaces)) {
325 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
327 List<InterfaceDefinition> interfaces = new ArrayList<>();
328 for (ComponentInstanceInterface componentInstanceInterface : componentInstancesInterfaces.get(serviceInstanceId)) {
329 interfaces.add(componentInstanceInterface);
331 ComponentInstance serviceInstance = serviceInstanceCandidate.get();
332 Optional<InterfaceDefinition> interfaceCandidate = InterfaceOperationUtils.getInterfaceDefinitionFromOperationId(interfaces, operationId);
333 if (!interfaceCandidate.isPresent()) {
334 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
336 InterfaceDefinition interfaceDefinition = interfaceCandidate.get();
337 Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
338 if (MapUtils.isEmpty(operations)) {
339 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
341 Operation operation = operations.get(operationId);
342 Either<Operation, ResponseFormat> operationEither = Either.left(operation);
343 ListDataDefinition<OperationInputDefinition> inputs = operation.getInputs();
344 Optional<OperationInputDefinition> inputCandidate = getOperationInputByInputId(serviceConsumptionData, inputs);
345 if (!inputCandidate.isPresent()) {
346 return Either.right(new ResponseFormat(HttpStatus.NOT_FOUND.value()));
348 OperationInputDefinition operationInputDefinition = inputCandidate.get();
349 // add data to operation
350 if (Objects.nonNull(serviceConsumptionData.getValue())) {
351 operationEither = handleConsumptionValue(parentService, serviceInstanceId, serviceConsumptionData, operation, operationInputDefinition);
353 if (operationEither.isRight()) {
354 return Either.right(operationEither.right().value());
356 Operation updatedOperation = operationEither.left().value();
357 operations.remove(operationId);
358 operations.put(operationId, updatedOperation);
359 interfaceDefinition.setOperationsMap(operations);
360 parentService.getComponentInstances().remove(serviceInstance);
361 if (CollectionUtils.isEmpty(parentService.getComponentInstances())) {
362 parentService.setComponentInstances(new ArrayList<>());
364 Map<String, Object> instanceInterfaces =
365 MapUtils.isEmpty(serviceInstance.getInterfaces()) ? new HashMap<>() : serviceInstance.getInterfaces();
366 instanceInterfaces.remove(interfaceDefinition.getUniqueId());
367 instanceInterfaces.put(interfaceDefinition.getUniqueId(), interfaceDefinition);
368 serviceInstance.setInterfaces(instanceInterfaces);
369 removeComponentInstanceInterfaceByInterfaceId(interfaceDefinition.getUniqueId(), componentInstancesInterfaces.get(serviceInstanceId));
370 componentInstancesInterfaces.get(serviceInstanceId)
371 .add(new ComponentInstanceInterface(interfaceDefinition.getUniqueId(), interfaceDefinition));
372 parentService.getComponentInstances().add(serviceInstance);
373 StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(parentService, serviceInstanceId);
374 if (status != StorageOperationStatus.OK) {
375 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
377 return Either.left(operation);
380 private void removeComponentInstanceInterfaceByInterfaceId(String interfaceIdToRemove, List<ComponentInstanceInterface> instanceInterfaces) {
381 if (CollectionUtils.isEmpty(instanceInterfaces)) {
384 Optional<ComponentInstanceInterface> interfaceToRemove = instanceInterfaces.stream()
385 .filter(instInterface -> instInterface.getUniqueId().equals(interfaceIdToRemove)).findAny();
386 if (interfaceToRemove.isPresent()) {
387 instanceInterfaces.remove(interfaceToRemove.get());
391 private Either<Operation, ResponseFormat> handleConsumptionValue(Service containerService, String serviceInstanceId,
392 ServiceConsumptionData serviceConsumptionData, Operation operation,
393 OperationInputDefinition operationInputDefinition) {
394 String source = serviceConsumptionData.getSource();
395 String consumptionValue = serviceConsumptionData.getValue();
396 String type = serviceConsumptionData.getType();
397 String operationIdentifier =
398 consumptionValue.contains(".") ? consumptionValue.substring(0, consumptionValue.lastIndexOf('.')) : consumptionValue;
399 ServiceConsumptionSource sourceValue = ServiceConsumptionSource.getSourceValue(source);
400 if (STATIC.equals(sourceValue)) {
401 // Validate constraint on input value
402 Either<Boolean, ResponseFormat> constraintValidationResult = validateOperationInputConstraint(operationInputDefinition, consumptionValue,
403 type, containerService.getModel());
404 if (constraintValidationResult.isRight()) {
405 return Either.right(constraintValidationResult.right().value());
407 return handleConsumptionStaticValue(consumptionValue, type, operation, operationInputDefinition, containerService.getModel());
409 if (Objects.isNull(sourceValue)) {
410 List<PropertyDefinition> propertyDefinitions;
411 Map<String, List<CapabilityDefinition>> capabilities = null;
412 String componentName;
413 List<OperationOutputDefinition> outputs = null;
414 if (source.equals(containerService.getUniqueId())) {
415 Either<Service, StorageOperationStatus> serviceToTakePropEither = toscaOperationFacade.getToscaElement(source);
416 if (serviceToTakePropEither.isRight()) {
417 return Either.right(componentsUtils.getResponseFormat(serviceToTakePropEither.right().value()));
419 Service service = serviceToTakePropEither.left().value();
420 operationInputDefinition.setSource(service.getUniqueId());
421 sourceValue = SERVICE_INPUT;
422 propertyDefinitions = service.getProperties();
423 componentName = service.getName();
424 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier, service.getInterfaces())
425 .getListToscaDataDefinition();
427 Optional<ComponentInstance> getComponentInstance = containerService.getComponentInstanceById(source);
428 if (!getComponentInstance.isPresent()) {
429 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, source));
431 ComponentInstance componentInstance = getComponentInstance.get();
432 operationInputDefinition.setSource(componentInstance.getUniqueId());
433 propertyDefinitions = componentInstance.getProperties();
434 capabilities = componentInstance.getCapabilities();
435 componentName = source.equals(serviceInstanceId) ? SELF : componentInstance.getName();
436 if (MapUtils.isNotEmpty(componentInstance.getInterfaces())) {
437 Map<String, InterfaceDataDefinition> componentInstanceInterfaces = componentInstance.getInterfaces().entrySet().stream()
438 .collect(Collectors.toMap((Map.Entry::getKey), (interfaceEntry -> (InterfaceDataDefinition) interfaceEntry.getValue())));
439 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier, componentInstanceInterfaces)
440 .getListToscaDataDefinition();
443 if (sourceValue == ServiceConsumptionSource.SERVICE_INPUT) {
444 //The operation input in service consumption has been mapped to an input in the parent service
445 return handleConsumptionInputValue(consumptionValue, containerService, operation, operationInputDefinition);
447 return handleConsumptionPropertyValue(operation, operationInputDefinition, serviceConsumptionData, propertyDefinitions, capabilities,
448 outputs, componentName);
450 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.SOURCE, source);
451 operationInputDefinition.setSource(source);
452 return Either.left(operation);
455 private Optional<OperationInputDefinition> getOperationInputByInputId(ServiceConsumptionData serviceConsumptionData,
456 ListDataDefinition<OperationInputDefinition> inputs) {
457 if (CollectionUtils.isEmpty(inputs.getListToscaDataDefinition())) {
458 return Optional.empty();
460 return inputs.getListToscaDataDefinition().stream()
461 .filter(operationInput -> operationInput.getInputId().equals(serviceConsumptionData.getInputId())).findAny();
464 private Either<Operation, ResponseFormat> handleConsumptionPropertyValue(Operation operation, OperationInputDefinition operationInputDefinition,
465 ServiceConsumptionData serviceConsumptionData,
466 List<PropertyDefinition> properties,
467 Map<String, List<CapabilityDefinition>> capabilities,
468 List<OperationOutputDefinition> outputs, String componentName) {
469 if (CollectionUtils.isEmpty(properties) && CollectionUtils.isEmpty(outputs)) {
470 return Either.left(operation);
472 String consumptionValue = serviceConsumptionData.getValue();
473 if (CollectionUtils.isNotEmpty(outputs) && isOperationInputMappedToOtherOperationOutput(getOperationOutputName(consumptionValue), outputs)) {
474 return handleConsumptionInputMappedToOperationOutput(operation, operationInputDefinition, outputs, consumptionValue, componentName);
476 if (CollectionUtils.isNotEmpty(properties) && PropertiesUtils.isNodeProperty(consumptionValue, properties)) {
477 return handleConsumptionInputMappedToProperty(operation, operationInputDefinition, serviceConsumptionData, properties, componentName);
479 if (MapUtils.isNotEmpty(capabilities)) {
480 return handleConsumptionInputMappedToCapabilityProperty(operation, operationInputDefinition, serviceConsumptionData, capabilities,
483 return Either.left(operation);
486 private Either<Operation, ResponseFormat> handleConsumptionInputMappedToProperty(Operation operation,
487 OperationInputDefinition operationInputDefinition,
488 ServiceConsumptionData serviceConsumptionData,
489 List<PropertyDefinition> properties, String componentName) {
490 Optional<PropertyDefinition> servicePropertyCandidate = properties.stream()
491 .filter(property -> property.getName().equals(serviceConsumptionData.getValue())).findAny();
492 if (servicePropertyCandidate.isPresent()) {
493 boolean isInputTypeSimilarToOperation = isAssignedValueFromValidType(operationInputDefinition.getType(), servicePropertyCandidate.get());
494 if (!isInputTypeSimilarToOperation) {
495 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
497 addPropertyToInputValue(componentName, operation, operationInputDefinition, servicePropertyCandidate.get());
499 return Either.left(operation);
502 private Either<Operation, ResponseFormat> handleConsumptionInputMappedToOperationOutput(Operation operation,
503 OperationInputDefinition operationInputDefinition,
504 List<OperationOutputDefinition> outputs,
505 String consumptionValue, String componentName) {
506 String outputName = getOperationOutputName(consumptionValue);
507 Optional<OperationOutputDefinition> servicePropertyOutputCandidate = outputs.stream().filter(output -> output.getName().equals(outputName))
509 if (servicePropertyOutputCandidate.isPresent()) {
510 boolean isInputTypeSimilarToOperation = isAssignedValueFromValidType(operationInputDefinition.getType(),
511 servicePropertyOutputCandidate.get());
512 if (!isInputTypeSimilarToOperation) {
513 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
515 addOutputToInputValue(componentName, consumptionValue, operation, operationInputDefinition);
517 return Either.left(operation);
520 private void addPropertyToInputValue(String componentName, Operation operation, OperationInputDefinition operationInputDefinition,
521 PropertyDefinition serviceProperty) {
522 Map<String, List<String>> getProperty = new HashMap<>();
523 List<String> getPropertyValues = new ArrayList<>();
524 getPropertyValues.add(componentName);
525 getPropertyValues.add(serviceProperty.getName());
526 getProperty.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), getPropertyValues);
527 operationInputDefinition.setSourceProperty(serviceProperty.getUniqueId());
528 operation.getInputs().delete(operationInputDefinition);
529 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_PROPERTY, getPropertyValues);
530 operationInputDefinition.setValue((new Gson()).toJson(getProperty));
531 operation.getInputs().add(operationInputDefinition);
534 private void addOutputToInputValue(String componentName, String consumptionValue, Operation operation,
535 OperationInputDefinition operationInputDefinition) {
536 Map<String, List<String>> getOperationOutput = InterfaceOperationUtils.createMappedOutputDefaultValue(componentName, consumptionValue);
537 operation.getInputs().delete(operationInputDefinition);
538 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_OPERATION_OUTPUT, getOperationOutput);
539 operationInputDefinition.setValue((new Gson()).toJson(getOperationOutput));
540 operation.getInputs().add(operationInputDefinition);
543 public Either<Operation, ResponseFormat> handleConsumptionStaticValue(String value, String type, Operation operation,
544 OperationInputDefinition operationInputDefinition, String model) {
545 boolean isInputTypeSimilarToOperation = isAssignedValueFromValidType(type, value);
546 if (!isInputTypeSimilarToOperation) {
547 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONSUMPTION_TYPE, type));
549 //Validate Constraint and Value
550 Either<Boolean, ResponseFormat> constraintValidationResponse = validateOperationInputConstraint(operationInputDefinition, value, type, model);
551 if (constraintValidationResponse.isRight()) {
552 return Either.right(constraintValidationResponse.right().value());
554 addStaticValueToInputOperation(value, operation, operationInputDefinition);
555 return Either.left(operation);
558 private Either<Boolean, ResponseFormat> validateOperationInputConstraint(OperationInputDefinition operationInputDefinition, String value,
559 String type, String model) {
560 ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
561 propertyDefinition.setType(operationInputDefinition.getParentPropertyType());
562 InputDefinition inputDefinition = new InputDefinition();
563 inputDefinition.setDefaultValue(value);
564 inputDefinition.setInputPath(operationInputDefinition.getSubPropertyInputPath());
565 inputDefinition.setType(type);
566 if (Objects.nonNull(operationInputDefinition.getParentPropertyType())) {
567 inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
569 return new PropertyValueConstraintValidationUtil().validatePropertyConstraints(Collections.singletonList(inputDefinition),
570 applicationDataTypeCache, model);
573 private void addStaticValueToInputOperation(String value, Operation operation, OperationInputDefinition operationInputDefinition) {
574 operation.getInputs().delete(operationInputDefinition);
575 operationInputDefinition.setSource(STATIC.getSource());
576 operationInputDefinition.setSourceProperty(null);
577 operationInputDefinition.setValue(value);
578 operation.getInputs().add(operationInputDefinition);
581 private Either<Operation, ResponseFormat> handleConsumptionInputValue(String inputId, Service service, Operation operation,
582 OperationInputDefinition operationInputDefinition) {
583 List<InputDefinition> serviceInputs = service.getInputs();
584 Optional<InputDefinition> inputForValue = serviceInputs.stream().filter(input -> input.getUniqueId().contains(inputId)).findAny();
585 if (inputForValue.isPresent()) {
586 boolean isInputTypeSimilarToOperation = isAssignedValueFromValidType(operationInputDefinition.getType(), inputForValue.get());
587 if (!isInputTypeSimilarToOperation) {
588 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
590 addGetInputValueToOperationInput(operation, operationInputDefinition, inputForValue.get());
592 return Either.left(operation);
595 private void addGetInputValueToOperationInput(Operation operation, OperationInputDefinition operationInputDefinition,
596 InputDefinition inputForValue) {
597 operation.getInputs().delete(operationInputDefinition);
598 Map<String, String> getInputMap = new HashMap<>();
599 getInputMap.put(ToscaFunctions.GET_INPUT.getFunctionName(), inputForValue.getName());
600 operationInputDefinition.setSourceProperty(inputForValue.getUniqueId());
601 operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_INPUT, getInputMap);
602 operationInputDefinition.setValue(new Gson().toJson(getInputMap));
603 operation.getInputs().add(operationInputDefinition);
606 private Either<List<Map<String, Object>>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) {
608 Either<List<ResourceAdminEvent>, ActionStatus> eitherprevVerAudit = auditCassandraDao
609 .getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion);
610 if (eitherprevVerAudit.isRight()) {
611 return Either.right(eitherprevVerAudit.right().value());
614 Either<List<ResourceAdminEvent>, ActionStatus> eitherCurrVerAudit = auditCassandraDao
615 .getAuditByServiceIdAndCurrVersion(componentUUID, componentVersion);
616 if (eitherCurrVerAudit.isRight()) {
617 return Either.right(eitherCurrVerAudit.right().value());
619 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveRestoreList = getArchiveRestoreEventList(componentUUID);
620 if (eitherArchiveRestoreList.isRight()) {
621 return Either.right(eitherArchiveRestoreList.right().value());
623 List<Map<String, Object>> prevVerAuditList = getAuditingFieldsList(eitherprevVerAudit.left().value());
624 List<Map<String, Object>> currVerAuditList = getAuditingFieldsList(eitherCurrVerAudit.left().value());
625 List<Map<String, Object>> duplicateElements = new ArrayList<>();
626 duplicateElements.addAll(prevVerAuditList);
627 duplicateElements.retainAll(currVerAuditList);
628 List<Map<String, Object>> joinedNonDuplicatedList = new ArrayList<>();
629 joinedNonDuplicatedList.addAll(prevVerAuditList);
630 joinedNonDuplicatedList.removeAll(duplicateElements);
631 joinedNonDuplicatedList.addAll(currVerAuditList);
632 joinedNonDuplicatedList.addAll(getAuditingFieldsList(eitherArchiveRestoreList.left().value()));
633 return Either.left(joinedNonDuplicatedList);
636 private Either<List<ResourceAdminEvent>, ActionStatus> getArchiveRestoreEventList(String componentUUID) {
638 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveAudit = auditCassandraDao.getArchiveAuditByServiceInstanceId(componentUUID);
639 if (eitherArchiveAudit.isRight()) {
640 return Either.right(eitherArchiveAudit.right().value());
643 Either<List<ResourceAdminEvent>, ActionStatus> eitherRestoreAudit = auditCassandraDao.getRestoreAuditByServiceInstanceId(componentUUID);
644 if (eitherRestoreAudit.isRight()) {
645 return Either.right(eitherRestoreAudit.right().value());
647 List<ResourceAdminEvent> archiveAudit = new ArrayList<>();
648 archiveAudit.addAll(eitherArchiveAudit.left().value());
649 archiveAudit.addAll(eitherRestoreAudit.left().value());
650 return Either.left(archiveAudit);
653 private List<Map<String, Object>> getAuditingFieldsList(List<? extends AuditingGenericEvent> prevVerAuditList) {
654 List<Map<String, Object>> prevVerAudit = new ArrayList<>();
655 for (AuditingGenericEvent auditEvent : prevVerAuditList) {
656 auditEvent.fillFields();
657 prevVerAudit.add(auditEvent.getFields());
665 * @param service - Service
666 * @param user - modifier data (userId)
667 * @return Either<Service, responseFormat>
669 public Either<Service, ResponseFormat> createService(Service service, User user) {
671 user = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false);
672 log.debug("User returned from validation: {}", user);
673 // validate user role
674 validateUserRole(user, service, new ArrayList<>(), AuditingActionEnum.CREATE_RESOURCE, null);
675 service.setCreatorUserId(user.getUserId());
676 // warn on overridden fields
677 checkFieldsForOverideAttampt(service);
679 log.debug("enrich service with version and state");
680 service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
681 service.setVersion(INITIAL_VERSION);
682 service.setConformanceLevel(ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
683 service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED);
684 service.setComponentType(ComponentTypeEnum.SERVICE);
685 Either<Service, ResponseFormat> createServiceResponse = validateServiceBeforeCreate(service, user, AuditingActionEnum.CREATE_RESOURCE);
686 if (createServiceResponse.isRight()) {
687 return createServiceResponse;
689 return createServiceByDao(service, user).left().bind(c -> updateCatalog(c, ChangeTypeEnum.LIFECYCLE).left().map(Service.class::cast));
692 private void checkFieldsForOverideAttampt(Service service) {
693 checkComponentFieldsForOverrideAttempt(service);
694 if (service.getDistributionStatus() != null) {
695 log.info("Distribution Status cannot be defined by user. This field will be overridden by the application");
699 private Either<Service, ResponseFormat> createServiceByDao(final Service service, final User user) {
700 log.debug("send service {} to dao for create", service.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
701 Either<Boolean, ResponseFormat> lockResult = lockComponentByName(service.getSystemName(), service, "Create Service");
702 if (lockResult.isRight()) {
703 ResponseFormat responseFormat = lockResult.right().value();
704 componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
705 return Either.right(responseFormat);
707 log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult);
709 createMandatoryArtifactsData(service, user);
710 createServiceApiArtifactsData(service, user);
711 setToscaArtifactsPlaceHolders(service, user);
713 if (service.isSubstituteCandidate() || genericTypeBusinessLogic.hasMandatorySubstitutionType(service)) {
714 final Resource genericType = fetchAndSetDerivedFromGenericType(service);
715 generatePropertiesFromGenericType(service, genericType);
716 if (Constants.DEFAULT_MODEL_NAME.equals(service.getModel()) || service.getModel() == null) {
717 generateAndAddInputsFromGenericTypeProperties(service, genericType);
720 beforeCreate(service);
721 Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
722 if (dataModelResponse.isLeft()) {
723 log.debug("Service '{}' created successfully", service.getName());
724 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
725 componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
726 ASDCKpiApi.countCreatedServicesKPI();
727 return Either.left(dataModelResponse.left().value());
729 janusGraphDao.rollback();
730 ResponseFormat responseFormat = componentsUtils
731 .getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service,
732 ComponentTypeEnum.SERVICE);
733 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
734 componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
735 return Either.right(responseFormat);
737 graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service);
741 private void beforeCreate(final Service service) {
742 if (CollectionUtils.isEmpty(serviceCreationPluginList)) {
745 serviceCreationPluginList.stream().sorted(Comparator.comparingInt(ServiceCreationPlugin::getOrder)).forEach(serviceCreationPlugin -> {
747 serviceCreationPlugin.beforeCreate(service);
748 } catch (final Exception e) {
749 log.error("An error has occurred while running the serviceCreationPlugin '{}'", serviceCreationPlugin.getClass(), e);
754 @SuppressWarnings("unchecked")
755 private void createServiceApiArtifactsData(Service service, User user) {
756 // create mandatory artifacts
758 // TODO it must be removed after that artifact uniqueId creation will be
760 // moved to ArtifactOperation
761 String serviceUniqueId = service.getUniqueId();
762 Map<String, ArtifactDefinition> artifactMap = service.getServiceApiArtifacts();
763 if (artifactMap == null) {
764 artifactMap = new HashMap<>();
766 Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts();
767 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
768 List<CategoryDefinition> categories = service.getCategories();
769 boolean isCreateArtifact = true;
770 if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
771 for (String exlude : exludeServiceCategory) {
772 if (exlude.equalsIgnoreCase(categories.get(0).getName())) {
773 isCreateArtifact = false;
778 if (serviceApiArtifacts != null && isCreateArtifact) {
779 Set<String> keys = serviceApiArtifacts.keySet();
780 for (String serviceApiArtifactName : keys) {
781 Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName);
782 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user,
784 artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API);
785 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
787 service.setServiceApiArtifacts(artifactMap);
792 protected Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) {
794 serviceValidator.validate(user, service, actionEnum);
795 } catch (ComponentException exp) {
796 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exp);
797 componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_SERVICE, ComponentTypeEnum.SERVICE);
800 service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
801 service.setContactId(service.getContactId().toLowerCase());
802 // Generate invariant UUID - must be here and not in operation since it
804 // should stay constant during clone
805 String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
806 service.setInvariantUUID(invariantUUID);
807 return Either.left(service);
810 public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) {
811 validateUserExists(userId);
812 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade
813 .validateComponentNameUniqueness(serviceName, null, ComponentTypeEnum.SERVICE);
815 janusGraphDao.commit();
816 if (dataModelResponse.isLeft()) {
817 Map<String, Boolean> result = new HashMap<>();
818 result.put(IS_VALID, dataModelResponse.left().value());
819 log.debug("validation was successfully performed.");
820 return Either.left(result);
822 ResponseFormat responseFormat = componentsUtils
823 .getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
824 return Either.right(responseFormat);
827 public void setElementDao(IElementOperation elementDao) {
828 this.elementDao = elementDao;
832 public void setCassandraAuditingDao(AuditCassandraDao auditingDao) {
833 this.auditCassandraDao = auditingDao;
836 public ArtifactsBusinessLogic getArtifactBl() {
837 return artifactsBusinessLogic;
840 public void setArtifactBl(ArtifactsBusinessLogic artifactBl) {
841 this.artifactsBusinessLogic = artifactBl;
844 public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) {
845 user = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false);
846 // validate user role
847 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
848 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
849 if (storageStatus.isRight()) {
850 return Either.right(componentsUtils
851 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
853 Service currentService = storageStatus.left().value();
854 if (!ComponentValidationUtils.canWorkOnComponent(currentService, user.getUserId())) {
855 log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
856 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
858 List<String> subNodePropsToBeRemoved = getSubstitutionNodePropertiesToBeRemoved(currentService, serviceUpdate);
859 List<PropertyDefinition> subNodePropsToBeAdded = getSubstitutionNodePropertiesToBeAdded(currentService, serviceUpdate);
860 boolean subNodeChanged = isSubstitutionNodeChanged(currentService, serviceUpdate);
861 Either<Service, ResponseFormat> validationResponse =
862 validateAndUpdateServiceMetadata(user, currentService, serviceUpdate, subNodeChanged, ListUtils.emptyIfNull(subNodePropsToBeRemoved));
863 if (validationResponse.isRight()) {
864 log.info("service update metadata: validations field.");
865 return validationResponse;
867 Service serviceToUpdate = validationResponse.left().value();
869 lockComponent(serviceId, currentService, "Update Service Metadata");
871 if (subNodeChanged) {
872 if (!subNodePropsToBeRemoved.isEmpty()) {
873 removePropertiesFromService(currentService, subNodePropsToBeRemoved);
874 removeInputsFromService(currentService, subNodePropsToBeRemoved);
876 if (!subNodePropsToBeAdded.isEmpty()) {
877 addPropertiesToService(currentService, subNodePropsToBeAdded);
878 if (Constants.DEFAULT_MODEL_NAME.equals(currentService.getModel()) || currentService.getModel() == null) {
879 addInputsToService(currentService, subNodePropsToBeAdded);
883 return toscaOperationFacade.updateToscaElement(serviceToUpdate).right().map(rf -> {
884 janusGraphDao.rollback();
885 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
886 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
887 return (componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
888 }).left().bind(this::updateCatalogAndCommit);
889 } catch (ComponentException e) {
890 janusGraphDao.rollback();
891 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
892 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
893 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
895 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
899 private Either<Service, ResponseFormat> updateCatalogAndCommit(Service service) {
900 Either<Service, ResponseFormat> res = updateCatalog(service, ChangeTypeEnum.LIFECYCLE).left().map(Service.class::cast);
901 janusGraphDao.commit();
905 public Set<String> deleteForwardingPaths(String serviceId, Set<String> pathIdsToDelete, User user, boolean lock) {
906 Service serviceToDelete = initServiceToDeletePaths(serviceId, pathIdsToDelete);
907 user = validateUser(user, "deleteForwardingPaths", serviceToDelete, null, false);
908 // validate user role
909 validateUserRole(user, serviceToDelete, new ArrayList<>(), null, null);
910 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
911 if (storageStatus.isRight()) {
912 throw new ByActionStatusComponentException(
913 componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), "");
915 Service service = storageStatus.left().value();
916 Either<Set<String>, StorageOperationStatus> result = null;
919 lockComponent(service.getUniqueId(), service, "Delete Forwarding Path on Service");
920 } catch (ComponentException e) {
921 janusGraphDao.rollback();
922 throw new ByActionStatusComponentException(
923 componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), "");
927 result = forwardingPathOperation.deleteForwardingPath(service, pathIdsToDelete);
928 if (result.isRight()) {
929 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, service.getName(), result.right().value());
930 janusGraphDao.rollback();
931 throw new ByActionStatusComponentException(
932 componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE));
934 janusGraphDao.commit();
935 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, service.getSystemName());
936 } catch (ComponentException e) {
937 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
938 janusGraphDao.rollback();
939 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
941 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
943 return result.left().value();
946 private Service initServiceToDeletePaths(String serviceId, Collection<String> pathIdsToDelete) {
947 Service serviceToDelete = new Service();
948 serviceToDelete.setUniqueId(serviceId);
949 serviceToDelete.setForwardingPaths(new HashMap<>());
950 pathIdsToDelete.forEach(pathIdToDelete -> serviceToDelete.getForwardingPaths().put(pathIdToDelete, new ForwardingPathDataDefinition()));
951 return serviceToDelete;
954 public Service updateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
955 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, true, "updateForwardingPath", lock);
958 public Service createForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
959 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, false, "createForwardingPath", lock);
962 private ForwardingPathDataDefinition getTrimmedValues(ForwardingPathDataDefinition path) {
963 ForwardingPathDataDefinition dataDefinition = new ForwardingPathDataDefinition(path.getName());
964 dataDefinition.setName(Strings.nullToEmpty(path.getName()).trim());
965 dataDefinition.setProtocol(Strings.nullToEmpty(path.getProtocol()).trim());
966 dataDefinition.setDestinationPortNumber(Strings.nullToEmpty(path.getDestinationPortNumber()).trim());
967 dataDefinition.setUniqueId(path.getUniqueId());
968 dataDefinition.setPathElements(path.getPathElements());
969 dataDefinition.setDescription(path.getDescription());
970 dataDefinition.setToscaResourceName(path.getToscaResourceName());
971 return dataDefinition;
974 private Service createOrUpdateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean isUpdate, String errorContext,
976 validateUserAndRole(serviceUpdate, user, errorContext);
977 Map<String, ForwardingPathDataDefinition> forwardingPaths = serviceUpdate.getForwardingPaths();
978 Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths = forwardingPaths.entrySet().stream()
979 .collect(Collectors.toMap(Map.Entry::getKey, entry -> new ForwardingPathDataDefinition(getTrimmedValues(entry.getValue()))));
980 forwardingPathValidator.validateForwardingPaths(trimmedForwardingPaths.values(), serviceId, isUpdate);
981 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
982 if (serviceStorageOperationStatusEither.isRight()) {
983 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
984 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
985 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(errorStatus));
987 Service storedService = serviceStorageOperationStatusEither.left().value();
988 Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
989 Component component = getForwardingPathOriginComponent();
990 final String toscaResourceName;
991 if (component.getComponentType() == ComponentTypeEnum.RESOURCE) {
992 toscaResourceName = ((Resource) component).getToscaResourceName();
994 toscaResourceName = "";
997 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Forwarding Path on Service");
998 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, storedService.getSystemName());
1000 Map<String, ForwardingPathDataDefinition> resultMap = new HashMap<>();
1002 trimmedForwardingPaths.values().forEach(fp -> fp.setToscaResourceName(toscaResourceName));
1003 populateForwardingPaths(serviceId, isUpdate, trimmedForwardingPaths, resultMap);
1004 janusGraphDao.commit();
1007 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
1010 return createServiceWithForwardingPathForResponse(serviceId, resultMap);
1013 private Component getForwardingPathOriginComponent() {
1014 Either<Component, StorageOperationStatus> forwardingPathOrigin = toscaOperationFacade
1015 .getLatestByName(ForwardingPathUtils.FORWARDING_PATH_NODE_NAME, null);
1016 if (forwardingPathOrigin.isRight()) {
1017 StorageOperationStatus errorStatus = forwardingPathOrigin.right().value();
1018 log.debug("Failed to fetch normative forwarding path resource by tosca name, error {}", errorStatus);
1019 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(errorStatus));
1021 return forwardingPathOrigin.left().value();
1024 private void populateForwardingPaths(String serviceId, boolean isUpdate, Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths,
1025 Map<String, ForwardingPathDataDefinition> resultMap) {
1026 Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
1028 for (ForwardingPathDataDefinition forwardingPathDataDefinition : trimmedForwardingPaths.values()) {
1030 result = forwardingPathOperation.updateForwardingPath(serviceId, forwardingPathDataDefinition);
1032 result = forwardingPathOperation.addForwardingPath(serviceId, forwardingPathDataDefinition);
1034 if (result.isRight()) {
1035 janusGraphDao.rollback();
1036 throw new ByResponseFormatComponentException(componentsUtils
1037 .getResponseFormat(componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE), ""));
1039 ForwardingPathDataDefinition fpDataDefinition = result.left().value();
1040 resultMap.put(fpDataDefinition.getUniqueId(), forwardingPathDataDefinition);
1043 } catch (ComponentException e) {
1044 janusGraphDao.rollback();
1045 log.error("Exception occurred during add or update forwarding path property values: {}", e.getMessage(), e);
1046 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1050 private Service createServiceWithForwardingPathForResponse(String serviceId,
1051 Map<String, ForwardingPathDataDefinition> forwardingPathDataDefinitionMap) {
1052 Service service = new Service();
1053 service.setUniqueId(serviceId);
1054 service.setForwardingPaths(forwardingPathDataDefinitionMap);
1058 private void validateUserAndRole(Service serviceUpdate, User user, String errorContext) {
1059 user = validateUser(user, errorContext, serviceUpdate, null, false);
1060 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1064 Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate, boolean subNodeChanged,
1065 List<String> subNodePropsToBeRemoved) {
1067 boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
1068 if (subNodeChanged) {
1069 if (!subNodePropsToBeRemoved.isEmpty()) {
1070 areSubstitutionNodePropertiesInUse(currentService, subNodePropsToBeRemoved);
1072 currentService.setDerivedFromGenericVersion(serviceUpdate.getDerivedFromGenericVersion());
1073 currentService.setDerivedFromGenericType(serviceUpdate.getDerivedFromGenericType());
1076 Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified,
1077 UPDATE_SERVICE_METADATA);
1078 if (response.isRight()) {
1079 ResponseFormat errorResponse = response.right().value();
1080 return Either.right(errorResponse);
1082 verifyValuesAreIdentical(serviceUpdate.getCreatorUserId(), currentService.getCreatorUserId(), "creatorUserId");
1083 verifyValuesAreIdentical(serviceUpdate.getCreatorFullName(), currentService.getCreatorFullName(), "creatorFullName");
1084 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterUserId(), currentService.getLastUpdaterUserId(), "lastUpdaterUserId");
1085 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterFullName(), currentService.getLastUpdaterFullName(), "lastUpdaterFullName");
1086 response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null);
1087 if (response.isRight()) {
1088 return Either.right(response.right().value());
1090 verifyValuesAreIdentical(serviceUpdate.getDistributionStatus(), currentService.getDistributionStatus(), "distributionStatus");
1091 if (serviceUpdate.getProjectCode() != null) {
1092 response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1093 if (response.isRight()) {
1094 return Either.right(response.right().value());
1097 response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1098 if (response.isRight()) {
1099 return Either.right(response.right().value());
1101 verifyValuesAreIdentical(serviceUpdate.getCreationDate(), currentService.getCreationDate(), "creationDate");
1102 verifyValuesAreIdentical(serviceUpdate.getVersion(), currentService.getVersion(), "version");
1103 response = validateAndUpdateDescription(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1104 if (response.isRight()) {
1105 return Either.right(response.right().value());
1107 response = validateAndUpdateTags(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1108 if (response.isRight()) {
1109 return Either.right(response.right().value());
1111 response = validateAndUpdateContactId(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1112 if (response.isRight()) {
1113 return Either.right(response.right().value());
1115 verifyValuesAreIdentical(serviceUpdate.getLastUpdateDate(), currentService.getLastUpdateDate(), "lastUpdateDate");
1116 verifyValuesAreIdentical(serviceUpdate.getLifecycleState(), currentService.getLifecycleState(), "lifecycleState");
1117 verifyValuesAreIdentical(serviceUpdate.isHighestVersion(), currentService.isHighestVersion(), "isHighestVersion");
1118 verifyValuesAreIdentical(serviceUpdate.getUUID(), currentService.getUUID(), "uuid");
1119 validateAndUpdateServiceType(currentService, serviceUpdate);
1120 validateAndUpdateServiceFunction(currentService, serviceUpdate);
1121 response = validateAndUpdateServiceRole(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1122 if (response.isRight()) {
1123 return Either.right(response.right().value());
1125 response = validateAndUpdateInstantiationTypeValue(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1126 if (response.isRight()) {
1127 return Either.right(response.right().value());
1129 verifyValuesAreIdentical(serviceUpdate.getInvariantUUID(), currentService.getInvariantUUID(), "invariantUUID");
1130 validateAndUpdateEcompNaming(currentService, serviceUpdate);
1131 currentService.setEnvironmentContext(serviceUpdate.getEnvironmentContext());
1132 currentService.setCategorySpecificMetadata(serviceUpdate.getCategorySpecificMetadata());
1133 return Either.left(currentService);
1134 } catch (ComponentException exception) {
1135 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
1137 .auditComponentAdmin(responseFormat, user, serviceUpdate, AuditingActionEnum.UPDATE_SERVICE_METADATA, ComponentTypeEnum.SERVICE);
1138 return Either.right(responseFormat);
1142 private void addPropertiesToService(Service currentService, List<PropertyDefinition> subNodePropsToBeAdded) {
1143 ListUtils.emptyIfNull(subNodePropsToBeAdded).forEach(prop -> {
1144 Either<PropertyDefinition, StorageOperationStatus> addPropertyEither =
1145 toscaOperationFacade.addPropertyToComponent(prop, currentService);
1146 if (addPropertyEither.isRight()) {
1147 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1152 private void addInputsToService(Service currentService, List<PropertyDefinition> subNodePropsToBeAdded) {
1153 ListUtils.emptyIfNull(subNodePropsToBeAdded).forEach(prop -> {
1154 InputDefinition inputDef = new InputDefinition(prop);
1155 Either<InputDefinition, StorageOperationStatus> status =
1156 toscaOperationFacade.addInputToComponent(prop.getName(), inputDef, currentService);
1157 if (status.isRight()) {
1158 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1163 private void removePropertiesFromService(Service currentService, List<String> subNodePropsToBeRemoved) {
1164 List<PropertyDefinition> props = currentService.getProperties();
1165 List<String> propsUniqueIdsToBeRemoved =
1166 props.stream().filter(prop -> subNodePropsToBeRemoved.contains(prop.getName())).map(PropertyDefinition::getUniqueId)
1167 .collect(Collectors.toList());
1168 ListUtils.emptyIfNull(props).stream().filter(prop -> propsUniqueIdsToBeRemoved.contains(prop.getUniqueId())).forEach(prop -> {
1169 StorageOperationStatus status = toscaOperationFacade.deletePropertyOfComponent(currentService, prop.getName());
1170 if (status != StorageOperationStatus.OK) {
1171 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1176 private void removeInputsFromService(Service currentService, List<String> subNodePropsToBeRemoved) {
1177 List<PropertyDefinition> props = currentService.getProperties();
1178 List<InputDefinition> inputs = currentService.getInputs();
1179 List<String> propsUniqueIdsToBeRemoved =
1180 props.stream().filter(prop -> subNodePropsToBeRemoved.contains(prop.getName())).map(PropertyDefinition::getUniqueId)
1181 .collect(Collectors.toList());
1182 ListUtils.emptyIfNull(inputs).stream().filter(input -> input.isMappedToComponentProperty() &&
1183 (propsUniqueIdsToBeRemoved.contains(input.getPropertyId()) || subNodePropsToBeRemoved.contains(input.getName()))).forEach(input -> {
1184 StorageOperationStatus status = toscaOperationFacade.deleteInputOfResource(currentService, input.getName());
1185 if (status != StorageOperationStatus.OK) {
1186 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1191 private void areSubstitutionNodePropertiesInUse(Service service, List<String> subNodePropsToBeRemoved) {
1192 Map<String, List<ComponentInstanceProperty>> componentInstancesProps = service.getComponentInstancesProperties();
1193 List<String> propsUniqueIdsToBeRemoved =
1194 ListUtils.emptyIfNull(service.getProperties()).stream().filter(prop -> subNodePropsToBeRemoved.contains(prop.getName()))
1195 .map(PropertyDefinition::getUniqueId)
1196 .collect(Collectors.toList());
1197 List<String> inputsUniqueIdsToBeRemoved = ListUtils.emptyIfNull(service.getInputs()).stream()
1198 .filter(input -> propsUniqueIdsToBeRemoved.contains(input.getPropertyId()) || subNodePropsToBeRemoved.contains(input.getName()))
1199 .map(PropertyDefinition::getUniqueId)
1200 .collect(Collectors.toList());
1201 Map<String, List<String>> inUse = new HashMap<>();
1202 if (componentInstancesProps != null && !componentInstancesProps.isEmpty()) {
1203 componentInstancesProps.forEach((compInstanceId, listOfProps) -> {
1204 List<String> propsInUse = new ArrayList<>();
1205 listOfProps.stream()
1206 .filter(PropertyDataDefinition::isToscaFunction)
1207 .filter(compProp -> ToscaFunctionType.isGetFunction(compProp.getToscaFunction().getType()))
1208 .forEach(compProp -> {
1209 ToscaFunction toscaFunction = compProp.getToscaFunction();
1210 ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) toscaFunction;
1211 String propName = toscaGetFunction.getPropertyName();
1212 String propUniqueId = toscaGetFunction.getPropertyUniqueId();
1213 if (inputsUniqueIdsToBeRemoved.contains(propUniqueId) || propsUniqueIdsToBeRemoved.contains(propUniqueId) ||
1214 subNodePropsToBeRemoved.contains(propName)) {
1215 propsInUse.add(compProp.getName());
1218 if (!propsInUse.isEmpty()) {
1219 Optional<ComponentInstance> componentInstance = service.getComponentInstanceById(compInstanceId);
1220 componentInstance.ifPresent(instance -> inUse.put(instance.getName(), propsInUse));
1225 if (!inUse.isEmpty()) {
1226 String propsInUse = inUse.entrySet().stream().map(entry -> {
1227 String properties = entry.getValue().stream().map(Object::toString).collect(Collectors.joining(", "));
1228 return properties + " on " + entry.getKey();
1229 }).collect(Collectors.joining(", properties "));
1230 throw new ByActionStatusComponentException(ActionStatus.SUBSTITUTION_NODE_TYPE_PROPERTY_IN_USE, propsInUse);
1235 private boolean isSubstitutionNodeChanged(Service currentService, Service updatedService) {
1236 String currentServiceType = currentService.getDerivedFromGenericType();
1237 String updatedServiceType = updatedService.getDerivedFromGenericType();
1238 String currentServiceVersion = currentService.getDerivedFromGenericVersion();
1239 String updatedServiceVersion = updatedService.getDerivedFromGenericVersion();
1240 return !(StringUtils.equals(currentServiceType, updatedServiceType) && StringUtils.equals(currentServiceVersion, updatedServiceVersion));
1243 private List<String> getSubstitutionNodePropertiesToBeRemoved(Service currentService, Service serviceUpdate) {
1244 List<PropertyDefinition> currentProps = ListUtils.emptyIfNull(fetchDerivedFromGenericType(currentService, null).getProperties());
1245 List<PropertyDefinition> updatedProps = ListUtils.emptyIfNull(fetchDerivedFromGenericType(serviceUpdate, null).getProperties());
1246 if (!StringUtils.equals(currentService.getDerivedFromGenericType(), serviceUpdate.getDerivedFromGenericType())) {
1247 return currentProps.stream().map(PropertyDefinition::getName).collect(Collectors.toList());
1250 Map<String, PropertyDefinition> currentPropsMap = currentProps.stream().collect(Collectors.toMap(prop -> prop.getName(), prop -> prop));
1251 Map<String, PropertyDefinition> updatedPropsMap = updatedProps.stream().collect(Collectors.toMap(prop -> prop.getName(), prop -> prop));
1253 List<String> propNamesToBeRemoved = new ArrayList<>();
1254 for (String currentPropertyName: currentPropsMap.keySet()) {
1255 if (updatedPropsMap.containsKey(currentPropertyName)) {
1256 if (!haveSameType(currentPropsMap.get(currentPropertyName), updatedPropsMap.get(currentPropertyName))) {
1257 propNamesToBeRemoved.add(currentPropertyName);
1260 propNamesToBeRemoved.add(currentPropertyName);
1264 return propNamesToBeRemoved;
1267 private boolean haveSameType(final PropertyDefinition property1, final PropertyDefinition property2){
1268 if (property1.getType().equals("list")) {
1269 return property2.getType().equals("list") && property1.getSchema().equals(property2.getSchema());
1271 if (property1.getType().equals("map")) {
1272 return property2.getType().equals("map") && property1.getSchema().equals(property2.getSchema());
1274 return property1.getType().equals(property2.getType());
1277 private List<PropertyDefinition> getSubstitutionNodePropertiesToBeAdded(Service currentService, Service serviceUpdate) {
1278 List<PropertyDefinition> propsInCurrentVersion = ListUtils.emptyIfNull(fetchDerivedFromGenericType(currentService, null).getProperties());
1279 List<PropertyDefinition> propsInUpdatedVersion = ListUtils.emptyIfNull(fetchDerivedFromGenericType(serviceUpdate, null).getProperties());
1280 if (!StringUtils.equals(currentService.getDerivedFromGenericType(), serviceUpdate.getDerivedFromGenericType())) {
1281 return propsInUpdatedVersion;
1284 Map<String, PropertyDefinition> mapOfPropsInCurrentVersion = propsInCurrentVersion.stream().collect(Collectors.toMap(prop -> prop.getName(), prop -> prop));
1285 Map<String, PropertyDefinition> mapOfPropsInUpdatedVersion = propsInUpdatedVersion.stream().collect(Collectors.toMap(prop -> prop.getName(), prop -> prop));
1287 List<PropertyDefinition> propsToBeAdded = new ArrayList<>();
1288 for (Entry<String, PropertyDefinition> propertyInUpdatedVersion: mapOfPropsInUpdatedVersion.entrySet()) {
1289 if (mapOfPropsInCurrentVersion.containsKey(propertyInUpdatedVersion.getKey())) {
1290 if (!haveSameType(mapOfPropsInCurrentVersion.get(propertyInUpdatedVersion.getKey()), propertyInUpdatedVersion.getValue())) {
1291 propsToBeAdded.add(propertyInUpdatedVersion.getValue());
1294 propsToBeAdded.add(propertyInUpdatedVersion.getValue());
1298 return propsToBeAdded;
1302 private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
1303 if (updatedValue != null && !updatedValue.equals(originalValue)) {
1304 log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
1308 private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
1309 Boolean isEcompGeneratedCurr = currentService.isEcompGeneratedNaming();
1310 Boolean isEcompGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
1311 if (isEcompGeneratedUpdate != null && !isEcompGeneratedUpdate.equals(isEcompGeneratedCurr)) {
1312 currentService.setEcompGeneratedNaming(isEcompGeneratedUpdate);
1314 String namingPolicyUpdate = serviceUpdate.getNamingPolicy();
1315 if (currentService.isEcompGeneratedNaming() != null && currentService.isEcompGeneratedNaming()) {
1316 currentService.setNamingPolicy(namingPolicyUpdate);
1318 if (!StringUtils.isEmpty(namingPolicyUpdate)) {
1319 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
1321 currentService.setNamingPolicy("");
1325 private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate,
1326 AuditingActionEnum audatingAction) {
1327 String contactIdUpdated = serviceUpdate.getContactId();
1328 String contactIdCurrent = currentService.getContactId();
1329 if (!contactIdCurrent.equals(contactIdUpdated)) {
1330 componentContactIdValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1331 currentService.setContactId(contactIdUpdated.toLowerCase());
1333 return Either.left(true);
1336 private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate,
1337 AuditingActionEnum audatingAction) {
1338 List<String> tagsUpdated = serviceUpdate.getTags();
1339 List<String> tagsCurrent = currentService.getTags();
1340 if (tagsUpdated == null || tagsUpdated.isEmpty()) {
1341 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
1342 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
1343 return Either.right(responseFormat);
1345 if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
1346 componentTagsValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1347 currentService.setTags(tagsUpdated);
1349 return Either.left(true);
1352 private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate,
1353 AuditingActionEnum audatingAction) {
1354 String descriptionUpdated = serviceUpdate.getDescription();
1355 String descriptionCurrent = currentService.getDescription();
1356 if (!descriptionCurrent.equals(descriptionUpdated)) {
1357 componentDescriptionValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1358 currentService.setDescription(serviceUpdate.getDescription());
1360 return Either.left(true);
1363 private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate,
1364 AuditingActionEnum audatingAction) {
1365 String projectCodeUpdated = serviceUpdate.getProjectCode();
1366 String projectCodeCurrent = currentService.getProjectCode();
1367 if (StringUtils.isEmpty(projectCodeCurrent) || !projectCodeCurrent.equals(projectCodeUpdated)) {
1369 componentProjectCodeValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1370 } catch (ComponentException exp) {
1371 ResponseFormat errorRespons = exp.getResponseFormat();
1372 return Either.right(errorRespons);
1374 currentService.setProjectCode(projectCodeUpdated);
1376 return Either.left(true);
1379 private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified,
1380 AuditingActionEnum audatingAction) {
1381 String iconUpdated = serviceUpdate.getIcon();
1382 String iconCurrent = currentService.getIcon();
1383 if (!iconCurrent.equals(iconUpdated)) {
1384 if (!hasBeenCertified) {
1385 componentIconValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1386 currentService.setIcon(iconUpdated);
1388 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
1389 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
1390 return Either.right(errorResponse);
1393 return Either.left(true);
1396 private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate,
1397 boolean hasBeenCertified, AuditingActionEnum auditingAction) {
1398 String serviceNameUpdated = serviceUpdate.getName();
1399 String serviceNameCurrent = currentService.getName();
1400 if (!serviceNameCurrent.equals(serviceNameUpdated)) {
1401 if (!hasBeenCertified) {
1402 componentNameValidator.validateAndCorrectField(user, serviceUpdate, auditingAction);
1404 componentNameValidator.validateComponentNameUnique(user, serviceUpdate, auditingAction);
1405 } catch (ComponentException exp) {
1406 return Either.right(exp.getResponseFormat());
1408 currentService.setName(serviceNameUpdated);
1409 currentService.getComponentMetadataDefinition().getMetadataDataDefinition()
1410 .setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
1411 currentService.getComponentMetadataDefinition().getMetadataDataDefinition()
1412 .setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
1414 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
1415 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
1416 return Either.right(errorResponse);
1419 return Either.left(true);
1422 private void validateAndUpdateServiceType(Service currentService, Service updatedService) {
1423 String updatedServiceType = updatedService.getServiceType();
1424 String currentServiceType = currentService.getServiceType();
1425 if (!currentServiceType.equals(updatedServiceType)) {
1426 serviceTypeValidator.validateAndCorrectField(null, updatedService, null);
1427 currentService.setServiceType(updatedServiceType);
1431 private void validateAndUpdateServiceFunction(Service currentService, Service updatedService) {
1432 String updatedServiceFunction = updatedService.getServiceFunction();
1433 String currentServiceFunction = currentService.getServiceFunction();
1434 if (!currentServiceFunction.equals(updatedServiceFunction)) {
1435 serviceFunctionValidator.validateAndCorrectField(null, updatedService, null);
1436 currentService.setServiceFunction(updatedService.getServiceFunction());
1440 private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService,
1441 AuditingActionEnum auditingAction) {
1442 String updatedServiceRole = updatedService.getServiceRole();
1443 String currentServiceRole = currentService.getServiceRole();
1444 if (!currentServiceRole.equals(updatedServiceRole)) {
1446 serviceRoleValidator.validateAndCorrectField(user, updatedService, auditingAction);
1447 } catch (ComponentException exp) {
1448 ResponseFormat errorResponse = exp.getResponseFormat();
1449 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1450 return Either.right(errorResponse);
1452 currentService.setServiceRole(updatedServiceRole);
1454 return Either.left(true);
1457 private Either<Boolean, ResponseFormat> validateAndUpdateInstantiationTypeValue(User user, Service currentService, Service updatedService,
1458 AuditingActionEnum auditingAction) {
1459 String updatedInstaType = updatedService.getInstantiationType();
1460 String currentInstaType = currentService.getInstantiationType();
1461 if (!currentInstaType.equals(updatedInstaType)) {
1463 serviceInstantiationTypeValidator.validateAndCorrectField(user, updatedService, auditingAction);
1464 } catch (ComponentException exp) {
1465 ResponseFormat errorResponse = exp.getResponseFormat();
1466 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1467 return Either.right(errorResponse);
1469 currentService.setInstantiationType(updatedInstaType);
1471 return Either.left(true);
1474 private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate,
1475 boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1477 List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1478 List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1479 serviceCategoryValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1480 if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1481 if (!hasBeenCertified) {
1482 currentService.setCategories(categoryUpdated);
1484 log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1485 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1486 return Either.right(errorResponse);
1489 } catch (ComponentException exp) {
1490 return Either.right(exp.getResponseFormat());
1492 return Either.left(true);
1495 public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1496 Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1497 if (serviceResponseFormatEither.isRight()) {
1498 return Either.right(serviceResponseFormatEither.right().value());
1500 final ServiceRelations serviceRelations = new ForwardingPathUtils()
1501 .convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1502 return Either.left(serviceRelations);
1505 public void deleteServiceAllVersions(String serviceId, User user) {
1506 validateUserExists(user);
1507 Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1508 if (serviceStatus.isRight()) {
1509 log.debug("Failed to get service {}", serviceId);
1510 componentException(serviceStatus.right().value());
1512 Service service = serviceStatus.left().value();
1513 if (Boolean.FALSE.equals(service.isArchived())) {
1514 log.debug("The service, {}, requested for delete has not been archived.", serviceId);
1515 throw new ComponentException(ActionStatus.COMPONENT_NOT_ARCHIVED, serviceId);
1517 List<String> deletedServiceList = new ArrayList<>();
1519 String model = service.getModel();
1520 final Optional<Model> modelOptional = modelOperation.findModelByName(model);
1521 deletedServiceList = toscaOperationFacade.deleteService(service.getInvariantUUID(), true);
1522 if (log.isDebugEnabled()) {
1523 deletedServiceList.forEach(deletedS -> log.debug("Component {} was deleted.", deletedS));
1525 if (modelOptional.isPresent() && modelOptional.get().getModelType() == ModelTypeEnum.NORMATIVE_EXTENSION) {
1526 modelOperation.deleteModel(modelOptional.get(), false);
1528 toscaOperationFacade.commitAndCheck(service.getUniqueId());
1529 updateCatalog(service, ChangeTypeEnum.DELETE);
1530 } catch (ComponentException exception) {
1531 log.debug("Failed to delete service, {}, in ServiceServlet", serviceId);
1532 janusGraphDao.rollback();
1537 public ResponseFormat markServiceForDeletion(String serviceId, User user) {
1538 ResponseFormat responseFormat;
1539 validateUserExists(user);
1540 Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1541 if (serviceStatus.isRight()) {
1542 log.debug("failed to get service {}", serviceId);
1543 return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1545 Service service = serviceStatus.left().value();
1546 StorageOperationStatus result = StorageOperationStatus.OK;
1548 lockComponent(service, "Mark service to delete");
1549 result = markComponentToDelete(service);
1550 if (result == StorageOperationStatus.OK) {
1551 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1553 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1554 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1556 return responseFormat;
1557 } catch (ComponentException e) {
1558 return e.getResponseFormat();
1560 if (result == null || result != StorageOperationStatus.OK) {
1561 log.warn("operation failed. do rollback");
1562 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1563 janusGraphDao.rollback();
1565 log.debug("operation success. do commit");
1566 janusGraphDao.commit();
1568 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1572 public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1573 ResponseFormat responseFormat;
1574 String ecompErrorContext = "delete service";
1575 validateUserNotEmpty(user, ecompErrorContext);
1576 user = validateUserExists(user);
1577 Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1578 if (getResult.isRight()) {
1579 return getResult.right().value();
1581 Service service = getResult.left().value();
1582 StorageOperationStatus result = StorageOperationStatus.OK;
1584 lockComponent(service, "Mark service to delete");
1585 result = markComponentToDelete(service);
1586 if (result == StorageOperationStatus.OK) {
1587 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1589 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1590 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1592 return responseFormat;
1593 } catch (ComponentException e) {
1594 result = StorageOperationStatus.GENERAL_ERROR;
1595 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1597 if (result == null || result != StorageOperationStatus.OK) {
1598 log.warn("operation failed. do rollback");
1599 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1600 janusGraphDao.rollback();
1602 log.debug("operation success. do commit");
1603 janusGraphDao.commit();
1605 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1609 public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1610 String ecompErrorContext = "Get service";
1611 validateUserNotEmpty(user, ecompErrorContext);
1612 validateUserExists(user);
1613 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1614 if (storageStatus.isRight()) {
1615 log.debug("failed to get service by id {}", serviceId);
1616 return Either.right(componentsUtils
1617 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1619 if (!(storageStatus.left().value() instanceof Service)) {
1621 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1623 Service service = storageStatus.left().value();
1624 return Either.left(service);
1627 public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1628 validateUserExists(userId);
1629 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade
1630 .getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1631 if (storageStatus.isRight()) {
1632 log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1633 return Either.right(componentsUtils
1634 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE),
1637 Service service = storageStatus.left().value();
1638 return Either.left(service);
1641 @SuppressWarnings("unchecked")
1642 private void createMandatoryArtifactsData(Service service, User user) {
1643 // create mandatory artifacts
1645 // TODO it must be removed after that artifact uniqueId creation will be
1647 // moved to ArtifactOperation
1648 String serviceUniqueId = service.getUniqueId();
1649 Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1650 if (artifactMap == null) {
1651 artifactMap = new HashMap<>();
1653 Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
1654 .getInformationalServiceArtifacts();
1655 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1656 String category = service.getCategories().get(0).getName();
1657 boolean isCreateArtifact = true;
1658 if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1659 for (String exlude : exludeServiceCategory) {
1660 if (exlude.equalsIgnoreCase(category)) {
1661 isCreateArtifact = false;
1666 if (informationalServiceArtifacts != null && isCreateArtifact) {
1667 Set<String> keys = informationalServiceArtifacts.keySet();
1668 for (String informationalServiceArtifactName : keys) {
1669 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1670 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap,
1672 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1674 service.setArtifacts(artifactMap);
1678 private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user,
1679 Boolean isServiceApi) {
1680 ArtifactDefinition artifactInfo = artifactsBusinessLogic
1681 .createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1682 if (Boolean.TRUE.equals(isServiceApi)) {
1683 artifactInfo.setMandatory(false);
1684 artifactInfo.setServiceApi(true);
1686 return artifactInfo;
1689 private String getEnvNameFromConfiguration() {
1690 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1691 log.trace("Update environment name to be {}", configuredEnvName);
1692 return configuredEnvName;
1695 public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier,
1696 ServiceDistributionReqInfo data) {
1697 Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation
1698 .validateActivateServiceRequest(serviceId, envId, modifier, data);
1699 if (activationRequestInformationEither.isRight()) {
1700 return Either.right(activationRequestInformationEither.right().value());
1702 ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1703 String did = ThreadLocalsHolder.getUuid();
1704 Service service = activationRequestInformation.getServiceToActivate();
1705 return buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1708 private Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext,
1710 String envName = getEnvNameFromConfiguration();
1711 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1712 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1713 if (notifyServiceResponse == ActionStatus.OK) {
1714 return Either.left(did);
1716 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1717 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1718 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1719 return Either.right(error);
1723 public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1724 User user = validateUserExists(modifier.getUserId());
1725 validateUserRole(user, Collections.singletonList(Role.DESIGNER));
1726 Either<Service, ResponseFormat> result;
1727 ResponseFormat response;
1728 Service updatedService;
1729 String did = ThreadLocalsHolder.getUuid();
1731 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1732 if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1733 log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1734 envName = configuredEnvName;
1736 if (!kafkaHandler.isKafkaActive()) {
1738 ServletContext servletContext = request.getSession().getServletContext();
1739 boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1740 if (!isDistributionEngineUp) {
1741 BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1742 log.debug("Distribution Engine is DOWN");
1743 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1744 return Either.right(response);
1747 Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1748 if (serviceRes.isRight()) {
1749 log.debug("failed retrieving service");
1750 response = componentsUtils
1751 .getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1752 componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1753 new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()), ResourceVersionInfo.newBuilder().build(), did);
1754 return Either.right(response);
1756 Service service = serviceRes.left().value();
1757 if (Boolean.TRUE.equals(service.isArchived())) {
1758 log.info("Component is archived. Component id: {}", serviceId);
1759 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, service.getName()));
1761 if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1762 log.info("service {} is not available for distribution. Should be in certified state", service.getUniqueId());
1763 ResponseFormat responseFormat = componentsUtils
1764 .getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1765 return Either.right(responseFormat);
1767 String dcurrStatus = service.getDistributionStatus().name();
1768 String updatedStatus = dcurrStatus;
1769 StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1770 if (readyForDistribution == StorageOperationStatus.OK) {
1771 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1772 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1773 if (notifyServiceResponse == ActionStatus.OK) {
1774 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user,
1775 DistributionStatusEnum.DISTRIBUTED);
1776 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1777 updatedService = updateStateRes.left().value();
1778 updatedStatus = updatedService.getDistributionStatus().name();
1780 // The response is not relevant
1781 updatedService = service;
1783 ASDCKpiApi.countActivatedDistribution();
1784 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1785 result = Either.left(updatedService);
1787 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1788 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1789 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1790 result = Either.right(response);
1793 response = componentsUtils
1794 .getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution, ComponentTypeEnum.SERVICE), envName);
1795 result = Either.right(response);
1797 componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1798 new ResourceCommonInfo(service.getName(), ComponentTypeEnum.SERVICE.getValue()),
1799 ResourceVersionInfo.newBuilder().distributionStatus(dcurrStatus).build(),
1800 ResourceVersionInfo.newBuilder().distributionStatus(updatedStatus).build(), null, null, did);
1804 // convert to private after deletion of temp url
1805 public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1806 validateUserExists(user.getUserId());
1807 String serviceId = service.getUniqueId();
1808 lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1810 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
1811 if (result.isRight()) {
1812 janusGraphDao.rollback();
1813 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
1814 log.debug("service {} change distribution status failed", serviceId);
1815 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1817 janusGraphDao.commit();
1818 updateCatalog(service, ChangeTypeEnum.LIFECYCLE);
1819 return Either.left(result.left().value());
1821 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1825 public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
1826 validateUserExists(user.getUserId());
1827 log.debug("mark distribution deployed");
1828 AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
1829 Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
1830 if (getServiceResponse.isRight()) {
1831 BeEcompErrorManager.getInstance()
1832 .logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
1833 log.debug("service {} not found", serviceId);
1834 ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null,
1835 componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
1836 return Either.right(responseFormat);
1838 Service service = getServiceResponse.left().value();
1839 user = validateRoleForDeploy(did, user, auditAction, service);
1840 return checkDistributionAndDeploy(did, user, auditAction, service);
1843 public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1844 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
1845 // Only one VF Module Artifact per instance - add it to a list of one
1846 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
1847 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1850 private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock,
1851 boolean inTransaction, ComponentInstance ri) {
1852 List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
1853 if (ri.getOriginType() == OriginTypeEnum.VF) {
1854 asList = Arrays.asList(new VfModuleArtifactGenerator(modifier, ri, service, shouldLock, inTransaction));
1859 public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1860 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
1861 // Get All Deployment Artifacts
1862 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance)
1863 .filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
1864 // Filter in Only Heat Env
1865 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
1866 // Create ArtifactGenerator from those Artifacts
1868 depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction,
1869 resourceInstance.getUniqueId())).collect(Collectors.toList());
1870 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1873 private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service,
1874 Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
1875 // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
1878 if (service.getComponentInstances() != null) {
1879 List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream()
1880 .flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
1881 if (artifactGenList != null && !artifactGenList.isEmpty()) {
1882 Either<Service, ResponseFormat> callRes = checkDeploymentArtifact(artifactGenList);
1883 if (callRes != null) {
1888 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
1889 if (storageStatus.isRight()) {
1890 return Either.right(componentsUtils
1891 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1893 Service currentService = storageStatus.left().value();
1894 return Either.left(currentService);
1897 private <CallVal> Either<Service, ResponseFormat> checkDeploymentArtifact(List<ArtifactGenerator<CallVal>> artifactGenList) {
1898 for (ArtifactGenerator<CallVal> entry : artifactGenList) {
1899 Either<CallVal, ResponseFormat> callRes;
1901 callRes = entry.call();
1902 if (callRes.isRight()) {
1903 log.debug("Failed to generate artifact error : {}", callRes.right().value());
1904 return Either.right(callRes.right().value());
1906 } catch (Exception e) {
1907 log.debug("Failed to generate artifact exception : {}", e);
1908 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1914 private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction,
1916 boolean isDeployed = isDistributionDeployed(distributionId);
1918 return Either.left(service);
1920 Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
1921 if (distributionSuccess.isRight()) {
1922 return Either.right(distributionSuccess.right().value());
1924 log.debug("mark distribution {} as deployed - success", distributionId);
1926 .auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK",
1928 return Either.left(service);
1931 private boolean isDistributionDeployed(String distributionId) {
1932 Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao
1933 .getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
1934 boolean isDeployed = false;
1935 if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
1937 log.debug("distribution {} is already deployed", distributionId);
1943 protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
1944 log.trace("checkDistributionSuccess");
1945 // get all "DRequest" records for this distribution
1946 Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao
1947 .getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
1948 if (distRequestsResponse.isRight()) {
1949 ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
1950 return Either.right(error);
1952 List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
1953 if (distributionRequests.isEmpty()) {
1954 BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
1955 log.info("distribution {} is not found", did);
1956 ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
1957 return Either.right(error);
1959 boolean isRequestSucceeded = false;
1960 for (ResourceAdminEvent event : distributionRequests) {
1961 String eventStatus = event.getStatus();
1962 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1963 isRequestSucceeded = true;
1967 // get all "DNotify" records for this distribution
1968 Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao
1969 .getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
1970 if (distNotificationsResponse.isRight()) {
1971 ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
1972 return Either.right(error);
1974 List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
1975 boolean isNotificationsSucceeded = false;
1976 for (DistributionNotificationEvent event : distributionNotifications) {
1977 String eventStatus = event.getStatus();
1978 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1979 isNotificationsSucceeded = true;
1983 // if request failed OR there are notifications that failed
1984 if (!(isRequestSucceeded && isNotificationsSucceeded)) {
1985 log.info("distribution {} has failed", did);
1986 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1987 auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1988 return Either.right(error);
1990 return Either.left(true);
1993 private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status,
1995 ResponseFormat error = componentsUtils.getResponseFormat(status, params);
1996 String message = "";
1997 if (error.getMessageId() != null) {
1998 message = error.getMessageId() + ": ";
2000 message += error.getFormattedMessage();
2001 if (service != null) {
2003 .auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(),
2006 componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
2011 private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
2012 user = userAdmin.getUser(user.getUserId());
2013 log.debug("validate user role");
2014 List<Role> roles = new ArrayList<>();
2015 roles.add(Role.ADMIN);
2016 roles.add(Role.DESIGNER);
2018 validateUserRole(user, service, roles, auditAction, null);
2019 } catch (ByActionStatusComponentException e) {
2020 log.info("role {} is not allowed to perform this action", user.getRole());
2021 auditDeployError(did, user, auditAction, service, e.getActionStatus());
2028 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
2029 if (component instanceof Service) {
2030 Service service = (Service) component;
2031 Map<String, ArtifactDefinition> artifactMap = service.getDeploymentArtifacts();
2032 if (artifactMap == null) {
2033 artifactMap = new HashMap<>();
2035 service.setDeploymentArtifacts(artifactMap);
2036 } else if (component instanceof Resource) {
2037 Resource resource = (Resource) component;
2038 Map<String, ArtifactDefinition> artifactMap = resource.getDeploymentArtifacts();
2039 if (artifactMap == null) {
2040 artifactMap = new HashMap<>();
2042 Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
2043 .getDeploymentResourceArtifacts();
2044 if (deploymentResourceArtifacts != null) {
2045 Map<String, ArtifactDefinition> finalArtifactMap = artifactMap;
2046 deploymentResourceArtifacts.forEach((k, v) -> processDeploymentResourceArtifacts(user, resource, finalArtifactMap, k, v));
2048 resource.setDeploymentArtifacts(artifactMap);
2052 private void processDeploymentResourceArtifacts(User user, Resource resource, Map<String, ArtifactDefinition> artifactMap, String k, Object v) {
2053 Map<String, Object> artifactDetails = (Map<String, Object>) v;
2054 Object object = artifactDetails.get(PLACE_HOLDER_RESOURCE_TYPES);
2055 if (object != null) {
2056 List<String> artifactTypes = (List<String>) object;
2057 if (!artifactTypes.contains(resource.getResourceType().name())) {
2061 log.info("resource types for artifact placeholder {} were not defined. default is all resources", k);
2063 if (artifactsBusinessLogic != null) {
2064 ArtifactDefinition artifactDefinition = artifactsBusinessLogic
2065 .createArtifactPlaceHolderInfo(resource.getUniqueId(), k, (Map<String, Object>) v, user, ArtifactGroupTypeEnum.DEPLOYMENT);
2066 if (artifactDefinition != null && !artifactMap.containsKey(artifactDefinition.getArtifactLabel())) {
2067 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
2073 public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
2074 return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
2077 private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
2078 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context
2079 .getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
2080 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
2081 return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
2085 public ComponentInstanceBusinessLogic getComponentInstanceBL() {
2086 return componentInstanceBusinessLogic;
2090 public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
2091 validateUserExists(userId);
2092 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2093 if (getComponentRes.isRight()) {
2094 ResponseFormat responseFormat = componentsUtils
2095 .getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
2096 return Either.right(responseFormat);
2098 List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
2099 return Either.left(componentInstances);
2103 public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
2104 this.forwardingPathOperation = forwardingPathOperation;
2108 * updates group instance with new property values in case of successful update of group instance related component instance will be updated with
2109 * new modification time and related service will be updated with new last update date
2111 public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId,
2112 String componentInstanceId, String groupInstanceId,
2113 List<GroupInstanceProperty> newProperties) {
2114 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2115 Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
2116 Component component = null;
2117 Either<Boolean, ResponseFormat> lockResult = null;
2118 log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
2120 validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2121 if (validateUserAndComponentRes.isRight()) {
2122 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed. ", groupInstanceId, serviceId);
2123 actionResult = Either.right(validateUserAndComponentRes.right().value());
2125 if (actionResult == null) {
2126 component = validateUserAndComponentRes.left().value().getKey();
2127 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2128 if (lockResult.isRight()) {
2129 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
2130 actionResult = Either.right(lockResult.right().value());
2132 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
2135 if (actionResult == null) {
2136 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId,
2138 if (actionResult.isRight()) {
2139 log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ",
2140 groupInstanceId, actionResult.right().value().getFormattedMessage());
2143 } catch (Exception e) {
2144 log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2145 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2147 if (lockResult != null && lockResult.isLeft() && Boolean.TRUE.equals(lockResult.left().value())) {
2148 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2151 return actionResult;
2154 private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component,
2155 String componentInstanceId,
2156 String groupInstanceId,
2157 List<GroupInstanceProperty> newProperties) {
2158 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2159 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2160 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2161 ComponentInstance relatedComponentInstance = null;
2162 GroupInstance oldGroupInstance = null;
2163 Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2164 GroupInstance updatedGroupInstance = null;
2165 boolean inTransaction = true;
2166 findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2167 if (findGroupInstanceRes.isRight()) {
2168 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
2169 actionResult = Either.right(findGroupInstanceRes.right().value());
2171 if (actionResult == null) {
2172 oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2173 relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2174 updateGroupInstanceResult = groupBusinessLogic
2175 .validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
2176 if (updateGroupInstanceResult.isRight()) {
2177 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ",
2178 oldGroupInstance.getName());
2179 actionResult = Either.right(updateGroupInstanceResult.right().value());
2182 if (actionResult == null) {
2183 updatedGroupInstance = updateGroupInstanceResult.left().value();
2184 if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2185 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance,
2186 updatedGroupInstance, inTransaction);
2187 if (updateParentsModificationTimeRes.isRight()) {
2189 "#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ",
2190 oldGroupInstance.getName());
2191 actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2195 if (actionResult == null) {
2196 actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2198 return actionResult;
2201 private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(
2202 Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance, boolean inTranscation) {
2203 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2204 Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2205 Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic
2206 .updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2207 updatedGroupInstance.getModificationTime(), inTranscation);
2208 if (updateComponentInstanceRes.isRight()) {
2209 log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(),
2210 updatedGroupInstance.getName());
2211 actionResult = Either.right(updateComponentInstanceRes.right().value());
2213 serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2214 if (serviceMetadataUpdateResult.isRight()) {
2215 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ",
2216 component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2217 actionResult = Either.right(
2218 componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2220 actionResult = Either
2221 .left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2224 return actionResult;
2227 private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2228 Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2229 User currUser = null;
2230 Component component = null;
2231 Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2232 if (validationUserResult.isRight()) {
2233 log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2234 result = Either.right(validationUserResult.right().value());
2236 if (result == null) {
2237 currUser = validationUserResult.left().value();
2239 component = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2240 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2241 log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(),
2242 component.getCreatorUserId());
2243 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2245 } catch (ComponentException e) {
2246 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2247 result = Either.right(e.getResponseFormat());
2250 if (result == null) {
2251 result = Either.left(new ImmutablePair<>(component, currUser));
2256 private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component,
2257 String componentInstanceId,
2258 String groupInstanceId) {
2259 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2260 GroupInstance groupInstance = null;
2261 ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2262 if (foundComponentInstance == null) {
2263 log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2264 actionResult = Either.right(componentsUtils
2265 .getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service",
2266 component.getName()));
2267 } else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2268 groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst()
2270 if (groupInstance == null) {
2271 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2272 actionResult = Either.right(componentsUtils
2273 .getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId,
2274 foundComponentInstance.getName()));
2277 if (actionResult == null) {
2278 actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2280 return actionResult;
2283 private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2284 ComponentInstance componentInstance = null;
2285 if (isNotEmpty(component.getComponentInstances())) {
2286 componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst()
2289 return componentInstance;
2292 private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2293 User user = validateUser(modifier, ecompErrorContext, null, null, false);
2294 List<Role> roles = new ArrayList<>();
2295 roles.add(Role.ADMIN);
2296 roles.add(Role.DESIGNER);
2297 validateUserRole(user, roles);
2298 return Either.left(user);
2301 public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId,
2302 List<String> dataParamsToReturn) {
2303 ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2304 paramsToReturn.setIgnoreComponentInstancesProperties(false);
2305 Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2306 if (serviceResultEither.isRight()) {
2307 if (serviceResultEither.right().value() == StorageOperationStatus.NOT_FOUND) {
2308 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2309 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2311 log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2312 return Either.right(
2313 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2315 Service service = serviceResultEither.left().value();
2316 if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
2317 ListUtils.emptyIfNull(service.getInputs()).stream().filter(input -> CollectionUtils.isEmpty(input.getConstraints()))
2318 .forEach(input -> input.setConstraints(setInputConstraint(input)));
2320 UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2321 return Either.left(dataTransfer);
2324 @Autowired(required = false)
2325 public void setServiceCreationPluginList(List<ServiceCreationPlugin> serviceCreationPluginList) {
2326 this.serviceCreationPluginList = serviceCreationPluginList;
2329 public boolean isServiceExist(String serviceName) {
2330 Either<Service, StorageOperationStatus> latestByName = toscaOperationFacade.getLatestByServiceName(serviceName);
2331 return latestByName.isLeft();
2334 interface ArtifactGenerator<CallVal> extends Callable<Either<CallVal, ResponseFormat>> {
2339 class HeatEnvArtifactGenerator implements ArtifactGenerator<ArtifactDefinition> {
2341 private ArtifactDefinition artifactDefinition;
2342 private Service service;
2343 private String resourceInstanceName;
2344 private User modifier;
2345 private String instanceId;
2346 private boolean shouldLock;
2347 private boolean inTransaction;
2349 HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier,
2350 boolean shouldLock, boolean inTransaction, String instanceId) {
2351 this.artifactDefinition = artifactDefinition;
2352 this.service = service;
2353 this.resourceInstanceName = resourceInstanceName;
2354 this.modifier = modifier;
2355 this.shouldLock = shouldLock;
2356 this.instanceId = instanceId;
2357 this.inTransaction = inTransaction;
2361 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2362 return artifactsBusinessLogic
2363 .forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier,
2364 shouldLock, inTransaction, instanceId);
2368 class VfModuleArtifactGenerator implements ArtifactGenerator<ArtifactDefinition> {
2371 boolean inTransaction;
2373 private ComponentInstance componentInstance;
2374 private Service service;
2376 private VfModuleArtifactGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock,
2377 boolean inTransaction) {
2380 this.componentInstance = componentInstance;
2381 this.service = service;
2382 this.shouldLock = shouldLock;
2383 this.inTransaction = inTransaction;
2386 private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance,
2387 Service service, boolean shouldLock,
2388 boolean inTransaction) {
2389 ArtifactDefinition vfModuleArtifact = null;
2390 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
2391 Wrapper<String> payloadWrapper = new Wrapper<>();
2392 List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
2393 if (responseWrapper.isEmpty()) {
2394 fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
2396 if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
2397 vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
2399 if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
2400 vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper,
2401 responseWrapper, service);
2403 Either<ArtifactDefinition, ResponseFormat> result;
2404 if (responseWrapper.isEmpty()) {
2405 result = Either.left(vfModuleArtifact);
2407 result = Either.right(responseWrapper.getInnerElement());
2412 private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
2413 List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
2414 if (groupsForCurrVF != null) {
2415 for (GroupInstance groupInstance : groupsForCurrVF) {
2416 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
2417 vfModulePayloads.add(modulePayload);
2419 vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
2420 final Gson gson = new GsonBuilder().setPrettyPrinting().create();
2421 String vfModulePayloadString = gson.toJson(vfModulePayloads);
2422 payloadWrapper.setInnerElement(vfModulePayloadString);
2426 private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper,
2427 Wrapper<ResponseFormat> responseWrapper) {
2428 ArtifactDefinition vfModuleAertifact = null;
2429 if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
2430 final Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream()
2431 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.getType())).findAny();
2432 if (optionalVfModuleArtifact.isPresent()) {
2433 vfModuleAertifact = optionalVfModuleArtifact.get();
2436 if (vfModuleAertifact == null) {
2437 Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service,
2438 payloadWrapper.getInnerElement());
2439 if (createVfModuleArtifact.isLeft()) {
2440 vfModuleAertifact = createVfModuleArtifact.left().value();
2442 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
2445 return vfModuleAertifact;
2448 private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
2449 Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
2450 if (currVF.getGroupInstances() != null) {
2451 currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
2453 return currVF.getGroupInstances();
2456 private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service,
2457 String vfModulePayloadString) {
2458 ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
2459 String newCheckSum = null;
2460 vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
2461 vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
2462 vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
2463 vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
2464 vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
2465 vfModuleArtifactDefinition.setTimeout(0);
2466 vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
2467 vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
2468 if (vfModulePayloadString != null) {
2469 newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
2471 vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
2472 Either<ArtifactDefinition, StorageOperationStatus> addArtifactToComponent = artifactToscaOperation
2473 .addArtifactToComponent(vfModuleArtifactDefinition, service, NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
2474 Either<ArtifactDefinition, ResponseFormat> result;
2475 if (addArtifactToComponent.isLeft()) {
2476 result = Either.left(addArtifactToComponent.left().value());
2479 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArtifactToComponent.right().value())));
2484 private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact,
2486 boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper,
2488 ArtifactDefinition result = null;
2489 Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic
2490 .generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock,
2491 inTransaction, System::currentTimeMillis, () -> Either.left(
2492 artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact,
2493 payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))),
2494 currVF.getUniqueId());
2495 if (eitherPayload.isLeft()) {
2496 result = eitherPayload.left().value();
2498 responseWrapper.setInnerElement(eitherPayload.right().value());
2500 if (result == null) {
2501 result = vfModuleArtifact;
2507 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2508 return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);