| // |
| // ======================================================================== |
| // Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. |
| // ------------------------------------------------------------------------ |
| // 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 org.eclipse.jetty.websocket.jsr356; |
| |
| import static org.hamcrest.Matchers.*; |
| |
| import java.io.BufferedReader; |
| import java.io.File; |
| import java.io.FileReader; |
| import java.io.IOException; |
| import java.io.Reader; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.concurrent.CountDownLatch; |
| import java.util.concurrent.TimeUnit; |
| |
| import javax.websocket.ClientEndpoint; |
| import javax.websocket.CloseReason; |
| import javax.websocket.ContainerProvider; |
| import javax.websocket.DecodeException; |
| import javax.websocket.Decoder; |
| import javax.websocket.EndpointConfig; |
| import javax.websocket.OnClose; |
| import javax.websocket.OnMessage; |
| import javax.websocket.WebSocketContainer; |
| |
| import org.eclipse.jetty.toolchain.test.EventQueue; |
| import org.eclipse.jetty.toolchain.test.MavenTestingUtils; |
| import org.eclipse.jetty.toolchain.test.TestTracker; |
| import org.eclipse.jetty.util.BufferUtil; |
| import org.eclipse.jetty.util.log.Log; |
| import org.eclipse.jetty.util.log.Logger; |
| import org.eclipse.jetty.websocket.common.WebSocketFrame; |
| import org.eclipse.jetty.websocket.common.frames.ContinuationFrame; |
| import org.eclipse.jetty.websocket.common.frames.TextFrame; |
| import org.eclipse.jetty.websocket.common.test.BlockheadServer; |
| import org.eclipse.jetty.websocket.common.test.BlockheadServer.ServerConnection; |
| import org.junit.After; |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.Ignore; |
| import org.junit.Rule; |
| import org.junit.Test; |
| |
| public class DecoderReaderTest |
| { |
| public static class Quotes |
| { |
| private String author; |
| private List<String> quotes = new ArrayList<>(); |
| |
| public String getAuthor() |
| { |
| return author; |
| } |
| |
| public void setAuthor(String author) |
| { |
| this.author = author; |
| } |
| |
| public List<String> getQuotes() |
| { |
| return quotes; |
| } |
| |
| public void addQuote(String quote) |
| { |
| quotes.add(quote); |
| } |
| } |
| |
| public static class QuotesDecoder implements Decoder.TextStream<Quotes> |
| { |
| @Override |
| public void init(EndpointConfig config) |
| { |
| } |
| |
| @Override |
| public void destroy() |
| { |
| } |
| |
| @Override |
| public Quotes decode(Reader reader) throws DecodeException, IOException |
| { |
| Quotes quotes = new Quotes(); |
| try (BufferedReader buf = new BufferedReader(reader)) |
| { |
| String line; |
| while ((line = buf.readLine()) != null) |
| { |
| switch (line.charAt(0)) |
| { |
| case 'a': |
| quotes.setAuthor(line.substring(2)); |
| break; |
| case 'q': |
| quotes.addQuote(line.substring(2)); |
| break; |
| } |
| } |
| } |
| return quotes; |
| } |
| } |
| |
| @ClientEndpoint(decoders = { QuotesDecoder.class }) |
| public static class QuotesSocket |
| { |
| public EventQueue<Quotes> messageQueue = new EventQueue<>(); |
| private CountDownLatch closeLatch = new CountDownLatch(1); |
| |
| @OnClose |
| public void onClose(CloseReason close) |
| { |
| closeLatch.countDown(); |
| } |
| |
| @OnMessage |
| public void onMessage(Quotes msg) |
| { |
| messageQueue.add(msg); |
| System.out.printf("Quotes from: %s%n",msg.author); |
| for (String quote : msg.quotes) |
| { |
| System.out.printf(" - %s%n",quote); |
| } |
| } |
| |
| public void awaitClose() throws InterruptedException |
| { |
| closeLatch.await(4,TimeUnit.SECONDS); |
| } |
| } |
| |
| private static class QuoteServer implements Runnable |
| { |
| private BlockheadServer server; |
| private ServerConnection sconnection; |
| private CountDownLatch connectLatch = new CountDownLatch(1); |
| |
| public QuoteServer(BlockheadServer server) |
| { |
| this.server = server; |
| } |
| |
| @Override |
| public void run() |
| { |
| try |
| { |
| sconnection = server.accept(); |
| sconnection.setSoTimeout(60000); |
| sconnection.upgrade(); |
| } |
| catch (Exception e) |
| { |
| LOG.warn(e); |
| } |
| finally |
| { |
| connectLatch.countDown(); |
| } |
| } |
| |
| public void writeQuotes(String filename) throws IOException |
| { |
| // read file |
| File qfile = MavenTestingUtils.getTestResourceFile(filename); |
| List<String> lines = new ArrayList<>(); |
| try (FileReader reader = new FileReader(qfile); BufferedReader buf = new BufferedReader(reader)) |
| { |
| String line; |
| while ((line = buf.readLine()) != null) |
| { |
| lines.add(line); |
| } |
| } |
| // write file out, each line on a separate frame, but as |
| // 1 whole message |
| for (int i = 0; i < lines.size(); i++) |
| { |
| WebSocketFrame frame; |
| if (i == 0) |
| { |
| frame = new TextFrame(); |
| } |
| else |
| { |
| frame = new ContinuationFrame(); |
| } |
| frame.setFin((i >= (lines.size() - 1))); |
| frame.setPayload(BufferUtil.toBuffer(lines.get(i) + "\n")); |
| sconnection.write(frame); |
| } |
| } |
| |
| public void close() throws IOException |
| { |
| sconnection.close(); |
| } |
| |
| public void awaitConnect() throws InterruptedException |
| { |
| connectLatch.await(1,TimeUnit.SECONDS); |
| } |
| } |
| |
| private static final Logger LOG = Log.getLogger(DecoderReaderTest.class); |
| |
| @Rule |
| public TestTracker tt = new TestTracker(); |
| |
| private BlockheadServer server; |
| private WebSocketContainer client; |
| |
| @Before |
| public void initClient() |
| { |
| client = ContainerProvider.getWebSocketContainer(); |
| } |
| |
| @Before |
| public void startServer() throws Exception |
| { |
| server = new BlockheadServer(); |
| server.start(); |
| } |
| |
| @After |
| public void stopServer() throws Exception |
| { |
| server.stop(); |
| } |
| |
| // TODO analyse and fix |
| @Ignore |
| @Test |
| public void testSingleQuotes() throws Exception |
| { |
| QuotesSocket quoter = new QuotesSocket(); |
| QuoteServer qserver = new QuoteServer(server); |
| new Thread(qserver).start(); |
| client.connectToServer(quoter,server.getWsUri()); |
| qserver.awaitConnect(); |
| qserver.writeQuotes("quotes-ben.txt"); |
| quoter.messageQueue.awaitEventCount(1,1000,TimeUnit.MILLISECONDS); |
| qserver.close(); |
| quoter.awaitClose(); |
| Quotes quotes = quoter.messageQueue.poll(); |
| Assert.assertThat("Quotes Author",quotes.author,is("Benjamin Franklin")); |
| Assert.assertThat("Quotes Count",quotes.quotes.size(),is(3)); |
| } |
| |
| // TODO analyse and fix |
| @Ignore |
| @Test |
| public void testTwoQuotes() throws Exception |
| { |
| QuotesSocket quoter = new QuotesSocket(); |
| QuoteServer qserver = new QuoteServer(server); |
| new Thread(qserver).start(); |
| client.connectToServer(quoter,server.getWsUri()); |
| qserver.awaitConnect(); |
| qserver.writeQuotes("quotes-ben.txt"); |
| qserver.writeQuotes("quotes-twain.txt"); |
| quoter.messageQueue.awaitEventCount(2,1000,TimeUnit.MILLISECONDS); |
| qserver.close(); |
| quoter.awaitClose(); |
| Quotes quotes = quoter.messageQueue.poll(); |
| Assert.assertThat("Quotes Author",quotes.author,is("Benjamin Franklin")); |
| Assert.assertThat("Quotes Count",quotes.quotes.size(),is(3)); |
| } |
| } |