Kraken Message Bus
Kraken Message Bus provides convenient message switching infrastructure. Kraken RPC provides similar functions, but Kraken Message Bus supports also user interface aware features. (e.g. localization)
How to create Message Bus Plugin
package org.krakenapps.example.msgbus;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Requires;
import org.krakenapps.msgbus.Request;
import org.krakenapps.msgbus.Response;
import org.krakenapps.msgbus.handler.MsgbusMethod;
import org.krakenapps.msgbus.handler.MsgbusPlugin;
@Component(name = "my-hello-plugin")
@MsgbusPlugin
public class HelloPlugin {
@MsgbusMethod
public void hello(Request req, Response resp) {
String name = req.getString("name");
resp.put("hello", name);
}
}
..and instanciate this iPOJO component. That's all.
Request contains Session and all parameters, and you should write output to Response object. You can pass only well-known primitive types or reference types.
- Integer
- Long
- Float
- Double
- String
- Collection (List, Set, etc)
- Map
How to receive session event
You can also receive session opened or closed callback by annotating methods.
@MsgbusMethod(type = CallbackType.SessionOpened)
public void onSessionOpened(Session session) {
// pre-allocate or preparing tasks
}
@MsgbusMethod(type = CallbackType.SessionClosed)
public void onSessionClosed(Session session) {
// clean up resources even if unexpected termination occurred
}
Exception handling
You should extends MessageBusException for custom exception. MessageBusException can provide localized messages, because it contains group id, error code, and properties. Caller (e.g. webconsole) can inspect these informations, choose appropriate ResourceHandler from ResourceApi, and get localized text using ResourceHandler.getText(String code, Locale locale).
All other exceptions can also be used, but they will be represented as an unknown exception with e.getMessage().
How it works?
Registration
MsgbusPluginHandler extends iPOJO component. When iPOJO component is initializing (see configure callback), handler finds all declared (i.e. public) method which is annotated by @MsgbusMethod and register them to message bus service.
Dispatch and Invocation
Caller (e.g. webconsole protocol decoder) dispatches message via MessageBus.dispatch(Session, Message). Message Bus service looks up service table, and invokes it using reflection. Method is consists of package name, class name, and method name. For example, hello() method in the above example is exposed as "org.krakenapps.example.msgbus.HelloPlugin.hello".
Core Interfaces and Classes
Message Bus interface
public interface MessageBus {
Collection<String> getPluginNames();
Collection<String> getMethodNames(String pluginName);
Collection<Session> getSessions();
Session getSession(int id);
void dispatch(Session session, Message msg);
void send(Message msg);
void openSession(Session session);
void closeSession(Session session);
void register(MessageHandler handler);
void unregister(MessageHandler handler);
void register(SessionEventHandler callback);
void unregister(SessionEventHandler callback);
}
Request class
public class Request {
public Session getSession();
public String getMethod();
public String getSource();
public boolean has(String key);
public String getString(String key);
public Integer getInteger(String key);
public Boolean getBoolean(String key);
public Date getDate(String key);
public Object get(String key);
}
Response class
public class Response implements Map<String, Object> {
public void clear();
public boolean containsKey(Object key);
public boolean containsValue(Object value);
public Set<java.util.Map.Entry<String, Object>> entrySet();
public Object get(Object key);
public boolean isEmpty();
public Set<String> keySet();
public Object put(String key, Object value);
public void putAll(Map<? extends String, ? extends Object> m);
public Object remove(Object key);
public int size();
public Collection<Object> values();
}
Session interface
public interface Session {
int getId();
Object get(String key);
String getString(String key);
Integer getInt(String key);
void setProperty(String key, Object value);
void unsetProperty(String key);
void send(Message msg);
void close();
}
Marshalable interface
public interface Marshalable {
Map<String, Object> marshal();
}
When you define any data transfer object (DTO) or domain entity classes, it is useful to mark it with Marshalable interface. Then you can easily serialize collection or map using Marshaler.marshal(Map m) or Marshaler.marshal(Collection c) helper methods.
Resource API interface
public interface ResourceApi {
ResourceHandler getResourceHandler(String groupId);
void register(String groupId, ResourceHandler handler);
void unregister(String groupId, ResourceHandler handler);
}
Create your own ResourceHandler and register it to ResourceApi. iPOJO's @Validate and @Invalidate callback can be used for registration and unregistration tasks.
public interface ResourceHandler {
String formatText(String key, Locale locale, String[] params);
String getText(String key, Locale locale);
}
See Also
History
- 1.0.0
