Skip to content

Instantly share code, notes, and snippets.

@bduisenov
Last active December 30, 2015 21:50
Show Gist options
  • Save bduisenov/7889800 to your computer and use it in GitHub Desktop.
Save bduisenov/7889800 to your computer and use it in GitHub Desktop.
jboss errai and spring integration
package kz.bas.app.server.core.integration;
import kz.bas.app.server.core.utils.Pair;
import org.jboss.errai.bus.client.api.builder.DefaultRemoteCallBuilder;
import org.jboss.errai.bus.client.api.messaging.Message;
import org.jboss.errai.bus.client.api.messaging.MessageCallback;
import org.jboss.errai.bus.server.annotations.Remote;
import org.jboss.errai.bus.server.api.ServerMessageBus;
import org.jboss.errai.bus.server.io.RPCEndpointFactory;
import org.jboss.errai.bus.server.io.RemoteServiceCallback;
import org.jboss.errai.bus.server.io.ServiceInstanceProvider;
import org.jboss.errai.bus.server.service.ErraiService;
import org.jboss.errai.bus.server.service.ErraiServiceSingleton.ErraiInitCallback;
import org.jboss.errai.common.client.api.Assert;
import org.jboss.errai.common.client.framework.ProxyFactory;
import org.jboss.errai.config.rebind.ProxyUtil;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import static org.jboss.errai.bus.server.service.ErraiServiceSingleton.registerInitCallback;
/**
* This class is a simple integration of Errai Bus and Spring.
* Spring based @Service bean which extends Errai's @Remote interface.
*
* @author Babur Duisenov.
*/
@Component
public class ErraiApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
private static final Logger logger = Logger.getLogger(ErraiApplicationListener.class.toString());
boolean initialized = false;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (!initialized) {
logger.info("discovering spring beans for rpc");
final List<Pair<Class<?>, Object>> beans = new ArrayList<Pair<Class<?>, Object>>();
for (Object type : event.getApplicationContext().getBeansWithAnnotation(Service.class).values()) {
for (Class<?> intf : type.getClass().getInterfaces()) {
if (intf.isAnnotationPresent(Remote.class)) {
logger.info("discovered " + type.getClass().getName() + " bean with errai remote " + intf.getName());
beans.add(new Pair<Class<?>, Object>(intf, type));
}
}
}
registerInitCallback(new ErraiInitCallback() {
@Override
public void onInit(ErraiService service) {
logger.info("registering " + beans.size() + " beans");
for (Pair<Class<?>, Object> pair : beans) {
registerErraiRPCSpringServices(service, pair._1(), pair._2());
}
logger.info("registered all discovered rpc services.");
}
});
initialized = true;
}
}
/**
* Method produced based on @link{org.jboss.errai.bus.server.service.ServiceProcessor}
*
* @param service
* @param remoteIface
* @param svc
*/
private void registerErraiRPCSpringServices(ErraiService service, final Class<?> remoteIface, final Object svc) {
final ServerMessageBus bus = service.getBus();
final Map<String, MessageCallback> epts = new HashMap<String, MessageCallback>();
final ServiceInstanceProvider genericSvc = new ServiceInstanceProvider() {
@Override
public Object get(Message message) {
return svc;
}
};
// beware of classloading issues. better reflect on the actual instance
for (Class<?> intf : svc.getClass().getInterfaces()) {
for (final Method method : intf.getMethods()) {
if (ProxyUtil.isMethodInInterface(remoteIface, method)) {
epts.put(ProxyUtil.createCallSignature(intf, method), RPCEndpointFactory.createEndpointFor(genericSvc, method, bus));
}
}
}
bus.subscribe(remoteIface.getName() + ":RPC", new RemoteServiceCallback(epts));
// note: this method just exists because we want AbstractRemoteCallBuilder to be package
// private.
DefaultRemoteCallBuilder.setProxyFactory(Assert.notNull(new ProxyFactory() {
@Override
public <T> T getRemoteProxy(Class<T> proxyType) {
throw new RuntimeException(
"There is not yet an available Errai RPC implementation for the server-side environment");
}
}));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment