Search in sources :

Example 1 with ReactiveStreamsSubscribableChannel

use of org.springframework.integration.channel.ReactiveStreamsSubscribableChannel in project spring-integration by spring-projects.

the class MessagingGatewaySupport method doSendAndReceiveMessageReactive.

@SuppressWarnings("unchecked")
private Mono<Message<?>> doSendAndReceiveMessageReactive(MessageChannel requestChannel, Object object, boolean error) {
    return Mono.defer(() -> {
        Message<?> message;
        try {
            message = object instanceof Message<?> ? (Message<?>) object : this.requestMapper.toMessage(object);
            message = this.historyWritingPostProcessor.postProcessMessage(message);
        } catch (Exception e) {
            throw new MessageMappingException("Cannot map to message: " + object, e);
        }
        Object originalReplyChannelHeader = message.getHeaders().getReplyChannel();
        Object originalErrorChannelHeader = message.getHeaders().getErrorChannel();
        FutureReplyChannel replyChannel = new FutureReplyChannel();
        Message<?> requestMessage = MutableMessageBuilder.fromMessage(message).setReplyChannel(replyChannel).setHeader(this.messagingTemplate.getSendTimeoutHeader(), null).setHeader(this.messagingTemplate.getReceiveTimeoutHeader(), null).setErrorChannel(replyChannel).build();
        if (requestChannel instanceof ReactiveStreamsSubscribableChannel) {
            ((ReactiveStreamsSubscribableChannel) requestChannel).subscribeTo(Mono.just(requestMessage));
        } else {
            long sendTimeout = sendTimeout(requestMessage);
            boolean sent = sendTimeout >= 0 ? requestChannel.send(requestMessage, sendTimeout) : requestChannel.send(requestMessage);
            if (!sent) {
                throw new MessageDeliveryException(requestMessage, "Failed to send message to channel '" + requestChannel + "' within timeout: " + sendTimeout);
            }
        }
        return Mono.fromFuture(replyChannel.messageFuture).doOnSubscribe(s -> {
            if (!error && this.countsEnabled) {
                this.messageCount.incrementAndGet();
            }
        }).<Message<?>>map(replyMessage -> MessageBuilder.fromMessage(replyMessage).setHeader(MessageHeaders.REPLY_CHANNEL, originalReplyChannelHeader).setHeader(MessageHeaders.ERROR_CHANNEL, originalErrorChannelHeader).build()).onErrorResume(t -> error ? Mono.error(t) : handleSendError(requestMessage, t));
    });
}
Also used : MessagingException(org.springframework.messaging.MessagingException) AbstractEndpoint(org.springframework.integration.endpoint.AbstractEndpoint) TrackableComponent(org.springframework.integration.support.management.TrackableComponent) IntegrationManagedResource(org.springframework.integration.support.management.IntegrationManagedResource) SubscribableChannel(org.springframework.messaging.SubscribableChannel) CompletableFuture(java.util.concurrent.CompletableFuture) ReactiveStreamsConsumer(org.springframework.integration.endpoint.ReactiveStreamsConsumer) ErrorMessage(org.springframework.messaging.support.ErrorMessage) PollingConsumer(org.springframework.integration.endpoint.PollingConsumer) ErrorMessageStrategy(org.springframework.integration.support.ErrorMessageStrategy) MessagingTemplate(org.springframework.integration.core.MessagingTemplate) OutboundMessageMapper(org.springframework.integration.mapping.OutboundMessageMapper) MessageTimeoutException(org.springframework.integration.MessageTimeoutException) EventDrivenConsumer(org.springframework.integration.endpoint.EventDrivenConsumer) Map(java.util.Map) InboundMessageMapper(org.springframework.integration.mapping.InboundMessageMapper) Nullable(org.springframework.lang.Nullable) Message(org.springframework.messaging.Message) PollableChannel(org.springframework.messaging.PollableChannel) Subscriber(org.reactivestreams.Subscriber) HistoryWritingMessagePostProcessor(org.springframework.integration.history.HistoryWritingMessagePostProcessor) DefaultErrorMessageStrategy(org.springframework.integration.support.DefaultErrorMessageStrategy) MessageBuilderFactory(org.springframework.integration.support.MessageBuilderFactory) SimpleMessageConverter(org.springframework.integration.support.converter.SimpleMessageConverter) Mono(reactor.core.publisher.Mono) ReactiveStreamsSubscribableChannel(org.springframework.integration.channel.ReactiveStreamsSubscribableChannel) MessageSourceMetrics(org.springframework.integration.support.management.MessageSourceMetrics) MessageChannel(org.springframework.messaging.MessageChannel) MessageHeaders(org.springframework.messaging.MessageHeaders) BridgeHandler(org.springframework.integration.handler.BridgeHandler) AtomicLong(java.util.concurrent.atomic.AtomicLong) MessageDeliveryException(org.springframework.messaging.MessageDeliveryException) AttributeAccessor(org.springframework.core.AttributeAccessor) MessageMappingException(org.springframework.integration.mapping.MessageMappingException) ErrorMessageUtils(org.springframework.integration.support.ErrorMessageUtils) MessageBuilder(org.springframework.messaging.support.MessageBuilder) DefaultMessageBuilderFactory(org.springframework.integration.support.DefaultMessageBuilderFactory) MutableMessageBuilder(org.springframework.integration.support.MutableMessageBuilder) Assert(org.springframework.util.Assert) MessageMappingException(org.springframework.integration.mapping.MessageMappingException) ErrorMessage(org.springframework.messaging.support.ErrorMessage) Message(org.springframework.messaging.Message) ReactiveStreamsSubscribableChannel(org.springframework.integration.channel.ReactiveStreamsSubscribableChannel) MessageDeliveryException(org.springframework.messaging.MessageDeliveryException) MessagingException(org.springframework.messaging.MessagingException) MessageTimeoutException(org.springframework.integration.MessageTimeoutException) MessageDeliveryException(org.springframework.messaging.MessageDeliveryException) MessageMappingException(org.springframework.integration.mapping.MessageMappingException)

Example 2 with ReactiveStreamsSubscribableChannel

use of org.springframework.integration.channel.ReactiveStreamsSubscribableChannel in project spring-integration by spring-projects.

the class MessagingGatewaySupport method registerReplyMessageCorrelatorIfNecessary.

protected void registerReplyMessageCorrelatorIfNecessary() {
    MessageChannel replyChannel = getReplyChannel();
    if (replyChannel != null && this.replyMessageCorrelator == null) {
        boolean shouldStartCorrelator;
        synchronized (this.replyMessageCorrelatorMonitor) {
            if (this.replyMessageCorrelator != null) {
                return;
            }
            AbstractEndpoint correlator;
            BridgeHandler handler = new BridgeHandler();
            if (getBeanFactory() != null) {
                handler.setBeanFactory(getBeanFactory());
            }
            handler.afterPropertiesSet();
            if (replyChannel instanceof SubscribableChannel) {
                correlator = new EventDrivenConsumer((SubscribableChannel) replyChannel, handler);
            } else if (replyChannel instanceof PollableChannel) {
                PollingConsumer endpoint = new PollingConsumer((PollableChannel) replyChannel, handler);
                endpoint.setBeanFactory(getBeanFactory());
                endpoint.setReceiveTimeout(this.replyTimeout);
                endpoint.afterPropertiesSet();
                correlator = endpoint;
            } else if (replyChannel instanceof ReactiveStreamsSubscribableChannel) {
                ReactiveStreamsConsumer endpoint = new ReactiveStreamsConsumer(replyChannel, (Subscriber<Message<?>>) handler);
                endpoint.afterPropertiesSet();
                correlator = endpoint;
            } else {
                throw new MessagingException("Unsupported 'replyChannel' type [" + replyChannel.getClass() + "]." + "SubscribableChannel or PollableChannel type are supported.");
            }
            this.replyMessageCorrelator = correlator;
            shouldStartCorrelator = true;
        }
        if (shouldStartCorrelator && isRunning()) {
            if (isRunning()) {
                this.replyMessageCorrelator.start();
            }
        }
    }
}
Also used : AbstractEndpoint(org.springframework.integration.endpoint.AbstractEndpoint) EventDrivenConsumer(org.springframework.integration.endpoint.EventDrivenConsumer) PollingConsumer(org.springframework.integration.endpoint.PollingConsumer) ReactiveStreamsConsumer(org.springframework.integration.endpoint.ReactiveStreamsConsumer) MessageChannel(org.springframework.messaging.MessageChannel) ErrorMessage(org.springframework.messaging.support.ErrorMessage) Message(org.springframework.messaging.Message) BridgeHandler(org.springframework.integration.handler.BridgeHandler) MessagingException(org.springframework.messaging.MessagingException) PollableChannel(org.springframework.messaging.PollableChannel) ReactiveStreamsSubscribableChannel(org.springframework.integration.channel.ReactiveStreamsSubscribableChannel) SubscribableChannel(org.springframework.messaging.SubscribableChannel) ReactiveStreamsSubscribableChannel(org.springframework.integration.channel.ReactiveStreamsSubscribableChannel)

Example 3 with ReactiveStreamsSubscribableChannel

use of org.springframework.integration.channel.ReactiveStreamsSubscribableChannel in project spring-integration by spring-projects.

the class AbstractMessageSplitter method handleRequestMessage.

@Override
@SuppressWarnings("unchecked")
protected final Object handleRequestMessage(Message<?> message) {
    Object result = this.splitMessage(message);
    // return null if 'null'
    if (result == null) {
        return null;
    }
    boolean reactive = getOutputChannel() instanceof ReactiveStreamsSubscribableChannel;
    setAsync(reactive);
    Iterator<Object> iterator = null;
    Flux<Object> flux = null;
    final int sequenceSize;
    if (result instanceof Iterable<?>) {
        Iterable<Object> iterable = (Iterable<Object>) result;
        sequenceSize = obtainSizeIfPossible(iterable);
        if (reactive) {
            flux = Flux.fromIterable(iterable);
        } else {
            iterator = iterable.iterator();
        }
    } else if (result.getClass().isArray()) {
        Object[] items = (Object[]) result;
        sequenceSize = items.length;
        if (reactive) {
            flux = Flux.fromArray(items);
        } else {
            iterator = Arrays.asList(items).iterator();
        }
    } else if (result instanceof Iterator<?>) {
        Iterator<Object> iter = (Iterator<Object>) result;
        sequenceSize = obtainSizeIfPossible(iter);
        if (reactive) {
            flux = Flux.fromIterable(() -> iter);
        } else {
            iterator = iter;
        }
    } else if (result instanceof Stream<?>) {
        Stream<Object> stream = ((Stream<Object>) result);
        sequenceSize = 0;
        if (reactive) {
            flux = Flux.fromStream(stream);
        } else {
            iterator = stream.iterator();
        }
    } else if (result instanceof Publisher<?>) {
        Publisher<Object> publisher = (Publisher<Object>) result;
        sequenceSize = 0;
        if (reactive) {
            flux = Flux.from(publisher);
        } else {
            iterator = Flux.from((Publisher<Object>) result).toIterable().iterator();
        }
    } else {
        sequenceSize = 1;
        if (reactive) {
            flux = Flux.just(result);
        } else {
            iterator = Collections.singleton(result).iterator();
        }
    }
    if (iterator != null && !iterator.hasNext()) {
        return null;
    }
    Map<String, Object> messageHeaders = message.getHeaders();
    if (willAddHeaders(message)) {
        messageHeaders = new HashMap<>(messageHeaders);
        addHeaders(message, messageHeaders);
    }
    final Map<String, Object> headers = messageHeaders;
    final Object correlationId = message.getHeaders().getId();
    final AtomicInteger sequenceNumber = new AtomicInteger(1);
    Function<Object, AbstractIntegrationMessageBuilder<?>> messageBuilderFunction = object -> createBuilder(object, headers, correlationId, sequenceNumber.getAndIncrement(), sequenceSize);
    if (reactive) {
        return flux.map(messageBuilderFunction);
    } else {
        return new FunctionIterator<>(iterator, messageBuilderFunction);
    }
}
Also used : Arrays(java.util.Arrays) Iterator(java.util.Iterator) Collection(java.util.Collection) Publisher(org.reactivestreams.Publisher) AbstractReplyProducingMessageHandler(org.springframework.integration.handler.AbstractReplyProducingMessageHandler) HashMap(java.util.HashMap) ReactiveStreamsSubscribableChannel(org.springframework.integration.channel.ReactiveStreamsSubscribableChannel) Function(java.util.function.Function) Flux(reactor.core.publisher.Flux) Stream(java.util.stream.Stream) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Closeable(java.io.Closeable) Map(java.util.Map) Message(org.springframework.messaging.Message) AbstractIntegrationMessageBuilder(org.springframework.integration.support.AbstractIntegrationMessageBuilder) Collections(java.util.Collections) FunctionIterator(org.springframework.integration.util.FunctionIterator) FunctionIterator(org.springframework.integration.util.FunctionIterator) ReactiveStreamsSubscribableChannel(org.springframework.integration.channel.ReactiveStreamsSubscribableChannel) Publisher(org.reactivestreams.Publisher) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AbstractIntegrationMessageBuilder(org.springframework.integration.support.AbstractIntegrationMessageBuilder) Iterator(java.util.Iterator) FunctionIterator(org.springframework.integration.util.FunctionIterator) Stream(java.util.stream.Stream)

Example 4 with ReactiveStreamsSubscribableChannel

use of org.springframework.integration.channel.ReactiveStreamsSubscribableChannel in project spring-integration by spring-projects.

the class AbstractMessageProducingHandler method produceOutput.

protected void produceOutput(Object reply, final Message<?> requestMessage) {
    final MessageHeaders requestHeaders = requestMessage.getHeaders();
    Object replyChannel = null;
    if (getOutputChannel() == null) {
        Map<?, ?> routingSlipHeader = requestHeaders.get(IntegrationMessageHeaderAccessor.ROUTING_SLIP, Map.class);
        if (routingSlipHeader != null) {
            Assert.isTrue(routingSlipHeader.size() == 1, "The RoutingSlip header value must be a SingletonMap");
            Object key = routingSlipHeader.keySet().iterator().next();
            Object value = routingSlipHeader.values().iterator().next();
            Assert.isInstanceOf(List.class, key, "The RoutingSlip key must be List");
            Assert.isInstanceOf(Integer.class, value, "The RoutingSlip value must be Integer");
            List<?> routingSlip = (List<?>) key;
            AtomicInteger routingSlipIndex = new AtomicInteger((Integer) value);
            replyChannel = getOutputChannelFromRoutingSlip(reply, requestMessage, routingSlip, routingSlipIndex);
            if (replyChannel != null) {
                // TODO Migrate to the SF MessageBuilder
                AbstractIntegrationMessageBuilder<?> builder = null;
                if (reply instanceof Message) {
                    builder = this.getMessageBuilderFactory().fromMessage((Message<?>) reply);
                } else if (reply instanceof AbstractIntegrationMessageBuilder) {
                    builder = (AbstractIntegrationMessageBuilder<?>) reply;
                } else {
                    builder = this.getMessageBuilderFactory().withPayload(reply);
                }
                builder.setHeader(IntegrationMessageHeaderAccessor.ROUTING_SLIP, Collections.singletonMap(routingSlip, routingSlipIndex.get()));
                reply = builder;
            }
        }
        if (replyChannel == null) {
            replyChannel = requestHeaders.getReplyChannel();
            if (replyChannel == null && reply instanceof Message) {
                replyChannel = ((Message<?>) reply).getHeaders().getReplyChannel();
            }
        }
    }
    if (this.async && (reply instanceof ListenableFuture<?> || reply instanceof Publisher<?>)) {
        if (reply instanceof ListenableFuture<?> || !(getOutputChannel() instanceof ReactiveStreamsSubscribableChannel)) {
            ListenableFuture<?> future;
            if (reply instanceof ListenableFuture<?>) {
                future = (ListenableFuture<?>) reply;
            } else {
                SettableListenableFuture<Object> settableListenableFuture = new SettableListenableFuture<>();
                Mono.from((Publisher<?>) reply).subscribe(settableListenableFuture::set, settableListenableFuture::setException);
                future = settableListenableFuture;
            }
            Object theReplyChannel = replyChannel;
            future.addCallback(new ListenableFutureCallback<Object>() {

                @Override
                public void onSuccess(Object result) {
                    Message<?> replyMessage = null;
                    try {
                        replyMessage = createOutputMessage(result, requestHeaders);
                        sendOutput(replyMessage, theReplyChannel, false);
                    } catch (Exception e) {
                        Exception exceptionToLogAndSend = e;
                        if (!(e instanceof MessagingException)) {
                            exceptionToLogAndSend = new MessageHandlingException(requestMessage, e);
                            if (replyMessage != null) {
                                exceptionToLogAndSend = new MessagingException(replyMessage, exceptionToLogAndSend);
                            }
                        }
                        logger.error("Failed to send async reply: " + result.toString(), exceptionToLogAndSend);
                        onFailure(exceptionToLogAndSend);
                    }
                }

                @Override
                public void onFailure(Throwable ex) {
                    sendErrorMessage(requestMessage, ex);
                }
            });
        } else {
            ((ReactiveStreamsSubscribableChannel) getOutputChannel()).subscribeTo(Flux.from((Publisher<?>) reply).map(result -> createOutputMessage(result, requestHeaders)));
        }
    } else {
        sendOutput(createOutputMessage(reply, requestHeaders), replyChannel, false);
    }
}
Also used : MessagingException(org.springframework.messaging.MessagingException) Arrays(java.util.Arrays) ListenableFuture(org.springframework.util.concurrent.ListenableFuture) SettableListenableFuture(org.springframework.util.concurrent.SettableListenableFuture) HashMap(java.util.HashMap) ErrorMessage(org.springframework.messaging.support.ErrorMessage) ListenableFutureCallback(org.springframework.util.concurrent.ListenableFutureCallback) MessagingTemplate(org.springframework.integration.core.MessagingTemplate) HashSet(java.util.HashSet) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) MessageHandlingException(org.springframework.messaging.MessageHandlingException) Map(java.util.Map) IntegrationMessageHeaderAccessor(org.springframework.integration.IntegrationMessageHeaderAccessor) RoutingSlipRouteStrategy(org.springframework.integration.routingslip.RoutingSlipRouteStrategy) Message(org.springframework.messaging.Message) AbstractIntegrationMessageBuilder(org.springframework.integration.support.AbstractIntegrationMessageBuilder) Collection(java.util.Collection) Publisher(org.reactivestreams.Publisher) ObjectUtils(org.springframework.util.ObjectUtils) PatternMatchUtils(org.springframework.util.PatternMatchUtils) Set(java.util.Set) Mono(reactor.core.publisher.Mono) ReactiveStreamsSubscribableChannel(org.springframework.integration.channel.ReactiveStreamsSubscribableChannel) DestinationResolutionException(org.springframework.messaging.core.DestinationResolutionException) MessageProducer(org.springframework.integration.core.MessageProducer) MessageChannel(org.springframework.messaging.MessageChannel) MessageHeaders(org.springframework.messaging.MessageHeaders) Flux(reactor.core.publisher.Flux) List(java.util.List) Collections(java.util.Collections) Assert(org.springframework.util.Assert) StringUtils(org.springframework.util.StringUtils) SettableListenableFuture(org.springframework.util.concurrent.SettableListenableFuture) ErrorMessage(org.springframework.messaging.support.ErrorMessage) Message(org.springframework.messaging.Message) MessagingException(org.springframework.messaging.MessagingException) ReactiveStreamsSubscribableChannel(org.springframework.integration.channel.ReactiveStreamsSubscribableChannel) Publisher(org.reactivestreams.Publisher) MessagingException(org.springframework.messaging.MessagingException) MessageHandlingException(org.springframework.messaging.MessageHandlingException) DestinationResolutionException(org.springframework.messaging.core.DestinationResolutionException) MessageHandlingException(org.springframework.messaging.MessageHandlingException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AbstractIntegrationMessageBuilder(org.springframework.integration.support.AbstractIntegrationMessageBuilder) ListenableFuture(org.springframework.util.concurrent.ListenableFuture) SettableListenableFuture(org.springframework.util.concurrent.SettableListenableFuture) List(java.util.List) MessageHeaders(org.springframework.messaging.MessageHeaders)

Aggregations

ReactiveStreamsSubscribableChannel (org.springframework.integration.channel.ReactiveStreamsSubscribableChannel)4 Message (org.springframework.messaging.Message)4 Map (java.util.Map)3 MessageChannel (org.springframework.messaging.MessageChannel)3 MessagingException (org.springframework.messaging.MessagingException)3 ErrorMessage (org.springframework.messaging.support.ErrorMessage)3 Arrays (java.util.Arrays)2 Collection (java.util.Collection)2 Collections (java.util.Collections)2 HashMap (java.util.HashMap)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 Publisher (org.reactivestreams.Publisher)2 MessagingTemplate (org.springframework.integration.core.MessagingTemplate)2 AbstractEndpoint (org.springframework.integration.endpoint.AbstractEndpoint)2 EventDrivenConsumer (org.springframework.integration.endpoint.EventDrivenConsumer)2 PollingConsumer (org.springframework.integration.endpoint.PollingConsumer)2 ReactiveStreamsConsumer (org.springframework.integration.endpoint.ReactiveStreamsConsumer)2 BridgeHandler (org.springframework.integration.handler.BridgeHandler)2 AbstractIntegrationMessageBuilder (org.springframework.integration.support.AbstractIntegrationMessageBuilder)2 PollableChannel (org.springframework.messaging.PollableChannel)2