You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by el...@apache.org on 2016/02/16 11:07:17 UTC

[3/4] mina git commit: o Improved the ctp.perf tests o Added some tests over SSL

o Improved the ctp.perf tests
o Added some tests over SSL

Project: http://git-wip-us.apache.org/repos/asf/mina/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina/commit/6f8d9275
Tree: http://git-wip-us.apache.org/repos/asf/mina/tree/6f8d9275
Diff: http://git-wip-us.apache.org/repos/asf/mina/diff/6f8d9275

Branch: refs/heads/2.0
Commit: 6f8d9275698717d8eceb607e36176a760c4dc198
Parents: 83602ea
Author: Emmanuel Lécharny <el...@symas.com>
Authored: Tue Feb 16 10:27:57 2016 +0100
Committer: Emmanuel Lécharny <el...@symas.com>
Committed: Tue Feb 16 10:27:57 2016 +0100

----------------------------------------------------------------------
 .../tcp/perf/BogusSslContextFactory.java        | 146 +++++++++++++++
 .../tcp/perf/BogusTrustManagerFactory.java      |  74 ++++++++
 .../apache/mina/example/tcp/perf/TcpClient.java |  74 +++++---
 .../apache/mina/example/tcp/perf/TcpServer.java |   2 +-
 .../mina/example/tcp/perf/TcpSslClient.java     | 179 +++++++++++++++++++
 .../mina/example/tcp/perf/TcpSslServer.java     | 163 +++++++++++++++++
 6 files changed, 610 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina/blob/6f8d9275/mina-example/src/main/java/org/apache/mina/example/tcp/perf/BogusSslContextFactory.java
----------------------------------------------------------------------
diff --git a/mina-example/src/main/java/org/apache/mina/example/tcp/perf/BogusSslContextFactory.java b/mina-example/src/main/java/org/apache/mina/example/tcp/perf/BogusSslContextFactory.java
new file mode 100644
index 0000000..9b836c0
--- /dev/null
+++ b/mina-example/src/main/java/org/apache/mina/example/tcp/perf/BogusSslContextFactory.java
@@ -0,0 +1,146 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses 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 org.apache.mina.example.tcp.perf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.Security;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+
+/**
+ * Factory to create a bogus SSLContext.
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class BogusSslContextFactory {
+
+    /**
+     * Protocol to use.
+     */
+    private static final String PROTOCOL = "TLS";
+
+    private static final String KEY_MANAGER_FACTORY_ALGORITHM;
+
+    static {
+        String algorithm = Security
+                .getProperty("ssl.KeyManagerFactory.algorithm");
+        if (algorithm == null) {
+            algorithm = KeyManagerFactory.getDefaultAlgorithm();
+        }
+
+        KEY_MANAGER_FACTORY_ALGORITHM = algorithm;
+    }
+
+    /**
+     * Bougus Server certificate keystore file name.
+     */
+    private static final String BOGUS_KEYSTORE = "bogus.cert";
+
+    // NOTE: The keystore was generated using keytool:
+    //   keytool -genkey -alias bogus -keysize 512 -validity 3650
+    //           -keyalg RSA -dname "CN=bogus.com, OU=XXX CA,
+    //               O=Bogus Inc, L=Stockholm, S=Stockholm, C=SE"
+    //           -keypass boguspw -storepass boguspw -keystore bogus.cert
+
+    /**
+     * Bougus keystore password.
+     */
+    private static final char[] BOGUS_PW = { 'b', 'o', 'g', 'u', 's', 'p', 'w' };
+
+    private static SSLContext serverInstance = null;
+    
+    private static SSLContext clientInstance = null;
+
+    /**
+     * Get SSLContext singleton.
+     *
+     * @param server A flag to tell if this is a Client or Server instance we want to create
+     * @return SSLContext The created SSLContext 
+     * @throws GeneralSecurityException If we had an issue creating the SSLContext
+     */
+    public static SSLContext getInstance(boolean server)
+            throws GeneralSecurityException {
+        SSLContext retInstance = null;
+        if (server) {
+            synchronized(BogusSslContextFactory.class) {
+                if (serverInstance == null) {
+                    try {
+                        serverInstance = createBougusServerSslContext();
+                    } catch (Exception ioe) {
+                        throw new GeneralSecurityException(
+                                "Can't create Server SSLContext:" + ioe);
+                    }
+                }
+            }
+            retInstance = serverInstance;
+        } else {
+            synchronized (BogusSslContextFactory.class) {
+                if (clientInstance == null) {
+                    clientInstance = createBougusClientSslContext();
+                }
+            }
+            retInstance = clientInstance;
+        }
+        return retInstance;
+    }
+
+    private static SSLContext createBougusServerSslContext()
+            throws GeneralSecurityException, IOException {
+        // Create keystore
+        KeyStore ks = KeyStore.getInstance("JKS");
+        InputStream in = null;
+        try {
+            in = BogusSslContextFactory.class
+                    .getResourceAsStream(BOGUS_KEYSTORE);
+            ks.load(in, BOGUS_PW);
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException ignored) {
+                }
+            }
+        }
+
+        // Set up key manager factory to use our key store
+        KeyManagerFactory kmf = KeyManagerFactory
+                .getInstance(KEY_MANAGER_FACTORY_ALGORITHM);
+        kmf.init(ks, BOGUS_PW);
+
+        // Initialize the SSLContext to work with our key managers.
+        SSLContext sslContext = SSLContext.getInstance(PROTOCOL);
+        sslContext.init(kmf.getKeyManagers(),
+                BogusTrustManagerFactory.X509_MANAGERS, null);
+
+        return sslContext;
+    }
+
+    private static SSLContext createBougusClientSslContext()
+            throws GeneralSecurityException {
+        SSLContext context = SSLContext.getInstance(PROTOCOL);
+        context.init(null, BogusTrustManagerFactory.X509_MANAGERS, null);
+        return context;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/6f8d9275/mina-example/src/main/java/org/apache/mina/example/tcp/perf/BogusTrustManagerFactory.java
----------------------------------------------------------------------
diff --git a/mina-example/src/main/java/org/apache/mina/example/tcp/perf/BogusTrustManagerFactory.java b/mina-example/src/main/java/org/apache/mina/example/tcp/perf/BogusTrustManagerFactory.java
new file mode 100644
index 0000000..bcb3c82
--- /dev/null
+++ b/mina-example/src/main/java/org/apache/mina/example/tcp/perf/BogusTrustManagerFactory.java
@@ -0,0 +1,74 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses 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 org.apache.mina.example.tcp.perf;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.ManagerFactoryParameters;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactorySpi;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * Bogus trust manager factory. Creates BogusX509TrustManager
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+class BogusTrustManagerFactory extends TrustManagerFactorySpi {
+
+    static final X509TrustManager X509 = new X509TrustManager() {
+        public void checkClientTrusted(X509Certificate[] x509Certificates,
+                String s) throws CertificateException {
+        }
+
+        public void checkServerTrusted(X509Certificate[] x509Certificates,
+                String s) throws CertificateException {
+        }
+
+        public X509Certificate[] getAcceptedIssuers() {
+            return new X509Certificate[0];
+        }
+    };
+
+    static final TrustManager[] X509_MANAGERS = new TrustManager[] { X509 };
+
+    public BogusTrustManagerFactory() {
+    }
+
+    @Override
+    protected TrustManager[] engineGetTrustManagers() {
+        return X509_MANAGERS;
+    }
+
+    @Override
+    protected void engineInit(KeyStore keystore) throws KeyStoreException {
+        // noop
+    }
+
+    @Override
+    protected void engineInit(ManagerFactoryParameters managerFactoryParameters)
+            throws InvalidAlgorithmParameterException {
+        // noop
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/6f8d9275/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpClient.java
----------------------------------------------------------------------
diff --git a/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpClient.java b/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpClient.java
index fdab45d..d324d7c 100644
--- a/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpClient.java
+++ b/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpClient.java
@@ -20,6 +20,8 @@
 package org.apache.mina.example.tcp.perf;
 
 import java.net.InetSocketAddress;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.mina.core.buffer.IoBuffer;
 import org.apache.mina.core.future.ConnectFuture;
@@ -43,9 +45,17 @@ public class TcpClient extends IoHandlerAdapter {
 
     /** The session */
     private static IoSession session;
-
-    private boolean received = false;
-
+    
+    /** The buffer containing the message to send */
+    private IoBuffer buffer = IoBuffer.allocate(8);
+    
+    /** Timers **/
+    private long t0;
+    private long t1;
+
+    /** the counter used for the sent messages */
+    private CountDownLatch counter;
+    
     /**
      * Create the UdpClient's instance
      */
@@ -73,7 +83,26 @@ public class TcpClient extends IoHandlerAdapter {
      */
     @Override
     public void messageReceived(IoSession session, Object message) throws Exception {
-        received = true;
+        long received = ((IoBuffer)message).getLong();
+        
+        if (received != counter.getCount()) {
+            System.out.println("Error !");
+            session.closeNow();
+        } else {
+            if (counter.getCount() == 0L) {
+                t1 = System.currentTimeMillis();
+                
+                System.out.println("------------->  end " + (t1 - t0));
+                session.closeNow();
+            } else {
+                counter.countDown();
+                
+                buffer.flip();
+                buffer.putLong(counter.getCount());
+                buffer.flip();
+                session.write(buffer);
+            }
+        }
     }
 
     /**
@@ -81,6 +110,9 @@ public class TcpClient extends IoHandlerAdapter {
      */
     @Override
     public void messageSent(IoSession session, Object message) throws Exception {
+        if (counter.getCount() % 10000 == 0) {
+            System.out.println("Sent " + counter + " messages");
+        }
     }
 
     /**
@@ -120,31 +152,19 @@ public class TcpClient extends IoHandlerAdapter {
     public static void main(String[] args) throws Exception {
         TcpClient client = new TcpClient();
 
-        long t0 = System.currentTimeMillis();
-
-        for (int i = 0; i <= TcpServer.MAX_RECEIVED; i++) {
-            IoBuffer buffer = IoBuffer.allocate(4);
-            buffer.putInt(i);
-            buffer.flip();
-            session.write(buffer);
-
-            while (client.received == false) {
-                Thread.sleep(1);
-            }
-
-            client.received = false;
-
-            if (i % 10000 == 0) {
-                System.out.println("Sent " + i + " messages");
-            }
+        client.t0 = System.currentTimeMillis();
+        client.counter = new CountDownLatch(TcpServer.MAX_RECEIVED);
+        client.buffer.putLong(client.counter.getCount());
+        client.buffer.flip();
+        session.write(client.buffer);
+        int nbSeconds = 0;
+
+        while ((client.counter.getCount() > 0) && (nbSeconds < 120)) {
+            // Wait for one second
+            client.counter.await(1, TimeUnit.SECONDS);
+            nbSeconds++;
         }
 
-        long t1 = System.currentTimeMillis();
-
-        System.out.println("Sent messages delay : " + (t1 - t0));
-
-        Thread.sleep(100000);
-
         client.connector.dispose(true);
     }
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/6f8d9275/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpServer.java
----------------------------------------------------------------------
diff --git a/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpServer.java b/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpServer.java
index 702c808..9f95e0c 100644
--- a/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpServer.java
+++ b/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpServer.java
@@ -55,7 +55,7 @@ public class TcpServer extends IoHandlerAdapter {
     @Override
     public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
         cause.printStackTrace();
-        session.close(true);
+        session.closeNow();
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/mina/blob/6f8d9275/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpSslClient.java
----------------------------------------------------------------------
diff --git a/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpSslClient.java b/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpSslClient.java
new file mode 100644
index 0000000..d9132cf
--- /dev/null
+++ b/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpSslClient.java
@@ -0,0 +1,179 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses 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 org.apache.mina.example.tcp.perf;
+
+import java.net.InetSocketAddress;
+import java.security.GeneralSecurityException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.net.ssl.SSLContext;
+
+import org.apache.mina.core.buffer.IoBuffer;
+import org.apache.mina.core.future.ConnectFuture;
+import org.apache.mina.core.service.IoConnector;
+import org.apache.mina.core.service.IoHandlerAdapter;
+import org.apache.mina.core.session.IdleStatus;
+import org.apache.mina.core.session.IoSession;
+import org.apache.mina.filter.ssl.SslFilter;
+import org.apache.mina.transport.socket.nio.NioSocketConnector;
+
+/**
+ * An TCP client that just send thousands of small messages to a TcpServer through SSL. 
+ * 
+ * This class is used for performance test purposes. It does nothing at all, but send a message
+ * repeatedly to a server.
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class TcpSslClient extends IoHandlerAdapter {
+    /** The connector */
+    private IoConnector connector;
+
+    /** The session */
+    private static IoSession session;
+
+    /** The buffer containing the message to send */
+    private IoBuffer buffer = IoBuffer.allocate(8);
+
+    /** Timers **/
+    private long t0;
+    private long t1;
+
+    /** the counter used for the sent messages */
+    private CountDownLatch counter;
+
+    /**
+     * Create the TcpClient's instance
+     * @throws GeneralSecurityException 
+     */
+    public TcpSslClient() throws GeneralSecurityException {
+        connector = new NioSocketConnector();
+
+        // Inject teh SSL filter
+        SSLContext sslContext = BogusSslContextFactory
+            .getInstance(false);
+        SslFilter sslFilter = new SslFilter(sslContext);
+        sslFilter.setUseClientMode(true);
+        connector.getFilterChain().addFirst("sslFilter", sslFilter);
+
+        connector.setHandler(this);
+        ConnectFuture connFuture = connector.connect(new InetSocketAddress("localhost", TcpServer.PORT));
+
+        connFuture.awaitUninterruptibly();
+
+        session = connFuture.getSession();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
+        cause.printStackTrace();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void messageReceived(IoSession session, Object message) throws Exception {
+        long received = ((IoBuffer)message).getLong();
+        
+        if (received != counter.getCount()) {
+            System.out.println("Error !");
+            session.closeNow();
+        } else {
+            if (counter.getCount() == 0L) {
+                t1 = System.currentTimeMillis();
+                
+                System.out.println("------------->  end " + (t1 - t0));
+                session.closeNow();
+            } else {
+                counter.countDown();
+                
+                buffer.flip();
+                buffer.putLong(counter.getCount());
+                buffer.flip();
+                session.write(buffer);
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void messageSent(IoSession session, Object message) throws Exception {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void sessionClosed(IoSession session) throws Exception {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void sessionCreated(IoSession session) throws Exception {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void sessionOpened(IoSession session) throws Exception {
+    }
+
+    /**
+     * The main method : instanciates a client, and send N messages. We sleep 
+     * between each K messages sent, to avoid the server saturation.
+     * @param args The arguments
+     * @throws Exception If something went wrong
+     */
+    public static void main(String[] args) throws Exception {
+        TcpSslClient client = new TcpSslClient();
+
+        client.t0 = System.currentTimeMillis();
+        client.counter = new CountDownLatch(TcpServer.MAX_RECEIVED);
+        client.buffer.putLong(client.counter.getCount());
+        client.buffer.flip();
+        session.write(client.buffer);
+        int nbSeconds = 0;
+
+        while ((client.counter.getCount() > 0) && (nbSeconds < 120)) {
+            // Wait for one second
+            client.counter.await(1, TimeUnit.SECONDS);
+            nbSeconds++;
+        }
+
+        client.connector.dispose(true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/6f8d9275/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpSslServer.java
----------------------------------------------------------------------
diff --git a/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpSslServer.java b/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpSslServer.java
new file mode 100644
index 0000000..63b1680
--- /dev/null
+++ b/mina-example/src/main/java/org/apache/mina/example/tcp/perf/TcpSslServer.java
@@ -0,0 +1,163 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses 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 org.apache.mina.example.tcp.perf;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.security.GeneralSecurityException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
+import org.apache.mina.core.service.IoHandlerAdapter;
+import org.apache.mina.core.session.IdleStatus;
+import org.apache.mina.core.session.IoSession;
+import org.apache.mina.example.echoserver.ssl.BogusSslContextFactory;
+import org.apache.mina.filter.ssl.SslFilter;
+import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
+
+/**
+ * An TCP SSL server used for performance tests.
+ * 
+ * It does nothing fancy, except receiving the messages, and counting the number of
+ * received messages.
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class TcpSslServer extends IoHandlerAdapter {
+    /** The listening port (check that it's not already in use) */
+    public static final int PORT = 18567;
+
+    /** The number of message to receive */
+    public static final int MAX_RECEIVED = 100000;
+
+    /** The starting point, set when we receive the first message */
+    private static long t0;
+
+    /** A counter incremented for every recieved message */
+    private AtomicInteger nbReceived = new AtomicInteger(0);
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
+        cause.printStackTrace();
+        session.closeNow();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void messageReceived(IoSession session, Object message) throws Exception {
+
+        int nb = nbReceived.incrementAndGet();
+
+        if (nb == 1) {
+            t0 = System.currentTimeMillis();
+        }
+
+        if (nb == MAX_RECEIVED) {
+            long t1 = System.currentTimeMillis();
+            System.out.println("-------------> end " + (t1 - t0));
+        }
+
+        if (nb % 10000 == 0) {
+            System.out.println("Received " + nb + " messages");
+        }
+
+        // If we want to test the write operation, uncomment this line
+        session.write(message);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void sessionClosed(IoSession session) throws Exception {
+        System.out.println("Session closed...");
+
+        // Reinitialize the counter and expose the number of received messages
+        System.out.println("Nb message received : " + nbReceived.get());
+        nbReceived.set(0);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void sessionCreated(IoSession session) throws Exception {
+        System.out.println("Session created...");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
+        System.out.println("Session idle...");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @param session the current seession
+     * @throws Exception If something went wrong
+     */
+    @Override
+    public void sessionOpened(IoSession session) throws Exception {
+        System.out.println("Session Opened...");
+    }
+
+    /**
+     * Create the TCP server
+     * 
+     * @throws IOException If something went wrong
+     * @throws GeneralSecurityException 
+     */
+    public TcpSslServer() throws IOException, GeneralSecurityException {
+        NioSocketAcceptor acceptor = new NioSocketAcceptor();
+        
+        // Inject the SSL filter
+        DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
+        SslFilter sslFilter = new SslFilter(BogusSslContextFactory
+            .getInstance(true));
+        chain.addLast("sslFilter", sslFilter);
+
+        acceptor.setHandler(this);
+
+        // The logger, if needed. Commented atm
+        //DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
+        //chain.addLast("logger", new LoggingFilter());
+
+        acceptor.bind(new InetSocketAddress(PORT));
+
+        System.out.println("Server started...");
+    }
+
+    /**
+     * The entry point.
+     * 
+     * @param args The arguments
+     * @throws IOException If something went wrong
+     */
+    public static void main(String[] args) throws Exception {
+        new TcpSslServer();
+    }
+}