@Override public void run() { if (System.currentTimeMillis() > expiryTime) { scheduledExecutorService.shutdown(); throw new RuntimeException( "failed to discover beans: " + managedTypes.getServiceEndpoints()); } if (registered.isEmpty()) { scheduledExecutorService.shutdown(); log.info("all services registered successfully"); return; } for (final AnnotatedType<?> type : managedTypes.getServiceEndpoints()) { if (!registered.contains(type) || beanManager.getBeans(type.getJavaClass()).size() == 0) { continue; } final MessageCallback callback = (MessageCallback) CDIServerUtil.lookupBean(beanManager, type.getJavaClass()); registered.remove(type); // Discriminate on @Command final Map<String, Method> commandPoints = new HashMap<String, Method>(); for (final AnnotatedMethod method : type.getMethods()) { if (method.isAnnotationPresent(Command.class)) { final Command command = method.getAnnotation(Command.class); for (String cmdName : command.value()) { if (cmdName.equals("")) cmdName = method.getJavaMember().getName(); commandPoints.put(cmdName, method.getJavaMember()); } } } final String subjectName = CDIServerUtil.resolveServiceName(type.getJavaClass()); if (commandPoints.isEmpty()) { bus.subscribe(subjectName, callback); } else { bus.subscribeLocal( subjectName, new CommandBindingsCallback(commandPoints, callback, bus)); } } }
private void createRPCScaffolding( final Class remoteIface, final MessageBus bus, final BeanManager beanManager) { final Map<String, MessageCallback> epts = new HashMap<String, MessageCallback>(); // beware of classloading issues. better reflect on the actual instance for (final Method method : remoteIface.getMethods()) { if (ProxyUtil.isMethodInInterface(remoteIface, method)) { epts.put( ProxyUtil.createCallSignature(remoteIface, method), new ConversationalEndpointCallback( new ServiceInstanceProvider() { @SuppressWarnings("unchecked") @Override public Object get(final Message message) { if (message.hasPart(CDIProtocol.Qualifiers)) { final List<String> quals = message.get(List.class, CDIProtocol.Qualifiers); final Annotation[] qualAnnos = new Annotation[quals.size()]; for (int i = 0; i < quals.size(); i++) { qualAnnos[i] = beanQualifiers.get(quals.get(i)); } return lookupRPCBean(beanManager, remoteIface, qualAnnos); } else { return lookupRPCBean(beanManager, remoteIface, null); } } }, method, bus)); } } final RemoteServiceCallback delegate = new RemoteServiceCallback(epts); bus.subscribe( remoteIface.getName() + ":RPC", new MessageCallback() { @Override public void callback(final Message message) { delegate.callback(message); } }); log.debug("registered RPC service for: " + remoteIface.getName()); // note: this method just exists because we want AbstractRemoteCallBuilder to be package // private. DefaultRemoteCallBuilder.setProxyFactory( Assert.notNull( new ProxyFactory() { @Override public <T> T getRemoteProxy(final Class<T> proxyType) { throw new RuntimeException( "There is not yet an available Errai RPC implementation for the server-side environment."); } })); }
private void setup() { bus.unsubscribeAll(SUCCESS); bus.unsubscribeAll(FAILURE); bus.subscribe( SUCCESS, new MessageCallback() { @Override public void callback(Message message) { finishTest(); } }); bus.subscribe( FAILURE, new MessageCallback() { @Override public void callback(Message message) { fail(); } }); }
@SuppressWarnings({"UnusedDeclaration", "CdiInjectionPointsInspection"}) public void afterBeanDiscovery(@Observes final AfterBeanDiscovery abd, final BeanManager bm) { final ErraiService service = ErraiServiceSingleton.getService(); final MessageBus bus = service.getBus(); final EventRoutingTable eventRoutingTable = new EventRoutingTable(); if (bus.isSubscribed(CDI.SERVER_DISPATCHER_SUBJECT)) { return; } final byte[] randBytes = new byte[32]; final Random random = new Random(System.currentTimeMillis()); random.nextBytes(randBytes); abd.addBean(new ErraiServiceBean(bm, SecureHashUtil.hashToHexString(randBytes))); for (final MessageSender ms : messageSenders) { abd.addBean(new SenderBean(ms.getSenderType(), ms.getQualifiers(), bus)); } // Errai bus injection abd.addBean(new MessageBusBean(bus)); // Support to inject the request dispatcher. abd.addBean(new RequestDispatcherMetaData(bm, service.getDispatcher())); // Register observers abd.addObserverMethod(new ShutdownEventObserver(managedTypes, bus)); // subscribe service and rpc endpoints subscribeServices(bm, bus); final EventDispatcher eventDispatcher = new EventDispatcher(bm, eventRoutingTable, bus, observableEvents, eventQualifiers, abd); // subscribe event dispatcher bus.subscribe(CDI.SERVER_DISPATCHER_SUBJECT, eventDispatcher); }
private void subscribeServices(final BeanManager beanManager, final MessageBus bus) { for (final Map.Entry<AnnotatedType, List<AnnotatedMethod>> entry : managedTypes.getServiceMethods().entrySet()) { final Class<?> type = entry.getKey().getJavaClass(); for (final AnnotatedMethod method : entry.getValue()) { final Service svc = method.getAnnotation(Service.class); final String svcName = svc.value().equals("") ? method.getJavaMember().getName() : svc.value(); final Method callMethod = method.getJavaMember(); bus.subscribe( svcName, new MessageCallback() { @Override public void callback(final Message message) { final Object targetBean = CDIServerUtil.lookupBean(beanManager, type); try { callMethod.invoke(targetBean, message); } catch (Exception e) { ErrorHelper.sendClientError(bus, message, "Error dispatching service", e); } } }); } } /** * Due to the lack of contract in CDI guaranteeing when beans will be available, we use an * executor to search for the beans every 100ms until it finds them. Or, after a 25 seconds, * blow up if they don't become available. */ final ScheduledExecutorService startupScheduler = Executors.newScheduledThreadPool(1); startupScheduler.scheduleAtFixedRate( new StartupCallback(beanManager, bus, startupScheduler, 25), 0, 100, TimeUnit.MILLISECONDS); for (final Class<?> remoteInterfaceType : managedTypes.getRemoteInterfaces()) { createRPCScaffolding(remoteInterfaceType, bus, beanManager); } }
public static void startOTService(final MessageBus messageBus, final OTEngine engine) { messageBus.subscribe( "ClientOTEngineSyncService", new MessageCallback() { @Override public void callback(Message message) { final Integer value = message.getValue(Integer.class); final OTPeer peer = engine.getPeerState().getPeer("<ServerEngine>"); peer.beginSyncRemoteEntity( "<ServerEngine>", value, new StateEntitySyncCompletionCallback( engine, value, new EntitySyncCompletionCallback<State>() { @Override public void syncComplete(OTEntity<State> entity) { engine.getPeerState().notifyResync(entity); } })); } }); messageBus.subscribe( "ClientOTEngine", new MessageCallback() { @Override public void callback(Message message) { final OpDto opDto = message.getValue(OpDto.class); if (opDto == null && message.hasPart("PurgeHint")) { final Integer entityId = message.get(Integer.class, "EntityId"); final Integer purgeHint = message.get(Integer.class, "PurgeHint"); final int i = engine .getEntityStateSpace() .getEntity(entityId) .getTransactionLog() .purgeTo(purgeHint - 100); LogUtil.log("purged " + i + " old entries from log."); } else { final OTPeer peer = engine.getPeerState().getPeer("<ServerEngine>"); if (!engine.receive("<ServerEngine>", opDto.otOperation(engine))) { peer.beginSyncRemoteEntity( "<ServerEngine>", opDto.getEntityId(), new StateEntitySyncCompletionCallback( engine, opDto.getEntityId(), new EntitySyncCompletionCallback<State>() { @Override public void syncComplete(OTEntity<State> entity) { engine.getPeerState().notifyResync(entity); } })); } } } }); new Timer() { @Override public void run() { LogUtil.log("PURGE EVENT"); for (OTEntity otEntity : engine.getEntityStateSpace().getEntities()) { engine .getPeerState() .getPeer("<ServerEngine>") .sendPurgeHint(otEntity.getId(), otEntity.getRevision()); } } }.scheduleRepeating(30000); }