All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sap.cds.feature.messaging.em.service.EnterpriseMessagingServiceConfiguration Maven / Gradle / Ivy

/**************************************************************************
 * (C) 2019-2024 SAP SE or an SAP affiliate company. All rights reserved. *
 **************************************************************************/
package com.sap.cds.feature.messaging.em.service;

import static com.sap.cds.services.messaging.utils.MessagingOutboxUtils.outboxed;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sap.cds.feature.messaging.em.jms.EnterpriseMessagingConnectionProvider;
import com.sap.cds.feature.messaging.em.mt.service.EnterpriseMessagingMtHandler;
import com.sap.cds.feature.messaging.em.mt.service.EnterpriseMessagingMtService;
import com.sap.cds.services.ServiceCatalog;
import com.sap.cds.services.environment.CdsProperties.Messaging;
import com.sap.cds.services.environment.CdsProperties.Messaging.MessagingServiceConfig;
import com.sap.cds.services.messaging.MessagingService;
import com.sap.cds.services.outbox.OutboxService;
import com.sap.cds.services.runtime.CdsRuntime;
import com.sap.cds.services.runtime.CdsRuntimeConfiguration;
import com.sap.cds.services.runtime.CdsRuntimeConfigurer;
import com.sap.cds.services.utils.StringUtils;
import com.sap.cds.services.utils.environment.ServiceBindingUtils;
import com.sap.cloud.environment.servicebinding.api.ServiceBinding;

public class EnterpriseMessagingServiceConfiguration implements CdsRuntimeConfiguration {

	private static final Logger logger = LoggerFactory.getLogger(EnterpriseMessagingServiceConfiguration.class);

	public static final String BINDING_EM_LABEL = "enterprise-messaging";
	public static final String EM_SHARED_KIND = "enterprise-messaging-shared";
	public static final String INSTANCE_TYPE = "instancetype";
	public static final String MT_INSTANCE_TYPE_VALUE = "reuse";

	private MessagingService createMessagingService(ServiceBinding binding, EnterpriseMessagingConnectionProvider sharedConnectionProvider, MessagingServiceConfig serviceConfig, CdsRuntime runtime, boolean forceShared) {
		MessagingService service;
		if (!forceShared && Objects.equals(MT_INSTANCE_TYPE_VALUE, binding.getCredentials().get(INSTANCE_TYPE))) {
			logger.info("Enterprise messaging service '{}' is going to be created multitenant-aware", serviceConfig.getName());
			service = new EnterpriseMessagingMtService(serviceConfig, binding, runtime);
		} else {
			service = new EnterpriseMessagingService(serviceConfig, binding, sharedConnectionProvider, runtime);
		}
		return outboxed(service, serviceConfig, runtime);
	}


	@Override
	public void services(CdsRuntimeConfigurer configurer) {
		Messaging config = configurer.getCdsRuntime().getEnvironment().getCdsProperties().getMessaging();
		List bindings = configurer.getCdsRuntime().getEnvironment().getServiceBindings()
				.filter(b -> ServiceBindingUtils.matches(b, BINDING_EM_LABEL))
				.collect(Collectors.toList());

		if(bindings.isEmpty()) {
			logger.info("No service bindings with label '{}' found", BINDING_EM_LABEL);
		} else {

			boolean isSingleBinding = bindings.size() == 1;

			bindings.forEach(binding -> {

				logger.debug("Starting the initialization of the enterprise-messaging service binding '{}'", binding.getName().get());

				EnterpriseMessagingConnectionProvider sharedConnectionProvider = new EnterpriseMessagingConnectionProvider(binding);

				// determines whether no configuration is available and the default service should be created
				boolean createDefaultService = true;

				// check the services configured by binding
				List serviceConfigs = config.getServicesByBinding(binding.getName().get());

				if (!serviceConfigs.isEmpty()) {
					createDefaultService = false;
					serviceConfigs.forEach(serviceConfig -> {
						if (serviceConfig.isEnabled()) {
							// register the service
							configurer.service(createMessagingService(binding, sharedConnectionProvider, serviceConfig, configurer.getCdsRuntime(), Objects.equals(EM_SHARED_KIND, serviceConfig.getKind())));
						}
					});
				}

				// check the services configured by kind if only one service binding is available
				List serviceConfigsByKind = config.getServicesByKind(BINDING_EM_LABEL);
				serviceConfigsByKind.addAll(config.getServicesByKind(EM_SHARED_KIND));

				if (isSingleBinding && !serviceConfigsByKind.isEmpty()) {
					createDefaultService = false;
					serviceConfigsByKind.forEach(serviceConfig -> {
						// check that the service is enabled and whether not already found by name or binding
						if (serviceConfig.isEnabled() && !serviceConfigs.stream().anyMatch(c -> c.getName().equals(serviceConfig.getName()))) {
							// register the service
							configurer.service(createMessagingService(binding, sharedConnectionProvider, serviceConfig, configurer.getCdsRuntime(), Objects.equals(EM_SHARED_KIND, serviceConfig.getKind())));
						}
					});
				}

				if (createDefaultService) {
					// otherwise create default service instance for the binding
					MessagingServiceConfig defConfig = config.getService(binding.getName().get());
					if (StringUtils.isEmpty(defConfig.getBinding()) && StringUtils.isEmpty(defConfig.getKind())) {
						// register the service
						configurer.service(createMessagingService(binding, sharedConnectionProvider, defConfig, configurer.getCdsRuntime(), false));
					} else {
						logger.warn("Could not create service for binding '{}': A configuration with the same name is already defined for another kind or binding.", binding.getName().get());
					}
				}

				logger.debug("Finished the initialization of the enterprise-messaging service binding '{}'", binding.getName().get());
			});
		}
	}

	@Override
	public void eventHandlers(CdsRuntimeConfigurer configurer) {
		// check whether the MT subscription service is available in order to register EM MT subscription service
		// register the MT handler for enterprise messaging only if any MT aware EM services are available
		ServiceCatalog catalog = configurer.getCdsRuntime().getServiceCatalog();
		if (catalog.getServices(MessagingService.class).map(OutboxService::unboxed).anyMatch(EnterpriseMessagingMtService.class::isInstance)) {
			configurer.eventHandler(new EnterpriseMessagingMtHandler());
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy