View Javadoc
1   package com.ericsson.research.trap.spi.transports;
2   
3   /*
4    * ##_BEGIN_LICENSE_##
5    * Transport Abstraction Package (trap)
6    * ----------
7    * Copyright (C) 2014 Ericsson AB
8    * ----------
9    * Redistribution and use in source and binary forms, with or without modification,
10   * are permitted provided that the following conditions are met:
11   * 
12   * 1. Redistributions of source code must retain the above copyright notice, this
13   *    list of conditions and the following disclaimer.
14   * 
15   * 2. Redistributions in binary form must reproduce the above copyright notice,
16   *    this list of conditions and the following disclaimer in the documentation
17   *    and/or other materials provided with the distribution.
18   * 
19   * 3. Neither the name of the Ericsson AB nor the names of its contributors
20   *    may be used to endorse or promote products derived from this software without
21   *    specific prior written permission.
22   * 
23   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26   * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28   * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
32   * OF THE POSSIBILITY OF SUCH DAMAGE.
33   * ##_END_LICENSE_##
34   */
35  
36  import java.net.InetSocketAddress;
37  import java.util.Collection;
38  import java.util.HashSet;
39  
40  import com.ericsson.research.transport.ws.WSAcceptListener;
41  import com.ericsson.research.transport.ws.WSFactory;
42  import com.ericsson.research.transport.ws.WSInterface;
43  import com.ericsson.research.transport.ws.WSSecurityContext;
44  import com.ericsson.research.transport.ws.WSServer;
45  import com.ericsson.research.transport.ws.WSURI;
46  import com.ericsson.research.trap.TrapException;
47  import com.ericsson.research.trap.spi.ListenerTrapTransport;
48  import com.ericsson.research.trap.spi.ListenerTrapTransportDelegate;
49  import com.ericsson.research.trap.spi.TrapConfiguration;
50  import com.ericsson.research.trap.spi.TrapMessage;
51  import com.ericsson.research.trap.spi.TrapTransport;
52  import com.ericsson.research.trap.spi.TrapTransportDelegate;
53  import com.ericsson.research.trap.spi.TrapTransportProtocol;
54  import com.ericsson.research.trap.spi.TrapTransportState;
55  
56  public class ServerWebSocketTransport extends AbstractListenerTransport implements ListenerTrapTransport, WSAcceptListener
57  {
58  
59  	private WSServer						serverSocket;
60  	private ListenerTrapTransportDelegate	listenerDelegate;
61  	private Object							listenerContext;
62  	private String							host;
63  	private boolean							defaultHost	= false;
64  
65  	public String getTransportName()
66  	{
67  		return "websocket";
68  	}
69  
70  	@Override
71  	public String getProtocolName()
72  	{
73  		return TrapTransportProtocol.WEBSOCKET;
74  	}
75  	
76  	public void listen(ListenerTrapTransportDelegate listener, Object context) throws TrapException
77  	{
78  		this.listenerDelegate = listener;
79  		this.listenerContext = context;
80  
81  		this.delegate = new TrapTransportDelegate() {
82  
83  			@Override
84  			public void ttStateChanged(TrapTransportState newState, TrapTransportState oldState, TrapTransport transport, Object context)
85  			{
86  				// TODO Auto-generated method stub
87  
88  			}
89  
90  			@Override
91  			public void ttMessageReceived(TrapMessage message, TrapTransport transport, Object context)
92  			{
93  				// TODO Auto-generated method stub
94  
95  			}
96  
97  			@Override
98  			public void ttMessageSent(TrapMessage message, TrapTransport transport, Object context)
99  			{
100 				// TODO Auto-generated method stub
101 				
102 			}
103 
104             @Override
105             public void ttMessagesFailedSending(Collection<TrapMessage> messages, TrapTransport transport, Object context)
106             {
107                 // TODO Auto-generated method stub
108                 
109             }
110 
111             @Override
112             public void ttNeedTransport(TrapMessage message, TrapTransport transport, Object context)
113             {
114                 // TODO Auto-generated method stub
115                 
116             }
117 		};
118 
119 		try
120 		{
121 
122 			int port = 0;
123 			try
124 			{
125 				port = Integer.parseInt(this.getOption(WebSocketConstants.CONFIG_SERVER_PORT));
126 			}
127 			catch (Throwable t)
128 			{
129 			}
130 
131 			this.host = this.getOption(WebSocketConstants.CONFIG_SERVER_HOST);
132 
133 			if ((this.host == null) || (this.host.trim().length() == 0))
134 			{
135 				this.host = "0.0.0.0";
136 				this.defaultHost = true;
137 			}
138 			// TODO: This listener IP# should be configurable
139             
140             WSSecurityContext secContext = null;
141             
142             if (this.getOption(CERT_USE_INSECURE_TEST) != null)
143             {
144                 secContext = new WSSecurityContext("jks", "trapserver.jks", "Ericsson", "jks", "trapserver.jks", "Ericsson");
145                 this.logger.warn("Using insecure SSL context");
146             }
147             else
148             {
149                 try
150                 {
151                     String keyType = this.getOption(CERT_KEYSTORE_TYPE);
152                     String keyName = this.getOption(CERT_KEYSTORE_NAME);
153                     String keyPass = this.getOption(CERT_KEYSTORE_PASS);
154                     
155                     String trustType = this.getOption(CERT_TRUSTSTORE_TYPE);
156                     String trustName = this.getOption(CERT_TRUSTSTORE_NAME);
157                     String trustPass = this.getOption(CERT_TRUSTSTORE_PASS);
158                     
159                     if (keyName != null)
160                         secContext = new WSSecurityContext(keyType, keyName, keyPass, trustType, trustName, trustPass);
161                     
162                     this.logger.info("Using provided SSL context. Keystore [{}], Truststore [{}]", keyName, trustName);
163                     
164                 }
165                 catch (Exception e)
166                 {
167                 }
168             }
169             
170             this.serverSocket = WSFactory.startWebSocketServer(this.host, port, this, secContext);
171 			this.setState(TrapTransportState.CONNECTED);
172 		}
173 		catch (Exception e)
174 		{
175 			throw new TrapException(e);
176 		}
177 	}
178 
179 	public void getClientConfiguration(TrapConfiguration destination, String defaultHost)
180 	{
181 
182 
183 		WSURI uri = this.serverSocket.getURI();
184 		InetSocketAddress address = this.serverSocket.getAddress();
185 
186 		// Check for pre-existing port
187 		String port = this.getOption("autoconfig.port");
188 
189 		if (port == null)
190 			port = Integer.toString(uri.getPort());
191 
192 		String hostName = this.getOption("autoconfig.host");
193 		
194 		if (hostName == null)
195 		    hostName = defaultHost;
196 
197 		if (hostName == null)
198 			hostName = this.getHostName(address.getAddress(), this.defaultHost, true);
199 
200 		String targetUri = uri.getScheme() + "://" + hostName + ":" + port + uri.getPath();
201 
202 		destination.setOption(this.prefix, WebSocketConstants.CONFIG_URI, targetUri);
203 
204 	}
205 
206 	@Override
207 	protected void internalDisconnect()
208 	{
209         try
210         {
211 			WSFactory.stopWebSocketServer(this.serverSocket);
212 		}
213         catch (Exception e)
214         {
215         }
216 	}
217 
218 	public void notifyError(Exception e)
219 	{
220 		System.err.println("Error!");
221 		this.setState(TrapTransportState.ERROR);
222 	}
223 
224 	@Override
225 	public void notifyAccept(WSInterface socket)
226 	{
227 		WebSocketTransport transport = new WebSocketTransport(socket);
228 		this.listenerDelegate.ttsIncomingConnection(transport, this, this.listenerContext);
229 
230 	}
231 
232 	@Override
233 	public void notifyReady(WSServer server)
234 	{
235 		this.serverSocket = server;
236 	}
237 
238 	@Override
239 	public void fillAuthenticationKeys(@SuppressWarnings("rawtypes") HashSet keys)
240 	{
241 		// Authentication is redundant on servers.
242 	}
243 
244 	@Override
245     public void notifyError(Throwable t)
246     {
247 		this.logger.error("WebSocket Error", t);
248 	}
249 
250 	@Override
251 	public void flushTransport()
252 	{
253 		
254 	}
255 
256 }