Search in sources :

Example 16 with Tree

use of io.datatree.Tree in project moleculer-java by moleculer-java.

the class TcpTransporter method received.

// --- MESSAGE RECEIVED ---
public void received(byte packetID, byte[] packet) {
    executor.execute(() -> {
        // Parse message
        Tree data;
        try {
            data = serializer.read(packet);
        } catch (Exception cause) {
            logger.warn("Unable to parse incoming message!", cause);
            return;
        }
        // Send message to proper component
        try {
            switch(packetID) {
                case PACKET_EVENT_ID:
                    // Incoming event
                    if (debug) {
                        logger.info("Event message received:\r\n" + data);
                    }
                    eventbus.receiveEvent(data);
                    return;
                case PACKET_REQUEST_ID:
                    // Incoming request
                    if (debug) {
                        logger.info("Request message received:\r\n" + data);
                    }
                    registry.receiveRequest(data);
                    return;
                case PACKET_RESPONSE_ID:
                    // Incoming response
                    if (debug) {
                        logger.info("Response message received:\r\n" + data);
                    }
                    registry.receiveResponse(data);
                    return;
                case PACKET_PING_ID:
                    // Send pong
                    if (debug) {
                        logger.info("Ping message received:\r\n" + data);
                    }
                    String id = data.get("id", "");
                    if (id == null || id.isEmpty()) {
                        logger.warn("Missing \"id\" property:\r\n" + data);
                        return;
                    }
                    String sender = data.get("sender", "");
                    if (sender == null || sender.isEmpty()) {
                        logger.warn("Missing \"sender\" property:\r\n" + data);
                        return;
                    }
                    long time = data.get("time", 0L);
                    FastBuildTree msg = new FastBuildTree(5);
                    msg.putUnsafe("ver", PROTOCOL_VERSION);
                    msg.putUnsafe("sender", this.nodeID);
                    msg.putUnsafe("id", id);
                    msg.putUnsafe("received", time);
                    msg.putUnsafe("time", System.currentTimeMillis());
                    writer.send(sender, serialize(PACKET_PONG_ID, msg));
                    return;
                case PACKET_PONG_ID:
                    // Pong received
                    if (debug) {
                        logger.info("Pong message received:\r\n" + data);
                    }
                    registry.receiveResponse(data);
                    return;
                case PACKET_GOSSIP_REQ_ID:
                    // Incoming gossip request
                    processGossipRequest(data);
                    return;
                case PACKET_GOSSIP_RSP_ID:
                    // Incoming gossip request
                    processGossipResponse(data);
                    return;
                case PACKET_GOSSIP_HELLO_ID:
                    // Incoming "hello" message
                    processGossipHello(data);
                    return;
                default:
                    logger.warn("Unsupported message ID (" + packetID + ")!");
            }
        } catch (Exception cause) {
            logger.warn("Unable to process incoming message!", cause);
        }
    });
}
Also used : FastBuildTree(services.moleculer.util.FastBuildTree) CommonUtils.readTree(services.moleculer.util.CommonUtils.readTree) FastBuildTree(services.moleculer.util.FastBuildTree) Tree(io.datatree.Tree)

Example 17 with Tree

use of io.datatree.Tree in project moleculer-java by moleculer-java.

the class TcpWriter method run.

// --- WRITER LOOP ---
@Override
public void run() {
    try {
        // Loop
        while (true) {
            // Waiting for sockets
            int n;
            try {
                n = selector.select(3000);
            } catch (NullPointerException nullPointer) {
                continue;
            } catch (Exception cause) {
                break;
            }
            // Open new connections
            SendBuffer buffer = opened.poll();
            SelectionKey key = null;
            while (buffer != null) {
                try {
                    InetSocketAddress address;
                    try {
                        address = new InetSocketAddress(buffer.host, buffer.port);
                    } catch (UnresolvedAddressException dnsError) {
                        // Workaround: unable to resolve host name
                        Tree info = transporter.getDescriptor(buffer.nodeID);
                        if (info == null) {
                            throw dnsError;
                        }
                        String ip = getHostOrIP(false, info);
                        if (ip == null || buffer.host.equalsIgnoreCase(ip)) {
                            throw dnsError;
                        }
                        if (debug) {
                            logger.info("Unable to resolve hostname \"" + buffer.host + "\", trying with \"" + ip + "\"...");
                        }
                        address = new InetSocketAddress(ip, buffer.port);
                    }
                    SocketChannel channel = SocketChannel.open(address);
                    channel.configureBlocking(false);
                    channel.setOption(StandardSocketOptions.SO_KEEPALIVE, true);
                    channel.setOption(StandardSocketOptions.TCP_NODELAY, true);
                    channel.setOption(StandardSocketOptions.SO_LINGER, -1);
                    key = channel.register(selector, SelectionKey.OP_WRITE);
                    key.attach(buffer);
                    buffer.connected(key, channel);
                    if (debug) {
                        logger.info("Client channel opened to \"" + buffer.nodeID + "\".");
                    }
                } catch (Throwable cause) {
                    if (buffer != null) {
                        synchronized (buffers) {
                            buffers.remove(buffer.nodeID);
                        }
                        transporter.unableToSend(buffer.nodeID, buffer.getUnsentPackets(), cause);
                    }
                }
                buffer = opened.poll();
            }
            if (n < 1) {
                continue;
            }
            Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
            while (keys.hasNext()) {
                key = keys.next();
                if (key == null) {
                    continue;
                }
                if (!key.isValid()) {
                    keys.remove();
                    continue;
                }
                if (key.isWritable()) {
                    // Write data
                    buffer = null;
                    try {
                        buffer = (SendBuffer) key.attachment();
                        if (buffer != null) {
                            buffer.write();
                        }
                    } catch (Exception cause) {
                        if (buffer != null) {
                            synchronized (buffers) {
                                buffers.remove(buffer.nodeID);
                            }
                            transporter.unableToSend(buffer.nodeID, buffer.getUnsentPackets(), cause);
                        }
                        close(key, cause);
                    }
                }
                keys.remove();
            }
        }
    } catch (Exception fatal) {
        logger.error("TCP writer closed!", fatal);
    }
}
Also used : SelectionKey(java.nio.channels.SelectionKey) SocketChannel(java.nio.channels.SocketChannel) InetSocketAddress(java.net.InetSocketAddress) Tree(io.datatree.Tree) UnresolvedAddressException(java.nio.channels.UnresolvedAddressException) UnresolvedAddressException(java.nio.channels.UnresolvedAddressException) ConcurrentModificationException(java.util.ConcurrentModificationException)

Example 18 with Tree

use of io.datatree.Tree in project moleculer-java by moleculer-java.

the class CommonUtils method parseURLs.

// --- PARSE URL LIST OR URL ARRAY ---
public static final String[] parseURLs(Tree config, String name, String[] defaultURLs) {
    Tree urlNode = config.get(name);
    List<String> urlList;
    if (urlNode == null) {
        return defaultURLs;
    } else if (urlNode.isPrimitive()) {
        urlList = new ArrayList<>();
        String[] urls = urlNode.asString().split(",");
        for (String url : urls) {
            url = url.trim();
            if (!url.isEmpty()) {
                urlList.add(url);
            }
        }
    } else if (urlNode.isEnumeration()) {
        urlList = urlNode.asList(String.class);
    } else {
        return defaultURLs;
    }
    if (urlList.isEmpty()) {
        return defaultURLs;
    }
    String[] urls = new String[urlList.size()];
    urlList.toArray(urls);
    return urls;
}
Also used : ArrayList(java.util.ArrayList) Tree(io.datatree.Tree)

Example 19 with Tree

use of io.datatree.Tree in project moleculer-java by moleculer-java.

the class CommonUtils method parseParams.

// --- PARSE CALL / BROADCAST PARAMS ---
public static final ParseResult parseParams(Object[] params) {
    Tree data = null;
    CallOptions.Options opts = null;
    Groups groups = null;
    if (params != null) {
        if (params.length == 1) {
            if (params[0] instanceof Tree) {
                data = (Tree) params[0];
            } else {
                data = new CheckedTree(params[0]);
            }
        } else {
            LinkedHashMap<String, Object> map = new LinkedHashMap<>();
            String prev = null;
            Object value;
            for (int i = 0; i < params.length; i++) {
                value = params[i];
                if (prev == null) {
                    if (!(value instanceof String)) {
                        if (value instanceof CallOptions.Options) {
                            opts = (CallOptions.Options) value;
                            continue;
                        }
                        if (value instanceof Groups) {
                            groups = (Groups) value;
                            continue;
                        }
                        i++;
                        throw new IllegalArgumentException("Parameter #" + i + " (\"" + value + "\") must be String, Context, Groups, or CallOptions!");
                    }
                    prev = (String) value;
                    continue;
                }
                map.put(prev, value);
                prev = null;
            }
            data = new Tree(map);
        }
    }
    return new ParseResult(data, opts, groups);
}
Also used : CallOptions(services.moleculer.context.CallOptions) CallOptions(services.moleculer.context.CallOptions) LinkedHashMap(java.util.LinkedHashMap) Groups(services.moleculer.eventbus.Groups) Tree(io.datatree.Tree)

Example 20 with Tree

use of io.datatree.Tree in project moleculer-java by moleculer-java.

the class CircuitBreakerTest method testRoundRobin.

@Test
public void testRoundRobin() throws Exception {
    // Simple round-robin test
    currentID = 1;
    for (int i = 0; i < 20; i++) {
        Promise p = br.call("test.test", (Tree) null);
        assertTrue(tr.hasMessage(getCurrentID()));
        assertEquals(1, tr.getMessageCount());
        createResponse(true);
        boolean ok = false;
        try {
            p.waitFor();
            ok = true;
        } catch (Exception e) {
        }
        assertTrue(ok);
    }
    // Create fault
    Promise p = br.call("test.test", (Tree) null);
    String nodeID = createResponse(false);
    boolean ok = true;
    try {
        p.waitFor();
    } catch (Exception e) {
        ok = e.toString().contains("unknown error");
    }
    assertFalse(ok);
    ErrorCounter ec = cb.errorCounters.get(new EndpointKey(nodeID, "test.test"));
    assertNotNull(ec);
    assertEquals(1, ec.pointer);
    long now = ec.timestamps[0];
    assertTrue(ec.isAvailable(now));
    // Create faults2
    p = br.call("test.test", (Tree) null);
    nodeID = createResponse(false);
    try {
        p.waitFor();
        ok = true;
    } catch (Exception e) {
        ok = e.toString().contains("unknown error");
    }
    assertFalse(ok);
    ec = cb.errorCounters.get(new EndpointKey(nodeID, "test.test"));
    assertNotNull(ec);
    assertEquals(1, ec.pointer);
    // Create fault
    int node1Count = 0;
    for (int i = 0; i < 30; i++) {
        p = br.call("test.test", (Tree) null);
        nodeID = createResponse(false);
        now = System.currentTimeMillis();
        try {
            p.waitFor();
            ok = true;
        } catch (Exception e) {
            ok = e.toString().contains("unknown error");
        }
        assertFalse(ok);
        if (nodeID.equals("node0")) {
            node1Count++;
            ec = cb.errorCounters.get(new EndpointKey(nodeID, "test.test"));
            assertNotNull(ec);
            if (node1Count < 3) {
                if (node1Count == 1) {
                    assertTrue(ec.timestamps[0] == 0);
                    assertTrue(ec.timestamps[1] > 0);
                    assertTrue(ec.timestamps[2] == 0);
                } else if (node1Count == 2) {
                    assertTrue(ec.timestamps[0] == 0);
                    assertTrue(ec.timestamps[1] > 0);
                    assertTrue(ec.timestamps[2] > 0);
                }
                assertTrue(ec.isAvailable(now));
            } else {
                assertTrue(ec.timestamps[0] > 0);
                assertTrue(ec.timestamps[1] > 0);
                assertTrue(ec.timestamps[2] > 0);
                assertFalse(ec.isAvailable(now));
            }
        }
    }
    // All endpoint is locked
    for (EndpointKey key : cb.errorCounters.keySet()) {
        ec = cb.errorCounters.get(key);
        boolean avail = ec.isAvailable(now);
        assertFalse(avail);
    }
    // Retrying once
    now += 10001;
    assertTrue(ec.isAvailable(now));
    assertFalse(ec.isAvailable(now));
    assertFalse(ec.isAvailable(now));
    // + 5 sec
    now += 5000;
    assertFalse(ec.isAvailable(now));
    assertFalse(ec.isAvailable(now));
    assertFalse(ec.isAvailable(now));
    // + 10 sec (5000 + 5001)
    now += 5001;
    assertTrue(ec.isAvailable(now));
    assertFalse(ec.isAvailable(now));
    assertFalse(ec.isAvailable(now));
}
Also used : Promise(services.moleculer.Promise) Tree(io.datatree.Tree) TimeoutException(java.util.concurrent.TimeoutException) ExecutionException(java.util.concurrent.ExecutionException) Test(org.junit.Test)

Aggregations

Tree (io.datatree.Tree)60 FastBuildTree (services.moleculer.util.FastBuildTree)26 Test (org.junit.Test)12 NodeDescriptor (services.moleculer.transporter.tcp.NodeDescriptor)12 CheckedTree (services.moleculer.util.CheckedTree)9 TimeoutException (java.util.concurrent.TimeoutException)6 Promise (services.moleculer.Promise)6 CommonUtils.readTree (services.moleculer.util.CommonUtils.readTree)6 RemoteException (java.rmi.RemoteException)4 LinkedHashMap (java.util.LinkedHashMap)4 CallOptions (services.moleculer.context.CallOptions)4 Context (services.moleculer.context.Context)4 Annotation (java.lang.annotation.Annotation)3 HashSet (java.util.HashSet)3 LinkedHashSet (java.util.LinkedHashSet)3 Map (java.util.Map)3 NoSuchElementException (java.util.NoSuchElementException)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 ServiceBrokerConfig (services.moleculer.config.ServiceBrokerConfig)3 Action (services.moleculer.service.Action)3