001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 *
019 */
020package org.apache.mina.example.tcp.perf;
021
022import java.net.InetSocketAddress;
023import java.security.GeneralSecurityException;
024import java.util.concurrent.CountDownLatch;
025import java.util.concurrent.TimeUnit;
026
027import javax.net.ssl.SSLContext;
028
029import org.apache.mina.core.buffer.IoBuffer;
030import org.apache.mina.core.future.ConnectFuture;
031import org.apache.mina.core.service.IoConnector;
032import org.apache.mina.core.service.IoHandlerAdapter;
033import org.apache.mina.core.session.IdleStatus;
034import org.apache.mina.core.session.IoSession;
035import org.apache.mina.filter.ssl.SslFilter;
036import org.apache.mina.transport.socket.nio.NioSocketConnector;
037
038/**
039 * An TCP client that just send thousands of small messages to a TcpServer through SSL. 
040 * 
041 * This class is used for performance test purposes. It does nothing at all, but send a message
042 * repeatedly to a server.
043 * 
044 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
045 */
046public class TcpSslClient extends IoHandlerAdapter {
047    /** The connector */
048    private IoConnector connector;
049
050    /** The session */
051    private static IoSession session;
052
053    /** The buffer containing the message to send */
054    private IoBuffer buffer = IoBuffer.allocate(8);
055
056    /** Timers **/
057    private long t0;
058    private long t1;
059
060    /** the counter used for the sent messages */
061    private CountDownLatch counter;
062
063    /**
064     * Create the TcpClient's instance
065     * @throws GeneralSecurityException 
066     */
067    public TcpSslClient() throws GeneralSecurityException {
068        connector = new NioSocketConnector();
069
070        // Inject teh SSL filter
071        SSLContext sslContext = BogusSslContextFactory
072            .getInstance(false);
073        SslFilter sslFilter = new SslFilter(sslContext);
074        sslFilter.setUseClientMode(true);
075        connector.getFilterChain().addFirst("sslFilter", sslFilter);
076
077        connector.setHandler(this);
078        ConnectFuture connFuture = connector.connect(new InetSocketAddress("localhost", TcpServer.PORT));
079
080        connFuture.awaitUninterruptibly();
081
082        session = connFuture.getSession();
083    }
084
085    /**
086     * {@inheritDoc}
087     */
088    @Override
089    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
090        cause.printStackTrace();
091    }
092
093    /**
094     * {@inheritDoc}
095     */
096    @Override
097    public void messageReceived(IoSession session, Object message) throws Exception {
098        long received = ((IoBuffer)message).getLong();
099        
100        if (received != counter.getCount()) {
101            System.out.println("Error !");
102            session.closeNow();
103        } else {
104            if (counter.getCount() == 0L) {
105                t1 = System.currentTimeMillis();
106                
107                System.out.println("------------->  end " + (t1 - t0));
108                session.closeNow();
109            } else {
110                counter.countDown();
111                
112                buffer.flip();
113                buffer.putLong(counter.getCount());
114                buffer.flip();
115                session.write(buffer);
116            }
117        }
118    }
119
120    /**
121     * {@inheritDoc}
122     */
123    @Override
124    public void messageSent(IoSession session, Object message) throws Exception {
125        if (counter.getCount() % 10000 == 0) {
126            System.out.println("Sent " + counter + " messages");
127        }
128    }
129
130    /**
131     * {@inheritDoc}
132     */
133    @Override
134    public void sessionClosed(IoSession session) throws Exception {
135    }
136
137    /**
138     * {@inheritDoc}
139     */
140    @Override
141    public void sessionCreated(IoSession session) throws Exception {
142    }
143
144    /**
145     * {@inheritDoc}
146     */
147    @Override
148    public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
149    }
150
151    /**
152     * {@inheritDoc}
153     */
154    @Override
155    public void sessionOpened(IoSession session) throws Exception {
156    }
157
158    /**
159     * The main method : instanciates a client, and send N messages. We sleep 
160     * between each K messages sent, to avoid the server saturation.
161     * @param args The arguments
162     * @throws Exception If something went wrong
163     */
164    public static void main(String[] args) throws Exception {
165        TcpSslClient client = new TcpSslClient();
166
167        client.t0 = System.currentTimeMillis();
168        client.counter = new CountDownLatch(TcpServer.MAX_RECEIVED);
169        client.buffer.putLong(client.counter.getCount());
170        client.buffer.flip();
171        session.write(client.buffer);
172        int nbSeconds = 0;
173
174        while ((client.counter.getCount() > 0) && (nbSeconds < 120)) {
175            // Wait for one second
176            client.counter.await(1, TimeUnit.SECONDS);
177            nbSeconds++;
178        }
179
180        client.connector.dispose(true);
181    }
182}