/* * Copyright 2015 Red Hat, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Apache License v2.0 which accompanies this distribution. * * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * * The Apache License v2.0 is available at * http://www.opensource.org/licenses/apache2.0.php * * You may elect to redistribute this code under either of these licenses. */ package io.vertx.ext.eventbus.bridge.tcp; import io.vertx.core.Vertx; import io.vertx.core.buffer.Buffer; import io.vertx.core.eventbus.EventBus; import io.vertx.core.eventbus.Message; import io.vertx.core.json.JsonObject; import io.vertx.core.net.NetClient; import io.vertx.core.net.NetSocket; import io.vertx.ext.bridge.BridgeOptions; import io.vertx.ext.bridge.PermittedOptions; import io.vertx.ext.eventbus.bridge.tcp.impl.protocol.FrameHelper; import io.vertx.ext.eventbus.bridge.tcp.impl.protocol.FrameParser; import io.vertx.ext.unit.Async; import io.vertx.ext.unit.TestContext; import io.vertx.ext.unit.junit.VertxUnitRunner; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; @RunWith(VertxUnitRunner.class) public class TcpEventBusBridgeInteropTest { private Vertx vertx; @Before public void before(TestContext context) { vertx = Vertx.vertx(); final Async async = context.async(); vertx.eventBus().consumer("hello", (Message<JsonObject> msg) -> msg.reply(new JsonObject().put("value", "Hello " + msg.body().getString("value")))); TcpEventBusBridge bridge = TcpEventBusBridge.create( vertx, new BridgeOptions() .addInboundPermitted(new PermittedOptions()) .addOutboundPermitted(new PermittedOptions())); bridge.listen(7000, res -> { context.assertTrue(res.succeeded()); async.complete(); }); } @After public void after(TestContext context) { vertx.close(context.asyncAssertSuccess()); } @Test public void testInteropWithPlainJava(TestContext context) { final Async async = context.async(); // register a local consumer final EventBus eb = vertx.eventBus(); eb.consumer("io.vertx", msg -> { // assert that headers are received context.assertEquals("findAll", msg.headers().get("action")); // assert body is not null context.assertNotNull(msg.body()); msg.reply(msg.body()); }); // run some plain java (blocking) vertx.executeBlocking(f -> { try { JsonObject headers = new JsonObject(); headers.put("action", "findAll"); JsonObject body = new JsonObject(); body.put("model", "news"); JsonObject protocol = new JsonObject(); protocol.put("type", "send"); protocol.put("headers", headers); protocol.put("body", body); protocol.put("address", "io.vertx"); protocol.put("replyAddress", "durp"); Buffer buffer = Buffer.buffer(); buffer.appendInt(protocol.encode().getBytes().length); buffer.appendString(protocol.encode()); Socket clientSocket = new Socket("localhost", 7000); DataOutputStream output = new DataOutputStream(clientSocket.getOutputStream()); output.write(buffer.getBytes()); DataInputStream input = new DataInputStream(clientSocket.getInputStream()); int bytesLength = input.readInt(); byte[] bytes = new byte[bytesLength]; for(int i = 0; i < bytesLength; i++) { bytes[i] = input.readByte(); } input.close(); output.close(); clientSocket.close(); JsonObject reply = new JsonObject(new String(bytes)); // assert that the body is the same we sent context.assertEquals(body, reply.getJsonObject("body")); f.complete(); } catch (IOException e) { f.fail(e); } }, res -> { context.assertTrue(res.succeeded()); async.complete(); }); } @Test public void testSendMessageWithReplyBacktrack(TestContext context) { // Send a request and get a response NetClient client = vertx.createNetClient(); final Async async = context.async(); client.connect(7000, "localhost", conn -> { context.assertFalse(conn.failed()); NetSocket socket = conn.result(); final FrameParser parser = new FrameParser(parse -> { context.assertTrue(parse.succeeded()); JsonObject frame = parse.result(); context.assertNotEquals("err", frame.getString("type")); context.assertEquals("Hello vert.x", frame.getJsonObject("body").getString("value")); client.close(); async.complete(); }); socket.handler(parser); FrameHelper.sendFrame("send", "hello", "#backtrack", new JsonObject().put("value", "vert.x"), socket); }); } @Test public void testSendMessageWithDuplicateReplyID(TestContext context) { // replies must always return to the same origin NetClient client = vertx.createNetClient(); final Async async = context.async(); client.connect(7000, "localhost", conn -> { context.assertFalse(conn.failed()); NetSocket socket = conn.result(); vertx.eventBus().consumer("third-party-receiver", msg -> context.fail()); final FrameParser parser = new FrameParser(parse -> { context.assertTrue(parse.succeeded()); client.close(); async.complete(); }); socket.handler(parser); FrameHelper.sendFrame("send", "hello", "third-party-receiver", new JsonObject().put("value", "vert.x"), socket); }); } @Test public void testRegister(TestContext context) { // Send a request and get a response NetClient client = vertx.createNetClient(); final Async async = context.async(); client.connect(7000, "localhost", conn -> { context.assertFalse(conn.failed()); NetSocket socket = conn.result(); // 1 reply will arrive // MESSAGE for echo final FrameParser parser = new FrameParser(parse -> { context.assertTrue(parse.succeeded()); JsonObject frame = parse.result(); context.assertNotEquals("err", frame.getString("type")); context.assertEquals("Vert.x", frame.getJsonObject("body").getString("value")); client.close(); async.complete(); }); socket.handler(parser); FrameHelper.sendFrame("register", "echo", null, socket); // now try to publish a message so it gets delivered both to the consumer registred on the startup and to this // remote consumer FrameHelper.sendFrame("publish", "echo", new JsonObject().put("value", "Vert.x"), socket); }); } }