Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public static DomainEventPublisher instance() {
}

public <T> void publish(final T aDomainEvent) {
if (!this.isPublishing() && this.hasSubscribers()) {
if (this.hasSubscribers()) {

try {
this.setPublishing(true);
Expand All @@ -49,7 +49,7 @@ public <T> void publish(final T aDomainEvent) {
for (DomainEventSubscriber<T> subscriber : allSubscribers) {
Class<?> subscribedToType = subscriber.subscribedToEventType();

if (eventType == subscribedToType || subscribedToType == DomainEvent.class) {
if (eventType == subscribedToType || subscribedToType == DomainEvent.class || subscribedToType.isAssignableFrom(eventType)) {
subscriber.handleEvent(aDomainEvent);
}
}
Expand All @@ -67,18 +67,18 @@ public void publishAll(Collection<DomainEvent> aDomainEvents) {
}

public void reset() {
if (!this.isPublishing()) {
this.setSubscribers(null);
}
this.setSubscribers(null);
}

@SuppressWarnings("unchecked")
public <T> void subscribe(DomainEventSubscriber<T> aSubscriber) {
if (!this.isPublishing()) {
this.ensureSubscribersList();

this.subscribers().add(aSubscriber);
if (this.isPublishing()) {
throw new IllegalStateException("cannot subscribe while handling an event");
}

this.ensureSubscribersList();

this.subscribers().add(aSubscriber);
}

private DomainEventPublisher() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.saasovation.common.event;

public class AKindOfTestableDomainEvent extends TestableDomainEvent {
private Integer value;

public AKindOfTestableDomainEvent(long anId, String aName, Integer aValue) {
super(anId, aName);
}

public Integer value() { return value; }

private void setValue(Integer value) {
this.value = value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ public DomainEventPublisherTest() {
super();
}

public void testDomainEventPublisherPublish() throws Exception {
@Override
protected void setUp() throws Exception {
DomainEventPublisher.instance().reset();
}

public void testDomainEventPublisherPublish() throws Exception {
DomainEventPublisher.instance().subscribe(new DomainEventSubscriber<TestableDomainEvent>(){
@Override
public void handleEvent(TestableDomainEvent aDomainEvent) {
Expand All @@ -51,18 +54,15 @@ public Class<TestableDomainEvent> subscribedToEventType() {
assertTrue(this.eventHandled);
}

public void testDomainEventPublisherBlocked() throws Exception {
DomainEventPublisher.instance().reset();

DomainEventPublisher.instance().subscribe(new DomainEventSubscriber<TestableDomainEvent>(){
public void testCanPublishInEventHandler() throws Exception {
DomainEventPublisher.instance().subscribe(new DomainEventSubscriber<TestableDomainEvent>() {
@Override
public void handleEvent(TestableDomainEvent aDomainEvent) {
assertEquals(100L, aDomainEvent.id());
assertEquals("test", aDomainEvent.name());
eventHandled = true;
// attempt nested publish, which should not work
DomainEventPublisher.instance().publish(new AnotherTestableDomainEvent(1000.0));
}

@Override
public Class<TestableDomainEvent> subscribedToEventType() {
return TestableDomainEvent.class;
Expand All @@ -72,7 +72,6 @@ public Class<TestableDomainEvent> subscribedToEventType() {
DomainEventPublisher.instance().subscribe(new DomainEventSubscriber<AnotherTestableDomainEvent>(){
@Override
public void handleEvent(AnotherTestableDomainEvent aDomainEvent) {
// should never be reached due to blocked publisher
assertEquals(1000.0, aDomainEvent.value());
anotherEventHandled = true;
}
Expand All @@ -88,6 +87,66 @@ public Class<AnotherTestableDomainEvent> subscribedToEventType() {
DomainEventPublisher.instance().publish(new TestableDomainEvent(100L, "test"));

assertTrue(this.eventHandled);
assertTrue(this.anotherEventHandled);
}

public void testCannotSubscribeWhenPublishing() throws Exception {
final DomainEventSubscriber<AnotherTestableDomainEvent> anotherHandler = new DomainEventSubscriber<AnotherTestableDomainEvent>() {
@Override
public void handleEvent(AnotherTestableDomainEvent aDomainEvent) {
// should never be reached due to incapacitated handler
anotherEventHandled = true;
}

@Override
public Class<AnotherTestableDomainEvent> subscribedToEventType() {
return AnotherTestableDomainEvent.class;
}
};

DomainEventPublisher.instance().subscribe(new DomainEventSubscriber<TestableDomainEvent>(){
@Override
public void handleEvent(TestableDomainEvent aDomainEvent) {
eventHandled = true;
DomainEventPublisher.instance().subscribe(anotherHandler);
}
@Override
public Class<TestableDomainEvent> subscribedToEventType() {
return TestableDomainEvent.class;
}
});

try {
DomainEventPublisher.instance().publish(new TestableDomainEvent(100L, "test"));
fail("the event subscriber should not be allowed to complete as it's trying to modify the publisher's subscribers while handling an event (causing a ConcurrentModificationException)");
} catch(IllegalStateException e) {
// we're good
}

assertFalse(this.anotherEventHandled);

DomainEventPublisher.instance().publish(new AnotherTestableDomainEvent(1000.0));

assertFalse(this.anotherEventHandled);
}

public void testPublishesEventsInheritingFromTheSubscribedToEventType() throws Exception {
DomainEventPublisher.instance().subscribe(new DomainEventSubscriber<TestableDomainEvent>() {
@Override
public void handleEvent(TestableDomainEvent aDomainEvent) {
eventHandled = true;
}

@Override
public Class<TestableDomainEvent> subscribedToEventType() {
return TestableDomainEvent.class;
}
});

assertFalse(this.eventHandled);

DomainEventPublisher.instance().publish(new AKindOfTestableDomainEvent(100L, "test", 1));

assertTrue(this.eventHandled);
}
}