/** * Copyright 2015 Santhosh Kumar Tekuri * * The JLibs authors license this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package jlibs.wamp4j; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import jlibs.wamp4j.client.ClientOperator; import jlibs.wamp4j.client.SubscriptionOperator; import jlibs.wamp4j.client.WAMPClient; import jlibs.wamp4j.msg.EventMessage; import jlibs.wamp4j.netty.NettyClientEndpoint; import jlibs.wamp4j.netty.NettyServerEndpoint; import jlibs.wamp4j.router.RouterOperator; import jlibs.wamp4j.router.WAMPRouter; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import java.net.URI; import java.util.concurrent.atomic.AtomicReference; import static com.fasterxml.jackson.databind.node.JsonNodeFactory.instance; import static org.testng.Assert.assertEquals; /** * @author Santhosh Kumar Tekuri */ public class PubSubTest{ private URI uri = URI.create("ws://localhost:8080/wamp4j"); private RouterOperator router; private ClientOperator jlibsClient1; private ClientOperator jlibsClient2; private ClientOperator marsClient; @BeforeClass(description="starts router and clients") public void start() throws Throwable{ router = new RouterOperator(new WAMPRouter(new NettyServerEndpoint(), uri)); router.bind(); jlibsClient1 = new ClientOperator(new WAMPClient(new NettyClientEndpoint(), uri, "jlibs")); jlibsClient1.connect(); jlibsClient2 = new ClientOperator(new WAMPClient(new NettyClientEndpoint(), uri, "jlibs")); jlibsClient2.connect(); marsClient = new ClientOperator(new WAMPClient(new NettyClientEndpoint(), uri, "mars")); marsClient.connect(); } @Test(description="sanity test") public void test1() throws Throwable{ jlibsClient1.publish(null, "t1", null, null); final AtomicReference<Object> atomic = new AtomicReference<Object>(); SubscriptionOperator s1 = new SubscriptionOperator("t1"){ @Override public void onMessage(EventMessage event){ atomic.set(event); } }; ObjectNode options = instance.objectNode().put("option1", "value1"); s1.subscribeWith(options, jlibsClient2); atomic.set(null); jlibsClient1.publish(null, "t1", null, null); EventMessage em = Await.getResult(atomic); assertEquals(em.details, instance.objectNode()); assertEquals(em.arguments, null); assertEquals(em.argumentsKw, null); ArrayNode arguments = instance.arrayNode().add("arg"); atomic.set(null); jlibsClient1.publish(options, "t1", arguments, null); em = Await.getResult(atomic); assertEquals(em.details, instance.objectNode()); assertEquals(em.arguments, arguments); assertEquals(em.argumentsKw, null); ObjectNode argumentsKw = instance.objectNode().put("key", "value"); atomic.set(null); jlibsClient1.publish(options, "t1", arguments, argumentsKw); em = Await.getResult(atomic); assertEquals(em.details, instance.objectNode()); assertEquals(em.arguments, arguments); assertEquals(em.argumentsKw, argumentsKw); s1.unsubscribe(); atomic.set(null); jlibsClient1.publish(options, "t1", arguments, argumentsKw); Thread.sleep(10 * 1000); assertEquals(atomic.get(), null); } @Test(description="multiple subscriptions on same topic from a client and diffrent client publishes") public void test2() throws Throwable{ final AtomicReference<Object> atomic1 = new AtomicReference<Object>(); SubscriptionOperator s1 = new SubscriptionOperator("t1"){ @Override public void onMessage(EventMessage event){ atomic1.set(event); } }; s1.subscribeWith(null, jlibsClient1); final AtomicReference<Object> atomic2 = new AtomicReference<Object>(); SubscriptionOperator s2 = new SubscriptionOperator("t1"){ @Override public void onMessage(EventMessage event){ atomic2.set(event); } }; s2.subscribeWith(null, jlibsClient1); jlibsClient2.publish(null, "t1", null, null); Await.getResult(atomic1); Await.getResult(atomic2); s1.unsubscribe(); atomic1.set("blah1"); jlibsClient2.publish(null, "t1", null, null); assertEquals(Await.getResult(atomic1), "blah1"); Await.getResult(atomic2); s2.unsubscribe(); atomic1.set("blah1"); atomic2.set("blah2"); assertEquals(Await.getResult(atomic1), "blah1"); assertEquals(Await.getResult(atomic2), "blah2"); } @Test(description="multiple subscriptions on same topic from a client and same client publishes") public void test3() throws Throwable{ final AtomicReference<Object> atomic1 = new AtomicReference<Object>(); SubscriptionOperator s1 = new SubscriptionOperator("t1"){ @Override public void onMessage(EventMessage event){ atomic1.set(event); } }; s1.subscribeWith(null, jlibsClient1); final AtomicReference<Object> atomic2 = new AtomicReference<Object>(); SubscriptionOperator s2 = new SubscriptionOperator("t1"){ @Override public void onMessage(EventMessage event){ atomic2.set(event); } }; s2.subscribeWith(null, jlibsClient1); jlibsClient1.publish(null, "t1", null, null); Await.getResult(atomic1); Await.getResult(atomic2); s1.unsubscribe(); atomic1.set("blah1"); jlibsClient1.publish(null, "t1", null, null); assertEquals(Await.getResult(atomic1), "blah1"); Await.getResult(atomic2); s2.unsubscribe(); atomic1.set("blah1"); atomic2.set("blah2"); assertEquals(Await.getResult(atomic1), "blah1"); assertEquals(Await.getResult(atomic2), "blah2"); } @Test(description="when client closes it should call onUnsubscribe on subscriptions") public void test4() throws Throwable{ SubscriptionOperator s1 = new SubscriptionOperator("t1"); s1.subscribeWith(null, jlibsClient1); SubscriptionOperator s2 = new SubscriptionOperator("t1"); s2.subscribeWith(null, jlibsClient1); SubscriptionOperator s3 = new SubscriptionOperator("t2"); s3.subscribeWith(null, jlibsClient1); jlibsClient1.close(); s1.assertUnsubscribed(); s2.assertUnsubscribed(); s3.assertUnsubscribed(); jlibsClient1 = new ClientOperator(new WAMPClient(new NettyClientEndpoint(), uri, "jlibs")); jlibsClient1.connect(); } @Test(description="when router closes clients should call onUnsubscribe on subscriptions") public void test5() throws Throwable{ SubscriptionOperator s1 = new SubscriptionOperator("t1"); s1.subscribeWith(null, jlibsClient1); SubscriptionOperator s2 = new SubscriptionOperator("t1"); s2.subscribeWith(null, jlibsClient1); SubscriptionOperator s3 = new SubscriptionOperator("t2"); s3.subscribeWith(null, jlibsClient1); SubscriptionOperator s4 = new SubscriptionOperator("t1"); s4.subscribeWith(null, jlibsClient2); SubscriptionOperator s5 = new SubscriptionOperator("t1"); s5.subscribeWith(null, jlibsClient2); SubscriptionOperator s6 = new SubscriptionOperator("t2"); s6.subscribeWith(null, jlibsClient2); SubscriptionOperator s7 = new SubscriptionOperator("t1"); s7.subscribeWith(null, marsClient); SubscriptionOperator s8 = new SubscriptionOperator("t1"); s8.subscribeWith(null, marsClient); SubscriptionOperator s9 = new SubscriptionOperator("t2"); s9.subscribeWith(null, marsClient); router.close(); for(SubscriptionOperator s: new SubscriptionOperator[]{s1, s2, s3, s4, s5, s6, s7, s8, s9}) s.assertUnsubscribed(); start(); } @AfterClass(description="stops clients and router") public void stop() throws Throwable{ jlibsClient1.close(); jlibsClient2.close(); marsClient.close(); router.close(); } }