summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/imagemaster/thrift/server/BinaryListener.java
blob: bf015a1535a2a432bcbd72328ea2b9e171305771 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package org.openslx.imagemaster.thrift.server;

import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;

import org.apache.log4j.Logger;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.server.THsHaServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TNonblockingServerTransport;
import org.apache.thrift.transport.TSSLTransportFactory;
import org.apache.thrift.transport.TSSLTransportFactory.TSSLTransportParameters;
import org.apache.thrift.transport.TServerTransport;
import org.apache.thrift.transport.TTransportException;
import org.openslx.bwlp.thrift.iface.MasterServer;
import org.openslx.imagemaster.Globals;
import org.openslx.thrifthelper.TBinaryProtocolSafe;

public class BinaryListener implements Runnable
{
	private static final int MAX_MSG_LEN = 30 * 1000 * 1000;

	private final MasterServer.Processor<MasterServerHandler> processor = new MasterServer.Processor<MasterServerHandler>(
			new MasterServerHandler() );
	final TProtocolFactory protFactory = new TBinaryProtocolSafe.Factory( true, true );

	private static Logger log = Logger.getLogger( BinaryListener.class );
	final TServer server;

	@Override
	public void run()
	{
		log.info( "Starting Binary Thrift" );
		server.serve();
		log.info( "Stopped Binary Thrift" );
		System.exit( 1 ); // Exit so the server can fully restart
	}

	public BinaryListener( int port, boolean secure ) throws TTransportException, NoSuchAlgorithmException
	{
		if ( secure )
			server = initSecure( port );
		else
			server = initNormal( port );
	}

	/**
	 * Listen with TLS wrapping - has to use the thread pool server, since encrypted
	 * servers cannot use nonblocking sockets :(
	 * 
	 * @param port listen port
	 * @return the server
	 * @throws NoSuchAlgorithmException
	 * @throws TTransportException
	 */
	private TServer initSecure( int port ) throws NoSuchAlgorithmException, TTransportException
	{
		SSLContext context = SSLContext.getDefault();
		SSLSocketFactory sf = context.getSocketFactory();
		String[] cipherSuites = sf.getSupportedCipherSuites();
		// TODO: Remove insecure ones
		final TSSLTransportParameters params = new TSSLTransportParameters( "TLSv1.2", cipherSuites );
		params.setKeyStore( Globals.getSslKeystoreFile(), Globals.getSslKeystorePassword() );
		TServerTransport serverTransport;
		try {
			serverTransport = TSSLTransportFactory.getServerSocket( port, 0, null, params );
		} catch ( TTransportException e ) {
			log.fatal( "Could not listen on port " + port );
			throw e;
		}
		TThreadPoolServer.Args args = new TThreadPoolServer.Args( serverTransport );
		args.protocolFactory( protFactory );
		args.processor( processor );
		args.minWorkerThreads( 4 ).maxWorkerThreads( 256 );
		args.requestTimeout( 2 ).requestTimeoutUnit( TimeUnit.MINUTES );
		args.transportFactory( new TFramedTransport.Factory( MAX_MSG_LEN ) );
		return new TThreadPoolServer( args );
	}

	/**
	 * Create normal plain server, no encryption.
	 * 
	 * @param port listen port
	 * @return server instance
	 * @throws TTransportException
	 */
	public TServer initNormal( int port ) throws TTransportException
	{
		final TNonblockingServerTransport serverTransport;
		try {
			serverTransport = new TNonblockingServerSocket( port );
		} catch ( TTransportException e ) {
			log.fatal( "Could not listen on port " + port );
			throw e;
		}
		THsHaServer.Args args = new THsHaServer.Args( serverTransport );
		args.protocolFactory( protFactory );
		args.processor( processor );
		args.minWorkerThreads( 2 ).maxWorkerThreads( 6 );
		args.maxReadBufferBytes = MAX_MSG_LEN;
		return new THsHaServer( args );
	}

}