001 /**
002 * Copyright (C) 2012 FuseSource, Inc.
003 * http://fusesource.com
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.fusesource.hawtdispatch.example;
018
019 import org.fusesource.hawtbuf.AsciiBuffer;
020 import org.fusesource.hawtbuf.Buffer;
021 import org.fusesource.hawtdispatch.Dispatch;
022 import org.fusesource.hawtdispatch.Task;
023 import org.fusesource.hawtdispatch.transport.AbstractProtocolCodec;
024 import org.fusesource.hawtdispatch.transport.DefaultTransportListener;
025 import org.fusesource.hawtdispatch.transport.SslTransport;
026
027 import javax.net.ssl.SSLContext;
028 import javax.net.ssl.TrustManager;
029 import javax.net.ssl.X509TrustManager;
030 import java.io.IOException;
031 import java.net.URI;
032 import java.security.SecureRandom;
033 import java.security.cert.X509Certificate;
034 import java.util.concurrent.CountDownLatch;
035 import java.util.concurrent.Executors;
036
037 /**
038 */
039 public class SSLClientExample {
040
041 // A fake trust manager to accept self signed certs.
042 static final TrustManager[] TRUST_ALL_CERTS = new TrustManager[]{
043 new X509TrustManager() {
044 public X509Certificate[] getAcceptedIssuers() {
045 return new X509Certificate[0];
046 }
047
048 public void checkClientTrusted(X509Certificate[] certs, String authType) {
049 }
050
051 public void checkServerTrusted(X509Certificate[] certs, String authType) {
052 }
053 }
054 };
055
056 // A very simple codec that just passes along byte buffers..
057 // A more realistic example can be found at:
058 // https://github.com/fusesource/stompjms/blob/master/stompjms-client/src/main/java/org/fusesource/stomp/codec/StompProtocolCodec.java
059 private static class BufferProtocolCodec extends AbstractProtocolCodec {
060 @Override
061 protected void encode(Object value) throws IOException {
062 Buffer buffer = (Buffer) value;
063 nextWriteBuffer.write(buffer);
064 }
065
066 @Override
067 protected Action initialDecodeAction() {
068 return readCommand();
069 }
070
071 protected Action readCommand() {
072 return new Action() {
073 public Object apply() throws IOException {
074 int length = readBuffer.position() - readStart;
075 if (length > 0) {
076 int offset = readStart;
077 readEnd = offset + length;
078 readStart = readEnd;
079 return new Buffer(readBuffer.array(), offset, length);
080 } else {
081 return null;
082 }
083 }
084 };
085 }
086 }
087
088 public static void main(String[] args) throws Exception {
089
090 // Setup an SSLContext that accepts self signed certs.
091 SSLContext sslContext = SSLContext.getInstance("SSL");
092 sslContext.init(null, TRUST_ALL_CERTS, new SecureRandom());
093
094 final SslTransport client = new SslTransport();
095 client.setDispatchQueue(Dispatch.createQueue());
096 client.setSSLContext(sslContext);
097 client.setBlockingExecutor(Executors.newCachedThreadPool());
098 client.setProtocolCodec(new BufferProtocolCodec());
099 client.connecting(new URI("ssl://localhost:61614"), null);
100
101 final CountDownLatch done = new CountDownLatch(1);
102 final Task onClose = new Task() {
103 public void run() {
104 System.out.println("Client closed.");
105 done.countDown();
106 }
107 };
108 client.setTransportListener(new DefaultTransportListener() {
109
110 @Override
111 public void onTransportConnected() {
112 System.out.println("Connected");
113 client.resumeRead();
114
115 // Once we are connected send some data..
116 client.offer(new AsciiBuffer(
117 "CONNECT\n" +
118 "login:admin\n" +
119 "passcode:password\n" +
120 "\n\u0000\n"
121 ));
122 }
123
124 // all we do is echo back the request, but change the frame,
125 // command to RESPONSE.
126 @Override
127 public void onTransportCommand(Object command) {
128 Buffer frame = (Buffer) command;
129 System.out.println("Received :" + frame.ascii());
130 client.stop(onClose);
131 }
132
133 @Override
134 public void onTransportFailure(IOException error) {
135 System.out.println("Transport failure :" + error);
136 client.stop(onClose);
137 }
138 });
139 client.start(Dispatch.NOOP);
140 done.await();
141
142 }
143
144 }