提交 8a4b56d4 编写于 作者: F Frankie Wu

add event and rule to dog-home

上级 d559839e
package com.dianping.dog.alarm.rule;
import java.util.HashMap;
import java.util.Map;
public class DefaultRuleContext implements RuleContext {
private Map<String, Object> m_attributes = new HashMap<String, Object>();
@SuppressWarnings("unchecked")
@Override
public <T> T getAttribute(String name) {
return (T) m_attributes.get(name);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getAttribute(String name, T defaultValue) {
Object value = m_attributes.get(name);
if (value == null) {
return defaultValue;
} else {
return (T) value;
}
}
@Override
public void setAttribute(String name, Object value) {
m_attributes.put(name, value);
}
}
\ No newline at end of file
package com.dianping.dog.alarm.rule;
public interface Rule {
public String getName();
public boolean apply(RuleContext ctx);
}
package com.dianping.dog.alarm.rule;
public interface RuleContext {
public <T> T getAttribute(String name);
public <T> T getAttribute(String name, T defaultValue);
public void setAttribute(String name, Object value);
}
package com.dianping.dog.alarm.rule.reactor;
import com.dianping.dog.alarm.rule.DefaultRuleContext;
import com.dianping.dog.alarm.rule.Rule;
import com.dianping.dog.alarm.rule.RuleContext;
import com.dianping.dog.event.Event;
import com.dianping.dog.event.EventDispatcher;
import com.dianping.dog.event.EventListener;
import com.site.lookup.annotation.Inject;
public abstract class AbstractRuleReactor<T extends Event> implements EventListener<T> {
@Inject
private EventDispatcher m_dispatcher;
@Inject
private Rule m_rule;
protected abstract Event createNextEvent(RuleContext ctx);
protected T getEvent(RuleContext ctx) {
return ctx.getAttribute("event");
}
@Override
public void onEvent(T event) {
DefaultRuleContext ctx = new DefaultRuleContext();
prepare(ctx, event);
ctx.setAttribute("event", event);
if (m_rule.apply(ctx)) {
Event nextEvent = createNextEvent(ctx);
if (nextEvent != null) {
m_dispatcher.dispatch(nextEvent);
}
}
}
protected abstract void prepare(RuleContext ctx, T event);
protected void setDispatcher(EventDispatcher dispatcher) {
m_dispatcher = dispatcher;
}
protected void setRule(Rule rule) {
m_rule = rule;
}
}
package com.dianping.dog.alarm.rule.reactor;
import com.dianping.dog.alarm.rule.DefaultRuleContext;
import com.dianping.dog.event.Event;
public class ReactorRuleContext<T extends Event> extends DefaultRuleContext {
private T m_event;
public ReactorRuleContext(T event) {
m_event = event;
}
public T getEvent() {
return m_event;
}
}
package com.dianping.dog.event;
import java.util.List;
import com.dianping.cat.Cat;
import com.site.lookup.annotation.Inject;
public class DefaultEventDispatcher implements EventDispatcher {
@Inject
private EventListenerRegistry m_registry;
@Override
public void dispatch(Event event) {
List<EventListener<Event>> listeners = m_registry.getListeners(event.getType());
if (listeners != null && !listeners.isEmpty()) {
for (EventListener<Event> listener : listeners) {
try {
listener.onEvent(event);
} catch (Exception e) {
// ignore it
Cat.getProducer().logError(e);
}
}
} else {
Cat.getProducer().logEvent("UnhandledEvent", event.getType().getClass().getName(), "0", null);
}
}
}
package com.dianping.dog.event;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DefaultEventListenerRegistry implements EventListenerRegistry {
private Map<EventType, List<EventListener<Event>>> m_map = new HashMap<EventType, List<EventListener<Event>>>();
@Override
public List<EventListener<Event>> getListeners(EventType type) {
return m_map.get(type);
}
@SuppressWarnings("unchecked")
@Override
public void register(EventType type, EventListener<?> listener) {
List<EventListener<Event>> listeners = m_map.get(type);
if (listeners == null) {
synchronized (m_map) {
listeners = m_map.get(type);
if (listeners == null) {
listeners = new ArrayList<EventListener<Event>>();
m_map.put(type, listeners);
}
}
}
synchronized (listeners) {
listeners.add((EventListener<Event>) listener);
}
}
}
package com.dianping.dog.event;
public interface Event {
public EventType getType();
}
package com.dianping.dog.event;
public interface EventDispatcher {
public void dispatch(Event event);
}
package com.dianping.dog.event;
public interface EventListener<T extends Event> {
public void onEvent(T event);
}
package com.dianping.dog.event;
import java.util.List;
public interface EventListenerRegistry {
public List<EventListener<Event>> getListeners(EventType type);
public void register(EventType type, EventListener<?> listener);
}
package com.dianping.dog.event;
public interface EventType {
}
package com.dianping.dog.event;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import com.site.lookup.ComponentTestCase;
@RunWith(JUnit4.class)
public class EventTest extends ComponentTestCase {
private static StringBuilder s_result = new StringBuilder();
@Test
public void test() throws Exception {
EventListenerRegistry registry = lookup(EventListenerRegistry.class);
registry.register(MockEventType.TYPE1, MockEventListener.INSTANCE);
EventDispatcher dispatcher = lookup(EventDispatcher.class);
s_result.setLength(0);
for (int i = 0; i < 10; i++) {
dispatcher.dispatch(new MockEvent(i));
}
Assert.assertEquals("0:1:2:3:4:5:6:7:8:9:", s_result.toString());
}
static enum MockEventType implements EventType {
TYPE1;
}
static enum MockEventListener implements EventListener<MockEvent> {
INSTANCE;
@Override
public void onEvent(MockEvent event) {
s_result.append(event.getIndex()).append(':');
}
}
static class MockEvent implements Event {
private int m_index;
public MockEvent(int index) {
m_index = index;
}
public int getIndex() {
return m_index;
}
@Override
public EventType getType() {
return MockEventType.TYPE1;
}
}
}
package com.dianping.dog.rule;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import com.dianping.dog.alarm.rule.Rule;
import com.dianping.dog.alarm.rule.RuleContext;
import com.dianping.dog.alarm.rule.reactor.AbstractRuleReactor;
import com.dianping.dog.event.Event;
import com.dianping.dog.event.EventDispatcher;
import com.dianping.dog.event.EventListener;
import com.dianping.dog.event.EventListenerRegistry;
import com.dianping.dog.event.EventType;
import com.site.lookup.ComponentTestCase;
@RunWith(JUnit4.class)
public class RuleTest extends ComponentTestCase {
private static StringBuilder s_result = new StringBuilder();
@Test
public void test() throws Exception {
EventListenerRegistry registry = lookup(EventListenerRegistry.class);
EventDispatcher dispatcher = lookup(EventDispatcher.class);
registry.register(MockEventType.CONNECTION, new ConnectionEventListener(dispatcher));
registry.register(MockEventType.ALARM, new AlarmEventListener());
s_result.setLength(0);
dispatcher.dispatch(new ConnectionEvent(10));
dispatcher.dispatch(new ConnectionEvent(2));
dispatcher.dispatch(new ConnectionEvent(100));
dispatcher.dispatch(new ConnectionEvent(25));
dispatcher.dispatch(new ConnectionEvent(70));
dispatcher.dispatch(new ConnectionEvent(20));
Assert.assertEquals("2:100:70:", s_result.toString());
}
static class AlarmEvent implements Event {
private int m_connections;
public AlarmEvent(int connections) {
m_connections = connections;
}
public int getConnections() {
return m_connections;
}
@Override
public EventType getType() {
return MockEventType.ALARM;
}
}
static class AlarmEventListener implements EventListener<AlarmEvent> {
@Override
public void onEvent(AlarmEvent event) {
s_result.append(event.getConnections()).append(":");
}
}
static class ConnectionEvent implements Event {
private int m_connections;
public ConnectionEvent(int connections) {
m_connections = connections;
}
public int getConnections() {
return m_connections;
}
@Override
public EventType getType() {
return MockEventType.CONNECTION;
}
}
static class ConnectionEventListener extends AbstractRuleReactor<ConnectionEvent> {
public ConnectionEventListener(EventDispatcher dispatcher) {
setDispatcher(dispatcher);
setRule(ConnectionRule.INSTANCE);
}
@Override
protected Event createNextEvent(RuleContext ctx) {
return new AlarmEvent(getEvent(ctx).getConnections());
}
@Override
protected void prepare(RuleContext ctx, ConnectionEvent event) {
}
}
static enum ConnectionRule implements Rule {
INSTANCE;
@Override
public boolean apply(RuleContext ctx) {
int connections = ctx.getAttribute("connections");
return connections < 3 || connections > 30;
}
@Override
public String getName() {
return getClass().getSimpleName();
}
}
static enum MockEventType implements EventType {
CONNECTION, ALARM;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册