Hi Folks,
I'm trying to build an EventListener that sends messages to a Rabbit Message Queue. I want to use Spring AMQP to wire up and send messages during build events.
I was able to to successfully wire up a very simple build listener using the following configuration:
<atlassian-plugin key="${project.groupId}.${project.artifactId}" name="${project.name}" plugins-version="2">
<plugin-info>
<description>${project.description}</description>
<version>${project.version}</version>
<vendor name="${project.organization.name}" url="${project.organization.url}" />
</plugin-info>
<bambooEventListener key="buildStateListener.event" name="Build State Listener"
class="com.jeffdoto.sherlock.bamboo.BuildStateListener">
<description>Listens for events and adds them to a message queue if enabled.</description>
</bambooEventListener>
</atlassian-plugin>
I cannot, however, seem to inject my own custom beans into my listener. I get a working listener that receives events, but I get null pointer exceptions because my custom beans are not getting injected.
Here's my implementation of the HibernateEventListener interface.
public class BuildStateListener implements HibernateEventListener {
Logger logger = LoggerFactory.getLogger(BuildStateListener.class);
private AmqpTemplate amqpTemplate;
private String completedTopicAddress;
@Override
public void handleEvent(Event event) {
if (event instanceof BuildCompletedEvent){
String planKey = ((BuildCompletedEvent) event).getBuildPlanKey();
logger.info(String.format("BuildCompletedEvent received. Publishing message to %s", completedTopicAddress));
amqpTemplate.convertAndSend(completedTopicAddress, planKey);
}
}
@Override
public Class[] getHandledEventClasses() {
return new Class[]{
BuildCompletedEvent.class
};
}
@Required
public void setAmqpTemplate(AmqpTemplate amqpTemplate) {
this.amqpTemplate = amqpTemplate;
}
@Required
public void setCompletedTopicAddress(String completedTopicAddress) {
this.completedTopicAddress = completedTopicAddress;
}
}
Now, my question is, is it possible for me to inject the AmqpTemplate and topic address? If so, what is the correct way to do so? I've tried using OSGi Felix instructions in my pom.xml to no avail (I had a bunch of issues with BundleExceptions and constraint errors), and I've tried using a custom Spring Dynamic Modules config file:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="
http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd"
default-autowire="autodetect">
<rabbit:connection-factory id="connectionFactory"/>
<rabbit:amqpTemplate id="amqpTemplate" exchange="bamboo-build-events" connection-factory="connectionFactory"/>
<rabbit:admin connection-factory="connectionFactory"/>
<rabbit:queue name="default"/>
<bean id="buildStateListener" class="com.jeffdoto.sherlock.bamboo.BuildStateListener">
<property name="amqpTemplate" ref="amqpTemplate"/>
<property name="completedTopicAddress" ref="bamboo.build.completed"/>
</bean>
<osgi:service id="buildStateListenerOsgi" ref="buildStateListener"
interface=" com.atlassian.bamboo.event.HibernateEventListener"/>
</beans:beans>
But i'm not making any progress here. Any suggestions? This has to be doable.
I do see that there are separate Notification plugin modules available, but there is no direct support for anything other than email and IM, hence my desire to wire up my own AMQP stuff here. This also seems simpler, just having the logic right in the event listener.
Thanks for your help!
Jeff