package org.yamcs.artemis; import static org.junit.Assert.*; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import org.apache.activemq.artemis.api.core.ActiveMQBuffer; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.client.ClientMessage; import org.apache.activemq.artemis.api.core.client.MessageHandler; import org.apache.activemq.artemis.core.server.embedded.EmbeddedActiveMQ; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.yamcs.yarch.Stream; import org.yamcs.yarch.StreamSubscriber; import org.yamcs.yarch.Tuple; import org.yamcs.yarch.TupleDefinition; import org.yamcs.api.artemis.YamcsClient; import org.yamcs.api.artemis.YamcsSession; import org.yamcs.artemis.ArtemisServer; import org.yamcs.artemis.StreamAdapter; import org.yamcs.artemis.TupleTranslator; import org.yamcs.yarch.YarchTestCase; public class StreamAdapterTest extends YarchTestCase { int n=10; static EmbeddedActiveMQ artemisServer; @BeforeClass public static void setUpBeforeClass1() throws Exception { artemisServer = ArtemisServer.setupArtemis(); } @AfterClass public static void tearDownAfterClass() throws Exception { artemisServer.stop(); } @Test public void testStream2Hornet() throws Exception { //setup the stream execute("create stream tests2h(x int, d double)"); Stream s=ydb.getStream("tests2h"); //setup the translator SimpleString hornetAddress=new SimpleString("tests2h"); MyTupleTranslator t=new MyTupleTranslator(); StreamAdapter streamAdapter=new StreamAdapter(s,hornetAddress,t); //independent stream subscribers work ok (i.e. no duplicate) s.addSubscriber(new StreamSubscriber() { @Override public void streamClosed(Stream stream) { } int k=0; @Override public void onTuple(Stream stream, Tuple tuple) { // System.out.println("independent stream subscriber received: "+tuple); int x=(Integer)tuple.getColumn("x"); assertEquals(k,x); k++; } }); //independent hornet subscriber YamcsSession ys=YamcsSession.newBuilder().build(); YamcsClient msgClient=ys.newClientBuilder().setDataConsumer(hornetAddress, null).build(); final Semaphore semaphore=new Semaphore(0); msgClient.dataConsumer.setMessageHandler(new MessageHandler() { int k=0; @Override public void onMessage(ClientMessage msg) { int x=msg.getBodyBuffer().readInt(); double d=msg.getBodyBuffer().readDouble(); // System.out.println("independent hornet subscriber received: "+x+" expecting "+k); assertEquals(k, x); assertEquals(k*10, d, 0.1); k++; if(k==n)semaphore.release(); } }); //long t0=System.currentTimeMillis(); //start pushing into the stream TupleDefinition tdef=s.getDefinition(); for(int i=0;i<n;i++) { s.emitTuple(new Tuple(tdef, new Object[]{i, (double)10*i})); } assertTrue(semaphore.tryAcquire(5000, TimeUnit.SECONDS)); // long t1=System.currentTimeMillis(); // System.out.println("pushed "+n+" tuples around, speed: "+1000L*n/(t1-t0)+" tuples/sec"); ys.close(); streamAdapter.quit(); execute("close stream tests2h"); } @Test public void testHornet2Stream() throws Exception { //setup the stream execute("create stream testh2s(x int, d double)"); Stream s=ydb.getStream("testh2s"); //setup the translator SimpleString hornetAddress=new SimpleString("tests2h"); MyTupleTranslator t=new MyTupleTranslator(); StreamAdapter streamAdapter=new StreamAdapter(s,hornetAddress,t); final Semaphore semaphore=new Semaphore(0); //independent hornet subscriber YamcsSession ys=YamcsSession.newBuilder().build(); YamcsClient indMsgClient= ys.newClientBuilder().setDataConsumer(hornetAddress, null).build(); indMsgClient.dataConsumer.setMessageHandler(new MessageHandler() { int k=0; @Override public void onMessage(ClientMessage msg) { int x=msg.getBodyBuffer().readInt(); double d=msg.getBodyBuffer().readDouble(); // System.out.println("independent hornet subscriber received: "+x); assertEquals(k,x); assertEquals(k*10,d,0.1); k++; if(k==n)semaphore.release(); } }); //independent stream subscriber s.addSubscriber(new StreamSubscriber() { @Override public void streamClosed(Stream stream) { } int k=0; @Override public void onTuple(Stream stream, Tuple tuple) { // System.out.println("independent stream subscriber received: "+tuple); int x=(Integer)tuple.getColumn("x"); assertEquals(k,x); k++; semaphore.release(); } }); //start pushing into hornet YamcsClient msg1Client=ys.newClientBuilder().setDataProducer(true).build(); // long t0=System.currentTimeMillis(); for(int i=0;i<n;i++) { ClientMessage msg=ys.session.createMessage(false); msg.getBodyBuffer().writeInt(i); msg.getBodyBuffer().writeDouble(i*10); msg1Client.sendData(hornetAddress, msg); } assertTrue(semaphore.tryAcquire(5, TimeUnit.SECONDS)); // long t1=System.currentTimeMillis(); // System.out.println("pushed "+n+" messages around, speed: "+1000L*n/(t1-t0)+" messages/sec"); ys.close(); msg1Client.close(); streamAdapter.quit(); execute("close stream testh2s"); } } class MyTupleTranslator implements TupleTranslator { @Override public ClientMessage buildMessage(ClientMessage msg, Tuple tuple) { int x=(Integer)tuple.getColumn("x"); double d=(Double)tuple.getColumn("d"); ActiveMQBuffer body=msg.getBodyBuffer(); body.writeInt(x); body.writeDouble(d); return msg; } @Override public Tuple buildTuple(TupleDefinition tdef, ClientMessage msg) { ActiveMQBuffer body=msg.getBodyBuffer(); return new Tuple(tdef, new Object[]{body.readInt(), body.readDouble()}); } }