Skip to content

Instantly share code, notes, and snippets.

@olostan
Created April 13, 2011 05:35
Show Gist options
  • Save olostan/917015 to your computer and use it in GitHub Desktop.
Save olostan/917015 to your computer and use it in GitHub Desktop.
Sime CQRS set on java
package simplejcqrs.domain;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import junit.framework.Assert;
import org.junit.Test;
import simplejcqrs.domain.DepartmentTests.AggregateRoot;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
public class DepartmentTests
{
public @interface Handler {
Class<?> value();
}
public static class DepartmentCreatedEvent extends Event {
private String id;
private String name;
public DepartmentCreatedEvent(Department department) {
this.id = department.getId();
this.name = department.getName();
}
}
public static class CreateDepartmentCommand extends Command {
private String name;
public CreateDepartmentCommand(String id, String name) {
super(id);
this.name = name;
}
public String getName() {
return name;
}
}
public static class DepartmentCommandHandler {
private Repository rep;
@Inject
public DepartmentCommandHandler(Repository rep) {
super();
this.rep = rep;
}
public void handleCreateDepartment(CreateDepartmentCommand cmd) {
Department dep = new Department(cmd.getId(), cmd.getName());
rep.put(cmd.getId(), dep);
}
}
public static abstract class AggregateRoot {
private String id;
public AggregateRoot(String id) {
super();
this.id = id;
}
public String getId() {
return id;
}
protected EventBus eventBus;
@Inject
public void setEventBus(EventBus eventBus) {
this.eventBus = eventBus;
}
}
@Handler(DepartmentCommandHandler.class)
public static class Department extends AggregateRoot {
public static final String TYPE = "department";
private String name;
public Department(String id, String name) {
super(id);
this.name = name;
eventBus.fire(new DepartmentCreatedEvent(this));
}
public String getName() {
return name;
}
}
public static abstract class Event
{
}
public static abstract class Command {
private String id;
public Command(String id) {
super();
this.id = id;
}
public String getId() {
return id;
}
}
public interface CommandBus
{
void Execute(Command cmd);
}
@Singleton
public static class StaticCommandBus implements CommandBus
{
private final Repository repository;
@Inject
public StaticCommandBus(Repository repository) {
super();
this.repository = repository;
}
@Override
public void Execute(Command cmd) {
Class<AggregateRoot> arClass = getARClassByCommand(cmd);
AggregateRoot root = repository.get(arClass,cmd.getId());
root.class
}
private Class<AggregateRoot> getARClassByCommand(Command cmd)
{
return null;
}
}
public interface EventBus
{
Iterable<Event> GetEvents(String type, String id);
}
@Singleton
public static class StaticEventBus implements EventBus {
private Map<String,Map<String,Event>> events =
new HashMap<String,Map<String,Event>>();
private static class EmptyEvents implements Iterable<Event> {
@Override
public Iterator<Event> iterator() {
return new Iterator<Event>() {
@Override
public boolean hasNext() {
return false;
}
@Override
public Event next() {
return null;
}
@Override
public void remove() {
}
};
}
}
@Override
public Iterable<Event> GetEvents(String type, String id) {
return new EmptyEvents();
}
}
public interface Repository {
<T extends AggregateRoot> T get(Class<T> cls, String Id);
<T extends AggregateRoot> void put(String id, T root);
}
@Singleton
public static class StaticRepository implements Repository {
private Map<Class<?>,Map<String,AggregateRoot>> roots =
new HashMap<Class<?>,Map<String,AggregateRoot>>();
@Override
public <T extends AggregateRoot> T get(Class<T> cls, String Id) {
Map<String, AggregateRoot> set = roots.get(cls);
if (set==null) return null;
return (T) set.get(Id);
}
@Override
public <T extends AggregateRoot> void put(String id, T root) {
Map<String, AggregateRoot> set = roots.get(root.getClass());
if (set==null)
{
set = new HashMap<String,AggregateRoot>();
roots.put(root.getClass(), set);
}
set.put(id, root);
}
}
public static class StaticTestingModule extends AbstractModule {
@Override
protected void configure() {
bind(EventBus.class).to(StaticEventBus.class);
bind(CommandBus.class).to(StaticCommandBus.class);
bind(Repository.class).to(StaticRepository.class);
}
}
@Test
public void Should_create_departments() {
Injector injector = Guice.createInjector(new StaticTestingModule());
String id = "d1";
String name = "some name";
Command cmd = new CreateDepartmentCommand(id,name);
CommandBus cmdbus = injector.getInstance(CommandBus.class);
EventBus evbus = injector.getInstance(EventBus.class);
cmdbus.Execute(cmd);
Repository rep = injector.getInstance(Repository.class);
Department root = rep.get(Department.class, id);
Assert.assertNotNull("Aggregate root should be created", root);
Assert.assertEquals(name, root.getName());
Iterable<Event> events = evbus.GetEvents(Department.TYPE,id);
Assert.assertNotNull("Event bus should return events", events);
boolean found = false;
for (Event ev : events) {
if (ev.getClass() == DepartmentCreatedEvent.class) found = true;
}
Assert.assertTrue("Command should produce creation event",found);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment