use of io.datatree.Tree in project moleculer-java by moleculer-java.
the class CacherTest method testAnnotations.
@Test
public void testAnnotations() throws Exception {
TestService testService = new TestService();
br.createService(testService);
Tree params = new Tree();
params.put("a", 4);
Tree rsp = br.call("test.test", params).waitFor();
assertEquals(8, (int) rsp.asInteger());
Tree rsp2 = cr.get("test.test:4").waitFor();
assertEquals(8, (int) rsp2.asInteger());
// --------
cr.clean("test.*").waitFor();
rsp2 = cr.get("test.test:4").waitFor();
assertNull(rsp2);
params.put("b", "3");
rsp = br.call("test.test2", params).waitFor();
assertEquals(7, rsp.get("c", 0));
rsp2 = cr.get("test.test2:4|3").waitFor();
assertEquals(7, rsp2.get("c", 0));
}
use of io.datatree.Tree in project moleculer-java by moleculer-java.
the class CacherTest method testCacher.
// --- TEST METHOD ---
@Test
public void testCacher() throws Exception {
Tree rsp, val = new Tree();
val.put("rsp", "3");
// 1.) simple set / get
cr.set("a.b", val, 0);
rsp = cr.get("a.b").waitFor();
assertEquals(3, rsp.get("rsp", 0));
// 2.) simple set / get
val.put("rsp", 4);
cr.set("a.c", val, 0);
rsp = cr.get("a.b").waitFor();
assertEquals(3, rsp.get("rsp", 0));
rsp = cr.get("a.c").waitFor();
assertEquals(4, rsp.get("rsp", 0));
// 3.) simple set / get
val.put("rsp", 5);
cr.set("a.b", val, 0);
rsp = cr.get("a.b").waitFor();
assertEquals(5, rsp.get("rsp", 0));
// 4.) Simple delete
cr.del("a.b").waitFor();
rsp = cr.get("a.b").waitFor();
assertNull(rsp);
rsp = cr.get("a.c").waitFor();
assertEquals(4, rsp.get("rsp", 0));
// 5.) Prefixed delete
val.put("rsp", 6);
cr.set("a.b", val, 0);
val.put("rsp", 7);
cr.set("b.d", val, 0);
rsp = cr.get("a.b").waitFor();
assertEquals(6, rsp.get("rsp", 0));
rsp = cr.get("a.c").waitFor();
assertEquals(4, rsp.get("rsp", 0));
rsp = cr.get("b.d").waitFor();
assertEquals(7, rsp.get("rsp", 0));
cr.clean("a.*").waitFor();
rsp = cr.get("a.b").waitFor();
// ERR
assertNull(rsp);
rsp = cr.get("a.c").waitFor();
assertNull(rsp);
rsp = cr.get("b.d").waitFor();
assertEquals(7, rsp.get("rsp", 0));
cr.clean("**").waitFor();
rsp = cr.get("b.d").waitFor();
assertNull(rsp);
// 6.) Multi-level + prefixed delete
val.put("rsp", 1);
cr.set("a.b", val, 0);
val.put("rsp", 2);
cr.set("a.b.c", val, 0);
val.put("rsp", 3);
cr.set("a.b.c.d", val, 0);
rsp = cr.get("a.b").waitFor();
assertEquals(1, rsp.get("rsp", 0));
rsp = cr.get("a.b.c").waitFor();
assertEquals(2, rsp.get("rsp", 0));
rsp = cr.get("a.b.c.d").waitFor();
assertEquals(3, rsp.get("rsp", 0));
// --------
cr.clean("b.*").waitFor();
rsp = cr.get("a.b").waitFor();
assertEquals(1, rsp.get("rsp", 0));
rsp = cr.get("a.b.c").waitFor();
assertEquals(2, rsp.get("rsp", 0));
rsp = cr.get("a.b.c.d").waitFor();
assertEquals(3, rsp.get("rsp", 0));
// --------
cr.clean("a.*").waitFor();
rsp = cr.get("a.b").waitFor();
assertNull(rsp);
rsp = cr.get("a.b.c").waitFor();
assertEquals(2, rsp.get("rsp", 0));
rsp = cr.get("a.b.c.d").waitFor();
assertEquals(3, rsp.get("rsp", 0));
// --------
cr.clean("a.b.*").waitFor();
rsp = cr.get("a.b").waitFor();
assertNull(rsp);
rsp = cr.get("a.b.c").waitFor();
assertNull(rsp);
rsp = cr.get("a.b.c.d").waitFor();
assertEquals(3, rsp.get("rsp", 0));
// --------
cr.clean("a.b.c.*").waitFor();
rsp = cr.get("a.b").waitFor();
assertNull(rsp);
rsp = cr.get("a.b.c").waitFor();
assertNull(rsp);
rsp = cr.get("a.b.c.d").waitFor();
assertNull(rsp);
// 7.) Multi-level + prefixed delete 2.
val.put("rsp", 1);
cr.set("a.b", val, 0);
val.put("rsp", 2);
cr.set("a.b.c", val, 0);
val.put("rsp", 3);
cr.set("a.b.c.d", val, 0);
// --------
cr.clean("a.b.**").waitFor();
rsp = cr.get("a.b").waitFor();
assertEquals(1, rsp.get("rsp", 0));
rsp = cr.get("a.b.c").waitFor();
assertNull(rsp);
rsp = cr.get("a.b.c.d").waitFor();
assertNull(rsp);
// 8.) Large key get / set
StringBuilder tmp = new StringBuilder();
for (int i = 0; i < 2048; i++) {
tmp.append(i % 9);
}
String key = "a." + tmp.toString();
val.put("rsp", 4);
cr.set(key, val, 0);
rsp = cr.get(key).waitFor();
assertEquals(4, rsp.get("rsp", 0));
cr.del(key).waitFor();
rsp = cr.get(key).waitFor();
assertNull(rsp);
// 9.) Large value get / set
Tree large = new Tree();
for (int i = 0; i < 100; i++) {
Tree row = large.putMap("row" + i);
for (int j = 0; j < 100; j++) {
Tree cell = row.putMap("cell" + i + '_' + j);
cell.put("value", i * j);
}
}
cr.set("large.value", large, 0).waitFor();
rsp = cr.get("large.value").waitFor();
String s1 = large.toString(false).replaceAll(".0", "").replaceAll(" ", "");
String s2 = rsp.toString(false).replaceAll(".0", "").replaceAll(" ", "");
assertEquals(s1, s2);
cr.del("large.value").waitFor();
rsp = cr.get("large.value").waitFor();
assertNull(rsp);
}
use of io.datatree.Tree in project moleculer-java by moleculer-java.
the class KeyTest method check.
protected void check(String json, String key, String[] keys, int maxKeyLength) throws Exception {
json = json.replace('\'', '\"');
Tree params = new Tree(json, "JsonBuiltin");
cacher.setMaxKeyLength(maxKeyLength);
String testKey = cacher.getCacheKey("abc.def", params, keys);
assertEquals(key, testKey);
}
use of io.datatree.Tree in project moleculer-java by moleculer-java.
the class TcpTransporter method unableToSend.
// --- CONNECTION ERROR ---
public void unableToSend(String nodeID, LinkedList<byte[]> packets, Throwable cause) {
if (nodeID != null) {
executor.execute(() -> {
// Debug
if (debug) {
logger.warn("Unable to send message to \"" + nodeID + "\".", cause);
}
// Mark endpoint as offline
NodeDescriptor node = nodes.get(nodeID);
boolean disconnected = false;
if (node != null) {
node.writeLock.lock();
try {
if (node != null && node.markAsOffline()) {
// Remove actions and listeners
registry.removeActions(nodeID);
eventbus.removeListeners(nodeID);
writer.close(node.nodeID);
disconnected = true;
}
} catch (Exception error) {
logger.warn("Unable to turn off node!", error);
} finally {
node.writeLock.unlock();
}
}
if (node != null && disconnected) {
// Notify listeners (unexpected disconnection)
logger.info("Node \"" + nodeID + "\" disconnected.");
broadcastNodeDisconnected(node.info, true);
}
// Send error back to the source
if (packets != null) {
FastBuildTree errorMap = null;
if (cause != null) {
errorMap = new FastBuildTree(2);
// Add message
errorMap.putUnsafe("message", cause.getMessage());
// Add trace
StringWriter sw = new StringWriter(128);
PrintWriter pw = new PrintWriter(sw);
cause.printStackTrace(pw);
errorMap.putUnsafe("trace", sw.toString());
}
for (byte[] packet : packets) {
try {
// Remove header
if (packet != null && packet.length > 6) {
byte[] copy = new byte[packet.length - 6];
System.arraycopy(packet, 6, copy, 0, copy.length);
// Deserialize packet
Tree message = serializer.read(copy);
// Get request's unique ID
String id = message.get("id", (String) null);
if (id == null || id.isEmpty()) {
// Not a request
return;
}
// Create response message
FastBuildTree response = new FastBuildTree(6);
response.putUnsafe("id", id);
response.putUnsafe("ver", ServiceBroker.PROTOCOL_VERSION);
response.putUnsafe("sender", nodeID);
response.putUnsafe("success", false);
response.putUnsafe("data", (String) null);
if (errorMap != null) {
response.putUnsafe("error", errorMap);
}
registry.receiveResponse(response);
}
} catch (Exception error) {
logger.warn("Unable to handle error!", error);
}
}
}
});
}
}
use of io.datatree.Tree in project moleculer-java by moleculer-java.
the class TcpTransporter method connect.
@Override
public void connect() {
try {
// Create reader and writer
disconnect();
reader = new TcpReader(this);
writer = new TcpWriter(this);
// Disable offline timeout when use host list
if (urls != null && urls.length > 0) {
offlineTimeout = 0;
nodes.clear();
for (String url : urls) {
int i = url.indexOf("://");
if (i > -1 && i < url.length() - 4) {
url = url.substring(i + 3);
}
url = url.replace('/', ':');
String[] parts = url.split(":");
if (parts.length < 3) {
logger.warn("Invalid URL format (" + url + ")! Valid syntax is \"tcp://host:port/nodeID\" or \"host:port/nodeID\"!");
continue;
}
int port;
try {
port = Integer.parseInt(parts[1]);
} catch (Exception e) {
logger.warn("Invalid URL format (" + url + ")! Valid syntax is \"tcp://host:port/nodeID\" or \"host:port/nodeID\"!");
continue;
}
String sender = parts[2];
if (sender.equals(nodeID)) {
// TCP server's port (port in URL list)
this.port = port;
continue;
}
String host = parts[0];
nodes.put(sender, new NodeDescriptor(sender, useHostname, host, port));
}
} else if (offlineTimeout > 0 && offlineTimeout < 15) {
offlineTimeout = 15;
}
// Process basic properties (eg. "prefix")
heartbeatTimeout = 0;
heartbeatInterval = 0;
// Start TCP server
reader.connect();
currentPort = reader.getCurrentPort();
// Create descriptor of current node
Tree info = registry.getDescriptor();
info.put("port", currentPort);
info.put("seq", "0");
cachedDescriptor = new NodeDescriptor(nodeID, useHostname, true, info);
// Start data writer (TCP client)
writer.connect();
// TCP + UDP mode ("zero config")
if (urls == null || urls.length == 0) {
locator = new UDPLocator(nodeID, this, scheduler);
locator.connect();
}
// Start gossiper
gossiperTimer = scheduler.scheduleWithFixedDelay(this::sendGossipRequest, gossipPeriod, gossipPeriod, TimeUnit.SECONDS);
// Start timeout checker's timer
if (checkTimeoutTimer == null && offlineTimeout > 0) {
int period = Math.max(offlineTimeout / 3, 10);
checkTimeoutTimer = scheduler.scheduleAtFixedRate(this::checkTimeouts, period, period, TimeUnit.SECONDS);
}
// Ok, transporter started
logger.info("Message receiver started on tcp://" + getHostName() + ':' + currentPort + ".");
} catch (Exception cause) {
String msg = cause.getMessage();
if (msg == null || msg.isEmpty()) {
msg = "Unable to start TCP transporter!";
} else if (!msg.endsWith("!") && !msg.endsWith(".")) {
msg += "!";
}
logger.warn(msg);
reconnect();
}
}
Aggregations