Last active
December 30, 2015 21:50
-
-
Save bduisenov/7889800 to your computer and use it in GitHub Desktop.
jboss errai and spring integration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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