Search in sources :

Example 1 with Strategy

use of services.moleculer.strategy.Strategy in project moleculer-java by moleculer-java.

the class DefaultEventbus method addListeners.

// --- ADD LOCAL LISTENER ---
@Override
public void addListeners(String serviceName, Service service) {
    // Service name with version
    if (serviceName == null || serviceName.isEmpty()) {
        serviceName = service.getName();
    }
    Class<? extends Service> clazz = service.getClass();
    Field[] fields = clazz.getFields();
    boolean hasListener = false;
    writeLock.lock();
    try {
        // Initialize listeners in service
        for (Field field : fields) {
            // Register event listener
            if (Listener.class.isAssignableFrom(field.getType())) {
                hasListener = true;
                // Name of the action (eg. "service.action")
                String listenerName = nameOf(serviceName, field);
                // Process "Subscribe" annotation
                Subscribe s = field.getAnnotation(Subscribe.class);
                String subscribe = null;
                if (s != null) {
                    subscribe = s.value();
                }
                if (subscribe == null || subscribe.isEmpty()) {
                    subscribe = listenerName;
                }
                // Process "Group" annotation
                String group = null;
                Group g = field.getAnnotation(Group.class);
                if (g != null) {
                    group = g.value();
                }
                if (group == null || group.isEmpty()) {
                    group = serviceName;
                }
                // Register listener in EventBus
                field.setAccessible(true);
                Listener listener = (Listener) field.get(service);
                // Get or create group map
                HashMap<String, Strategy<ListenerEndpoint>> groups = listeners.get(subscribe);
                if (groups == null) {
                    groups = new HashMap<String, Strategy<ListenerEndpoint>>();
                    listeners.put(subscribe, groups);
                }
                // Get or create strategy
                Strategy<ListenerEndpoint> strategy = groups.get(group);
                if (strategy == null) {
                    strategy = this.strategy.create();
                    groups.put(group, strategy);
                }
                // Add endpoint to strategy
                strategy.addEndpoint(new LocalListenerEndpoint(executor, nodeID, serviceName, group, subscribe, listener, asyncLocalInvocation));
            }
        }
    } catch (Exception cause) {
        logger.error("Unable to register local listener!", cause);
    } finally {
        // Clear caches
        if (hasListener) {
            emitterCache.clear();
            broadcasterCache.clear();
            localBroadcasterCache.clear();
        }
        // Unlock reader threads
        writeLock.unlock();
    }
}
Also used : Field(java.lang.reflect.Field) Strategy(services.moleculer.strategy.Strategy)

Example 2 with Strategy

use of services.moleculer.strategy.Strategy in project moleculer-java by moleculer-java.

the class DefaultServiceRegistry method receiveRequest.

// --- RECEIVE REQUEST FROM REMOTE SERVICE ---
@Override
public void receiveRequest(Tree message) {
    // Verify protocol version
    if (checkVersion) {
        String ver = message.get("ver", "unknown");
        if (!ServiceBroker.PROTOCOL_VERSION.equals(ver)) {
            logger.warn("Invalid protocol version (" + ver + ")!");
            return;
        }
    }
    // Get action property
    String action = message.get("action", (String) null);
    if (action == null || action.isEmpty()) {
        logger.warn("Missing \"action\" property!");
        return;
    }
    // Get strategy (action endpoint array) by action name
    Strategy<ActionEndpoint> strategy;
    readLock.lock();
    try {
        strategy = strategies.get(action);
    } finally {
        readLock.unlock();
    }
    if (strategy == null) {
        logger.warn("Invalid action name (" + action + ")!");
        return;
    }
    // Get local action endpoint (with cache handling)
    ActionEndpoint endpoint = strategy.getEndpoint(nodeID);
    if (endpoint == null) {
        logger.warn("Not a local action (" + action + ")!");
        return;
    }
    // Get request's unique ID
    String id = message.get("id", (String) null);
    if (id == null || id.isEmpty()) {
        logger.warn("Missing \"id\" property!");
        return;
    }
    // Get sender's nodeID
    String sender = message.get("sender", (String) null);
    if (sender == null || sender.isEmpty()) {
        logger.warn("Missing \"sender\" property!");
        return;
    }
    // Create CallOptions
    int timeout = message.get("timeout", 0);
    Tree params = message.get("params");
    // TODO Process other properties:
    // Tree meta = message.get("meta");
    // int level = message.get("level", 1);
    // boolean metrics = message.get("metrics", false);
    // String parentID = message.get("parentID", (String) null);
    // String requestID = message.get("requestID", (String) null);
    CallOptions.Options opts = CallOptions.nodeID(nodeID).timeout(timeout);
    Context ctx = contextFactory.create(action, params, opts, null);
    // Invoke action
    try {
        new Promise(endpoint.handler(ctx)).then(data -> {
            // Send response
            FastBuildTree msg = new FastBuildTree(5);
            msg.putUnsafe("sender", nodeID);
            msg.putUnsafe("id", id);
            msg.putUnsafe("ver", ServiceBroker.PROTOCOL_VERSION);
            msg.putUnsafe("success", true);
            msg.putUnsafe("data", data);
            transporter.publish(Transporter.PACKET_RESPONSE, sender, msg);
        }).catchError(error -> {
            // Send error
            transporter.publish(Transporter.PACKET_RESPONSE, sender, throwableToTree(id, sender, error));
        });
    } catch (Throwable error) {
        // Send error
        transporter.publish(Transporter.PACKET_RESPONSE, sender, throwableToTree(id, sender, error));
    }
}
Also used : Context(services.moleculer.context.Context) CallOptions(services.moleculer.context.CallOptions) Arrays(java.util.Arrays) ScheduledFuture(java.util.concurrent.ScheduledFuture) Enumeration(java.util.Enumeration) FastBuildTree(services.moleculer.util.FastBuildTree) CommonUtils.convertAnnotations(services.moleculer.util.CommonUtils.convertAnnotations) TimeoutException(java.util.concurrent.TimeoutException) HashMap(java.util.HashMap) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) AtomicReference(java.util.concurrent.atomic.AtomicReference) ServiceBroker(services.moleculer.ServiceBroker) InetAddress(java.net.InetAddress) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ContextFactory(services.moleculer.context.ContextFactory) LinkedList(java.util.LinkedList) NoSuchElementException(java.util.NoSuchElementException) ServiceBrokerConfig(services.moleculer.config.ServiceBrokerConfig) CommonUtils.getHostName(services.moleculer.util.CommonUtils.getHostName) LinkedHashSet(java.util.LinkedHashSet) PrintWriter(java.io.PrintWriter) Eventbus(services.moleculer.eventbus.Eventbus) Iterator(java.util.Iterator) StringWriter(java.io.StringWriter) Collection(java.util.Collection) NetworkInterface(java.net.NetworkInterface) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) UIDGenerator(services.moleculer.uid.UIDGenerator) Field(java.lang.reflect.Field) RemoteException(java.rmi.RemoteException) Promise(services.moleculer.Promise) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) Lock(java.util.concurrent.locks.Lock) Strategy(services.moleculer.strategy.Strategy) Tree(io.datatree.Tree) Transporter(services.moleculer.transporter.Transporter) Annotation(java.lang.annotation.Annotation) Context(services.moleculer.context.Context) StrategyFactory(services.moleculer.strategy.StrategyFactory) CommonUtils.nameOf(services.moleculer.util.CommonUtils.nameOf) Collections(java.util.Collections) Promise(services.moleculer.Promise) FastBuildTree(services.moleculer.util.FastBuildTree) FastBuildTree(services.moleculer.util.FastBuildTree) Tree(io.datatree.Tree) CallOptions(services.moleculer.context.CallOptions)

Example 3 with Strategy

use of services.moleculer.strategy.Strategy in project moleculer-java by moleculer-java.

the class DefaultServiceRegistry method currentDescriptor.

protected synchronized Tree currentDescriptor() {
    if (descriptor == null) {
        // Create new descriptor block
        descriptor = new Tree();
        // Services array
        Tree services = descriptor.putList("services");
        Tree servicesMap = new Tree();
        readLock.lock();
        try {
            for (Map.Entry<String, Strategy<ActionEndpoint>> entry : strategies.entrySet()) {
                // Split into parts ("math.add" -> "math" and "add")
                String name = entry.getKey();
                int i = name.lastIndexOf('.');
                String service = name.substring(0, i);
                // Get endpoint
                ActionEndpoint endpoint = entry.getValue().getEndpoint(nodeID);
                if (endpoint == null) {
                    continue;
                }
                // Service block
                Tree serviceMap = servicesMap.putMap(service, true);
                serviceMap.put("name", service);
                // Node ID
                serviceMap.put("nodeID", nodeID);
                // Action block
                @SuppressWarnings("unchecked") Map<String, Object> actionBlock = (Map<String, Object>) serviceMap.putMap("actions", true).asObject();
                actionBlock.put(name, endpoint.getConfig().asObject());
                // Listener block
                Tree listeners = eventbus.generateListenerDescriptor(service);
                if (listeners != null && !listeners.isEmpty()) {
                    serviceMap.putObject("events", listeners);
                }
            }
        } finally {
            readLock.unlock();
        }
        for (Tree service : servicesMap) {
            services.addObject(service);
        }
        // Host name
        descriptor.put("hostname", getHostName());
        // IP array
        Tree ipList = descriptor.putList("ipList");
        HashSet<String> ips = new HashSet<>();
        try {
            InetAddress local = InetAddress.getLocalHost();
            String defaultAddress = local.getHostAddress();
            if (!defaultAddress.startsWith("127.")) {
                ips.add(defaultAddress);
                ipList.add(defaultAddress);
            }
        } catch (Exception ignored) {
        }
        try {
            Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
            while (e.hasMoreElements()) {
                NetworkInterface n = (NetworkInterface) e.nextElement();
                Enumeration<InetAddress> ee = n.getInetAddresses();
                while (ee.hasMoreElements()) {
                    InetAddress i = (InetAddress) ee.nextElement();
                    if (!i.isLoopbackAddress()) {
                        String test = i.getHostAddress();
                        if (ips.add(test)) {
                            ipList.add(test);
                        }
                    }
                }
            }
        } catch (Exception ignored) {
        }
        // Client descriptor
        Tree client = descriptor.putMap("client");
        client.put("type", "java");
        client.put("version", ServiceBroker.SOFTWARE_VERSION);
        client.put("langVersion", System.getProperty("java.version", "1.8"));
        // Config (not used in this version)
        // root.putMap("config");
        // Set timestamp
        timestamp.set(System.currentTimeMillis());
    }
    return descriptor;
}
Also used : NetworkInterface(java.net.NetworkInterface) TimeoutException(java.util.concurrent.TimeoutException) NoSuchElementException(java.util.NoSuchElementException) RemoteException(java.rmi.RemoteException) FastBuildTree(services.moleculer.util.FastBuildTree) Tree(io.datatree.Tree) Strategy(services.moleculer.strategy.Strategy) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) InetAddress(java.net.InetAddress) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 4 with Strategy

use of services.moleculer.strategy.Strategy in project moleculer-java by moleculer-java.

the class DefaultEventbus method addListeners.

// --- ADD REMOTE LISTENER ---
@Override
public void addListeners(Tree config) {
    Tree events = config.get("events");
    if (events != null && events.isMap()) {
        String nodeID = Objects.requireNonNull(config.get("nodeID", (String) null));
        String serviceName = Objects.requireNonNull(config.get("name", (String) null));
        writeLock.lock();
        try {
            for (Tree listenerConfig : events) {
                String subscribe = listenerConfig.get("name", "");
                String group = listenerConfig.get("group", serviceName);
                // Register remote listener
                RemoteListenerEndpoint endpoint = new RemoteListenerEndpoint(transporter, nodeID, serviceName, group, subscribe);
                // Get or create group map
                HashMap<String, Strategy<ListenerEndpoint>> groups = listeners.get(subscribe);
                if (groups == null) {
                    groups = new HashMap<String, Strategy<ListenerEndpoint>>();
                    listeners.put(subscribe, groups);
                }
                // Get or create strategy
                Strategy<ListenerEndpoint> listenerStrategy = groups.get(group);
                if (listenerStrategy == null) {
                    listenerStrategy = strategy.create();
                    groups.put(group, listenerStrategy);
                }
                listenerStrategy.addEndpoint(endpoint);
            }
        } finally {
            // Clear caches
            emitterCache.clear();
            broadcasterCache.clear();
            localBroadcasterCache.clear();
            // Unlock reader threads
            writeLock.unlock();
        }
    }
}
Also used : CheckedTree(services.moleculer.util.CheckedTree) Tree(io.datatree.Tree) Strategy(services.moleculer.strategy.Strategy)

Aggregations

Strategy (services.moleculer.strategy.Strategy)4 Tree (io.datatree.Tree)3 Field (java.lang.reflect.Field)2 InetAddress (java.net.InetAddress)2 NetworkInterface (java.net.NetworkInterface)2 RemoteException (java.rmi.RemoteException)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 LinkedHashMap (java.util.LinkedHashMap)2 LinkedHashSet (java.util.LinkedHashSet)2 Map (java.util.Map)2 NoSuchElementException (java.util.NoSuchElementException)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 TimeoutException (java.util.concurrent.TimeoutException)2 FastBuildTree (services.moleculer.util.FastBuildTree)2 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 Annotation (java.lang.annotation.Annotation)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1