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));
});
}
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();
}
}
}
}
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);
}
}
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);
}
}
Aggregations