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

de.otto.synapse.consumer.MessageDispatcher Maven / Gradle / Ivy

Go to download

A library used at otto.de to implement Spring Boot based event-sourcing microservices.

There is a newer version: 0.33.1
Show newest version
package de.otto.synapse.consumer;

import de.otto.synapse.message.Message;
import de.otto.synapse.message.TextMessage;
import org.slf4j.Logger;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.regex.Pattern;

import static de.otto.synapse.message.Message.message;
import static de.otto.synapse.translator.ObjectMappers.currentObjectMapper;
import static java.util.Collections.synchronizedList;
import static java.util.Collections.unmodifiableList;
import static java.util.regex.Pattern.compile;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * A MessageConsumer that is acting as a Message Dispatcher for multiple {@link MessageConsumer message consumers}.
 * 

* MessageDispatcher *

*

* As it is implementing the MessageConsumer interface, the MessageDispatcher is an implementation * of the GoF Composite Pattern. *

*

* Messages are translated by the dispatcher using to the format expected by the registered consumers. *

* @see EIP: Message Dispatcher * @see Composite Pattern */ public class MessageDispatcher implements Consumer { private static final Logger LOG = getLogger(MessageDispatcher.class); private static final Pattern ACCEPT_ALL = compile(".*"); private final List> messageConsumers; public MessageDispatcher() { this.messageConsumers = synchronizedList(new ArrayList<>()); } public MessageDispatcher(final List> messageConsumers) { this.messageConsumers = synchronizedList(new ArrayList<>(messageConsumers)); } public void add(final MessageConsumer messageConsumer) { this.messageConsumers.add(messageConsumer); } public List> getAll() { return unmodifiableList(messageConsumers); } /** * Returns the expected payload type of {@link Message events} consumed by this EventConsumer. * * @return payload type */ @Nonnull public Class payloadType() { return String.class; } /** * Returns the pattern of {@link Message#getKey() event keys} accepted by this consumer. * * @return Pattern */ @Nonnull public Pattern keyPattern() { return ACCEPT_ALL; } /** * Accepts a message with JSON String payload, dispatches this method to the different registered * {@link MessageConsumer consumers} if their {@link MessageConsumer#keyPattern()} matches, and * translates the JSON payload into the expected {@link MessageConsumer#payloadType()} of the receiving * MessageConsumer. * * @param message the input argument */ @Override @SuppressWarnings({"unchecked", "raw"}) public void accept(final TextMessage message) { LOG.debug("Accepting message={}", message); messageConsumers .stream() .filter(consumer -> matchesKeyPattern(message, consumer.keyPattern())) .forEach((MessageConsumer consumer) -> { try { final Class payloadType = consumer.payloadType(); if (payloadType.equals(String.class)) { consumer.accept(message); } else { Object payload = null; if (message.getPayload() != null) { payload = currentObjectMapper().readValue(message.getPayload(), payloadType); } final Message tMessage = message(message.getKey(), message.getHeader(), payload); consumer.accept(tMessage); } } catch (final Exception e) { LOG.error(e.getMessage(), e); throw new IllegalStateException(e.getMessage(), e); } }); } private boolean matchesKeyPattern(final TextMessage message, final Pattern keyPattern) { return keyPattern.matcher(message.getKey().compactionKey()).matches(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy