/* * GrizzlySSLNIOClient.java */ package grizzly.ssl.client; import com.sun.grizzly.ConnectorHandler; import com.sun.grizzly.Context; import com.sun.grizzly.Controller; import com.sun.grizzly.ControllerStateListenerAdapter; import com.sun.grizzly.IOEvent; import com.sun.grizzly.SSLCallbackHandler; import com.sun.grizzly.SSLConfig; import com.sun.grizzly.SSLConnectorHandler; import com.sun.grizzly.SSLSelectorHandler; import static com.sun.grizzly.Controller.*; import com.sun.grizzly.Controller.Protocol; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; /** * @author Alexey Stashok */ public class GrizzlySSLNIOClient { public static final String HOST = "localhost"; public static final int PORT = 19888; private static final int TIME_OUT = 30000; private static final int FINAL_TIME_OUT = 2000; private static final int BUFFER_SIZE = 4096; public void process(String host, int port) throws Exception { // Create Grizzly Controller Controller grizzlyController = new Controller(); // Create and add SSL Selector Handler SSLSelectorHandler sslSelectorHandler = new SSLSelectorHandler(true); grizzlyController.addSelectorHandler(sslSelectorHandler); // Register Grizzly Controller state listener, to be sure Controller is started grizzlyController.addStateListener(new ControllerStateListenerAdapter() { public void onException(Throwable e) { System.out.println("Grizzly controller exception: " + e.getMessage()); // log synchronized(GrizzlySSLNIOClient.this) { GrizzlySSLNIOClient.this.notify(); } } public void onReady() { synchronized(GrizzlySSLNIOClient.this) { GrizzlySSLNIOClient.this.notify(); } } }); // Start Grizzly Controller new Thread(grizzlyController).start(); // Wait until Controller get started, or exception occur synchronized(this) { wait(TIME_OUT); } try { // Check whether controller is started assert grizzlyController.isStarted(); // Acquire client SSL connector final SSLConnectorHandler clientSSLConnector = (SSLConnectorHandler) grizzlyController.acquireConnectorHandler(Protocol.TLS); /* Configure SSL connector. * If default (based on System properties) configuration could be used - * following 4 lines could be skipped */ SSLConfig sslConfig = new SSLConfig(); sslConfig.setKeyStoreFile("mykeys.jks"); sslConfig.setTrustStoreFile("mycerts.jks"); clientSSLConnector.configure(sslConfig); // initialize in/out buffers final ByteBuffer inBuffer = ByteBuffer.allocate(BUFFER_SIZE); final ByteBuffer outBuffer = ByteBuffer.wrap("Hello world!".getBytes()); try { // SSL NIO core methods SSLCallbackHandler sslCallbackHander = new SSLCallbackHandler() { /* If connection is established - SSL handshake phase could * be started */ public void onConnect(IOEvent event) { try { SelectionKey key = event.attachment().getSelectionKey(); clientSSLConnector.finishConnect(key); if (clientSSLConnector.isConnected()) { System.out.println("Connected"); // start async. handshake if (clientSSLConnector.handshake(inBuffer, false)) { // call onHandshake, if handshake // was completed immediately onHandshake(event); } } } catch (IOException e) { // log } } // After handshake completes public void onHandshake(IOEvent event) { System.out.println("Handshake done"); // if handshake is done - write async. data on socket onWrite(event); } // Data is ready to be read public void onRead(IOEvent event) { System.out.println("Ready for async read"); receive(clientSSLConnector, inBuffer); } // Channel is ready to write data public void onWrite(IOEvent event) { System.out.println("Ready for async write"); if (outBuffer.hasRemaining()) { send(clientSSLConnector, outBuffer); } // if all the data was written - start reading reply if (!outBuffer.hasRemaining()) { receive(clientSSLConnector, inBuffer); } } }; // Connect SSL connector and register callback handler clientSSLConnector.connect(new InetSocketAddress(host, port), sslCallbackHander); // if is connected if (clientSSLConnector.isConnected()) { // give some time to to async. operations to be executed Thread.sleep(FINAL_TIME_OUT); System.out.println("Final out buffer state: " + outBuffer); System.out.println("Final in buffer state: " + inBuffer); } else { System.out.println("Can not connect!"); } } finally { // close client connector clientSSLConnector.close(); // return closed connection to queue grizzlyController.releaseConnectorHandler(clientSSLConnector); } } finally { // stop Controller grizzlyController.stop(); } } // Async write public void send(ConnectorHandler connectorHandler, ByteBuffer outBuffer) { try { long writeLen = connectorHandler.write(outBuffer, false); System.out.println("Written chunk length(secured): " + writeLen); } catch (IOException e) { // log } } // Async read public void receive(ConnectorHandler connectorHandler, ByteBuffer inBuffer) { try { long readLen = connectorHandler.read(inBuffer, false); System.out.println("Read chunk length(secured): " + readLen); } catch (IOException e) { // log } } public static void main(String[] args) { try { new GrizzlySSLNIOClient().process(HOST, PORT); } catch (Exception e) { // log exception e.printStackTrace(); } } }