HTTPS SSH

README

"The REFCODES.ORG codes represent a group of artifacts consolidating parts of my work in the past years. Several topics are covered which I consider useful for you, programmers, developers and software engineers."

What is this repository for?

"Simply speaking, the equation Observer pattern + Publish–subscribe pattern = Message broker solves to refcodes-eventbus ..." [Publish ... subscribe ... observe ... event-bus?, 01/05/2015]

The refcodes-eventbus artifacts implements a lightweight infrastructure for event based decoupled communication. This is achieved by implementing the Observer pattern combined with the Publish–subscribe pattern, ending up being a Message broker for events.

In your application, you subscribe an EventBusObserver (Observer) to an EventBus (EventBusImpl). You assign an BusMatcher for a Channel, a Group and some other attributes to your EventBusObserver. In case a MetaDataEvent is published with a matching attribute (such as Channel or Group), then your EventBusObserver is signaled (is passed the MetaDataEvent) ... voilà, the publisher is fully decoupled from the subscriber.

How do I get set up?

To get up and running, include the following dependency (without the three dots "...") in your pom.xml:

<dependencies>
    ...
    <dependency>
        <groupId>org.refcodes</groupId>
        <artifactId>refcodes-eventbus</artifactId>
        <version>1.3.0</version>
    </dependency>
    ...
</dependencies>

The artifact is hosted directly at Maven Central. Jump straight to the source codes at Bitbucket. Read the artifact's javadoc at javadoc.io.

How do I get started?

First of all you create your EventBus (EventBusImpl) instance:

EventBusImpl theEventBus = new EventBusImpl();

Then you create your event-listener instances being of type EventBusObserver:

For the sake of simplicity: I declared the event-listener types "on the fly" as inner classes:

EventBusObserver theSportsObserver = new EventBusObserver() {
    @Override
    public void onEvent( MetaDataEvent aEvent ) {
        LOGGER.debug( "Got a sports event on channel <" + aEvent.getMetaData().getChannel() + ">" );
    }
};

EventBusObserver thePoliticsObserver = new EventBusObserver() {
    @Override
    public void onEvent( MetaDataEvent aEvent ) {
        LOGGER.debug( "Got a politics event on channel <" + aEvent.getMetaData().getChannel() + ">" );
    }
};

I created two event-listener instances; one is to be registered for sports related channels and one is to be registered for the politics related channels. So I subscribe them event-listener instances as follows:

theEventBus.subscribe( theSportsObserver, or( channelEqualWith( "Soccer" ), channelEqualWith( "Football" ) ) );
theEventBus.subscribe( thePoliticsObserver, or( channelEqualWith( "War" ), channelEqualWith( "Education" ) ) );

On purpose, the event-listener code and the the event-matcher doing the filtering (as of the BusMatcher) of the events is separated: It is not up to the event-listener to decide which events it finds interesting because there could be top-secret events to which it must not have access. Also before processing an event, the event-bus can determine whether there actually are any matchers letting that event pass to an event-listener.

Now let's see how to publish a plain event (you can and actually should create your own event sub-classes):

theEventBus.publishEvent( new MetaDataEventImpl( "Soccer", this ) );
theEventBus.publishEvent( new MetaDataEventImpl( "Education", this ) );
theEventBus.publishEvent( new MetaDataEventImpl( "Football", this ) );
theEventBus.publishEvent( new MetaDataEventImpl( "War", this ) );
theEventBus.publishEvent( new MetaDataEventImpl( "Formular 1", this ) );
theEventBus.publishEvent( new MetaDataEventImpl( "Top Secret", this ) );

Below see the output of this example:

19:43:25,084 DEBUG [EventBusTest] Got a sports event on channel <Soccer>
19:43:25,085 DEBUG [EventBusTest] Got a politics event on channel <Education>
19:43:25,085 DEBUG [EventBusTest] Got a sports event on channel <Football>
19:43:25,086 DEBUG [EventBusTest] Got a politics event on channel <War>

As you can see, the "Top Secret" event was not passed to any of the event-listeners, so you can separate the event-listeners' business logic from the routing logic practicing the Separation of concerns idea.

You can determine beforehand whether there is an event-listener registered for some given event:

assertFalse( theEventBus.isMatching( new MetaDataEventImpl( "Top Secret", this ) ) );
assertTrue( theEventBus.isMatching( new MetaDataEventImpl( "Soccer", this ) ) );
assertTrue( theEventBus.isMatching( new MetaDataEventImpl( "Education", this ) ) );

Here I used the unit-test's assertion functionality to proof that the matching mechanism works correctly.

See the EventBusTest unit test for the source code of this example.

Contribution guidelines

Who do I talk to?

  • Siegfried Steiner (steiner@refcodes.org)

Terms and conditions

The REFCODES.ORG group of artifacts is published under some open source licenses; covered by the refcodes-licensing (org.refcodes group) artifact - evident in each artifact in question as of the pom.xml dependency included in such artifact.