de.otto.synapse.endpoint.sender.AbstractMessageSenderEndpoint Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of synapse-core Show documentation
Show all versions of synapse-core Show documentation
A library used at otto.de to implement Spring Boot based event-sourcing microservices.
package de.otto.synapse.endpoint.sender;
import de.otto.synapse.endpoint.AbstractMessageEndpoint;
import de.otto.synapse.endpoint.EndpointType;
import de.otto.synapse.endpoint.MessageInterceptor;
import de.otto.synapse.endpoint.MessageInterceptorRegistry;
import de.otto.synapse.message.Message;
import de.otto.synapse.message.TextMessage;
import de.otto.synapse.translator.MessageFormat;
import de.otto.synapse.translator.MessageTranslator;
import jakarta.annotation.Nonnull;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;
import static de.otto.synapse.endpoint.EndpointType.SENDER;
import static java.util.concurrent.CompletableFuture.allOf;
import static java.util.concurrent.CompletableFuture.completedFuture;
/**
* Sender-side {@code MessageEndpoint endpoint} of a Message Channel with support for {@link MessageTranslator message translation}.
* and {@link de.otto.synapse.endpoint.MessageInterceptor interception}.
*
*
*
*
*
* @see EIP: Message Endpoint
* @see EIP: Message Channel
*/
public abstract class AbstractMessageSenderEndpoint extends AbstractMessageEndpoint implements MessageSenderEndpoint {
public static final int BATCH_SENDER_TIMEOUT = 500;
private final MessageTranslator messageTranslator;
/**
* Constructor used to create a new MessageEndpoint.
*
* @param channelName the name of the underlying channel / stream / queue / message log.
* @param interceptorRegistry registry used to determine {@link MessageInterceptor message interceptors} for this
* endpoint.
* @param messageTranslator the MessageTranslator used to translate message payloads as expected by the
* {@link de.otto.synapse.consumer.MessageConsumer consumers}.
*/
public AbstractMessageSenderEndpoint(final @Nonnull String channelName,
final @Nonnull MessageInterceptorRegistry interceptorRegistry,
final @Nonnull MessageTranslator messageTranslator) {
super(channelName, interceptorRegistry);
this.messageTranslator = messageTranslator;
}
/**
* Sends a {@link Message} to the message channel.
*
* @param message the message to send
*/
@Override
public final CompletableFuture send(@Nonnull final Message> message) {
final TextMessage translatedMessage = messageTranslator.apply(message);
final TextMessage interceptedMessage = intercept(translatedMessage);
if (interceptedMessage != null) {
return doSend(interceptedMessage);
} else {
return completedFuture(null);
}
}
/**
* Sends a stream of messages to the message channel as one or more batches, if
* batches are supported by the infrastructure. If not, the messages are send one by one.
*
* @param batch a stream of messages that is sent in batched mode, if supported
*/
@Override
public final CompletableFuture sendBatch(@Nonnull final Stream extends Message>> batch) {
return doSendBatch(batch
.map(messageTranslator::apply)
.map(this::intercept)
.filter(Objects::nonNull));
}
@Nonnull
@Override
public final EndpointType getEndpointType() {
return SENDER;
}
protected CompletableFuture doSendBatch(final @Nonnull Stream batch) {
return allOf(batch.map(this::doSend).toArray(CompletableFuture[]::new));
}
protected abstract CompletableFuture doSend(final @Nonnull TextMessage message);
public MessageFormat getMessageFormat() {
return MessageFormat.defaultMessageFormat();
}
}