Last active
April 30, 2017 19:00
-
-
Save ndemengel/6041dc1e72bee15f1f30afee19302fdb to your computer and use it in GitHub Desktop.
RabbitMQ/Spring migration - Step 3: extraction of the exchange name from the event
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// the exchange is not mentioned anymore here | |
@RabbitEventListener(queue = "email.updated.mailchimp.queue") | |
public void emailUpdated(EmailUpdated event) { | |
updateMailChimpMember(event.getOldEmail(), event.getNewEmail()); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface Event { | |
String EXCHANGE_FIELD_NAME = "EXCHANGE_NAME"; | |
public static String getExchangeName(Event event) { | |
return getExchangeName(event.getClass()); | |
} | |
public static String getExchangeName(Class<? extends Event> eventClass) { | |
return (String) eventClass.getDeclaredField(EXCHANGE_FIELD_NAME).get(null); | |
// skipped: error handling and validation | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// just a single fire method defined once and for all, no more overloads | |
public void fire(Event event) { | |
String exchangeName = Event.getExchangeName(event); | |
String noRoutingKey = ""; | |
rabbitTemplate.convertAndSend(exchangeName, noRoutingKey, event); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// No more @PostConstruct configuration for individual exchanges, queues or bindings! | |
// Only generic plumbing is left. | |
// additionally, we scan the classpath for Event classes to find all the exchanges to create | |
@PostConstruct | |
public void createExchangesFromEventsInClasspath() { | |
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); | |
scanner.addIncludeFilter(new AssignableTypeFilter(Event.class)); | |
scanner.findCandidateComponents("com.hopwork").forEach(c -> { | |
Class<? extends Event> eventClass = (Class<? extends Event>) Class.forName(c.getBeanClassName()); | |
String exchangeName = Event.getExchangeName(eventClass); | |
// this method has been defined during previous step, we just made it visible and static, | |
// and gave it beanRegistry as a parameter | |
RabbitEventListenerPostProcessor.ensureExchangeExists(exchangeName, beanRegistry); | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// this method changes a bit to use Event.getExchangeName() | |
private void initRabbitListener(Object bean, String beanName, Method method) { | |
// same code as in previous step | |
RabbitEventListener bindingDescriptor = AnnotationUtils.findAnnotation(method, RabbitEventListener.class); | |
if (bindingDescriptor != null) { | |
// Previously, was: | |
// - FanoutExchange exchange = ensureExchangeExists(bindingDescriptor.exchange()); | |
// Now: | |
Class<? extends Event> eventClass = getEventClass(method); | |
String exchangeName = Event.getExchangeName(eventClass); | |
FanoutExchange exchange = ensureExchangeExists(exchangeName); | |
// same code as in previous step | |
createAndBindQueueToExchangeAndDeadLetter(exchange, bindingDescriptor.queue()); | |
processAmqpListener(toSpringRabbitListenerAnnotation(bindingDescriptor), method, bean, beanName); | |
} | |
} | |
private Class<? extends Event> getEventClass(Method method) { | |
return stream(method.getParameterTypes()) | |
.filter(Event.class::isAssignableFrom) | |
.map(cls -> (Class<Event>) cls) | |
.findFirst() | |
.orElseThrow(() -> new IllegalStateException(String.format( | |
"Method %s is annotated with %s but has no argument of type %s", | |
method.getName(), RabbitEventListener.class.getSimpleName(), Event.class.getSimpleName()))); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment