Search in sources :

Example 1 with FunctionProperties

use of org.springframework.cloud.function.context.FunctionProperties in project spring-cloud-stream by spring-cloud.

the class FunctionConfiguration method supplierInitializer.

/*
	 * Binding initializer responsible only for Suppliers
	 */
@Bean
InitializingBean supplierInitializer(FunctionCatalog functionCatalog, StreamFunctionProperties functionProperties, GenericApplicationContext context, BindingServiceProperties serviceProperties, @Nullable List<BindableFunctionProxyFactory> proxyFactories, StreamBridge streamBridge, TaskScheduler taskScheduler) {
    if (CollectionUtils.isEmpty(proxyFactories)) {
        return null;
    }
    return new InitializingBean() {

        @SuppressWarnings("rawtypes")
        @Override
        public void afterPropertiesSet() throws Exception {
            for (BindableFunctionProxyFactory proxyFactory : proxyFactories) {
                FunctionInvocationWrapper functionWrapper = functionCatalog.lookup(proxyFactory.getFunctionDefinition());
                if (functionWrapper != null && functionWrapper.isSupplier()) {
                    // gather output content types
                    List<String> contentTypes = new ArrayList<String>();
                    if (proxyFactory.getOutputs().size() == 0) {
                        return;
                    }
                    Assert.isTrue(proxyFactory.getOutputs().size() == 1, "Supplier with multiple outputs is not supported at the moment.");
                    String outputName = proxyFactory.getOutputs().iterator().next();
                    BindingProperties bindingProperties = serviceProperties.getBindingProperties(outputName);
                    ProducerProperties producerProperties = bindingProperties.getProducer();
                    if (!(bindingProperties.getProducer() != null && producerProperties.isUseNativeEncoding())) {
                        contentTypes.add(bindingProperties.getContentType());
                    }
                    // see https://github.com/spring-cloud/spring-cloud-stream/issues/2027
                    String functionDefinition = proxyFactory.getFunctionDefinition();
                    String[] functionNames = StringUtils.delimitedListToStringArray(functionDefinition.replaceAll(",", "|").trim(), "|");
                    Function supplier = null;
                    Function function = null;
                    if (!ObjectUtils.isEmpty(functionNames) && functionNames.length > 1) {
                        String supplierName = functionNames[0];
                        String remainingFunctionDefinition = StringUtils.arrayToCommaDelimitedString(Arrays.copyOfRange(functionNames, 1, functionNames.length));
                        supplier = functionCatalog.lookup(supplierName);
                        function = functionCatalog.lookup(remainingFunctionDefinition, contentTypes.toArray(new String[0]));
                        if (!((FunctionInvocationWrapper) supplier).isOutputTypePublisher() && ((FunctionInvocationWrapper) function).isInputTypePublisher()) {
                            functionWrapper = null;
                        } else {
                            functionWrapper = functionCatalog.lookup(proxyFactory.getFunctionDefinition(), contentTypes.toArray(new String[0]));
                        }
                    } else {
                        functionWrapper = functionCatalog.lookup(proxyFactory.getFunctionDefinition(), contentTypes.toArray(new String[0]));
                    }
                    Publisher<Object> beginPublishingTrigger = setupBindingTrigger(context);
                    if (!functionProperties.isComposeFrom() && !functionProperties.isComposeTo()) {
                        String integrationFlowName = proxyFactory.getFunctionDefinition() + "_integrationflow";
                        PollableBean pollable = extractPollableAnnotation(functionProperties, context, proxyFactory);
                        if (functionWrapper != null) {
                            // Type functionType = functionWrapper.getFunctionType();
                            IntegrationFlow integrationFlow = integrationFlowFromProvidedSupplier(new PartitionAwareFunctionWrapper(functionWrapper, context, producerProperties), beginPublishingTrigger, pollable, context, taskScheduler, producerProperties, outputName).route(Message.class, message -> {
                                if (message.getHeaders().get("spring.cloud.stream.sendto.destination") != null) {
                                    String destinationName = (String) message.getHeaders().get("spring.cloud.stream.sendto.destination");
                                    return streamBridge.resolveDestination(destinationName, producerProperties, null);
                                }
                                return outputName;
                            }).get();
                            IntegrationFlow postProcessedFlow = (IntegrationFlow) context.getAutowireCapableBeanFactory().applyBeanPostProcessorsBeforeInitialization(integrationFlow, integrationFlowName);
                            context.registerBean(integrationFlowName, IntegrationFlow.class, () -> postProcessedFlow);
                        } else {
                            // Type functionType = ((FunctionInvocationWrapper) supplier).getFunctionType();
                            IntegrationFlow integrationFlow = integrationFlowFromProvidedSupplier(new PartitionAwareFunctionWrapper(supplier, context, producerProperties), beginPublishingTrigger, pollable, context, taskScheduler, producerProperties, outputName).channel(c -> c.direct()).fluxTransform((Function<? super Flux<Message<Object>>, ? extends Publisher<Object>>) function).route(Message.class, message -> {
                                if (message.getHeaders().get("spring.cloud.stream.sendto.destination") != null) {
                                    String destinationName = (String) message.getHeaders().get("spring.cloud.stream.sendto.destination");
                                    return streamBridge.resolveDestination(destinationName, producerProperties, null);
                                }
                                return outputName;
                            }).get();
                            IntegrationFlow postProcessedFlow = (IntegrationFlow) context.getAutowireCapableBeanFactory().applyBeanPostProcessorsBeforeInitialization(integrationFlow, integrationFlowName);
                            context.registerBean(integrationFlowName, IntegrationFlow.class, () -> postProcessedFlow);
                        }
                    }
                }
            }
        }
    };
}
Also used : GenericArrayType(java.lang.reflect.GenericArrayType) Arrays(java.util.Arrays) BindingCreatedEvent(org.springframework.cloud.stream.binder.BindingCreatedEvent) DirectWithAttributesChannel(org.springframework.cloud.stream.messaging.DirectWithAttributesChannel) IntegrationFlow(org.springframework.integration.dsl.IntegrationFlow) IntegrationFlowBuilder(org.springframework.integration.dsl.IntegrationFlowBuilder) BindingServiceConfiguration(org.springframework.cloud.stream.config.BindingServiceConfiguration) Tuples(reactor.util.function.Tuples) FluxMessageChannel(org.springframework.integration.channel.FluxMessageChannel) BeanDefinitionRegistry(org.springframework.beans.factory.support.BeanDefinitionRegistry) ContextFunctionCatalogAutoConfiguration(org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration) ProducerProperties(org.springframework.cloud.stream.binder.ProducerProperties) AbstractMessageChannel(org.springframework.integration.channel.AbstractMessageChannel) ConfigurableListableBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory) MessagingTemplate(org.springframework.integration.core.MessagingTemplate) RoutingFunction(org.springframework.cloud.function.context.config.RoutingFunction) Map(java.util.Map) EnableConfigurationProperties(org.springframework.boot.context.properties.EnableConfigurationProperties) ConfigurableApplicationContext(org.springframework.context.ConfigurableApplicationContext) MessageUtils(org.springframework.cloud.function.context.message.MessageUtils) Method(java.lang.reflect.Method) ClassUtils(org.springframework.util.ClassUtils) MethodMetadata(org.springframework.core.type.MethodMetadata) AbstractSubscribableChannel(org.springframework.integration.channel.AbstractSubscribableChannel) ConsumerProperties(org.springframework.cloud.stream.binder.ConsumerProperties) AnnotationUtils(org.springframework.core.annotation.AnnotationUtils) Set(java.util.Set) TaskScheduler(org.springframework.scheduling.TaskScheduler) Instant(java.time.Instant) MessageChannel(org.springframework.messaging.MessageChannel) SupportedBindableFeatures(org.springframework.cloud.stream.binding.SupportedBindableFeatures) Configuration(org.springframework.context.annotation.Configuration) List(java.util.List) Type(java.lang.reflect.Type) Environment(org.springframework.core.env.Environment) CollectionUtils(org.springframework.util.CollectionUtils) LogFactory(org.apache.commons.logging.LogFactory) FunctionCatalog(org.springframework.cloud.function.context.FunctionCatalog) IntegrationReactiveUtils(org.springframework.integration.util.IntegrationReactiveUtils) CloudEventMessageUtils(org.springframework.cloud.function.cloudevent.CloudEventMessageUtils) FunctionInvocationWrapper(org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper) BindingProperties(org.springframework.cloud.stream.config.BindingProperties) ApplicationContextAware(org.springframework.context.ApplicationContextAware) RootBeanDefinition(org.springframework.beans.factory.support.RootBeanDefinition) MessagingException(org.springframework.messaging.MessagingException) BinderFactory(org.springframework.cloud.stream.binder.BinderFactory) BindingServiceProperties(org.springframework.cloud.stream.config.BindingServiceProperties) SubscribableChannel(org.springframework.messaging.SubscribableChannel) MonoSink(reactor.core.publisher.MonoSink) PollableBean(org.springframework.cloud.function.context.PollableBean) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) InitializingBean(org.springframework.beans.factory.InitializingBean) ArrayList(java.util.ArrayList) AutoConfigureAfter(org.springframework.boot.autoconfigure.AutoConfigureAfter) MessageBuilder(org.springframework.integration.support.MessageBuilder) NewDestinationBindingCallback(org.springframework.cloud.stream.binding.NewDestinationBindingCallback) BinderFactoryAutoConfiguration(org.springframework.cloud.stream.config.BinderFactoryAutoConfiguration) ConfigurableEnvironment(org.springframework.core.env.ConfigurableEnvironment) FunctionTypeUtils(org.springframework.cloud.function.context.catalog.FunctionTypeUtils) BeanDefinition(org.springframework.beans.factory.config.BeanDefinition) IntegrationFlows(org.springframework.integration.dsl.IntegrationFlows) Nullable(org.springframework.lang.Nullable) Message(org.springframework.messaging.Message) BindableProxyFactory(org.springframework.cloud.stream.binding.BindableProxyFactory) ConditionalOnBean(org.springframework.boot.autoconfigure.condition.ConditionalOnBean) Iterator(java.util.Iterator) Publisher(org.reactivestreams.Publisher) BeanFactoryPostProcessor(org.springframework.beans.factory.config.BeanFactoryPostProcessor) ObjectUtils(org.springframework.util.ObjectUtils) Import(org.springframework.context.annotation.Import) Mono(reactor.core.publisher.Mono) BeansException(org.springframework.beans.BeansException) AbstractMessageHandler(org.springframework.integration.handler.AbstractMessageHandler) Field(java.lang.reflect.Field) FunctionProperties(org.springframework.cloud.function.context.FunctionProperties) ApplicationContext(org.springframework.context.ApplicationContext) MessageHeaders(org.springframework.messaging.MessageHeaders) GenericApplicationContext(org.springframework.context.support.GenericApplicationContext) Flux(reactor.core.publisher.Flux) ParameterizedType(java.lang.reflect.ParameterizedType) FunctionContextUtils(org.springframework.cloud.function.context.config.FunctionContextUtils) EnvironmentAware(org.springframework.context.EnvironmentAware) ReflectionUtils(org.springframework.util.ReflectionUtils) Log(org.apache.commons.logging.Log) FunctionRegistry(org.springframework.cloud.function.context.FunctionRegistry) Bean(org.springframework.context.annotation.Bean) AutoConfigureBefore(org.springframework.boot.autoconfigure.AutoConfigureBefore) Collections(java.util.Collections) Assert(org.springframework.util.Assert) StringUtils(org.springframework.util.StringUtils) ProducerProperties(org.springframework.cloud.stream.binder.ProducerProperties) Message(org.springframework.messaging.Message) BindingProperties(org.springframework.cloud.stream.config.BindingProperties) ArrayList(java.util.ArrayList) IntegrationFlow(org.springframework.integration.dsl.IntegrationFlow) RoutingFunction(org.springframework.cloud.function.context.config.RoutingFunction) Function(java.util.function.Function) FunctionInvocationWrapper(org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper) InitializingBean(org.springframework.beans.factory.InitializingBean) PollableBean(org.springframework.cloud.function.context.PollableBean) PollableBean(org.springframework.cloud.function.context.PollableBean) InitializingBean(org.springframework.beans.factory.InitializingBean) ConditionalOnBean(org.springframework.boot.autoconfigure.condition.ConditionalOnBean) Bean(org.springframework.context.annotation.Bean)

Aggregations

Field (java.lang.reflect.Field)1 GenericArrayType (java.lang.reflect.GenericArrayType)1 Method (java.lang.reflect.Method)1 ParameterizedType (java.lang.reflect.ParameterizedType)1 Type (java.lang.reflect.Type)1 Instant (java.time.Instant)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1 Iterator (java.util.Iterator)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 Function (java.util.function.Function)1 Supplier (java.util.function.Supplier)1 Log (org.apache.commons.logging.Log)1 LogFactory (org.apache.commons.logging.LogFactory)1 Publisher (org.reactivestreams.Publisher)1 BeansException (org.springframework.beans.BeansException)1