├── .arcconfig ├── .gitignore ├── CHANGES.md ├── LICENSE.txt ├── NEWS.md ├── README.md ├── license └── LICENSE-HEADER.txt ├── nifty-client ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── facebook │ │ └── nifty │ │ └── client │ │ ├── AbstractClientChannel.java │ │ ├── AbstractClientConnector.java │ │ ├── ClientRequestContext.java │ │ ├── FramedClientChannel.java │ │ ├── FramedClientConnector.java │ │ ├── HttpClientChannel.java │ │ ├── HttpClientConnector.java │ │ ├── NettyClientConfig.java │ │ ├── NettyClientConfigBuilder.java │ │ ├── NiftyClient.java │ │ ├── NiftyClientChannel.java │ │ ├── NiftyClientChannelPipelineFactory.java │ │ ├── NiftyClientConnector.java │ │ ├── NiftyClientRequestContext.java │ │ ├── NiftyClientSecurityFactory.java │ │ ├── NiftyNoOpClientSecurityFactory.java │ │ ├── RequestChannel.java │ │ ├── TNiftyAsyncClientTransport.java │ │ ├── TNiftyClientAdapter.java │ │ ├── TNiftyClientChannelTransport.java │ │ ├── TNiftyClientListener.java │ │ ├── TNiftyClientTransport.java │ │ ├── TNiftyReadOnlyTransport.java │ │ ├── TimeoutHandler.java │ │ ├── UnframedClientChannel.java │ │ ├── UnframedClientConnector.java │ │ └── socks │ │ ├── SettableChannelFuture.java │ │ ├── Socks4ClientBootstrap.java │ │ ├── Socks4HandshakeHandler.java │ │ └── SocksProtocols.java │ └── test │ └── java │ └── com │ └── facebook │ └── nifty │ └── client │ └── TestHttpClientConnector.java ├── nifty-core ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── facebook │ │ └── nifty │ │ ├── codec │ │ ├── DefaultThriftFrameCodec.java │ │ ├── DefaultThriftFrameCodecFactory.java │ │ ├── DefaultThriftFrameDecoder.java │ │ ├── DefaultThriftFrameEncoder.java │ │ ├── ThriftFrameCodec.java │ │ ├── ThriftFrameCodecFactory.java │ │ ├── ThriftFrameDecoder.java │ │ └── ThriftFrameEncoder.java │ │ ├── core │ │ ├── ChannelStatistics.java │ │ ├── ConnectionContext.java │ │ ├── ConnectionContextHandler.java │ │ ├── ConnectionContexts.java │ │ ├── DefaultNettyServerConfigProvider.java │ │ ├── IdleDisconnectHandler.java │ │ ├── NettyConfigBuilderBase.java │ │ ├── NettyServerConfig.java │ │ ├── NettyServerConfigBuilder.java │ │ ├── NettyServerTransport.java │ │ ├── NiftyBootstrap.java │ │ ├── NiftyConnectionContext.java │ │ ├── NiftyDispatcher.java │ │ ├── NiftyExceptionLogger.java │ │ ├── NiftyIODispatcher.java │ │ ├── NiftyMetrics.java │ │ ├── NiftyNoOpSecurityFactory.java │ │ ├── NiftyRequestContext.java │ │ ├── NiftySecurityFactory.java │ │ ├── NiftySecurityHandlers.java │ │ ├── NiftyTimer.java │ │ ├── RequestContext.java │ │ ├── RequestContexts.java │ │ ├── ShutdownUtil.java │ │ ├── TChannelBufferInputTransport.java │ │ ├── TChannelBufferOutputTransport.java │ │ ├── TInputOutputCompositeTransport.java │ │ ├── TNiftyTransport.java │ │ ├── ThriftMessage.java │ │ ├── ThriftServerDef.java │ │ ├── ThriftServerDefBuilder.java │ │ ├── ThriftServerDefBuilderBase.java │ │ ├── ThriftTransportType.java │ │ └── ThriftUnframedDecoder.java │ │ ├── duplex │ │ ├── TDuplexProtocolFactory.java │ │ ├── TDuplexTransportFactory.java │ │ ├── TProtocolPair.java │ │ └── TTransportPair.java │ │ ├── guice │ │ └── NiftyModule.java │ │ ├── processor │ │ ├── NiftyProcessor.java │ │ ├── NiftyProcessorAdapters.java │ │ └── NiftyProcessorFactory.java │ │ └── ssl │ │ ├── JavaSslServerConfiguration.java │ │ ├── SessionAwareSslHandler.java │ │ ├── SslClientConfiguration.java │ │ ├── SslHandlerFactory.java │ │ ├── SslPlaintextHandler.java │ │ ├── SslServerConfiguration.java │ │ ├── SslSession.java │ │ └── TransportAttachObserver.java │ └── test │ └── java │ └── com │ └── facebook │ └── nifty │ └── core │ ├── AbstractLiveTest.java │ ├── TestConnectionContext.java │ ├── TestNettyConfigBuilder.java │ ├── TestNiftyTransport.java │ ├── TestServerDefBuilder.java │ └── TestThriftFrameDecoder.java ├── nifty-examples ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── facebook │ │ │ └── nifty │ │ │ ├── server │ │ │ └── Plain.java │ │ │ └── test │ │ │ ├── LogEntry.java │ │ │ ├── ResultCode.java │ │ │ └── scribe.java │ └── resources │ │ ├── README.txt │ │ ├── client.crt │ │ ├── client.key │ │ ├── client.pkcs12 │ │ ├── rsa.crt │ │ ├── rsa.key │ │ ├── rsa2.crt │ │ ├── rsa2.key │ │ ├── scribe.thrift │ │ ├── ticket_seeds.json │ │ └── ticket_seeds2.json │ └── test │ └── java │ ├── com │ └── facebook │ │ └── nifty │ │ └── server │ │ ├── DeafSelectorProvider.java │ │ ├── DelegateSelectorProvider.java │ │ ├── TestNiftyClient.java │ │ ├── TestNiftyClientTimeout.java │ │ ├── TestNiftyJavaSslServer.java │ │ ├── TestNiftyOpenSslServer.java │ │ ├── TestNiftyServer.java │ │ ├── TestPlainClient.java │ │ ├── TestPlainServer.java │ │ └── util │ │ └── ScopedNiftyServer.java │ └── org │ └── jboss │ └── netty │ └── handler │ └── ssl │ └── HackyJdkSslClientContext.java ├── nifty-load-tester ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── facebook │ │ └── nifty │ │ └── perf │ │ ├── LoadError.java │ │ ├── LoadTest.java │ │ ├── LoadTestHandler.java │ │ ├── LoadTesterNettyConfigProvider.java │ │ └── NiftyLoadTester.java │ └── resources │ ├── load.thrift │ └── logback.xml ├── nifty-ssl ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── facebook │ │ └── nifty │ │ └── ssl │ │ ├── BetterSslHandler.java │ │ ├── CryptoUtil.java │ │ ├── MultiFileWatcher.java │ │ ├── NettyTcNativeLoader.java │ │ ├── NiftyOpenSslServerContext.java │ │ ├── OpenSSLConstants.java │ │ ├── OpenSslServerConfiguration.java │ │ ├── OpenSslSessionHelper.java │ │ ├── PollingMultiFileWatcher.java │ │ ├── SslConfigFileWatcher.java │ │ ├── SslDefaults.java │ │ ├── ThreadLocalSslBufferPool.java │ │ └── TicketSeedFileParser.java │ └── test │ ├── java │ └── com │ │ └── facebook │ │ └── nifty │ │ └── ssl │ │ ├── CryptoUtilTest.java │ │ ├── PollingMultiFileWatcherTest.java │ │ ├── ThreadLocalSslBufferPoolTest.java │ │ └── TicketSeedFileParserTest.java │ └── resources │ ├── good_seeds.json │ ├── seeds_bad_json.json │ ├── seeds_with_no_current.json │ └── seeds_with_only_current.json ├── pom.xml └── src ├── findbugs └── findbugs-exclude-filter.xml └── license └── LICENSE-HEADER.txt /.arcconfig: -------------------------------------------------------------------------------- 1 | { 2 | "project_id" : "nifty", 3 | "conduit_uri" : "https://phabricator.fb.com/api/" 4 | } 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | pom.xml.versionsBackup 3 | test-output/ 4 | /atlassian-ide-plugin.x 5 | .idea/ 6 | .*.swo 7 | *~ 8 | *.swp 9 | *.iml 10 | *.ipr 11 | *.iws 12 | .DS_Store 13 | .project 14 | .classpath 15 | .settings 16 | eclipse-classes 17 | .arc 18 | *.releaseBackup 19 | release.properties 20 | dependency-reduced-pom.xml 21 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | Changes 2 | ======= 3 | 4 | * 0.11.0 5 | 6 | - Introduce receiveTimeout on NiftyClient and NiftyClientChannel 7 | - Changed the behaviour of readTimeout to measure the time that a 8 | server can not send a response at all. 9 | 10 | - Started CHANGES and NEWS files. 11 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | News 2 | ==== 3 | 4 | * 0.11.0 5 | 6 | The nifty client code has only one timeout when reading: readTimeout. 7 | 8 | It controls the amount of time that a client is willing for the server 9 | to complete a response. 10 | 11 | This release introduces a second timeout, receiveTimeout and changes 12 | the semantics of readTimeout: 13 | 14 | - receiveTimeout now reflects the amount of time that a client is 15 | willing to wait for the server complete a response. 16 | 17 | - readTimeout is the amount of a time that can pass without the server 18 | sending any data. 19 | 20 | In the most general sense, readTimeout is the maximum time to first 21 | byte and receiveTimeout is the maximum time to last byte for a 22 | response. However, readTimeout also controls the amount of time that a 23 | server can fall silent during sending out a response before the client 24 | times out. 25 | 26 | As long as a server makes progress and keeps sending out data 27 | continuously, the readTimeout will not fire. The receiveTimout will 28 | fire even if while the server sends data. 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Project Status: 🚨 Unmaintained 🚨 2 | 3 | This project is archived and no longer maintained. At the time of archiving, 4 | open issues and pull requests were closed and tagged with `2018-05-archive`. 5 | For pre-existing users who need an open source alternative, we recommend taking 6 | a look at [airlift/drift](https://github.com/airlift/drift). 7 | 8 | # Nifty 9 | 10 | Nifty is an implementation of [Thrift](http://thrift.apache.org/) clients and servers on [Netty](http://netty.io/). 11 | 12 | It is also the implementation used by [Swift](https://github.com/facebook/swift). 13 | 14 | # Examples 15 | 16 | To create a basic Thrift server using Nifty, use the [Thrift 0.9.0](https://dist.apache.org/repos/dist/release/thrift/0.9.0/thrift-0.9.0.tar.gz) code generator to generate Java stub code, write a Handler for your service interface, and pass it to Nifty like this: 17 | 18 | public void startServer() { 19 | // Create the handler 20 | MyService.Iface serviceInterface = new MyServiceHandler(); 21 | 22 | // Create the processor 23 | TProcessor processor = new MyService.Processor<>(serviceInterface); 24 | 25 | // Build the server definition 26 | ThriftServerDef serverDef = new ThriftServerDefBuilder().withProcessor(processor) 27 | .build(); 28 | 29 | // Create the server transport 30 | final NettyServerTransport server = new NettyServerTransport(serverDef, 31 | new NettyServerConfigBuilder(), 32 | new DefaultChannelGroup(), 33 | new HashedWheelTimer()); 34 | 35 | // Create netty boss and executor thread pools 36 | ExecutorService bossExecutor = Executors.newCachedThreadPool(); 37 | ExecutorService workerExecutor = Executors.newCachedThreadPool(); 38 | 39 | // Start the server 40 | server.start(bossExecutor, workerExecutor); 41 | 42 | // Arrange to stop the server at shutdown 43 | Runtime.getRuntime().addShutdownHook(new Thread() { 44 | @Override 45 | public void run() { 46 | try { 47 | server.stop(); 48 | } catch (InterruptedException e) { 49 | Thread.currentThread().interrupt(); 50 | } 51 | } 52 | }); 53 | } 54 | 55 | Or the same thing using guice: 56 | 57 | public void startGuiceServer() { 58 | final NiftyBootstrap bootstrap = Guice.createInjector( 59 | Stage.PRODUCTION, 60 | new NiftyModule() { 61 | @Override 62 | protected void configureNifty() { 63 | // Create the handler 64 | MyService.Iface serviceInterface = new MyServiceHandler(); 65 | 66 | // Create the processor 67 | TProcessor processor = new MyService.Processor<>(serviceInterface); 68 | 69 | // Build the server definition 70 | ThriftServerDef serverDef = new ThriftServerDefBuilder().withProcessor(processor) 71 | .build(); 72 | 73 | // Bind the definition 74 | bind().toInstance(serverDef); 75 | } 76 | }).getInstance(NiftyBootstrap.class); 77 | 78 | // Start the server 79 | bootstrap.start(); 80 | 81 | // Arrange to stop the server at shutdown 82 | Runtime.getRuntime().addShutdownHook(new Thread() { 83 | @Override 84 | public void run() { 85 | bootstrap.stop(); 86 | } 87 | }); 88 | } 89 | -------------------------------------------------------------------------------- /license/LICENSE-HEADER.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) ${year} Facebook, Inc. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | 15 | 16 | -------------------------------------------------------------------------------- /nifty-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 4.0.0 21 | 22 | 23 | com.facebook.nifty 24 | nifty-parent 25 | 0.24.0-SNAPSHOT 26 | ../pom.xml 27 | 28 | 29 | Nifty client 30 | nifty-client 31 | jar 32 | 33 | 34 | ${project.parent.basedir} 35 | 36 | 37 | 38 | 39 | com.facebook.nifty 40 | nifty-core 41 | 42 | 43 | 44 | com.google.guava 45 | guava 46 | 47 | 48 | 49 | org.apache.thrift 50 | libthrift 51 | true 52 | 53 | 54 | 55 | com.google.inject 56 | guice 57 | 58 | 59 | 60 | com.google.code.findbugs 61 | annotations 62 | 63 | 64 | 65 | io.airlift 66 | units 67 | 68 | 69 | 70 | io.netty 71 | netty 72 | 73 | 74 | 75 | io.airlift 76 | log 77 | 78 | 79 | 80 | org.easymock 81 | easymock 82 | test 83 | 84 | 85 | 86 | org.testng 87 | testng 88 | test 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/AbstractClientConnector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import com.facebook.nifty.client.socks.Socks4ClientBootstrap; 19 | import com.facebook.nifty.duplex.TDuplexProtocolFactory; 20 | import com.google.common.net.HostAndPort; 21 | import org.apache.thrift.protocol.TBinaryProtocol; 22 | import org.jboss.netty.bootstrap.ClientBootstrap; 23 | import org.jboss.netty.channel.ChannelFuture; 24 | 25 | import java.net.InetSocketAddress; 26 | import java.net.SocketAddress; 27 | 28 | public abstract class AbstractClientConnector 29 | implements NiftyClientConnector 30 | { 31 | protected final SocketAddress address; 32 | private final TDuplexProtocolFactory protocolFactory; 33 | private volatile SocketAddress resolvedAddress; 34 | 35 | public AbstractClientConnector(SocketAddress address, TDuplexProtocolFactory protocolFactory) 36 | { 37 | this.address = address; 38 | this.protocolFactory = protocolFactory; 39 | } 40 | 41 | @Override 42 | public ChannelFuture connect(ClientBootstrap bootstrap) 43 | { 44 | if (bootstrap instanceof Socks4ClientBootstrap) { 45 | return bootstrap.connect(address); 46 | } 47 | 48 | if (resolvedAddress == null) { 49 | resolvedAddress = resolvedAddress((InetSocketAddress) address); 50 | } 51 | return bootstrap.connect(resolvedAddress); 52 | } 53 | 54 | @Override 55 | public String toString() 56 | { 57 | return address.toString(); 58 | } 59 | 60 | protected TDuplexProtocolFactory getProtocolFactory() 61 | { 62 | return protocolFactory; 63 | } 64 | 65 | protected static SocketAddress toSocketAddress(HostAndPort address) 66 | { 67 | return InetSocketAddress.createUnresolved(address.getHostText(), address.getPort()); 68 | } 69 | 70 | protected static TDuplexProtocolFactory defaultProtocolFactory() 71 | { 72 | return TDuplexProtocolFactory.fromSingleFactory(new TBinaryProtocol.Factory()); 73 | } 74 | 75 | private static InetSocketAddress resolvedAddress(InetSocketAddress address) 76 | { 77 | if (!address.isUnresolved()) { 78 | return address; 79 | } 80 | return new InetSocketAddress(address.getHostString(), address.getPort()); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/ClientRequestContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import org.apache.thrift.protocol.TProtocol; 19 | 20 | import java.net.SocketAddress; 21 | 22 | public interface ClientRequestContext 23 | { 24 | TProtocol getOutputProtocol(); 25 | 26 | TProtocol getInputProtocol(); 27 | 28 | RequestChannel getRequestChannel(); 29 | 30 | SocketAddress getRemoteAddress(); 31 | } 32 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/FramedClientChannel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import com.facebook.nifty.duplex.TDuplexProtocolFactory; 19 | import org.jboss.netty.buffer.ChannelBuffer; 20 | import org.jboss.netty.channel.Channel; 21 | import org.jboss.netty.channel.ChannelFuture; 22 | import org.jboss.netty.util.Timer; 23 | 24 | import javax.annotation.concurrent.NotThreadSafe; 25 | 26 | @NotThreadSafe 27 | public class FramedClientChannel extends AbstractClientChannel { 28 | protected FramedClientChannel(Channel channel, Timer timer, TDuplexProtocolFactory protocolFactory) { 29 | super(channel, timer, protocolFactory); 30 | } 31 | 32 | @Override 33 | protected ChannelBuffer extractResponse(Object message) { 34 | if (!(message instanceof ChannelBuffer)) { 35 | return null; 36 | } 37 | 38 | ChannelBuffer buffer = (ChannelBuffer) message; 39 | if (!buffer.readable()) { 40 | return null; 41 | } 42 | 43 | return buffer; 44 | } 45 | 46 | @Override 47 | protected ChannelFuture writeRequest(ChannelBuffer request) { 48 | return getNettyChannel().write(request); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/NettyClientConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import com.facebook.nifty.ssl.SslClientConfiguration; 19 | import com.google.common.net.HostAndPort; 20 | import org.jboss.netty.util.Timer; 21 | 22 | import java.util.Map; 23 | import java.util.concurrent.ExecutorService; 24 | 25 | public class NettyClientConfig 26 | { 27 | private final Map bootstrapOptions; 28 | private final HostAndPort defaultSocksProxyAddress; 29 | private final Timer timer; 30 | private final ExecutorService bossExecutor; 31 | private final int bossThreadCount; 32 | private final ExecutorService workerExecutor; 33 | private final int workerThreadCount; 34 | private final SslClientConfiguration sslClientConfiguration; 35 | 36 | public NettyClientConfig(Map bootstrapOptions, 37 | HostAndPort defaultSocksProxyAddress, 38 | Timer timer, 39 | ExecutorService bossExecutor, 40 | int bossThreadCount, 41 | ExecutorService workerExecutor, 42 | int workerThreadCount, 43 | SslClientConfiguration sslClientConfiguration) 44 | 45 | { 46 | this.bootstrapOptions = bootstrapOptions; 47 | this.defaultSocksProxyAddress = defaultSocksProxyAddress; 48 | this.timer = timer; 49 | this.bossExecutor = bossExecutor; 50 | this.bossThreadCount = bossThreadCount; 51 | this.workerExecutor = workerExecutor; 52 | this.workerThreadCount = workerThreadCount; 53 | this.sslClientConfiguration = sslClientConfiguration; 54 | } 55 | 56 | public Map getBootstrapOptions() 57 | { 58 | return bootstrapOptions; 59 | } 60 | 61 | public ExecutorService getBossExecutor() 62 | { 63 | return bossExecutor; 64 | } 65 | 66 | public int getBossThreadCount() 67 | { 68 | return bossThreadCount; 69 | } 70 | 71 | public HostAndPort getDefaultSocksProxyAddress() 72 | { 73 | return defaultSocksProxyAddress; 74 | } 75 | 76 | public Timer getTimer() 77 | { 78 | return timer; 79 | } 80 | 81 | public ExecutorService getWorkerExecutor() 82 | { 83 | return workerExecutor; 84 | } 85 | 86 | public int getWorkerThreadCount() 87 | { 88 | return workerThreadCount; 89 | } 90 | 91 | public static NettyClientConfigBuilder newBuilder() 92 | { 93 | return new NettyClientConfigBuilder(); 94 | } 95 | 96 | public SslClientConfiguration sslClientConfiguration() { return sslClientConfiguration; } 97 | } 98 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/NiftyClientChannel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import com.facebook.nifty.duplex.TDuplexProtocolFactory; 19 | import io.airlift.units.Duration; 20 | import org.apache.thrift.TException; 21 | import org.jboss.netty.buffer.ChannelBuffer; 22 | import org.jboss.netty.channel.Channel; 23 | 24 | import javax.annotation.Nullable; 25 | 26 | public interface NiftyClientChannel extends RequestChannel { 27 | /** 28 | * Sets a timeout used to limit elapsed time for sending a message. 29 | * 30 | * @param sendTimeout 31 | */ 32 | void setSendTimeout(@Nullable Duration sendTimeout); 33 | 34 | /** 35 | * Returns the timeout most recently set by 36 | * {@link NiftyClientChannel#setSendTimeout(io.airlift.units.Duration)} 37 | * 38 | * @return 39 | */ 40 | Duration getSendTimeout(); 41 | 42 | /** 43 | * Sets a timeout used to limit elapsed time between successful send, and reception of the 44 | * response. 45 | * 46 | * @param receiveTimeout 47 | */ 48 | void setReceiveTimeout(@Nullable Duration receiveTimeout); 49 | 50 | /** 51 | * Returns the timeout most recently set by 52 | * {@link NiftyClientChannel#setReceiveTimeout(io.airlift.units.Duration)} 53 | * 54 | * @return 55 | */ 56 | Duration getReceiveTimeout(); 57 | 58 | /** 59 | * Sets a timeout used to limit the time that the client waits for data to be sent by the server. 60 | * 61 | * @param readTimeout 62 | */ 63 | void setReadTimeout(@Nullable Duration readTimeout); 64 | 65 | /** 66 | * Returns the timeout most recently set by 67 | * {@link NiftyClientChannel#setReadTimeout(io.airlift.units.Duration)} 68 | * 69 | * @return 70 | */ 71 | Duration getReadTimeout(); 72 | 73 | /** 74 | * Executes the given {@link Runnable} on the I/O thread that manages reads/writes for this 75 | * channel. 76 | * 77 | * @param runnable 78 | */ 79 | void executeInIoThread(Runnable runnable); 80 | 81 | Channel getNettyChannel(); 82 | } 83 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/NiftyClientChannelPipelineFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import org.jboss.netty.channel.ChannelPipeline; 19 | import org.jboss.netty.channel.ChannelPipelineFactory; 20 | import org.jboss.netty.channel.Channels; 21 | import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; 22 | import org.jboss.netty.handler.codec.frame.LengthFieldPrepender; 23 | 24 | class NiftyClientChannelPipelineFactory implements ChannelPipelineFactory 25 | { 26 | private final int maxFrameSize; 27 | 28 | NiftyClientChannelPipelineFactory(int maxFrameSize) 29 | { 30 | this.maxFrameSize = maxFrameSize; 31 | } 32 | 33 | @Override 34 | public ChannelPipeline getPipeline() 35 | throws Exception 36 | { 37 | ChannelPipeline cp = Channels.pipeline(); 38 | cp.addLast("frameEncoder", new LengthFieldPrepender(4)); 39 | cp.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(maxFrameSize, 0, 4, 0, 4)); 40 | return cp; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/NiftyClientConnector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import org.jboss.netty.bootstrap.ClientBootstrap; 19 | import org.jboss.netty.channel.Channel; 20 | import org.jboss.netty.channel.ChannelFuture; 21 | import org.jboss.netty.channel.ChannelPipelineFactory; 22 | import org.jboss.netty.util.Timer; 23 | 24 | public interface NiftyClientConnector { 25 | ChannelFuture connect(ClientBootstrap bootstrap); 26 | 27 | T newThriftClientChannel(Channel channel, NettyClientConfig clientConfig); 28 | 29 | ChannelPipelineFactory newChannelPipelineFactory(int maxFrameSize, NettyClientConfig clientConfig); 30 | } 31 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/NiftyClientRequestContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import org.apache.thrift.protocol.TProtocol; 19 | 20 | import java.net.SocketAddress; 21 | 22 | public class NiftyClientRequestContext implements ClientRequestContext{ 23 | private final TProtocol inputProtocol; 24 | private final TProtocol outputProtocol; 25 | private final RequestChannel requestChannel; 26 | private final SocketAddress remoteAddress; 27 | 28 | public NiftyClientRequestContext(TProtocol inputProtocol, 29 | TProtocol outputProtocol, 30 | RequestChannel requestChannel, 31 | SocketAddress remoteAddress) 32 | { 33 | this.inputProtocol = inputProtocol; 34 | this.outputProtocol = outputProtocol; 35 | this.requestChannel = requestChannel; 36 | this.remoteAddress = remoteAddress; 37 | } 38 | 39 | @Override 40 | public TProtocol getOutputProtocol() 41 | { 42 | return outputProtocol; 43 | } 44 | 45 | @Override 46 | public TProtocol getInputProtocol() 47 | { 48 | return inputProtocol; 49 | } 50 | 51 | @Override 52 | public RequestChannel getRequestChannel() 53 | { 54 | return requestChannel; 55 | } 56 | 57 | @Override 58 | public SocketAddress getRemoteAddress() 59 | { 60 | return remoteAddress; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/NiftyClientSecurityFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import com.facebook.nifty.core.NettyServerConfig; 19 | import com.facebook.nifty.core.NiftySecurityHandlers; 20 | 21 | public interface NiftyClientSecurityFactory 22 | { 23 | NiftySecurityHandlers getSecurityHandlers(int maxFrameSize, NettyClientConfig clientConfig); 24 | } 25 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/NiftyNoOpClientSecurityFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import com.facebook.nifty.core.NiftySecurityHandlers; 19 | import org.jboss.netty.channel.ChannelHandler; 20 | import org.jboss.netty.channel.ChannelHandlerContext; 21 | import org.jboss.netty.channel.ChannelStateEvent; 22 | import org.jboss.netty.channel.SimpleChannelHandler; 23 | 24 | public class NiftyNoOpClientSecurityFactory implements NiftyClientSecurityFactory 25 | { 26 | static final ChannelHandler noOpHandler = new SimpleChannelHandler() { 27 | @Override 28 | public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception 29 | { 30 | super.channelOpen(ctx, e); 31 | ctx.getPipeline().remove(this); 32 | } 33 | }; 34 | 35 | @Override 36 | public NiftySecurityHandlers getSecurityHandlers(int maxFrameSize, NettyClientConfig clientConfig) 37 | { 38 | return new NiftySecurityHandlers() 39 | { 40 | @Override 41 | public ChannelHandler getAuthenticationHandler() 42 | { 43 | return noOpHandler; 44 | } 45 | 46 | @Override 47 | public ChannelHandler getEncryptionHandler() 48 | { 49 | return noOpHandler; 50 | } 51 | }; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/RequestChannel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import com.facebook.nifty.duplex.TDuplexProtocolFactory; 19 | import org.apache.thrift.TException; 20 | import org.jboss.netty.buffer.ChannelBuffer; 21 | 22 | public interface RequestChannel 23 | { 24 | /** 25 | * Sends a single message asynchronously, and notifies the {@link Listener} 26 | * when the request is finished sending, when the response has arrived, and/or when an error 27 | * occurs. 28 | * 29 | * @param request 30 | * @param oneway 31 | * @param listener 32 | * @throws TException 33 | */ 34 | void sendAsynchronousRequest(final ChannelBuffer request, 35 | final boolean oneway, 36 | final Listener listener) 37 | throws TException; 38 | 39 | /** 40 | * Closes the channel 41 | */ 42 | void close(); 43 | 44 | /** 45 | * Checks whether the channel has encountered an error. This method is a shortcut for: 46 | * 47 | * 48 | * return (getError() != null); 49 | * 50 | * 51 | * @return {@code true} if the {@link RequestChannel} is broken 52 | */ 53 | boolean hasError(); 54 | 55 | /** 56 | * Returns the {@link TException} representing the error the channel encountered, if any. 57 | * 58 | * @return An instance of {@link TException} or {@code null} if the channel is still good. 59 | */ 60 | TException getError(); 61 | 62 | /** 63 | * Returns the {@link TDuplexProtocolFactory} that should be used by clients code to 64 | * serialize messages for sending on this channel 65 | * 66 | * @return An instance of {@link TDuplexProtocolFactory} 67 | */ 68 | TDuplexProtocolFactory getProtocolFactory(); 69 | 70 | /** 71 | * The listener interface that must be implemented for callback objects passed to 72 | * {@link #sendAsynchronousRequest} 73 | */ 74 | public interface Listener { 75 | /** 76 | * This will be called when the request has successfully been written to the transport 77 | * layer (e.g. socket) 78 | */ 79 | void onRequestSent(); 80 | 81 | /** 82 | * This will be called when a full response to the request has been received 83 | * 84 | * @param message The response buffer 85 | */ 86 | void onResponseReceived(ChannelBuffer message); 87 | 88 | /** 89 | * This will be called if the channel encounters an error before the request is sent or 90 | * before a response is received 91 | * 92 | * @param requestException A {@link TException} describing the problem that was encountered 93 | */ 94 | void onChannelError(TException requestException); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/TNiftyClientAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import org.jboss.netty.buffer.ChannelBuffer; 19 | import org.jboss.netty.channel.Channel; 20 | import org.jboss.netty.channel.ExceptionEvent; 21 | 22 | public abstract class TNiftyClientAdapter implements TNiftyClientListener 23 | { 24 | @Override 25 | public void onFrameRead(Channel channel, ChannelBuffer buffer) 26 | { 27 | onInput(new TNiftyReadOnlyTransport(channel, buffer)); 28 | } 29 | 30 | @Override 31 | public void onChannelClosedOrDisconnected(Channel channel) 32 | { 33 | } 34 | 35 | @Override 36 | public void onExceptionEvent(ExceptionEvent e) 37 | { 38 | } 39 | 40 | /** 41 | * called when a frame is ready to be read. 42 | * 43 | * @param tNiftyReadOnlyTransport a one-time-use transport for the frame 44 | */ 45 | public abstract void onInput(TNiftyReadOnlyTransport tNiftyReadOnlyTransport); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/TNiftyClientListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import org.jboss.netty.buffer.ChannelBuffer; 19 | import org.jboss.netty.channel.Channel; 20 | import org.jboss.netty.channel.ExceptionEvent; 21 | 22 | public interface TNiftyClientListener 23 | { 24 | /** 25 | * Called when a full frame as defined in TFramedTransport is available. 26 | * 27 | * @param channel the channel 28 | * @param buffer the payload of the frame, without the leading 4-bytes length header 29 | */ 30 | void onFrameRead(Channel channel, ChannelBuffer buffer); 31 | 32 | void onChannelClosedOrDisconnected(Channel channel); 33 | 34 | void onExceptionEvent(ExceptionEvent e); 35 | } 36 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/TNiftyReadOnlyTransport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import org.apache.thrift.transport.TTransport; 19 | import org.apache.thrift.transport.TTransportException; 20 | import org.jboss.netty.buffer.ChannelBuffer; 21 | import org.jboss.netty.channel.Channel; 22 | 23 | /** 24 | * Wraps incoming channel buffer into TTransport. 25 | */ 26 | public class TNiftyReadOnlyTransport extends TTransport 27 | { 28 | private final Channel channel; 29 | private final ChannelBuffer in; 30 | 31 | public TNiftyReadOnlyTransport(Channel channel, ChannelBuffer in) 32 | { 33 | this.channel = channel; 34 | this.in = in; 35 | } 36 | 37 | @Override 38 | public boolean isOpen() 39 | { 40 | return channel.isOpen(); 41 | } 42 | 43 | @Override 44 | public void open() 45 | throws TTransportException 46 | { 47 | // no-op 48 | } 49 | 50 | @Override 51 | public void close() 52 | { 53 | // no-op 54 | channel.close(); 55 | } 56 | 57 | @Override 58 | public int read(byte[] bytes, int offset, int length) 59 | throws TTransportException 60 | { 61 | int _read = Math.min(in.readableBytes(), length); 62 | in.readBytes(bytes, offset, _read); 63 | return _read; 64 | } 65 | 66 | @Override 67 | public void write(byte[] bytes, int offset, int length) 68 | throws TTransportException 69 | { 70 | throw new UnsupportedOperationException(); 71 | } 72 | 73 | @Override 74 | public void flush() 75 | throws TTransportException 76 | { 77 | throw new UnsupportedOperationException(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/TimeoutHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import org.jboss.netty.channel.ChannelDownstreamHandler; 19 | import org.jboss.netty.channel.ChannelEvent; 20 | import org.jboss.netty.channel.ChannelHandlerContext; 21 | import org.jboss.netty.channel.ChannelPipeline; 22 | import org.jboss.netty.channel.ChannelUpstreamHandler; 23 | import org.jboss.netty.channel.MessageEvent; 24 | 25 | import static com.google.common.base.Preconditions.checkNotNull; 26 | 27 | public final class TimeoutHandler implements ChannelUpstreamHandler, ChannelDownstreamHandler 28 | { 29 | private static final String NAME = "_TIMEOUT_HANDLER"; 30 | 31 | private volatile long lastMessageReceivedNanos = 0L; 32 | private volatile long lastMessageSentNanos = 0L; 33 | 34 | public static synchronized void addToPipeline(ChannelPipeline cp) 35 | { 36 | checkNotNull(cp, "cp is null"); 37 | if (cp.get(NAME) == null) { 38 | cp.addFirst(NAME, new TimeoutHandler()); 39 | } 40 | } 41 | 42 | public static TimeoutHandler findTimeoutHandler(ChannelPipeline cp) 43 | { 44 | return (TimeoutHandler) cp.get(NAME); 45 | } 46 | 47 | private TimeoutHandler() 48 | { 49 | } 50 | 51 | @Override 52 | public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) 53 | throws Exception 54 | { 55 | if (e instanceof MessageEvent) { 56 | lastMessageReceivedNanos = System.nanoTime(); 57 | } 58 | ctx.sendUpstream(e); 59 | } 60 | 61 | @Override 62 | public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e) 63 | throws Exception 64 | { 65 | if (e instanceof MessageEvent) { 66 | lastMessageSentNanos = System.nanoTime(); 67 | } 68 | ctx.sendDownstream(e); 69 | } 70 | 71 | public long getLastMessageReceivedNanos() 72 | { 73 | return lastMessageReceivedNanos; 74 | } 75 | 76 | public long getLastMessageSentNanos() 77 | { 78 | return lastMessageSentNanos; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/UnframedClientChannel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import com.facebook.nifty.duplex.TDuplexProtocolFactory; 19 | import org.jboss.netty.buffer.ChannelBuffer; 20 | import org.jboss.netty.channel.Channel; 21 | import org.jboss.netty.channel.ChannelFuture; 22 | import org.jboss.netty.util.Timer; 23 | 24 | import javax.annotation.concurrent.NotThreadSafe; 25 | 26 | @NotThreadSafe 27 | public class UnframedClientChannel extends AbstractClientChannel { 28 | protected UnframedClientChannel(Channel channel, Timer timer, TDuplexProtocolFactory protocolFactory) { 29 | super(channel, timer, protocolFactory); 30 | } 31 | 32 | @Override 33 | protected ChannelBuffer extractResponse(Object message) { 34 | if (!(message instanceof ChannelBuffer)) { 35 | return null; 36 | } 37 | 38 | ChannelBuffer buffer = (ChannelBuffer) message; 39 | if (!buffer.readable()) { 40 | return null; 41 | } 42 | 43 | return buffer; 44 | } 45 | 46 | @Override 47 | protected ChannelFuture writeRequest(ChannelBuffer request) { 48 | return getNettyChannel().write(request); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/UnframedClientConnector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import com.facebook.nifty.core.ThriftUnframedDecoder; 19 | import com.facebook.nifty.duplex.TDuplexProtocolFactory; 20 | import com.google.common.net.HostAndPort; 21 | import org.jboss.netty.channel.Channel; 22 | import org.jboss.netty.channel.ChannelPipeline; 23 | import org.jboss.netty.channel.ChannelPipelineFactory; 24 | import org.jboss.netty.channel.Channels; 25 | 26 | import java.net.InetSocketAddress; 27 | 28 | public class UnframedClientConnector extends AbstractClientConnector { 29 | public UnframedClientConnector(InetSocketAddress address) 30 | { 31 | this(address, defaultProtocolFactory()); 32 | } 33 | 34 | public UnframedClientConnector(HostAndPort address) 35 | { 36 | this(address, defaultProtocolFactory()); 37 | } 38 | 39 | public UnframedClientConnector(InetSocketAddress address, TDuplexProtocolFactory protocolFactory) 40 | { 41 | super(address, protocolFactory); 42 | } 43 | 44 | public UnframedClientConnector(HostAndPort address, TDuplexProtocolFactory protocolFactory) 45 | { 46 | super(toSocketAddress(address), protocolFactory); 47 | } 48 | 49 | @Override 50 | public UnframedClientChannel newThriftClientChannel(Channel nettyChannel, NettyClientConfig clientConfig) 51 | { 52 | UnframedClientChannel channel = new UnframedClientChannel(nettyChannel, clientConfig.getTimer(), getProtocolFactory()); 53 | ChannelPipeline cp = nettyChannel.getPipeline(); 54 | TimeoutHandler.addToPipeline(cp); 55 | cp.addLast("thriftHandler", channel); 56 | return channel; 57 | } 58 | 59 | @Override 60 | public ChannelPipelineFactory newChannelPipelineFactory(final int maxFrameSize, NettyClientConfig clientConfig) 61 | { 62 | return new ChannelPipelineFactory() { 63 | @Override 64 | public ChannelPipeline getPipeline() 65 | throws Exception { 66 | ChannelPipeline cp = Channels.pipeline(); 67 | TimeoutHandler.addToPipeline(cp); 68 | cp.addLast("thriftUnframedDecoder", new ThriftUnframedDecoder()); 69 | if (clientConfig.sslClientConfiguration() != null) { 70 | cp.addFirst("ssl", clientConfig.sslClientConfiguration().createHandler(address)); 71 | } 72 | return cp; 73 | } 74 | }; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/socks/SettableChannelFuture.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client.socks; 17 | 18 | import org.jboss.netty.channel.Channel; 19 | import org.jboss.netty.channel.DefaultChannelFuture; 20 | 21 | /** 22 | * A channel future that allow channel to be set at a later time. 23 | */ 24 | public class SettableChannelFuture extends DefaultChannelFuture 25 | { 26 | private Channel settableChannel = null; 27 | private boolean channelIsSet = false; 28 | 29 | public SettableChannelFuture() 30 | { 31 | super(null, false); 32 | } 33 | 34 | public void setChannel(Channel channel) 35 | { 36 | if (!channelIsSet) { 37 | this.settableChannel = channel; 38 | this.channelIsSet = true; 39 | } 40 | } 41 | 42 | @Override 43 | public Channel getChannel() 44 | { 45 | return this.settableChannel; 46 | } 47 | 48 | @Override 49 | public boolean setFailure(Throwable cause) 50 | { 51 | if (!this.channelIsSet) { 52 | throw new IllegalStateException("channel not set yet !"); 53 | } 54 | return super.setFailure(cause); 55 | } 56 | 57 | @Override 58 | public boolean setSuccess() 59 | { 60 | if (!this.channelIsSet) { 61 | throw new IllegalStateException("channel not set yet !"); 62 | } 63 | return super.setSuccess(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/socks/Socks4HandshakeHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client.socks; 17 | 18 | import org.jboss.netty.buffer.ChannelBuffer; 19 | import org.jboss.netty.channel.ChannelHandlerContext; 20 | import org.jboss.netty.channel.ChannelPipeline; 21 | import org.jboss.netty.channel.ChannelPipelineFactory; 22 | import org.jboss.netty.channel.ExceptionEvent; 23 | import org.jboss.netty.channel.MessageEvent; 24 | import org.jboss.netty.channel.SimpleChannelHandler; 25 | 26 | import java.io.IOException; 27 | import java.net.InetAddress; 28 | import java.net.InetSocketAddress; 29 | 30 | /** 31 | * This handshake handler swap out the channel pipeline with the delegate 32 | * upon handshake completion. 33 | */ 34 | public class Socks4HandshakeHandler extends SimpleChannelHandler 35 | { 36 | private final SettableChannelFuture channelFuture = new SettableChannelFuture(); 37 | private final ChannelPipelineFactory delegate; 38 | 39 | public Socks4HandshakeHandler(ChannelPipelineFactory delegate) 40 | { 41 | this.delegate = delegate; 42 | } 43 | 44 | public SettableChannelFuture getChannelFuture() 45 | { 46 | return channelFuture; 47 | } 48 | 49 | @Override 50 | public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) 51 | throws Exception 52 | { 53 | channelFuture.setChannel(ctx.getChannel()); 54 | if (e.getMessage() instanceof ChannelBuffer) { 55 | ChannelBuffer msg = (ChannelBuffer) e.getMessage(); 56 | if (msg.readableBytes() < 8) { 57 | channelFuture.setFailure(new IOException("invalid sock server reply length = " + msg.readableBytes())); 58 | } 59 | // ignore 60 | msg.readByte(); 61 | int status = msg.readByte(); 62 | int port = msg.readShort(); 63 | byte[] addr = new byte[4]; 64 | msg.readBytes(addr); 65 | 66 | ctx.getChannel().setAttachment(new InetSocketAddress(InetAddress.getByAddress(addr), port)); 67 | 68 | if (status == SocksProtocols.REQUEST_GRANTED) { 69 | ctx.getPipeline().remove(Socks4ClientBootstrap.FRAME_DECODER); 70 | ctx.getPipeline().remove(Socks4ClientBootstrap.HANDSHAKE); 71 | ChannelPipeline delegatePipeline = delegate.getPipeline(); 72 | for (String name : delegatePipeline.getNames()) { 73 | ctx.getPipeline().addLast(name, delegatePipeline.get(name)); 74 | } 75 | channelFuture.setSuccess(); 76 | } 77 | else { 78 | channelFuture.setFailure(new IOException("sock server reply failure code :" + Integer.toHexString(status))); 79 | } 80 | } 81 | } 82 | 83 | @Override 84 | public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) 85 | throws Exception 86 | { 87 | channelFuture.setChannel(ctx.getChannel()); 88 | channelFuture.setFailure(e.getCause()); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /nifty-client/src/main/java/com/facebook/nifty/client/socks/SocksProtocols.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client.socks; 17 | 18 | import com.google.common.base.Charsets; 19 | import org.jboss.netty.buffer.ChannelBuffer; 20 | import org.jboss.netty.buffer.ChannelBuffers; 21 | 22 | import java.net.InetAddress; 23 | 24 | /** 25 | * static helper for dealing with socks protocol. 26 | * 27 | * @see http://en.wikipedia.org/wiki/SOCKS 28 | * @see SOCKS Protocol Version 4 29 | */ 30 | public class SocksProtocols 31 | { 32 | public static final int SOCKS_VERSION_4 = 0x04; 33 | public static final int CONNECT = 0x01; 34 | public static final int REQUEST_GRANTED = 0x5a; 35 | public static final int REQUEST_FAILED = 0x5b; 36 | public static final int REQUEST_FAILED_NO_IDENTD = 0x5c; 37 | public static final int REQUEST_FAILED_USERID_NOT_CONFIRMED = 0x5d; 38 | 39 | public static ChannelBuffer createSocks4packet(InetAddress address, int port) 40 | { 41 | if (address == null) { 42 | throw new IllegalArgumentException("address is null"); 43 | } 44 | ChannelBuffer handshake = ChannelBuffers.dynamicBuffer(9); 45 | handshake.writeByte(SOCKS_VERSION_4); // SOCKS version 46 | handshake.writeByte(CONNECT); // CONNECT 47 | handshake.writeShort(port); // port 48 | handshake.writeBytes(address.getAddress()); // remote address to connect to 49 | handshake.writeByte(0x00); // empty user (null terminated) 50 | return handshake; 51 | } 52 | 53 | public static ChannelBuffer createSock4aPacket(String hostName, int port) 54 | { 55 | if (hostName == null) { 56 | throw new IllegalArgumentException("hostName is null"); 57 | } 58 | byte[] hostNameBytes = hostName.getBytes(Charsets.ISO_8859_1); 59 | ChannelBuffer handshake = ChannelBuffers.dynamicBuffer(10 + hostNameBytes.length); 60 | handshake.writeByte(SOCKS_VERSION_4); // SOCKS version 61 | handshake.writeByte(CONNECT); // CONNECT 62 | handshake.writeShort(port); // port 63 | handshake.writeByte(0x00); // fake ip 64 | handshake.writeByte(0x00); // fake ip 65 | handshake.writeByte(0x00); // fake ip 66 | handshake.writeByte(0x01); // fake ip 67 | handshake.writeByte(0x00); // empty user (null terminated) 68 | handshake.writeBytes(hostNameBytes); // remote host name to connect to 69 | handshake.writeByte(0x00); // null terminating the string 70 | return handshake; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /nifty-client/src/test/java/com/facebook/nifty/client/TestHttpClientConnector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.client; 17 | 18 | import org.testng.annotations.Test; 19 | 20 | import java.net.URI; 21 | import java.net.URISyntaxException; 22 | 23 | import static org.testng.Assert.assertEquals; 24 | 25 | public class TestHttpClientConnector 26 | { 27 | @Test 28 | public void testBasicUri() 29 | { 30 | new HttpClientConnector(URI.create("http://good.com/foo")); 31 | } 32 | 33 | @Test 34 | public void testUriWithUppercaseValidScheme() 35 | { 36 | new HttpClientConnector(URI.create("HTTP://good.com/foo")); 37 | } 38 | 39 | @Test 40 | public void testUriWithHttpsScheme() 41 | { 42 | new HttpClientConnector(URI.create("https://good.com/foo")); 43 | } 44 | 45 | @Test 46 | public void testUriWithExplicitHttpPort() 47 | { 48 | new HttpClientConnector(URI.create("http://good.com:8000/foo")); 49 | } 50 | 51 | @Test 52 | public void testUriWithExplicitHttpsPort() 53 | { 54 | new HttpClientConnector(URI.create("https://good.com:80/foo")); 55 | } 56 | 57 | @Test(expectedExceptions = { IllegalArgumentException.class }) 58 | public void testUriWithTooLongPortNumber() 59 | { 60 | new HttpClientConnector(URI.create("https://good.com:8888888/foo")); 61 | } 62 | 63 | @Test(expectedExceptions = { IllegalArgumentException.class }) 64 | public void testUriWithInvalidScheme() 65 | { 66 | new HttpClientConnector(URI.create("ftp://good.com/foo")); 67 | } 68 | 69 | @Test 70 | public void testHostNameAndPortWithServicePath() throws URISyntaxException 71 | { 72 | HttpClientConnector connector = new HttpClientConnector("good.com:1234", "/foo"); 73 | assertEquals(connector.toString(), "http://good.com:1234/foo"); 74 | } 75 | 76 | @Test 77 | public void testHostNameAndDefaultPortWithServicePath() throws URISyntaxException 78 | { 79 | HttpClientConnector connector = new HttpClientConnector("good.com", "/foo"); 80 | assertEquals(connector.toString(), "http://good.com/foo"); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /nifty-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 4.0.0 21 | 22 | 23 | com.facebook.nifty 24 | nifty-parent 25 | 0.24.0-SNAPSHOT 26 | ../pom.xml 27 | 28 | 29 | Nifty Core 30 | nifty-core 31 | jar 32 | 33 | 34 | ${project.parent.basedir} 35 | 36 | 37 | 38 | 39 | javax.inject 40 | javax.inject 41 | 42 | 43 | 44 | com.google.guava 45 | guava 46 | 47 | 48 | 49 | com.google.inject 50 | guice 51 | 52 | 53 | 54 | com.google.inject.extensions 55 | guice-multibindings 56 | 57 | 58 | 59 | io.airlift 60 | units 61 | 62 | 63 | 64 | io.netty 65 | netty 66 | 67 | 68 | 69 | org.apache.thrift 70 | libthrift 71 | true 72 | 73 | 74 | 75 | io.airlift 76 | log 77 | 78 | 79 | 80 | com.google.code.findbugs 81 | annotations 82 | 83 | 84 | 85 | org.easymock 86 | easymock 87 | test 88 | 89 | 90 | 91 | org.testng 92 | testng 93 | test 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/codec/DefaultThriftFrameCodec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.codec; 17 | 18 | import org.apache.thrift.protocol.TProtocolFactory; 19 | import org.jboss.netty.channel.ChannelEvent; 20 | import org.jboss.netty.channel.ChannelHandlerContext; 21 | 22 | public class DefaultThriftFrameCodec implements ThriftFrameCodec 23 | { 24 | private final ThriftFrameDecoder decoder; 25 | private final ThriftFrameEncoder encoder; 26 | 27 | public DefaultThriftFrameCodec(int maxFrameSize, TProtocolFactory inputProtocolFactory) 28 | { 29 | this.decoder = new DefaultThriftFrameDecoder(maxFrameSize, inputProtocolFactory); 30 | this.encoder = new DefaultThriftFrameEncoder(maxFrameSize); 31 | } 32 | 33 | @Override 34 | public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception 35 | { 36 | encoder.handleDownstream(ctx, e); 37 | } 38 | 39 | @Override 40 | public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception 41 | { 42 | decoder.handleUpstream(ctx, e); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/codec/DefaultThriftFrameCodecFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.codec; 17 | 18 | import org.apache.thrift.protocol.TProtocolFactory; 19 | import org.jboss.netty.channel.ChannelHandler; 20 | 21 | public class DefaultThriftFrameCodecFactory implements ThriftFrameCodecFactory 22 | { 23 | @Override 24 | public ChannelHandler create(int maxFrameSize, TProtocolFactory defaultProtocolFactory) 25 | { 26 | return new DefaultThriftFrameCodec(maxFrameSize, defaultProtocolFactory); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/codec/DefaultThriftFrameEncoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.codec; 17 | 18 | import com.facebook.nifty.core.ThriftMessage; 19 | import org.jboss.netty.buffer.ChannelBuffer; 20 | import org.jboss.netty.buffer.ChannelBuffers; 21 | import org.jboss.netty.channel.Channel; 22 | import org.jboss.netty.channel.ChannelHandlerContext; 23 | import org.jboss.netty.channel.Channels; 24 | import org.jboss.netty.handler.codec.frame.TooLongFrameException; 25 | 26 | public class DefaultThriftFrameEncoder extends ThriftFrameEncoder 27 | { 28 | private final long maxFrameSize; 29 | 30 | public DefaultThriftFrameEncoder(long maxFrameSize) 31 | { 32 | 33 | this.maxFrameSize = maxFrameSize; 34 | } 35 | 36 | @Override 37 | protected ChannelBuffer encode(ChannelHandlerContext ctx, 38 | Channel channel, 39 | ThriftMessage message) throws Exception 40 | { 41 | int frameSize = message.getBuffer().readableBytes(); 42 | 43 | if (message.getBuffer().readableBytes() > maxFrameSize) 44 | { 45 | Channels.fireExceptionCaught(ctx, new TooLongFrameException( 46 | String.format( 47 | "Frame size exceeded on encode: frame was %d bytes, maximum allowed is %d bytes", 48 | frameSize, 49 | maxFrameSize))); 50 | return null; 51 | } 52 | 53 | switch (message.getTransportType()) { 54 | case UNFRAMED: 55 | return message.getBuffer(); 56 | 57 | case FRAMED: 58 | ChannelBuffer frameSizeBuffer = ChannelBuffers.buffer(4); 59 | frameSizeBuffer.writeInt(message.getBuffer().readableBytes()); 60 | return ChannelBuffers.wrappedBuffer(frameSizeBuffer, message.getBuffer()); 61 | 62 | case HEADER: 63 | throw new UnsupportedOperationException("Header transport is not supported"); 64 | 65 | case HTTP: 66 | throw new UnsupportedOperationException("HTTP transport is not supported"); 67 | 68 | default: 69 | throw new UnsupportedOperationException("Unrecognized transport type"); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/codec/ThriftFrameCodec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.codec; 17 | 18 | import org.jboss.netty.channel.ChannelDownstreamHandler; 19 | import org.jboss.netty.channel.ChannelUpstreamHandler; 20 | 21 | public interface ThriftFrameCodec extends ChannelUpstreamHandler, ChannelDownstreamHandler 22 | { 23 | } 24 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/codec/ThriftFrameCodecFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.codec; 17 | 18 | import org.apache.thrift.protocol.TProtocolFactory; 19 | import org.jboss.netty.channel.ChannelHandler; 20 | 21 | public interface ThriftFrameCodecFactory 22 | { 23 | public ChannelHandler create(int maxFrameSize, TProtocolFactory defaultProtocolFactory); 24 | } 25 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/codec/ThriftFrameDecoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.codec; 17 | 18 | import com.facebook.nifty.core.ThriftMessage; 19 | import org.jboss.netty.buffer.ChannelBuffer; 20 | import org.jboss.netty.channel.Channel; 21 | import org.jboss.netty.channel.ChannelHandlerContext; 22 | import org.jboss.netty.handler.codec.frame.FrameDecoder; 23 | 24 | public abstract class ThriftFrameDecoder extends FrameDecoder 25 | { 26 | protected abstract ThriftMessage decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) 27 | throws Exception; 28 | } 29 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/codec/ThriftFrameEncoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.codec; 17 | 18 | import com.facebook.nifty.core.ThriftMessage; 19 | import org.jboss.netty.buffer.ChannelBuffer; 20 | import org.jboss.netty.channel.Channel; 21 | import org.jboss.netty.channel.ChannelHandlerContext; 22 | import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; 23 | 24 | public abstract class ThriftFrameEncoder extends OneToOneEncoder 25 | { 26 | protected abstract ChannelBuffer encode(ChannelHandlerContext ctx, Channel channel, ThriftMessage message) 27 | throws Exception; 28 | 29 | protected Object encode(ChannelHandlerContext ctx, Channel channel, Object message) 30 | throws Exception 31 | { 32 | if (!(message instanceof ThriftMessage)) { 33 | return message; 34 | } 35 | 36 | return encode(ctx, channel, (ThriftMessage) message); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/ConnectionContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import com.facebook.nifty.ssl.SslSession; 19 | 20 | import java.net.SocketAddress; 21 | import java.util.Iterator; 22 | import java.util.Map; 23 | 24 | public interface ConnectionContext 25 | { 26 | /** 27 | * Gets the remote address of the client that made the request 28 | * 29 | * @return The client's remote address as a {@link SocketAddress} 30 | */ 31 | public SocketAddress getRemoteAddress(); 32 | 33 | /** 34 | * Returns the SslSession of the connection. This could be null if the 35 | * channel is not using SSL. 36 | * 37 | * @return a {@link SslSession} object for the current connection or {@code null} if not using SSL. 38 | */ 39 | public SslSession getSslSession(); 40 | 41 | /** 42 | * Gets the value of an additional attribute specific to the connection 43 | * 44 | * @param attributeName Name of attribute 45 | * @return Attribute value, or {@code null} if not present 46 | */ 47 | public Object getAttribute(String attributeName); 48 | 49 | /** 50 | * Sets the value of an additional attribute specific to the connection 51 | * 52 | * @param attributeName Name of attribute 53 | * @param value New value of attribute. Must not be {@code null} 54 | * @return Old attribute value, or {@code null} if not present 55 | */ 56 | public Object setAttribute(String attributeName, Object value); 57 | 58 | /** 59 | * Removes an additional attribute specific to the connection 60 | * 61 | * @param attributeName Name of attribute 62 | * @return Old attribute value, or {@code null} if attribute was not present 63 | */ 64 | public Object removeAttribute(String attributeName); 65 | 66 | /** 67 | * Returns a read-only iterator over the additional attributes 68 | * @return Iterator 69 | */ 70 | public Iterator> attributeIterator(); 71 | } 72 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/ConnectionContextHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import com.facebook.nifty.ssl.SslSession; 19 | import org.jboss.netty.channel.ChannelHandlerContext; 20 | import org.jboss.netty.channel.ChannelStateEvent; 21 | import org.jboss.netty.channel.MessageEvent; 22 | import org.jboss.netty.channel.SimpleChannelUpstreamHandler; 23 | 24 | public class ConnectionContextHandler extends SimpleChannelUpstreamHandler 25 | { 26 | @Override 27 | public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception 28 | { 29 | super.channelConnected(ctx, e); 30 | 31 | NiftyConnectionContext context = new NiftyConnectionContext(); 32 | context.setRemoteAddress(ctx.getChannel().getRemoteAddress()); 33 | 34 | ctx.setAttachment(context); 35 | } 36 | 37 | @Override 38 | public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { 39 | if (e.getMessage() instanceof SslSession) { 40 | NiftyConnectionContext context = (NiftyConnectionContext) ctx.getAttachment(); 41 | context.setSslSession((SslSession) e.getMessage()); 42 | } else { 43 | super.messageReceived(ctx, e); 44 | } 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/ConnectionContexts.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import org.jboss.netty.channel.Channel; 19 | 20 | import com.google.common.base.Preconditions; 21 | 22 | public class ConnectionContexts 23 | { 24 | public static ConnectionContext getContext(Channel channel) 25 | { 26 | ConnectionContext context = (ConnectionContext) 27 | channel.getPipeline() 28 | .getContext(ConnectionContextHandler.class) 29 | .getAttachment(); 30 | Preconditions.checkState(context != null, "Context not yet set on channel %s", channel); 31 | return context; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/DefaultNettyServerConfigProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import com.google.inject.Provider; 19 | 20 | public class DefaultNettyServerConfigProvider implements Provider 21 | { 22 | @Override 23 | public NettyServerConfig get() 24 | { 25 | return NettyServerConfig.newBuilder().build(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/IdleDisconnectHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import org.jboss.netty.channel.ChannelHandlerContext; 19 | import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler; 20 | import org.jboss.netty.handler.timeout.IdleStateEvent; 21 | 22 | public class IdleDisconnectHandler extends IdleStateAwareChannelHandler { 23 | @Override 24 | public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) throws Exception { 25 | ctx.getChannel().close(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/NettyServerConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import com.google.inject.ProvidedBy; 19 | import org.jboss.netty.util.Timer; 20 | 21 | import java.util.Map; 22 | import java.util.concurrent.ExecutorService; 23 | 24 | @ProvidedBy(DefaultNettyServerConfigProvider.class) 25 | public class NettyServerConfig 26 | { 27 | private final Map bootstrapOptions; 28 | private final Timer timer; 29 | private final ExecutorService bossExecutor; 30 | private final int bossThreadCount; 31 | private final ExecutorService workerExecutor; 32 | private final int workerThreadCount; 33 | 34 | public NettyServerConfig(Map bootstrapOptions, 35 | Timer timer, 36 | ExecutorService bossExecutor, 37 | int bossThreadCount, 38 | ExecutorService workerExecutor, 39 | int workerThreadCount) 40 | { 41 | this.bootstrapOptions = bootstrapOptions; 42 | this.timer = timer; 43 | this.bossExecutor = bossExecutor; 44 | this.bossThreadCount = bossThreadCount; 45 | this.workerExecutor = workerExecutor; 46 | this.workerThreadCount = workerThreadCount; 47 | } 48 | 49 | public Timer getTimer() 50 | { 51 | return timer; 52 | } 53 | 54 | public ExecutorService getBossExecutor() 55 | { 56 | return bossExecutor; 57 | } 58 | 59 | public Map getBootstrapOptions() 60 | { 61 | return bootstrapOptions; 62 | } 63 | 64 | public int getBossThreadCount() 65 | { 66 | return bossThreadCount; 67 | } 68 | 69 | public ExecutorService getWorkerExecutor() 70 | { 71 | return workerExecutor; 72 | } 73 | 74 | public int getWorkerThreadCount() 75 | { 76 | return workerThreadCount; 77 | } 78 | 79 | public static NettyServerConfigBuilder newBuilder() 80 | { 81 | return new NettyServerConfigBuilder(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/NiftyBootstrap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import com.google.common.collect.ImmutableMap; 19 | import com.google.inject.Inject; 20 | import org.jboss.netty.channel.group.ChannelGroup; 21 | import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; 22 | import javax.annotation.PostConstruct; 23 | import javax.annotation.PreDestroy; 24 | import java.util.Map; 25 | import java.util.Set; 26 | import java.util.concurrent.ExecutorService; 27 | 28 | /** 29 | * A lifecycle object that manages starting up and shutting down multiple core channels. 30 | */ 31 | public class NiftyBootstrap 32 | { 33 | private final ChannelGroup allChannels; 34 | private final NettyServerConfig nettyServerConfig; 35 | private final Map transports; 36 | private ExecutorService bossExecutor; 37 | private ExecutorService workerExecutor; 38 | private NioServerSocketChannelFactory serverChannelFactory; 39 | 40 | /** 41 | * This takes a Set of ThriftServerDef. Use Guice Multibinder to inject. 42 | */ 43 | @Inject 44 | public NiftyBootstrap( 45 | Set thriftServerDefs, 46 | NettyServerConfig nettyServerConfig, 47 | ChannelGroup allChannels) 48 | { 49 | this.allChannels = allChannels; 50 | ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); 51 | this.nettyServerConfig = nettyServerConfig; 52 | for (ThriftServerDef thriftServerDef : thriftServerDefs) { 53 | builder.put(thriftServerDef, new NettyServerTransport(thriftServerDef, 54 | nettyServerConfig, 55 | allChannels)); 56 | } 57 | transports = builder.build(); 58 | } 59 | 60 | @PostConstruct 61 | public void start() 62 | { 63 | bossExecutor = nettyServerConfig.getBossExecutor(); 64 | workerExecutor = nettyServerConfig.getWorkerExecutor(); 65 | serverChannelFactory = new NioServerSocketChannelFactory(bossExecutor, workerExecutor); 66 | for (NettyServerTransport transport : transports.values()) { 67 | transport.start(serverChannelFactory); 68 | } 69 | } 70 | 71 | @PreDestroy 72 | public void stop() 73 | { 74 | for (NettyServerTransport transport : transports.values()) { 75 | try { 76 | transport.stop(); 77 | } 78 | catch (InterruptedException e) { 79 | Thread.currentThread().interrupt(); 80 | } 81 | } 82 | 83 | ShutdownUtil.shutdownChannelFactory(serverChannelFactory, bossExecutor, workerExecutor, allChannels); 84 | } 85 | 86 | public Map getBoundPorts() 87 | { 88 | ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); 89 | for (Map.Entry entry : transports.entrySet()) { 90 | builder.put(entry.getKey(), entry.getValue().getPort()); 91 | } 92 | return builder.build(); 93 | } 94 | 95 | public Map getNiftyMetrics() 96 | { 97 | ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); 98 | for (Map.Entry entry : transports.entrySet()) { 99 | builder.put(entry.getKey(), entry.getValue().getMetrics()); 100 | } 101 | return builder.build(); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/NiftyConnectionContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import com.facebook.nifty.ssl.SslSession; 19 | import com.google.common.base.Preconditions; 20 | 21 | import java.net.SocketAddress; 22 | import java.util.Collections; 23 | import java.util.Iterator; 24 | import java.util.Map; 25 | import java.util.concurrent.ConcurrentHashMap; 26 | 27 | public class NiftyConnectionContext implements ConnectionContext 28 | { 29 | private SocketAddress remoteAddress; 30 | private SslSession sslSession; 31 | private Map attributes = new ConcurrentHashMap<>(); 32 | 33 | @Override 34 | public SocketAddress getRemoteAddress() 35 | { 36 | return remoteAddress; 37 | } 38 | 39 | @Override 40 | public SslSession getSslSession() { 41 | return sslSession; 42 | } 43 | 44 | public void setSslSession(SslSession sslSession) { 45 | this.sslSession = sslSession; 46 | } 47 | 48 | public void setRemoteAddress(SocketAddress remoteAddress) 49 | { 50 | this.remoteAddress = remoteAddress; 51 | } 52 | 53 | @Override 54 | public Object getAttribute(String attributeName) 55 | { 56 | Preconditions.checkNotNull(attributeName); 57 | return attributes.get(attributeName); 58 | } 59 | 60 | @Override 61 | public Object setAttribute(String attributeName, Object value) 62 | { 63 | Preconditions.checkNotNull(attributeName); 64 | Preconditions.checkNotNull(value); 65 | return attributes.put(attributeName, value); 66 | } 67 | 68 | @Override 69 | public Object removeAttribute(String attributeName) 70 | { 71 | Preconditions.checkNotNull(attributeName); 72 | return attributes.remove(attributeName); 73 | } 74 | 75 | @Override 76 | public Iterator> attributeIterator() 77 | { 78 | return Collections.unmodifiableSet(attributes.entrySet()).iterator(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/NiftyExceptionLogger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import io.airlift.log.Logger; 19 | import org.jboss.netty.channel.ChannelEvent; 20 | import org.jboss.netty.channel.ExceptionEvent; 21 | import org.jboss.netty.handler.logging.LoggingHandler; 22 | 23 | import java.net.SocketAddress; 24 | 25 | public class NiftyExceptionLogger extends LoggingHandler 26 | { 27 | private static final Logger log = Logger.get(NiftyExceptionLogger.class); 28 | 29 | @Override 30 | public void log(ChannelEvent event) 31 | { 32 | if (event instanceof ExceptionEvent) { 33 | ExceptionEvent exceptionEvent = (ExceptionEvent) event; 34 | SocketAddress remoteAddress = exceptionEvent.getChannel().getRemoteAddress(); 35 | log.error(exceptionEvent.getCause(), "Exception triggered on channel connected to %s", remoteAddress); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/NiftyIODispatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import org.jboss.netty.channel.ChannelEvent; 19 | import org.jboss.netty.channel.ChannelHandlerContext; 20 | import org.jboss.netty.channel.Channels; 21 | import org.jboss.netty.channel.SimpleChannelDownstreamHandler; 22 | 23 | /** 24 | * Dispatches downstream messages from the worker threads to the IO threads, 25 | * so that code in IO threads do not have to worry about downstream paths 26 | * being invoked from multiple threads. 27 | */ 28 | public class NiftyIODispatcher extends SimpleChannelDownstreamHandler { 29 | 30 | @Override 31 | public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception { 32 | ctx.getPipeline().execute(new Runnable() { 33 | @Override 34 | public void run() { 35 | try { 36 | NiftyIODispatcher.super.handleDownstream(ctx, e); 37 | } 38 | catch (Exception ex) { 39 | Channels.fireExceptionCaught(ctx.getChannel(), ex); 40 | } 41 | } 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/NiftyMetrics.java: -------------------------------------------------------------------------------- 1 | package com.facebook.nifty.core; 2 | 3 | /* 4 | * Copyright (C) 2012-2016 Facebook, Inc. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | public interface NiftyMetrics 19 | { 20 | int getChannelCount(); 21 | long getBytesRead(); 22 | long getBytesWritten(); 23 | } 24 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/NiftyNoOpSecurityFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import org.jboss.netty.channel.ChannelHandler; 19 | import org.jboss.netty.channel.ChannelHandlerContext; 20 | import org.jboss.netty.channel.ChannelStateEvent; 21 | import org.jboss.netty.channel.SimpleChannelHandler; 22 | 23 | public class NiftyNoOpSecurityFactory implements NiftySecurityFactory 24 | { 25 | static final ChannelHandler noOpHandler = new SimpleChannelHandler() { 26 | @Override 27 | public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception 28 | { 29 | super.channelOpen(ctx, e); 30 | ctx.getPipeline().remove(this); 31 | } 32 | }; 33 | 34 | @Override 35 | public NiftySecurityHandlers getSecurityHandlers(ThriftServerDef def, NettyServerConfig serverConfig) 36 | { 37 | return new NiftySecurityHandlers() 38 | { 39 | @Override 40 | public ChannelHandler getAuthenticationHandler() 41 | { 42 | return noOpHandler; 43 | } 44 | 45 | @Override 46 | public ChannelHandler getEncryptionHandler() 47 | { 48 | return noOpHandler; 49 | } 50 | }; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/NiftyRequestContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import com.google.common.collect.Maps; 19 | import org.apache.thrift.protocol.TProtocol; 20 | import static com.google.common.base.Preconditions.checkNotNull; 21 | 22 | import java.util.Collections; 23 | import java.util.Iterator; 24 | import java.util.Map; 25 | import java.util.concurrent.ConcurrentMap; 26 | 27 | public class NiftyRequestContext implements RequestContext 28 | { 29 | private final ConnectionContext connectionContext; 30 | private final TProtocol inputProtocol; 31 | private final TProtocol outputProtocol; 32 | private final TNiftyTransport niftyTransport; 33 | private final ConcurrentMap data = Maps.newConcurrentMap(); 34 | 35 | @Override 36 | public TProtocol getInputProtocol() 37 | { 38 | return inputProtocol; 39 | } 40 | 41 | @Override 42 | public TProtocol getOutputProtocol() 43 | { 44 | return outputProtocol; 45 | } 46 | 47 | public TNiftyTransport getNiftyTransport() 48 | { 49 | return niftyTransport; 50 | } 51 | 52 | @Override 53 | public ConnectionContext getConnectionContext() 54 | { 55 | return connectionContext; 56 | } 57 | 58 | @Override 59 | public void setContextData(String key, Object val) 60 | { 61 | checkNotNull(key, "context data key is null"); 62 | data.put(key, val); 63 | } 64 | 65 | @Override 66 | public Object getContextData(String key) 67 | { 68 | checkNotNull(key, "context data key is null"); 69 | return data.get(key); 70 | } 71 | 72 | @Override 73 | public void clearContextData(String key) 74 | { 75 | checkNotNull(key, "context data key is null"); 76 | data.remove(key); 77 | } 78 | 79 | @Override 80 | public Iterator> contextDataIterator() 81 | { 82 | return Collections.unmodifiableSet(data.entrySet()).iterator(); 83 | } 84 | 85 | public NiftyRequestContext(ConnectionContext connectionContext, TProtocol inputProtocol, TProtocol outputProtocol, TNiftyTransport niftyTransport) 86 | { 87 | this.connectionContext = connectionContext; 88 | this.niftyTransport = niftyTransport; 89 | this.inputProtocol = inputProtocol; 90 | this.outputProtocol = outputProtocol; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/NiftySecurityFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | public interface NiftySecurityFactory 19 | { 20 | NiftySecurityHandlers getSecurityHandlers(ThriftServerDef def, NettyServerConfig serverConfig); 21 | } 22 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/NiftySecurityHandlers.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import org.jboss.netty.channel.ChannelHandler; 19 | 20 | public interface NiftySecurityHandlers 21 | { 22 | ChannelHandler getAuthenticationHandler(); 23 | ChannelHandler getEncryptionHandler(); 24 | } 25 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/NiftyTimer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import com.google.common.util.concurrent.ThreadFactoryBuilder; 19 | 20 | import org.jboss.netty.util.HashedWheelTimer; 21 | import org.jboss.netty.util.ThreadNameDeterminer; 22 | 23 | import javax.annotation.PreDestroy; 24 | 25 | import java.io.Closeable; 26 | import java.util.concurrent.TimeUnit; 27 | 28 | public final class NiftyTimer 29 | extends HashedWheelTimer 30 | implements Closeable 31 | { 32 | public NiftyTimer(String prefix, long tickDuration, TimeUnit unit, int ticksPerWheel) 33 | { 34 | super(new ThreadFactoryBuilder().setNameFormat(prefix + "-timer-%s").setDaemon(true).build(), 35 | ThreadNameDeterminer.CURRENT, 36 | tickDuration, 37 | unit, 38 | ticksPerWheel); 39 | } 40 | 41 | public NiftyTimer(String prefix) 42 | { 43 | this(prefix, 100, TimeUnit.MILLISECONDS, 512); 44 | } 45 | 46 | @PreDestroy 47 | @Override 48 | public void close() 49 | { 50 | stop(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/RequestContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import org.apache.thrift.protocol.TProtocol; 19 | 20 | import java.util.Iterator; 21 | import java.util.Map; 22 | 23 | public interface RequestContext 24 | { 25 | TProtocol getOutputProtocol(); 26 | 27 | TProtocol getInputProtocol(); 28 | 29 | ConnectionContext getConnectionContext(); 30 | 31 | void setContextData(String key, Object val); 32 | 33 | Object getContextData(String key); 34 | 35 | void clearContextData(String key); 36 | 37 | Iterator> contextDataIterator(); 38 | } 39 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/RequestContexts.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | public class RequestContexts 19 | { 20 | private static ThreadLocal threadLocalContext = new ThreadLocal<>(); 21 | 22 | private RequestContexts() 23 | { 24 | } 25 | 26 | /** 27 | * Gets the thread-local {@link NiftyRequestContext} for the Thrift request that is being processed 28 | * on the current thread. 29 | * 30 | * @return The {@link NiftyRequestContext} of the current request 31 | */ 32 | public static RequestContext getCurrentContext() 33 | { 34 | RequestContext currentContext = threadLocalContext.get(); 35 | return currentContext; 36 | } 37 | 38 | /** 39 | * Sets the thread-local context for the currently running request. 40 | * 41 | * This is normally called only by the server, but it can also be useful to call when 42 | * dispatching to another thread (e.g. a thread in an ExecutorService) if the code that will 43 | * run on that thread might also be interested in the {@link RequestContext} 44 | */ 45 | public static void setCurrentContext(RequestContext requestContext) 46 | { 47 | threadLocalContext.set(requestContext); 48 | } 49 | 50 | /** 51 | * Gets the thread-local context for the currently running request 52 | * 53 | * This is normally called only by the server, but it can also be useful to call when 54 | * cleaning up a context 55 | */ 56 | public static void clearCurrentContext() 57 | { 58 | threadLocalContext.remove(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/ShutdownUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import io.airlift.log.Logger; 19 | import org.jboss.netty.channel.ChannelFactory; 20 | import org.jboss.netty.channel.group.ChannelGroup; 21 | 22 | import java.util.concurrent.ExecutorService; 23 | import java.util.concurrent.TimeUnit; 24 | 25 | public class ShutdownUtil 26 | { 27 | private static final Logger log = Logger.get(ShutdownUtil.class); 28 | 29 | public static void shutdownChannelFactory(ChannelFactory channelFactory, 30 | ExecutorService bossExecutor, 31 | ExecutorService workerExecutor, 32 | ChannelGroup allChannels) 33 | { 34 | // Close all channels 35 | if (allChannels != null) { 36 | closeChannels(allChannels); 37 | } 38 | 39 | // Shutdown the channel factory 40 | if (channelFactory != null) { 41 | channelFactory.shutdown(); 42 | } 43 | 44 | // Stop boss threads 45 | if (bossExecutor != null) { 46 | shutdownExecutor(bossExecutor, "bossExecutor"); 47 | } 48 | 49 | // Finally stop I/O workers 50 | if (workerExecutor != null) { 51 | shutdownExecutor(workerExecutor, "workerExecutor"); 52 | } 53 | 54 | // Release any other resources netty might be holding onto via this channelFactory 55 | if (channelFactory != null) { 56 | channelFactory.releaseExternalResources(); 57 | } 58 | } 59 | 60 | public static void closeChannels(ChannelGroup allChannels) 61 | { 62 | if (allChannels.size() > 0) 63 | { 64 | // TODO : allow an option here to control if we need to drain connections and wait instead of killing them all 65 | try { 66 | log.info("Closing %s open client connections", allChannels.size()); 67 | if (!allChannels.close().await(5, TimeUnit.SECONDS)) { 68 | log.warn("Failed to close all open client connections"); 69 | } 70 | } catch (InterruptedException e) { 71 | log.warn("Interrupted while closing client connections"); 72 | Thread.currentThread().interrupt(); 73 | } 74 | } 75 | } 76 | 77 | // TODO : make wait time configurable ? 78 | public static void shutdownExecutor(ExecutorService executor, final String name) 79 | { 80 | executor.shutdown(); 81 | try { 82 | log.info("Waiting for %s to shutdown", name); 83 | if (!executor.awaitTermination(5, TimeUnit.SECONDS)) { 84 | log.warn("%s did not shutdown properly", name); 85 | } 86 | } 87 | catch (InterruptedException e) { 88 | log.warn("Interrupted while waiting for %s to shutdown", name); 89 | Thread.currentThread().interrupt(); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/TChannelBufferInputTransport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import org.apache.thrift.transport.TTransport; 19 | import org.apache.thrift.transport.TTransportException; 20 | import org.jboss.netty.buffer.ChannelBuffer; 21 | 22 | import javax.annotation.concurrent.NotThreadSafe; 23 | 24 | import static com.google.common.base.Preconditions.checkState; 25 | 26 | /** 27 | * Implementation of {@link TTransport} that wraps an incoming message received so that a 28 | * {@link org.apache.thrift.protocol.TProtocol} can * be constructed around the wrapper to read 29 | * the message. 30 | * 31 | * Allows for reusing the same transport to read multiple messages via 32 | * {@link TChannelBufferInputTransport#setInputBuffer(org.jboss.netty.buffer.ChannelBuffer)} 33 | */ 34 | @NotThreadSafe 35 | public class TChannelBufferInputTransport extends TTransport { 36 | private ChannelBuffer inputBuffer; 37 | 38 | public TChannelBufferInputTransport() { 39 | this.inputBuffer = null; 40 | } 41 | 42 | public TChannelBufferInputTransport(ChannelBuffer inputBuffer) { 43 | setInputBuffer(inputBuffer); 44 | } 45 | 46 | @Override 47 | public boolean isOpen() { 48 | throw new UnsupportedOperationException(); 49 | } 50 | 51 | @Override 52 | public void open() throws TTransportException { 53 | throw new UnsupportedOperationException(); 54 | } 55 | 56 | @Override 57 | public void close() { 58 | throw new UnsupportedOperationException(); 59 | } 60 | 61 | @Override 62 | public int read(byte[] buf, int off, int len) throws TTransportException { 63 | checkState(inputBuffer != null, "Tried to read before setting an input buffer"); 64 | inputBuffer.readBytes(buf, off, len); 65 | return len; 66 | } 67 | 68 | @Override 69 | public void write(byte[] buf, int off, int len) throws TTransportException { 70 | throw new UnsupportedOperationException(); 71 | } 72 | 73 | public void setInputBuffer(ChannelBuffer inputBuffer) { 74 | this.inputBuffer = inputBuffer; 75 | } 76 | 77 | public boolean isReadable() { 78 | return inputBuffer.readable(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/TInputOutputCompositeTransport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import org.apache.thrift.transport.TTransport; 19 | import org.apache.thrift.transport.TTransportException; 20 | 21 | /** 22 | * Composes a read-only transport and a write-only transport to produce a read/write transport 23 | */ 24 | public class TInputOutputCompositeTransport extends TTransport 25 | { 26 | private final TTransport inputTransport; 27 | private final TTransport outputTransport; 28 | 29 | public TInputOutputCompositeTransport(TTransport inputTransport, TTransport outputTransport) 30 | { 31 | this.inputTransport = inputTransport; 32 | this.outputTransport = outputTransport; 33 | } 34 | 35 | // Delegate input methods 36 | 37 | @Override 38 | public int read(byte[] buf, int off, int len) throws TTransportException 39 | { 40 | return inputTransport.read(buf, off, len); 41 | } 42 | 43 | @Override 44 | public int readAll(byte[] buf, int off, int len) throws TTransportException 45 | { 46 | return inputTransport.readAll(buf, off, len); 47 | } 48 | 49 | @Override 50 | public boolean peek() 51 | { 52 | return inputTransport.peek(); 53 | } 54 | 55 | @Override 56 | public byte[] getBuffer() 57 | { 58 | return inputTransport.getBuffer(); 59 | } 60 | 61 | @Override 62 | public int getBufferPosition() 63 | { 64 | return inputTransport.getBufferPosition(); 65 | } 66 | 67 | @Override 68 | public int getBytesRemainingInBuffer() 69 | { 70 | return inputTransport.getBytesRemainingInBuffer(); 71 | } 72 | 73 | @Override 74 | public void consumeBuffer(int len) 75 | { 76 | inputTransport.consumeBuffer(len); 77 | } 78 | 79 | // Delegate output methods 80 | 81 | @Override 82 | public void write(byte[] buf) throws TTransportException 83 | { 84 | outputTransport.write(buf); 85 | } 86 | 87 | @Override 88 | public void write(byte[] buf, int off, int len) throws TTransportException 89 | { 90 | outputTransport.write(buf, off, len); 91 | } 92 | 93 | @Override 94 | public void flush() throws TTransportException 95 | { 96 | outputTransport.flush(); 97 | } 98 | 99 | // Unsupported methods 100 | 101 | @Override 102 | public void close() 103 | { 104 | throw new UnsupportedOperationException(); 105 | } 106 | 107 | @Override 108 | public boolean isOpen() 109 | { 110 | throw new UnsupportedOperationException(); 111 | } 112 | 113 | @Override 114 | public void open() throws TTransportException 115 | { 116 | throw new UnsupportedOperationException(); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/ThriftMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import org.jboss.netty.buffer.ChannelBuffer; 19 | 20 | public class ThriftMessage 21 | { 22 | private final ChannelBuffer buffer; 23 | private final ThriftTransportType transportType; 24 | private long processStartTimeMillis; 25 | 26 | public ThriftMessage(ChannelBuffer buffer, ThriftTransportType transportType) 27 | { 28 | this.buffer = buffer; 29 | this.transportType = transportType; 30 | } 31 | 32 | public ChannelBuffer getBuffer() 33 | { 34 | return buffer; 35 | } 36 | 37 | public ThriftTransportType getTransportType() 38 | { 39 | return transportType; 40 | } 41 | 42 | /** 43 | * Gets a {@link Factory} for creating messages similar to this one. Used by {@link 44 | * NiftyDispatcher} to create response messages that are similar to their corresponding 45 | * request messages. 46 | * 47 | * @return The {@link Factory} 48 | */ 49 | public Factory getMessageFactory() 50 | { 51 | return new Factory() 52 | { 53 | @Override 54 | public ThriftMessage create(ChannelBuffer messageBuffer) 55 | { 56 | return new ThriftMessage(messageBuffer, getTransportType()); 57 | } 58 | }; 59 | } 60 | 61 | /** 62 | * Standard Thrift clients require ordered responses, so even though Nifty can run multiple 63 | * requests from the same client at the same time, the responses have to be held until all 64 | * previous responses are ready and have been written. However, through the use of extended 65 | * protocols and codecs, a request can indicate that the client understands 66 | * out-of-order responses. 67 | * 68 | * @return {@code true} if ordered responses are required 69 | */ 70 | public boolean isOrderedResponsesRequired() 71 | { 72 | return true; 73 | } 74 | 75 | public long getProcessStartTimeMillis() { return processStartTimeMillis; } 76 | 77 | public void setProcessStartTimeMillis(long processStartTimeMillis) 78 | { 79 | this.processStartTimeMillis = processStartTimeMillis; 80 | } 81 | 82 | public static interface Factory 83 | { 84 | public ThriftMessage create(ChannelBuffer messageBuffer); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/ThriftServerDefBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | /** 19 | * This is just a concrete, usable wrapper for {@link ThriftServerDefBuilderBase}, which 20 | * can't be used directly even if it was not abstract, because it uses a recursive generic 21 | * definition. 22 | */ 23 | public class ThriftServerDefBuilder 24 | extends ThriftServerDefBuilderBase {} 25 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/ThriftTransportType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | public enum ThriftTransportType { 19 | UNFRAMED, 20 | FRAMED, 21 | HTTP, 22 | HEADER 23 | } 24 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/core/ThriftUnframedDecoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import org.apache.thrift.protocol.TBinaryProtocol; 19 | import org.apache.thrift.protocol.TProtocolUtil; 20 | import org.apache.thrift.protocol.TType; 21 | import org.apache.thrift.transport.TTransport; 22 | import org.jboss.netty.buffer.ChannelBuffer; 23 | import org.jboss.netty.channel.Channel; 24 | import org.jboss.netty.channel.ChannelHandlerContext; 25 | import org.jboss.netty.handler.codec.frame.FrameDecoder; 26 | 27 | public class ThriftUnframedDecoder extends FrameDecoder { 28 | @Override 29 | protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) 30 | throws Exception { 31 | int messageBeginIndex = buffer.readerIndex(); 32 | ChannelBuffer messageBuffer = null; 33 | 34 | try 35 | { 36 | TTransport transport = new TChannelBufferInputTransport(buffer); 37 | TBinaryProtocol protocol = new TBinaryProtocol(transport); 38 | 39 | protocol.readMessageBegin(); 40 | TProtocolUtil.skip(protocol, TType.STRUCT); 41 | protocol.readMessageEnd(); 42 | 43 | messageBuffer = buffer.slice(messageBeginIndex, buffer.readerIndex()); 44 | } 45 | catch (IndexOutOfBoundsException e) 46 | { 47 | buffer.readerIndex(messageBeginIndex); 48 | return null; 49 | } 50 | catch (Throwable th) { 51 | buffer.readerIndex(messageBeginIndex); 52 | return null; 53 | } 54 | 55 | return messageBuffer; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/duplex/TDuplexProtocolFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.duplex; 17 | 18 | import org.apache.thrift.protocol.TProtocol; 19 | import org.apache.thrift.protocol.TProtocolFactory; 20 | import org.apache.thrift.transport.TTransport; 21 | 22 | /*** 23 | * A factory for creating a pair of protocols (one for input, one for output). Gives more 24 | * flexibility to the factory to enforce protocol restrictions (e.g. header protocol requires 25 | * the input/output transport/protocol are the same, a duplex header protocol factory can enforce 26 | * the transport restriction because it can see both transports, and can guarantee both protocols 27 | * are the same because it can fill in the input/output slots of the protocol pair with the same 28 | * protocol object). 29 | */ 30 | public abstract class TDuplexProtocolFactory { 31 | public abstract TProtocolPair getProtocolPair(TTransportPair transportPair); 32 | 33 | public TProtocolFactory getInputProtocolFactory() 34 | { 35 | return new TProtocolFactory() 36 | { 37 | @Override 38 | public TProtocol getProtocol(TTransport trans) 39 | { 40 | return getProtocolPair(TTransportPair.fromSingleTransport(trans)).getInputProtocol(); 41 | } 42 | }; 43 | } 44 | 45 | public TProtocolFactory getOutputProtocolFactory() 46 | { 47 | return new TProtocolFactory() 48 | { 49 | @Override 50 | public TProtocol getProtocol(TTransport trans) 51 | { 52 | return getProtocolPair(TTransportPair.fromSingleTransport(trans)).getOutputProtocol(); 53 | } 54 | }; 55 | } 56 | 57 | public static TDuplexProtocolFactory fromSingleFactory( 58 | final TProtocolFactory protocolFactory 59 | ) 60 | { 61 | return new TDuplexProtocolFactory() { 62 | @Override 63 | public TProtocolPair getProtocolPair(TTransportPair transportPair) { 64 | return TProtocolPair.fromSeparateProtocols( 65 | protocolFactory.getProtocol(transportPair.getInputTransport()), 66 | protocolFactory.getProtocol(transportPair.getOutputTransport())); 67 | } 68 | }; 69 | } 70 | 71 | public static TDuplexProtocolFactory fromSeparateFactories( 72 | final TProtocolFactory inputProtocolFactory, 73 | final TProtocolFactory outputProtocolFactory 74 | ) 75 | { 76 | return new TDuplexProtocolFactory() { 77 | @Override 78 | public TProtocolPair getProtocolPair(TTransportPair transportPair) { 79 | return TProtocolPair.fromSeparateProtocols( 80 | inputProtocolFactory.getProtocol(transportPair.getInputTransport()), 81 | outputProtocolFactory.getProtocol(transportPair.getOutputTransport()) 82 | ); 83 | } 84 | }; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/duplex/TDuplexTransportFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.duplex; 17 | 18 | import org.apache.thrift.transport.TTransportFactory; 19 | 20 | /*** 21 | * A factory for creating a pair of protocols (one for input, one for output). Gives more 22 | * flexibility to the factory to enforce protocol restrictions. See {@link TDuplexProtocolFactory} 23 | * documentation for more details. 24 | */ 25 | public abstract class TDuplexTransportFactory { 26 | public abstract TTransportPair getTransportPair(TTransportPair transportPair); 27 | 28 | public static TDuplexTransportFactory fromSingleTransportFactory( 29 | final TTransportFactory transportFactory 30 | ) 31 | { 32 | return new TDuplexTransportFactory() { 33 | @Override 34 | public TTransportPair getTransportPair(TTransportPair transportPair) { 35 | return TTransportPair.fromSeparateTransports( 36 | transportFactory.getTransport(transportPair.getInputTransport()), 37 | transportFactory.getTransport(transportPair.getOutputTransport())); 38 | } 39 | }; 40 | } 41 | 42 | public static TDuplexTransportFactory fromSeparateTransportFactories( 43 | final TTransportFactory inputTransportFactory, 44 | final TTransportFactory outputTransportFactory 45 | ) 46 | { 47 | return new TDuplexTransportFactory() { 48 | @Override 49 | public TTransportPair getTransportPair(TTransportPair transportPair) { 50 | return TTransportPair.fromSeparateTransports( 51 | inputTransportFactory.getTransport(transportPair.getInputTransport()), 52 | outputTransportFactory.getTransport(transportPair.getOutputTransport()) 53 | ); 54 | } 55 | }; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/duplex/TProtocolPair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.duplex; 17 | 18 | import org.apache.thrift.protocol.TProtocol; 19 | 20 | /*** 21 | * Represents a pair of protocols: one for input and one for output. 22 | */ 23 | public class TProtocolPair { 24 | private final TProtocol inputProtocol; 25 | private final TProtocol outputProtocol; 26 | 27 | protected TProtocolPair(TProtocol inputProtocol, TProtocol outputProtocol) 28 | { 29 | this.inputProtocol = inputProtocol; 30 | this.outputProtocol = outputProtocol; 31 | } 32 | 33 | public TProtocol getInputProtocol() 34 | { 35 | return inputProtocol; 36 | } 37 | 38 | public TProtocol getOutputProtocol() 39 | { 40 | return outputProtocol; 41 | } 42 | 43 | public static TProtocolPair fromSeparateProtocols(final TProtocol inputProtocol, 44 | final TProtocol outputProtocol) 45 | { 46 | return new TProtocolPair(inputProtocol, outputProtocol); 47 | } 48 | 49 | public static TProtocolPair fromSingleProtocol(final TProtocol protocol) 50 | { 51 | return new TProtocolPair(protocol, protocol); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/duplex/TTransportPair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.duplex; 17 | 18 | import org.apache.thrift.transport.TTransport; 19 | 20 | /*** 21 | * Represents a pair of transports: one for input and one for output. 22 | */ 23 | public class TTransportPair { 24 | private final TTransport inputTransport; 25 | private final TTransport outputTransport; 26 | 27 | protected TTransportPair(TTransport inputTransport, TTransport outputTransport) 28 | { 29 | this.inputTransport = inputTransport; 30 | this.outputTransport = outputTransport; 31 | } 32 | 33 | public TTransport getInputTransport() 34 | { 35 | return inputTransport; 36 | } 37 | 38 | public TTransport getOutputTransport() 39 | { 40 | return outputTransport; 41 | } 42 | 43 | public static TTransportPair fromSeparateTransports(final TTransport inputTransport, 44 | final TTransport outputTransport) { 45 | return new TTransportPair(inputTransport, outputTransport); 46 | } 47 | 48 | public static TTransportPair fromSingleTransport(final TTransport transport) { 49 | return new TTransportPair(transport, transport); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/processor/NiftyProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.processor; 17 | 18 | import com.facebook.nifty.core.RequestContext; 19 | import com.google.common.util.concurrent.ListenableFuture; 20 | import org.apache.thrift.TException; 21 | import org.apache.thrift.protocol.TProtocol; 22 | 23 | public interface NiftyProcessor 24 | { 25 | public ListenableFuture process(TProtocol in, TProtocol out, RequestContext requestContext) throws TException; 26 | } 27 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/processor/NiftyProcessorFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.processor; 17 | 18 | import org.apache.thrift.transport.TTransport; 19 | 20 | public interface NiftyProcessorFactory 21 | { 22 | public NiftyProcessor getProcessor(TTransport transport); 23 | } 24 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/ssl/JavaSslServerConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.ssl; 17 | 18 | import com.google.common.base.Throwables; 19 | import org.jboss.netty.handler.ssl.SslContext; 20 | import org.jboss.netty.handler.ssl.SslHandler; 21 | import org.jboss.netty.handler.ssl.SslProvider; 22 | 23 | import javax.net.ssl.SSLEngine; 24 | import javax.net.ssl.SSLException; 25 | import javax.net.ssl.SSLPeerUnverifiedException; 26 | import javax.net.ssl.SSLSession; 27 | import javax.security.cert.X509Certificate; 28 | 29 | public class JavaSslServerConfiguration extends SslServerConfiguration { 30 | 31 | private JavaSslServerConfiguration(BuilderBase builder) { 32 | super(builder); 33 | } 34 | 35 | public static class Builder extends BuilderBase { 36 | @Override 37 | protected SslServerConfiguration createServerConfiguration() { 38 | SslServerConfiguration sslServerConfiguration = new JavaSslServerConfiguration(this); 39 | sslServerConfiguration.initializeServerContext(); 40 | return sslServerConfiguration; 41 | } 42 | } 43 | 44 | public static JavaSslServerConfiguration.Builder newBuilder() { 45 | return new JavaSslServerConfiguration.Builder(); 46 | } 47 | 48 | protected SslHandlerFactory createSslHandlerFactory() { 49 | try { 50 | SslContext sslContext = 51 | SslContext.newServerContext( 52 | SslProvider.JDK, 53 | null, 54 | certFile, 55 | keyFile, 56 | keyPassword, 57 | ciphers, 58 | null, 59 | 0, 60 | 0); 61 | return new SslHandlerFactory() { 62 | @Override 63 | public SslHandler newHandler() { 64 | SessionAwareSslHandler handler = 65 | new SessionAwareSslHandler( 66 | sslContext.newEngine(), 67 | sslContext.bufferPool(), 68 | JavaSslServerConfiguration.this); 69 | handler.setCloseOnSSLException(true); 70 | return handler; 71 | } 72 | }; 73 | } 74 | catch (SSLException e) { 75 | throw Throwables.propagate(e); 76 | } 77 | } 78 | 79 | @Override 80 | public SslSession getSession(SSLEngine engine) throws SSLException { 81 | SSLSession session = engine.getSession(); 82 | String cipher = session.getCipherSuite(); 83 | long establishedTime = session.getCreationTime(); 84 | X509Certificate peerCert = null; 85 | try { 86 | X509Certificate[] certs = session.getPeerCertificateChain(); 87 | if (certs.length > 0) { 88 | peerCert = certs[0]; 89 | } 90 | } catch (SSLPeerUnverifiedException e) { 91 | // The peer might not have presented a certificate, in which case we consider them 92 | // to be an unauthenticated peer. 93 | } 94 | String version = session.getProtocol(); 95 | return new SslSession(null, null, version, cipher, establishedTime, peerCert); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/ssl/SessionAwareSslHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.ssl; 17 | 18 | import com.google.common.base.Throwables; 19 | import io.airlift.log.Logger; 20 | import org.jboss.netty.channel.ChannelFuture; 21 | import org.jboss.netty.channel.ChannelFutureListener; 22 | import org.jboss.netty.channel.ChannelHandlerContext; 23 | import org.jboss.netty.channel.ChannelStateEvent; 24 | import org.jboss.netty.channel.Channels; 25 | import org.jboss.netty.channel.MessageEvent; 26 | import org.jboss.netty.handler.ssl.SslBufferPool; 27 | import org.jboss.netty.handler.ssl.SslHandler; 28 | 29 | import javax.net.ssl.SSLEngine; 30 | 31 | /** 32 | * An SslHandler which propagates session events to other handlers in the pipeline. 33 | * This does not support the delayed handshake mode and will start the handshake as soon as the 34 | * channel is connected. 35 | */ 36 | public class SessionAwareSslHandler extends SslHandler { 37 | 38 | private static final Logger log = Logger.get(SessionAwareSslHandler.class); 39 | 40 | private final SslServerConfiguration sslServerConfiguration; 41 | 42 | public SessionAwareSslHandler(SSLEngine engine, SslBufferPool pool, SslServerConfiguration configuration) { 43 | super(engine, pool); 44 | this.sslServerConfiguration = configuration; 45 | } 46 | 47 | @Override 48 | public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { 49 | registerHandshakeListener(ctx); 50 | super.channelConnected(ctx, e); 51 | } 52 | 53 | @Override 54 | public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { 55 | if (e.getMessage() == SslPlaintextHandler.TLSConnectedEvent.SINGLETON) { 56 | // SslPlaintextHandler does not know if we're going to be doing an SSL handshake until it receives 57 | // some data and realizes that it's handling a TLS connection. If that happens, it sends us a special 58 | // MessageEvent with payload == SslPlaintextHandler.TLSConnectedEvent.SINGLETON. This message is 59 | // only intended for this class and should not be propagated up the handler chain. 60 | registerHandshakeListener(ctx); 61 | } else { 62 | super.messageReceived(ctx, e); 63 | } 64 | } 65 | 66 | private void registerHandshakeListener(final ChannelHandlerContext ctx) { 67 | handshake().addListener(new ChannelFutureListener() { 68 | @Override 69 | public void operationComplete(ChannelFuture future) throws Exception { 70 | if (future.isSuccess()) { 71 | try { 72 | SslSession sslSession = sslServerConfiguration.getSession(getEngine()); 73 | if (log.isDebugEnabled()) { 74 | log.debug("Got SSL session after handshake: %s", sslSession.toString()); 75 | } 76 | Channels.fireMessageReceived(ctx, sslSession); 77 | } catch (Exception e) { 78 | if (log.isDebugEnabled()) { 79 | log.debug("Exception on handshake getting SSL session: %s", e.toString()); 80 | } 81 | Throwables.propagate(e); 82 | } 83 | } else { 84 | if (log.isDebugEnabled()) { 85 | log.debug("Handshake future failed"); 86 | } 87 | } 88 | } 89 | }); 90 | 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/ssl/SslClientConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.ssl; 17 | 18 | import com.google.common.base.Throwables; 19 | import org.jboss.netty.handler.ssl.SslContext; 20 | import org.jboss.netty.handler.ssl.SslHandler; 21 | 22 | import javax.net.ssl.SSLException; 23 | import java.io.File; 24 | import java.net.InetSocketAddress; 25 | import java.net.SocketAddress; 26 | 27 | public class SslClientConfiguration { 28 | 29 | public static class Builder { 30 | Iterable ciphers; 31 | File caFile; 32 | long sessionCacheSize = 10000; 33 | long sessionTimeoutSeconds = 86400; 34 | SslContext clientContext; 35 | 36 | public Builder ciphers(Iterable ciphers) { 37 | this.ciphers = ciphers; 38 | return this; 39 | } 40 | 41 | public Builder caFile(File caFile) { 42 | this.caFile = caFile; 43 | return this; 44 | } 45 | 46 | public Builder sessionCacheSize(long sessionCacheSize) { 47 | this.sessionCacheSize = sessionCacheSize; 48 | return this; 49 | } 50 | 51 | public Builder sessionTimeoutSeconds(long sessionTimeoutSeconds) { 52 | this.sessionTimeoutSeconds = sessionTimeoutSeconds; 53 | return this; 54 | } 55 | 56 | /** 57 | * Overrides the SslContext with one explicitly provided by the caller. If this is not null, the other 58 | * builder parameters will be ignored. Currently only used for testing and may be removed in the future, 59 | * once we have netty support for client-side certs. 60 | * 61 | * @param clientContext the client context. 62 | * @return a reference to this builder. 63 | */ 64 | public Builder sslContext(SslContext clientContext) { 65 | this.clientContext = clientContext; 66 | return this; 67 | } 68 | 69 | public SslClientConfiguration build() { 70 | return new SslClientConfiguration(this); 71 | } 72 | } 73 | 74 | private SslContext clientContext; 75 | 76 | public SslClientConfiguration(Builder builder) { 77 | if (builder.clientContext == null) { 78 | try { 79 | clientContext = 80 | SslContext.newClientContext( 81 | null, 82 | null, 83 | builder.caFile, 84 | null, 85 | builder.ciphers, 86 | null, 87 | builder.sessionCacheSize, 88 | builder.sessionTimeoutSeconds); 89 | } catch (SSLException e) { 90 | Throwables.propagate(e); 91 | } 92 | } else { 93 | clientContext = builder.clientContext; 94 | } 95 | } 96 | 97 | public SslHandler createHandler() throws Exception { 98 | return clientContext.newHandler(); 99 | } 100 | 101 | public SslHandler createHandler(SocketAddress address) throws Exception { 102 | if (!(address instanceof InetSocketAddress)) { 103 | return createHandler(); 104 | } 105 | InetSocketAddress netAddress = (InetSocketAddress) address; 106 | String host = netAddress.getHostString(); 107 | if (host == null) { 108 | return createHandler(); 109 | } 110 | 111 | return clientContext.newHandler(host, netAddress.getPort()); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/ssl/SslHandlerFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.ssl; 17 | 18 | import org.jboss.netty.handler.ssl.SslHandler; 19 | 20 | /** 21 | * A Factory that returns a handler. 22 | */ 23 | public interface SslHandlerFactory { 24 | SslHandler newHandler(); 25 | } 26 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/ssl/SslSession.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.ssl; 17 | 18 | import javax.security.cert.X509Certificate; 19 | 20 | public class SslSession { 21 | private final String alpn; 22 | private final String npn; 23 | private final String version; 24 | private final String cipher; 25 | // Time at which the connection was established since epoch in seconds. 26 | private final long establishedTime; 27 | private final X509Certificate peerCert; 28 | 29 | public SslSession( 30 | String alpn, 31 | String npn, 32 | String version, 33 | String cipher, 34 | long establishedTime, 35 | X509Certificate peerCert) { 36 | this.alpn = alpn; 37 | this.npn = npn; 38 | this.version = version; 39 | this.cipher = cipher; 40 | this.establishedTime = establishedTime; 41 | this.peerCert = peerCert; 42 | } 43 | 44 | 45 | public String getAlpn() { 46 | return alpn; 47 | } 48 | 49 | public String getNpn() { 50 | return npn; 51 | } 52 | 53 | public String getVersion() { 54 | return version; 55 | } 56 | 57 | public String getCipher() { 58 | return cipher; 59 | } 60 | 61 | public long getEstablishedTime() { 62 | return establishedTime; 63 | } 64 | 65 | public X509Certificate getPeerCert() { 66 | return peerCert; 67 | } 68 | 69 | public String toString() { 70 | return "SslSession(alpn=" + alpn + 71 | ", npn=" + npn + 72 | ", version=" + version + 73 | ", cipher=" + cipher + 74 | ", establishedTime=" + Long.toString(establishedTime) + 75 | ", peerCert=" + peerCert + ")"; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /nifty-core/src/main/java/com/facebook/nifty/ssl/TransportAttachObserver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.ssl; 17 | 18 | import com.facebook.nifty.core.NettyServerTransport; 19 | 20 | /** 21 | * Listen to changes in the transport. 22 | */ 23 | public interface TransportAttachObserver { 24 | void attachTransport(NettyServerTransport transport); 25 | 26 | void detachTransport(); 27 | } 28 | -------------------------------------------------------------------------------- /nifty-core/src/test/java/com/facebook/nifty/core/TestNettyConfigBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import org.jboss.netty.bootstrap.ServerBootstrap; 19 | import org.jboss.netty.channel.Channel; 20 | import org.jboss.netty.channel.Channels; 21 | import org.jboss.netty.channel.socket.ServerSocketChannelConfig; 22 | import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; 23 | import org.testng.Assert; 24 | import org.testng.annotations.BeforeTest; 25 | import org.testng.annotations.Test; 26 | 27 | import java.io.IOException; 28 | import java.net.InetSocketAddress; 29 | import java.net.ServerSocket; 30 | 31 | public class TestNettyConfigBuilder 32 | { 33 | private int port; 34 | 35 | @BeforeTest(alwaysRun = true) 36 | public void setup() 37 | { 38 | try { 39 | ServerSocket s = new ServerSocket(); 40 | s.bind(new InetSocketAddress(0)); 41 | port = s.getLocalPort(); 42 | s.close(); 43 | } 44 | catch (IOException e) { 45 | port = 8080; 46 | } 47 | } 48 | 49 | @Test 50 | public void testNettyConfigBuilder() 51 | { 52 | NettyServerConfigBuilder configBuilder = new NettyServerConfigBuilder(); 53 | 54 | configBuilder.getServerSocketChannelConfig().setReceiveBufferSize(10000); 55 | configBuilder.getServerSocketChannelConfig().setBacklog(1000); 56 | configBuilder.getServerSocketChannelConfig().setReuseAddress(true); 57 | 58 | ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory()); 59 | bootstrap.setOptions(configBuilder.getBootstrapOptions()); 60 | bootstrap.setPipelineFactory(Channels.pipelineFactory(Channels.pipeline())); 61 | Channel serverChannel = bootstrap.bind(new InetSocketAddress(port)); 62 | 63 | Assert.assertEquals(((ServerSocketChannelConfig) serverChannel.getConfig()).getReceiveBufferSize(), 10000); 64 | Assert.assertEquals(((ServerSocketChannelConfig) serverChannel.getConfig()).getBacklog(), 1000); 65 | Assert.assertTrue(((ServerSocketChannelConfig) serverChannel.getConfig()).isReuseAddress()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /nifty-core/src/test/java/com/facebook/nifty/core/TestServerDefBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.core; 17 | 18 | import com.facebook.nifty.processor.NiftyProcessor; 19 | import org.easymock.EasyMock; 20 | import org.testng.Assert; 21 | import org.testng.annotations.Test; 22 | 23 | public class TestServerDefBuilder 24 | { 25 | @Test 26 | public void testServerDefBuilderWithoutProcessor() 27 | { 28 | try { 29 | new ThriftServerDefBuilder().build(); 30 | } 31 | catch (Exception e) { 32 | return; 33 | } 34 | Assert.fail(); 35 | } 36 | 37 | @Test 38 | public void testServerDefBuilder() 39 | { 40 | try { 41 | new ThriftServerDefBuilder() 42 | .withProcessor(EasyMock.createMock(NiftyProcessor.class)) 43 | .build(); 44 | } 45 | catch (Exception e) { 46 | Assert.fail(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /nifty-examples/src/main/java/com/facebook/nifty/test/ResultCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /** 17 | * Autogenerated by Thrift Compiler (0.9.0) 18 | * 19 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 20 | * @generated 21 | */ 22 | package com.facebook.nifty.test; 23 | 24 | 25 | import java.util.Map; 26 | import java.util.HashMap; 27 | import org.apache.thrift.TEnum; 28 | 29 | public enum ResultCode implements org.apache.thrift.TEnum { 30 | OK(0), 31 | TRY_LATER(1); 32 | 33 | private final int value; 34 | 35 | private ResultCode(int value) { 36 | this.value = value; 37 | } 38 | 39 | /** 40 | * Get the integer value of this enum value, as defined in the Thrift IDL. 41 | */ 42 | public int getValue() { 43 | return value; 44 | } 45 | 46 | /** 47 | * Find a the enum type by its integer value, as defined in the Thrift IDL. 48 | * @return null if the value is not found. 49 | */ 50 | public static ResultCode findByValue(int value) { 51 | switch (value) { 52 | case 0: 53 | return OK; 54 | case 1: 55 | return TRY_LATER; 56 | default: 57 | return null; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /nifty-examples/src/main/resources/README.txt: -------------------------------------------------------------------------------- 1 | # Project Status: 🚨 Unmaintained 🚨 2 | 3 | This project is archived and no longer maintained. At the time of archiving, 4 | open issues and pull requests were closed and tagged with `2018-05-archive`. 5 | For pre-existing users who need an open source alternative, we recommend taking 6 | a look at [airlift/drift](https://github.com/airlift/drift). 7 | 8 | The test certificate files were created with the openssl command line. They are self-signed certificates. 9 | The procedure to re-create them (if it's ever needed) goes something like this: 10 | 11 | openssl genrsa -out rsa.key 2048 12 | openssl req -new -key rsa.key -out rsa.csr 13 | # press [Enter] a bunch of times to accept default values for all fields 14 | openssl x509 -req -days 10000 -in rsa.csr -signkey rsa.key -out rsa.crt 15 | 16 | To create the client.pkcs12 file: 17 | 18 | cat client.key client.crt > client.pem 19 | openssl pkcs12 -export -in client.pem -out client.pkcs12 20 | # Type "12345" (without the quotes) twice for passphrase 21 | -------------------------------------------------------------------------------- /nifty-examples/src/main/resources/client.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDADCCAegCCQD8SYXElysQ2TANBgkqhkiG9w0BAQUFADBCMQswCQYDVQQGEwJY 3 | WDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBh 4 | bnkgTHRkMB4XDTE2MDkwODIyMTIyOFoXDTQ0MDEyNTIyMTIyOFowQjELMAkGA1UE 5 | BhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UECgwTRGVmYXVsdCBD 6 | b21wYW55IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5G9wAd 7 | L93e/X2Svk0aYCVFlF1GmO0nL4mcs3QdHC31Pen5ZkXtidgIWiH3wQB3B7j9TofN 8 | XWWd5ptb1rcUbfUurjrY4IJucJ9HWrfM6KwTA4V9Yx8iZ4EZNLeIT9xAkyeibgxr 9 | L/M5IOrOMf5P9j6CM428CkYigHPAQQxCLQxb5/8r8tQHiMpUgrQnjWvEaPRE9M7q 10 | FKn0Tma5QXk03WfH8f6MtjaJACPR2FhNzltjxwc0wBdShM2kca+xhB7DGoUadolZ 11 | tVijjFIONNWpIz5DWHIhRUOc+/K3vTiZ+8CuTgXha/RW0TXJ1em1SlgYxVGMj5+j 12 | QcMC7yY3diX+9BUCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAMQK07YK9UWgELOtR 13 | siGY5aDg+p8USyZM0P+VsP+WGo1yC/ozvdUBrDu1JzK+ju4UyTH+0kt50+gXLtBN 14 | xOz763+Eo7Ir68Sk491JA1lMJCkkqP4/IRAQwxGTrVNBbwZxFNF02gEfl4cR7LH/ 15 | pygtTdYxFgJ+fDDeQk2amL99uP7/v8Rb2TNmzEOcZpvrtMj5ca7uwXIO59t0EVVn 16 | gXRktHveXxgthv5S2mR5hfKeRV/fL75EkS7C6q9AzusyILeh7KeQuAj6aU4XRkv4 17 | n/RR3jxqxwYMRq/Mdc2gD3O2/e2pXkUltrr2YSMsV9zhaYgcE7+h7aK0U85SNHkm 18 | 8caOkg== 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /nifty-examples/src/main/resources/client.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpAIBAAKCAQEArkb3AB0v3d79fZK+TRpgJUWUXUaY7ScviZyzdB0cLfU96flm 3 | Re2J2AhaIffBAHcHuP1Oh81dZZ3mm1vWtxRt9S6uOtjggm5wn0dat8zorBMDhX1j 4 | HyJngRk0t4hP3ECTJ6JuDGsv8zkg6s4x/k/2PoIzjbwKRiKAc8BBDEItDFvn/yvy 5 | 1AeIylSCtCeNa8Ro9ET0zuoUqfROZrlBeTTdZ8fx/oy2NokAI9HYWE3OW2PHBzTA 6 | F1KEzaRxr7GEHsMahRp2iVm1WKOMUg401akjPkNYciFFQ5z78re9OJn7wK5OBeFr 7 | 9FbRNcnV6bVKWBjFUYyPn6NBwwLvJjd2Jf70FQIDAQABAoIBAFrHGjfT/C/szEuR 8 | mVCeMYCYmqxvbo7xP2DF3+/Wjewed06dmzlHfuqphxF0dPLiDYK9Zx9zyHd65Tj9 9 | gH1CxffVhemfOGqYTk+ZIlblBDlFeisZYf1AtXtYfs4u0bJfbIdTo1ESsBpYIp5M 10 | I1xdmF19Ao+MaCmaJSCl/vv8qGxrwr1tc3aSO5BDNwlLoD8W6p6sx+4sqNX8gFbf 11 | 1P2Hxivf81Epl4HIIRxF9WKFgtyTEjTMadGhNrm/QR/jcmA7wqo3zUqO8L4g5c1a 12 | f+yOiQW4E/79FJ6+yPTypyAEB+udHOOEB+mPtdiwmA22RuVxTPi1fTbZK0dgsJBT 13 | gEUruoECgYEA3gQgFN1JOiM5bVWbVOJqaYv9uWnGnMrFmW33Kbvo+IYYiRuvajWw 14 | ZSyLz2qmITE9QFY9FPYl9Pvilw2h/hHY1S1/d3Xu0Mq9ALGhnqHeixn7/Q6tD/a9 15 | gjY1HrePvCDSCob2+7JzUKyaxoElSknsQgunuKYtIGQUAtZ6kg61QXUCgYEAyPQn 16 | Nb3jA8jalKY6QhH0pfPXvpQtM76JMn93BPGY/O8jSSvW/CvsmVfTP00ocyCztxHO 17 | shxrWZILUxlagY+Sk3gO97V9B/UdW4hN80/XqTsAI6drJvDNY8QHAHvILHG1yf01 18 | 1vY/RETz7lPDxxBHmMXsmDBM2Kl7p0YV/e+G9CECgYAtgLryi8gOWlnSxtDnPOCC 19 | cWa3Ma67Q/Pr1lXp/9Fn3lP5BeuV4RseIVsmT71s4CKlpQcv3KM66sUuIGUrJY1D 20 | Y+fUHB+uO18xXTa6xIJQECtNWkyuEOwWW/XXLdgPvspNzgug2po31qiCNsXly/DY 21 | OHtPpP9qvBg93KeSd+E+YQKBgQCuoT3Rvgohp9ILi8jk0aXA8X5y52HArbucXpiX 22 | ezxv0YDgfXB+A83AFEpHoE2efrSuSpNMxNWlKP0eYdH89T9zV8nqCZV17NRuTq0u 23 | 3BuVvOgKE9tSI8DZCejryqXRuZ84wQqgm62vLhys564it0sAwD8yogal4eLLImTK 24 | H/UvAQKBgQCTmnvM//tf6Y1UQK5cGbsw5KaenzZizluHo0MbmT0bxOiJw6Vt0icR 25 | ngavgGfoOz41A11AMCGsFUPCo2rDDPlaLstETv6ZPrQGsrMnszrjJbDBRbymDBrq 26 | skRddZpVW7vFRJCcFrKGy4AQrcsuPk82R9ddqnIcmZuI7t+fbt3Obg== 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /nifty-examples/src/main/resources/client.pkcs12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookarchive/nifty/ccacff7f0a723abe0b9ed399bcc3bc85784e7396/nifty-examples/src/main/resources/client.pkcs12 -------------------------------------------------------------------------------- /nifty-examples/src/main/resources/rsa.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDADCCAegCCQDc8kDPGQB6tjANBgkqhkiG9w0BAQUFADBCMQswCQYDVQQGEwJY 3 | WDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBh 4 | bnkgTHRkMB4XDTE2MDkwNzE4Mzc1M1oXDTQ0MDEyNDE4Mzc1M1owQjELMAkGA1UE 5 | BhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UECgwTRGVmYXVsdCBD 6 | b21wYW55IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANyeX1NY 7 | eawwW5p0LSxURYHanQcEt8JyQW491wZ/NnZf8VAIWTELhE+pAz8gQeQRSIAV8h74 8 | PsKJDiLtLDXeUev/yhalD3bG0jS2zez41XAM9p37vumOpvAKZz1F1iO180/lndnS 9 | 6rIaSiJC6G8km16bVQCGJE7PYmkghQmKSrGsZg6zJck5HLoUCEQkVjZPzATurZUM 10 | Q/dCQhrwr+lSh46iIJmVsLBKnPPG9U7IwonyRHEiu0y4O8F2OB+sZCQ4RVe8Oamw 11 | JNYlwN8T+guqlhzrwBbudE1TiSct8PgdsGtv+/Uea7b9lYV7tNkKir3aD3Og95LY 12 | +gHWalO+Uu4IznECAwEAATANBgkqhkiG9w0BAQUFAAOCAQEArVLAsKsrkADF1L6F 13 | GcETTk+E0+0sXdT0k7WRBNB/Q0KyFcEcCvMZmcNsKwzb4YJo1b90GuwL9dYziYaK 14 | /mX09H9v1NeW76mLU0V0vQGXjmWdYBzk7b1IIsCr+lhPEZCrl0tGa1LrckOMZd4y 15 | 9pV/3PE1A3Jdvx6EknvCtyAiW3EKdwv06gR1KSktSQWNeizmgS2cCOOrpcqcFQvS 16 | HnHmJ+pegDrKGVEUQZkqHKqB0FLU0K+Ks16j4fnOJgVYlHIOc84upsJ/1AYNCI5R 17 | OOUag7ted5atqJP1VCbLnO7QPwvXvfbb9H+OUcH/PoBkPjwrx9Jxfp+LeGdOZaWQ 18 | ffoVDA== 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /nifty-examples/src/main/resources/rsa.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDcnl9TWHmsMFua 3 | dC0sVEWB2p0HBLfCckFuPdcGfzZ2X/FQCFkxC4RPqQM/IEHkEUiAFfIe+D7CiQ4i 4 | 7Sw13lHr/8oWpQ92xtI0ts3s+NVwDPad+77pjqbwCmc9RdYjtfNP5Z3Z0uqyGkoi 5 | QuhvJJtem1UAhiROz2JpIIUJikqxrGYOsyXJORy6FAhEJFY2T8wE7q2VDEP3QkIa 6 | 8K/pUoeOoiCZlbCwSpzzxvVOyMKJ8kRxIrtMuDvBdjgfrGQkOEVXvDmpsCTWJcDf 7 | E/oLqpYc68AW7nRNU4knLfD4HbBrb/v1Hmu2/ZWFe7TZCoq92g9zoPeS2PoB1mpT 8 | vlLuCM5xAgMBAAECggEAZt8WNgfYXFkELcYkVjpJWt50QBSMFwgtyFjfjfD9lT7x 9 | h88Mv9jN7lMx51qEPvNsKgWRq603noBH7jNHXSr4aiIQunRm/IyC8f+Xj/sLkz8I 10 | M+xyPfe9kcpYD3MkAezSspuv+iTmOPwXO1iVh1W7eObXQPJLtc/v5HM8dZFdePC7 11 | ztwZ6M6TxxBcGRp7Q79CVwGBQg/IRPe5btUKBEPm/p/T1IlUMxu4XhCaRraVY1J5 12 | F+Y1C16f3KlcpShT/7P8ETMh74CYSN1gpijzizsp+TSKkJBbRHNB6191Jtefb5NY 13 | YIN4pIjAVKBpVeU09eZU8MR37nCZVUFBit9x3YjpjQKBgQDyEKhXlt8OJsbHJNb1 14 | L8vIO7ULmyPbjjond5zSTMFFQZ++XGY2YETy9P9BwWnwFU9gkVNIk2d/Zw3nRm3t 15 | 6hr/8Y1M5sSKHAfp6E3tLoyAA8j375OaDjqwb9/+vYXoMK6KgmSNLoEYkyKuFZi8 16 | FNcujHAbVcoM5Z+3qgunBXu54wKBgQDpUaf7Kp2SlBrWvGEFQmACOcQoEN6YZ9NM 17 | iVqteTML4LwpdH2bKhla3ZtB3LIVJchTFDdAPwb45J8ka3Xkh6Mu41If91UPEPU0 18 | rxnxQDbdTkj+CyqItmJv/srr/D413Fq4zFr6nzoogmNdP1sqMGKMRFvr/Q1ArskG 19 | WbQsWS9WmwKBgQCUounbrsaUd/cC/XoI4Cpvb0pCMCcagADxjx76eysKDbu7Nh2F 20 | MiPkU9ARXmRgiZVOJK5RGEIrFuqQosyJlICzvG0ZVXJFo+SwGncPNtALI0faBoBJ 21 | zob3JBsU3udEpe/nGR4JGw8mOeLHpnc8tkdTS+TixBDnTnB+ZKn3CwToJQKBgQCG 22 | 7odUNRANrgNbfnQpg3pcryWm+iKRRzImyCSdwELqMpz+6HSfoJgrOY/JZiXDHyec 23 | DEvrpseUdzsl59O1R0/zFNnwzKvvW6JDRqSdJcLU96o06SY/DCMfm92k3iroITiC 24 | OQTAfgc3WDi4u6QwYO0NK5dxgdYBO1PcjVIqd6Vt0wKBgQDPg9LjSwU91UrhxoYt 25 | OgFaxOT0tzhKU/LiB7yf0zZoOlwkOVBqmEfcJMaUb9WvyQqFAB/1UuHbKQrhPhl7 26 | 1x1X05DOOJ2L3CF/ePxirPAghDU0ShkoE/TjlDRrApMrun42zp9dNcAcCbLPShMQ 27 | 8LihO1Ig1Eg/W+LL0DDvPO2WPQ== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /nifty-examples/src/main/resources/rsa2.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDADCCAegCCQD1RG1rsVpzezANBgkqhkiG9w0BAQUFADBCMQswCQYDVQQGEwJY 3 | WDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBh 4 | bnkgTHRkMB4XDTE2MDkwMjIyMDgwMFoXDTQ0MDExOTIyMDgwMFowQjELMAkGA1UE 5 | BhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UECgwTRGVmYXVsdCBD 6 | b21wYW55IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN4DDpeP 7 | MgjZwVZJs68BCplRLnQjouaEF5Xsp6KZ1omPF2AfgOokuP+QaFdvYRlV/hd+8MOq 8 | zG/T7eYAElwRE51aLsKWgDE04RTvUogwskdgA8sXq5fOylPNu/6swEQspkrty2pH 9 | gBdLERBB/sB298f/l4zaUujwgjPiXXTSQpelfJPxSGXRWiXFpqf5W5cLJ7O9bjnJ 10 | 63vfFv2OT5CVDaRLkP588REtnwJye1JlS7ToHVZjt2qlqUVJnBxNuWhzv9wX2CJQ 11 | EK6L87N5ThhRkWZ1x0X1IJY5UcdbZr/r0NVLSf9zGBcnuR/p8K264l9KBG9/n75T 12 | A7XUwnxe5VZPsWcCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAE5k2XK15dlNOY0ak 13 | ldcGoJwry/5UKE3IQ3orLC/WtGc/sMBEbfoijonoenGZQqjEe9kDGiZA461tZ0Ai 14 | oRIHbXYKmJME+lkKmqvZaeD6Aa8t8T2sQAn3gcFjQFNYrA0OJm5OAzCHqIauHsI4 15 | 1rwxqEDCxs44J1c+Zk9v900b7amvNgwTlSjJT8Oe4hSPqAkJ/IA1tmGb6Z+UUB6F 16 | gDGishP+tVaxnqjzIGZPJ90Ec+2/ULMkteUeTSrYdctgjuNPLqSVouOdECEi9361 17 | trNN2LKSTWCMqFI0TsXI78L+XbqoE8ntcKgfrtTvBGajn4+AbLCleYH0FhIBN4Kq 18 | QcdPnA== 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /nifty-examples/src/main/resources/rsa2.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEA3gMOl48yCNnBVkmzrwEKmVEudCOi5oQXleynopnWiY8XYB+A 3 | 6iS4/5BoV29hGVX+F37ww6rMb9Pt5gASXBETnVouwpaAMTThFO9SiDCyR2ADyxer 4 | l87KU827/qzARCymSu3LakeAF0sREEH+wHb3x/+XjNpS6PCCM+JddNJCl6V8k/FI 5 | ZdFaJcWmp/lblwsns71uOcnre98W/Y5PkJUNpEuQ/nzxES2fAnJ7UmVLtOgdVmO3 6 | aqWpRUmcHE25aHO/3BfYIlAQrovzs3lOGFGRZnXHRfUgljlRx1tmv+vQ1UtJ/3MY 7 | Fye5H+nwrbriX0oEb3+fvlMDtdTCfF7lVk+xZwIDAQABAoIBAHhGrbQcRt4WorCN 8 | s0PfS4+uNH2FBO7fpyt5D4R+1YSmueJAjwXKqVMDOBQOaktglAzEn8lRkfoPlbXi 9 | Wg/4zGiV//k5se92l25RDaRsxVj3wnZXt4XB6Uknj260xmDo05qKY4aLf/CeoXru 10 | VgaNLUXzyXXsnbhG/DMBsuHkO2GNqrS6mI7sj1+rxan6qe45dwIt8NLG7U/6vZGJ 11 | oTk6AZKA1nz1PZoMn8I+g81nOmMQx6v2fHYIaImqeu0c9hF9hWqw5SeFC8iY9+He 12 | 5yPLJSiKw8y7548tMUeXsZuXRbFCTr6j05kz01xNHtIsQI2GSm2CZexThM8wpxAF 13 | PhUz+jECgYEA7uL1RHfJK5ePe57FH6KlsAkmCP5aPkpAdJbR6MmmS4gcOXVVSEOm 14 | HUKGuMRvAJQXxpuWNdLWHKY/5sOEfFaWq3YOKz+SpwD01Tkk7PExEZUX5cICMar/ 15 | yOBnYC0bgaZhRTWDGcZzy8cMp7LKlAVYASipgKGAVFfc3JPDaO6+eY8CgYEA7eqg 16 | 00HBrYiZ2PEa4jPHYYiRCw460Un9bHHq6MlCiR3Y+GtqIkWZmx+e4kmWSIQVV8Fi 17 | c9qOlojo1vxO5qFJIhi2ejOsbFsMk+tqsB1PzlyCvpXaqVUFxrtLm28ud0ho2q5r 18 | Rch2SjMolLM/I0HdP2PYMellcuAJuFIP89FKbqkCgYAUGVBdhF6Opl/SHNelA8BB 19 | AWQL2aqqFwE5Tf83QNAXBsqpIvAb9mUhjRlcrlpQiCU/9pM60BRnsK0rs0OQWpCu 20 | uG4UwXKLTo9K6VXsAZcJTawHDr20hBilRAwukV0BGYiRlCEFqCbR/FtaOLbGoXR4 21 | FH2+btgnQIU6ocwNJhksjQKBgC4wFabNpj79PPjb3d86NCPgMmBWE98boSJTf0pQ 22 | ACXEcKHRoJokruxpmBvQM2fClK4jsexR6sqYq7NI6jxl5V/EMnDI5Vln16pD0sN7 23 | /UlPtmYvi3LCOcvaApSbYgbwPMLvh43Vm/lNszwjDEfY+o3a4VbXO8WwbtKkw8oO 24 | wId5AoGBALuheBhe+s+9pUl4h4B4tI6EiE6DWNERyL/N7Ig5JGq4YnXeS/uzv1zH 25 | Qc2LIfJ9A91Su1JNngm27mZKlX+6TOMlgNcWk/PdbaHWaD/q7u6ZbTMyfWfZfBTW 26 | bvUaeMG3qYGQKI7o7VfhZzPNUbcEIMmDv5nB3zYGlC1P3ILMfWEf 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /nifty-examples/src/main/resources/scribe.thrift: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/thrift --gen cpp:pure_enums --gen php 2 | 3 | ## Copyright (c) 2007-2008 Facebook 4 | ## 5 | ## Licensed under the Apache License, Version 2.0 (the "License"); 6 | ## you may not use this file except in compliance with the License. 7 | ## You may obtain a copy of the License at 8 | ## 9 | ## http://www.apache.org/licenses/LICENSE-2.0 10 | ## 11 | ## Unless required by applicable law or agreed to in writing, software 12 | ## distributed under the License is distributed on an "AS IS" BASIS, 13 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ## See the License for the specific language governing permissions and 15 | ## limitations under the License. 16 | ## 17 | ## See accompanying file LICENSE or visit the Scribe site at: 18 | ## http://developers.facebook.com/scribe/ 19 | 20 | namespace java com.facebook.nifty.test 21 | 22 | enum ResultCode 23 | { 24 | OK, 25 | TRY_LATER 26 | } 27 | 28 | struct LogEntry 29 | { 30 | 1: string category, 31 | 2: string message 32 | } 33 | 34 | service scribe 35 | { 36 | ResultCode Log(1: list messages); 37 | } 38 | -------------------------------------------------------------------------------- /nifty-examples/src/main/resources/ticket_seeds.json: -------------------------------------------------------------------------------- 1 | { 2 | "old" : ["aaaaaaaaaa"], 3 | "current" : ["bbbbbbbbbb"], 4 | "new" : ["cccccccccc"] 5 | } 6 | -------------------------------------------------------------------------------- /nifty-examples/src/main/resources/ticket_seeds2.json: -------------------------------------------------------------------------------- 1 | { 2 | "old" : ["bbbbbbbbbb"], 3 | "current" : ["cccccccccc"], 4 | "new" : ["dddddddddd"] 5 | } 6 | -------------------------------------------------------------------------------- /nifty-examples/src/test/java/com/facebook/nifty/server/DelegateSelectorProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.server; 17 | 18 | import java.io.IOException; 19 | import java.net.ProtocolFamily; 20 | import java.nio.channels.Channel; 21 | import java.nio.channels.DatagramChannel; 22 | import java.nio.channels.Pipe; 23 | import java.nio.channels.ServerSocketChannel; 24 | import java.nio.channels.SocketChannel; 25 | import java.nio.channels.spi.AbstractSelector; 26 | import java.nio.channels.spi.SelectorProvider; 27 | 28 | /** 29 | * SelectorProvider.provider() caches whatever initialized statically, so 30 | * when running in a test suite simply clearing the property 31 | * "java.nio.channels.spi.SelectorProvider" would not work to restore 32 | * other tests to operate on normal selector provider. 33 | * 34 | * This is a hack to make it work. 35 | */ 36 | public class DelegateSelectorProvider extends SelectorProvider { 37 | private static final SelectorProvider original ; 38 | private static final SelectorProvider deaf = new DeafSelectorProvider(); 39 | private static SelectorProvider delegate ; 40 | 41 | static { 42 | try { 43 | // hack to work around compiler complaints about sun.nio.ch.PollSelectorProvider 44 | // being proprietary 45 | delegate = original = (SelectorProvider) Class.forName("sun.nio.ch.PollSelectorProvider").newInstance(); 46 | } catch (Exception e) { 47 | throw new RuntimeException(e); 48 | } 49 | System.setProperty( 50 | "java.nio.channels.spi.SelectorProvider", 51 | DelegateSelectorProvider.class.getName() 52 | ); 53 | } 54 | 55 | public static void init() { 56 | } 57 | 58 | public static void makeDeaf() { 59 | delegate = deaf ; 60 | } 61 | 62 | public static void makeUndeaf() { 63 | delegate = original; 64 | } 65 | 66 | @Override 67 | public DatagramChannel openDatagramChannel() throws IOException { 68 | return delegate.openDatagramChannel(); 69 | } 70 | 71 | @Override 72 | public DatagramChannel openDatagramChannel(ProtocolFamily family) throws IOException { 73 | return delegate.openDatagramChannel(family); 74 | } 75 | 76 | @Override 77 | public Pipe openPipe() throws IOException { 78 | return delegate.openPipe(); 79 | } 80 | 81 | @Override 82 | public AbstractSelector openSelector() throws IOException { 83 | return delegate.openSelector(); 84 | } 85 | 86 | @Override 87 | public ServerSocketChannel openServerSocketChannel() throws IOException { 88 | return delegate.openServerSocketChannel(); 89 | } 90 | 91 | @Override 92 | public SocketChannel openSocketChannel() throws IOException { 93 | return delegate.openSocketChannel(); 94 | } 95 | 96 | @Override 97 | public Channel inheritedChannel() throws IOException { 98 | return delegate.inheritedChannel(); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /nifty-examples/src/test/java/com/facebook/nifty/server/TestPlainClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.server; 17 | 18 | import com.facebook.nifty.server.util.ScopedNiftyServer; 19 | import com.facebook.nifty.test.LogEntry; 20 | import com.facebook.nifty.test.ResultCode; 21 | import com.facebook.nifty.test.scribe; 22 | import io.airlift.log.Logger; 23 | import org.apache.thrift.TException; 24 | import org.apache.thrift.TProcessor; 25 | import org.apache.thrift.protocol.TBinaryProtocol; 26 | import org.apache.thrift.transport.TFramedTransport; 27 | import org.apache.thrift.transport.TSocket; 28 | import org.testng.annotations.Test; 29 | 30 | import java.io.IOException; 31 | import java.util.Arrays; 32 | import java.util.List; 33 | 34 | import static com.facebook.nifty.server.util.ScopedNiftyServer.defaultServerDefBuilder; 35 | 36 | public class TestPlainClient { 37 | private static final Logger log = Logger.get(TestPlainClient.class); 38 | 39 | @Test 40 | public void testPlainUnframedClient() throws Exception 41 | { 42 | try (ScopedNiftyServer server = makeServer()) { 43 | TSocket socket = new TSocket("localhost", server.getPort()); 44 | socket.open(); 45 | socket.setTimeout(1000); 46 | TBinaryProtocol protocol = new TBinaryProtocol(socket); 47 | 48 | scribe.Client client = new scribe.Client(protocol); 49 | 50 | LogEntry entry = new LogEntry("TestLog", "Test message from plain unframed client"); 51 | client.Log(Arrays.asList(entry)); 52 | 53 | socket.close(); 54 | } 55 | } 56 | 57 | @Test 58 | public void testPlainFramedClient() throws Exception { 59 | try (ScopedNiftyServer server = makeServer()) { 60 | TSocket socket = new TSocket("localhost", server.getPort()); 61 | socket.open(); 62 | socket.setTimeout(1000); 63 | TFramedTransport framedTransport = new TFramedTransport(socket); 64 | TBinaryProtocol protocol = new TBinaryProtocol(framedTransport); 65 | 66 | scribe.Client client = new scribe.Client(protocol); 67 | 68 | LogEntry entry = new LogEntry("TestLog", "Test message from plain framed client"); 69 | client.Log(Arrays.asList(entry)); 70 | 71 | socket.close(); 72 | } 73 | } 74 | 75 | public ScopedNiftyServer makeServer() throws IOException { 76 | TProcessor processor = new scribe.Processor<>(new scribe.Iface() 77 | { 78 | @Override 79 | public ResultCode Log(List messages) 80 | throws TException 81 | { 82 | for (LogEntry message : messages) { 83 | log.info("%s: %s", message.getCategory(), message.getMessage()); 84 | } 85 | return ResultCode.OK; 86 | } 87 | }); 88 | 89 | return new ScopedNiftyServer(defaultServerDefBuilder(processor)); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /nifty-examples/src/test/java/com/facebook/nifty/server/util/ScopedNiftyServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.server.util; 17 | 18 | import com.facebook.nifty.core.NettyServerTransport; 19 | import com.facebook.nifty.core.ThriftServerDef; 20 | import com.facebook.nifty.core.ThriftServerDefBuilder; 21 | import org.apache.thrift.TProcessor; 22 | 23 | import java.net.InetSocketAddress; 24 | 25 | public class ScopedNiftyServer implements AutoCloseable { 26 | private final NettyServerTransport server; 27 | 28 | public ScopedNiftyServer(ThriftServerDefBuilder defBuilder) { 29 | server = new NettyServerTransport(defBuilder.build()); 30 | server.start(); 31 | } 32 | 33 | public int getPort() { 34 | InetSocketAddress localAddress = (InetSocketAddress)server.getServerChannel() 35 | .getLocalAddress(); 36 | return localAddress.getPort(); 37 | } 38 | 39 | @Override 40 | public void close() throws Exception { 41 | server.stop(); 42 | } 43 | 44 | public static ThriftServerDefBuilder defaultServerDefBuilder(TProcessor processor) { 45 | return ThriftServerDef.newBuilder() 46 | .listen(0) 47 | .withProcessor(processor); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /nifty-load-tester/src/main/java/com/facebook/nifty/perf/LoadTestHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.perf; 17 | 18 | import java.lang.InterruptedException; 19 | import java.lang.Thread; 20 | import java.lang.System; 21 | import java.nio.ByteBuffer; 22 | 23 | import org.apache.thrift.TException; 24 | 25 | public class LoadTestHandler implements LoadTest.Iface { 26 | public void noop() { 27 | } 28 | 29 | public void onewayNoop() { 30 | } 31 | 32 | public void asyncNoop() { 33 | } 34 | 35 | public long add(long a, long b) { 36 | return a + b; 37 | } 38 | 39 | public ByteBuffer echo(ByteBuffer data) { 40 | return data; 41 | } 42 | 43 | public void send(ByteBuffer data) { 44 | } 45 | 46 | public ByteBuffer recv(long recvBytes) { 47 | return ByteBuffer.allocate((int)recvBytes); 48 | } 49 | 50 | public ByteBuffer sendrecv(ByteBuffer data, long recvBytes) { 51 | return recv(recvBytes); 52 | } 53 | 54 | public void onewaySend(ByteBuffer data) { 55 | } 56 | 57 | public void onewayThrow(int code) { 58 | // Because this is a one-way throw, it isn't declared in the thrift 59 | // IDL, and doesn't appear on the throws declaration of the generated 60 | // handler interface. Thus, this method must throw an unchecked exception. 61 | throw new Error(); 62 | } 63 | 64 | public void throwUnexpected(int code) { 65 | // Because this is an unexpected throw, it isn't declared in the thrift 66 | // IDL, and doesn't appear on the throws declaration of the generated 67 | // handler interface. Thus, this method must throw an unchecked exception. 68 | throw new Error(); 69 | } 70 | 71 | public void throwError(int code) throws LoadError { 72 | throw new LoadError(code); 73 | } 74 | 75 | public void sleep(long microseconds) { 76 | try { 77 | long ms = microseconds / 1000; 78 | int us = (int)(microseconds % 1000); 79 | Thread.sleep(ms, us); 80 | } 81 | catch (InterruptedException e) { 82 | } 83 | } 84 | 85 | public void onewaySleep(long microseconds) { 86 | sleep(microseconds); 87 | } 88 | 89 | public void badBurn(long microseconds) { 90 | burnImpl(microseconds); 91 | } 92 | 93 | public void badSleep(long microseconds) { 94 | burnImpl(microseconds); 95 | } 96 | 97 | public void onewayBurn(long microseconds) { 98 | burnImpl(microseconds); 99 | } 100 | 101 | public void burn(long microseconds) { 102 | burnImpl(microseconds); 103 | } 104 | 105 | @SuppressWarnings("PMD.EmptyWhileStmt") 106 | private void burnImpl(long microseconds) { 107 | long end = System.nanoTime() + microseconds * 1000; 108 | while (System.nanoTime() < end) {} 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /nifty-load-tester/src/main/java/com/facebook/nifty/perf/LoadTesterNettyConfigProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.perf; 17 | 18 | import com.facebook.nifty.core.NettyServerConfig; 19 | import com.facebook.nifty.core.NettyServerConfigBuilder; 20 | import com.google.inject.Inject; 21 | import com.google.inject.Provider; 22 | 23 | public class LoadTesterNettyConfigProvider implements Provider { 24 | private final NiftyLoadTester.LoadTesterConfig config; 25 | 26 | @Inject 27 | public LoadTesterNettyConfigProvider(NiftyLoadTester.LoadTesterConfig config) 28 | { 29 | this.config = config; 30 | } 31 | 32 | @Override 33 | public NettyServerConfig get() { 34 | NettyServerConfigBuilder configBuilder = new NettyServerConfigBuilder(); 35 | configBuilder.getServerSocketChannelConfig().setBacklog(config.getAcceptBacklog()); 36 | configBuilder.setBossThreadCount(config.getNumBossThreads()); 37 | configBuilder.setWorkerThreadCount(config.getNumIoThreads()); 38 | return configBuilder.build(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /nifty-load-tester/src/main/resources/load.thrift: -------------------------------------------------------------------------------- 1 | namespace java com.facebook.nifty.perf 2 | 3 | exception LoadError { 4 | 1: i32 code 5 | } 6 | 7 | service LoadTest { 8 | // Methods for testing server performance 9 | // Fairly simple requests, to minimize serialization overhead 10 | 11 | /** 12 | * noop() returns immediately, to test behavior of fast, cheap operations 13 | */ 14 | void noop() 15 | oneway void onewayNoop() 16 | 17 | /** 18 | * asyncNoop() is like noop() except for one minor difference in the async 19 | * implementation. 20 | * 21 | * In the async handler, noop() invokes the callback immediately, while 22 | * asyncNoop() uses runInLoop() to invoke the callback. 23 | */ 24 | void asyncNoop() 25 | 26 | /** 27 | * sleep() waits for the specified time period before returning, 28 | * to test slow, but not CPU-intensive operations 29 | */ 30 | void sleep(1: i64 microseconds) 31 | oneway void onewaySleep(1: i64 microseconds) 32 | 33 | /** 34 | * burn() uses as much CPU as possible for the desired time period, 35 | * to test CPU-intensive operations 36 | */ 37 | void burn(1: i64 microseconds) 38 | oneway void onewayBurn(1: i64 microseconds) 39 | 40 | /** 41 | * badSleep() is like sleep(), except that it exhibits bad behavior in the 42 | * async implementation. 43 | * 44 | * Instead of returning control to the event loop, it actually sleeps in the 45 | * worker thread for the specified duration. This tests how well the thrift 46 | * infrastructure responds to badly written handler code. 47 | */ 48 | void badSleep(1: i64 microseconds) 49 | 50 | /** 51 | * badBurn() is like burn(), except that it exhibits bad behavior in the 52 | * async implementation. 53 | * 54 | * The normal burn() call periodically yields to the event loop, while 55 | * badBurn() does not. This tests how well the thrift infrastructure 56 | * responds to badly written handler code. 57 | */ 58 | void badBurn(1: i64 microseconds) 59 | 60 | /** 61 | * throw an error 62 | */ 63 | void throwError(1: i32 code) throws (1: LoadError error) 64 | 65 | /** 66 | * throw an unexpected error (not declared in the .thrift file) 67 | */ 68 | void throwUnexpected(1: i32 code) 69 | 70 | /** 71 | * throw an error in a oneway call, 72 | * just to make sure the internal thrift code handles it properly 73 | */ 74 | oneway void onewayThrow(1: i32 code) 75 | 76 | /** 77 | * Send some data to the server. 78 | * 79 | * The data is ignored. This is primarily to test the server I/O 80 | * performance. 81 | */ 82 | void send(1: binary data) 83 | 84 | /** 85 | * Send some data to the server. 86 | * 87 | * The data is ignored. This is primarily to test the server I/O 88 | * performance. 89 | */ 90 | oneway void onewaySend(1: binary data) 91 | 92 | /** 93 | * Receive some data from the server. 94 | * 95 | * The contents of the data are undefined. This is primarily to test the 96 | * server I/O performance. 97 | */ 98 | binary recv(1: i64 bytes) 99 | 100 | /** 101 | * Send and receive data 102 | */ 103 | binary sendrecv(1: binary data, 2: i64 recvBytes) 104 | 105 | /** 106 | * Echo data back to the client. 107 | */ 108 | binary echo(1: binary data) 109 | 110 | /** 111 | * Add the two integers 112 | */ 113 | i64 add(1: i64 a, 2: i64 b) 114 | } 115 | -------------------------------------------------------------------------------- /nifty-load-tester/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | 22 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{15} - %msg%n%throwable{10} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /nifty-ssl/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 4.0.0 21 | 22 | 23 | com.facebook.nifty 24 | nifty-parent 25 | 0.24.0-SNAPSHOT 26 | ../pom.xml 27 | 28 | 29 | Nifty SSL 30 | nifty-ssl 31 | jar 32 | 33 | 34 | ${project.parent.basedir} 35 | 36 | 37 | 38 | 39 | com.facebook.nifty 40 | nifty-core 41 | 42 | 43 | 44 | com.google.guava 45 | guava 46 | 47 | 48 | 49 | io.netty 50 | netty 51 | 52 | 53 | 54 | io.netty 55 | netty-tcnative-boringssl-static 56 | 57 | 58 | 59 | com.fasterxml.jackson.core 60 | jackson-core 61 | 62 | 63 | 64 | com.fasterxml.jackson.core 65 | jackson-databind 66 | 67 | 68 | 69 | io.airlift 70 | log 71 | 72 | 73 | 74 | io.airlift 75 | units 76 | 77 | 78 | 79 | org.testng 80 | testng 81 | test 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /nifty-ssl/src/main/java/com/facebook/nifty/ssl/BetterSslHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.ssl; 17 | 18 | import org.jboss.netty.handler.ssl.OpenSslEngine; 19 | import org.jboss.netty.handler.ssl.SslBufferPool; 20 | import org.jboss.netty.handler.ssl.SslHandler; 21 | 22 | import javax.net.ssl.SSLEngine; 23 | 24 | /** 25 | * We're seeing SslEngine leaking in a few places. 26 | * This SslHandler uses a finalizer to clean up the SslEngine 27 | * correctly like netty 4 does as well. 28 | */ 29 | public class BetterSslHandler extends SessionAwareSslHandler { 30 | 31 | private final OpenSslEngine sslEngine; 32 | // Effective Java Item 7 - use a finalizer guardian object to make sure a misbehaving subclass cannot 33 | // prevent our finalizer from running (by overriding it and failing to call super.finalize()). 34 | private final Object finalizerGuardian = new Object() { 35 | @Override protected void finalize() throws Throwable { 36 | sslEngine.shutdown(); 37 | super.finalize(); 38 | } 39 | }; 40 | 41 | public BetterSslHandler(SSLEngine engine, SslBufferPool bufferPool, SslServerConfiguration configuration) { 42 | super(engine, bufferPool, configuration); 43 | sslEngine = (OpenSslEngine) engine; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /nifty-ssl/src/main/java/com/facebook/nifty/ssl/MultiFileWatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.ssl; 17 | 18 | import java.io.File; 19 | import java.util.Set; 20 | import java.util.function.Consumer; 21 | 22 | /** 23 | * An interface for classes that watch a set of file for changes and call a user-specified callback when any of 24 | * the watched files change. 25 | */ 26 | interface MultiFileWatcher { 27 | /** 28 | * Starts the watcher. When any of the provided files change, the provided callback will be called with the 29 | * files that changed since the last time the callback was invoked. It is up to the implementation how the 30 | * watched files are monitored for changes, and how much time passes between the file change and the callback 31 | * invocation. For example, a polling watcher such as {@link PollingMultiFileWatcher} will not call the user 32 | * callback until the next poll cycle, while a watcher that uses file system event listeners might respond to 33 | * changes much more quickly. 34 | * 35 | * @param files a set of one or more files to watch for changes. 36 | * @param callback the callback to call with the set of files that changed since the last time. The set of 37 | * modified files passed to the callback should never be null or empty. 38 | */ 39 | void start(Set files, Consumer> callback); 40 | 41 | /** 42 | * Stops the watcher. 43 | */ 44 | void shutdown(); 45 | 46 | /** 47 | * Checks if the watcher has been start()'ed and has not been shutdown(). 48 | * @return true if and only if start() has been called and shutdown() has not been called. 49 | */ 50 | boolean isStarted(); 51 | } 52 | -------------------------------------------------------------------------------- /nifty-ssl/src/main/java/com/facebook/nifty/ssl/OpenSSLConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.ssl; 17 | 18 | /** 19 | * Collection of constants defined by OpenSSL which are not available via 20 | * netty tc-native. 21 | */ 22 | public interface OpenSSLConstants { 23 | /* Session related */ 24 | long SSL_SESS_CACHE_NO_INTERNAL_LOOKUP = 0x0100; 25 | long SSL_SESS_CACHE_NO_INTERNAL_STORE = 0x0200; 26 | long SSL_SESS_CACHE_NO_INTERNAL = SSL_SESS_CACHE_NO_INTERNAL_LOOKUP | SSL_SESS_CACHE_NO_INTERNAL_STORE; 27 | } 28 | -------------------------------------------------------------------------------- /nifty-ssl/src/main/java/com/facebook/nifty/ssl/OpenSslSessionHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.ssl; 17 | 18 | import org.apache.tomcat.jni.SSL; 19 | import org.jboss.netty.handler.ssl.OpenSslEngine; 20 | 21 | import javax.net.ssl.SSLEngine; 22 | import javax.net.ssl.SSLException; 23 | import javax.net.ssl.SSLSession; 24 | import javax.security.cert.CertificateException; 25 | import javax.security.cert.X509Certificate; 26 | import java.lang.reflect.Field; 27 | 28 | /** 29 | * This class provides a method to extract properties of the SSL session 30 | * from an engine. 31 | * Netty's OpenSSL engine class does not implement getSession() fully, thus 32 | * we have to extract the properties that we need ourselves. 33 | */ 34 | public class OpenSslSessionHelper { 35 | private static Field sslField; 36 | 37 | static { 38 | try { 39 | sslField = OpenSslEngine.class.getDeclaredField("ssl"); 40 | sslField.setAccessible(true); 41 | } 42 | catch (Throwable t) { 43 | // Ignore. 44 | } 45 | } 46 | 47 | public static SslSession getSession(SSLEngine sslEngine) throws SSLException { 48 | if (!(sslEngine instanceof OpenSslEngine)) { 49 | throw new IllegalArgumentException("ssl engine not openssl engine"); 50 | } 51 | OpenSslEngine engine = (OpenSslEngine) sslEngine; 52 | if (sslField == null) { 53 | throw new SSLException("SSL field is null"); 54 | } 55 | try { 56 | long sslPtr = (long) sslField.get(engine); 57 | if (sslPtr == 0) { 58 | throw new SSLException("SSL not initialized"); 59 | } 60 | String alpn = SSL.getAlpnSelected(sslPtr); 61 | String npn = SSL.getNextProtoNegotiated(sslPtr); 62 | 63 | String version = SSL.getVersion(sslPtr); 64 | String cipher = SSL.getCipherForSSL(sslPtr); 65 | long establishedTime = SSL.getTime(sslPtr); 66 | 67 | // TODO: return the entire chain. 68 | // tc-native thinks that the chain is null, so we supply only the 69 | // leaf cert. 70 | byte[] cert = SSL.getPeerCertificate(sslPtr); 71 | X509Certificate certificate = null; 72 | if (cert != null) { 73 | certificate = X509Certificate.getInstance(cert); 74 | } 75 | return new SslSession(alpn, npn, version, cipher, establishedTime, certificate); 76 | } 77 | catch (IllegalAccessException e) { 78 | throw new SSLException(e); 79 | } 80 | catch (CertificateException e) { 81 | throw new SSLException(e); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /nifty-ssl/src/main/java/com/facebook/nifty/ssl/SslDefaults.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.ssl; 17 | 18 | import com.google.common.collect.ImmutableList; 19 | 20 | import java.util.ArrayList; 21 | import java.util.Collections; 22 | import java.util.List; 23 | 24 | public class SslDefaults { 25 | public static final ImmutableList SERVER_DEFAULTS = ImmutableList.of( 26 | "ECDHE-ECDSA-AES128-GCM-SHA256", 27 | "ECDHE-ECDSA-AES256-GCM-SHA256", 28 | "ECDHE-RSA-AES128-GCM-SHA256", 29 | "ECDHE-RSA-AES256-GCM-SHA384", 30 | "ECDHE-ECDSA-AES256-SHA", 31 | "ECDHE-RSA-AES256-SHA", 32 | "ECDHE-ECDSA-AES128-SHA", 33 | "ECDHE-RSA-AES128-SHA", 34 | "ECDHE-RSA-AES256-SHA384", 35 | "AES128-GCM-SHA256", 36 | "AES256-SHA", 37 | "AES128-SHA"); 38 | } 39 | -------------------------------------------------------------------------------- /nifty-ssl/src/test/java/com/facebook/nifty/ssl/CryptoUtilTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.ssl; 17 | 18 | import org.testng.Assert; 19 | import org.testng.annotations.Test; 20 | 21 | import static com.facebook.nifty.ssl.CryptoUtil.decodeHex; 22 | import static com.facebook.nifty.ssl.CryptoUtil.hkdf; 23 | 24 | public class CryptoUtilTest { 25 | 26 | class TestVector { 27 | String key; 28 | String salt; 29 | String info; 30 | String expected; 31 | } 32 | 33 | // Test cases taken from https://tools.ietf.org/html/rfc5869 34 | public void validateVector(TestVector vector) { 35 | byte[] key = decodeHex(vector.key); 36 | byte[] salt = vector.salt.isEmpty() ? null : decodeHex(vector.salt); 37 | byte[] info = vector.info.isEmpty() ? null : decodeHex(vector.info); 38 | byte[] expected = decodeHex(vector.expected); 39 | byte[] actual = hkdf(key, salt, info, expected.length); 40 | Assert.assertEquals(actual, expected); 41 | } 42 | 43 | /** 44 | * Test vector data is from RFC 5869, appendix A.1. (Test Case 1) 45 | */ 46 | @Test 47 | public void testHkdf1() { 48 | TestVector vector = new TestVector(); 49 | vector.key = "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"; 50 | vector.salt = "000102030405060708090a0b0c"; 51 | vector.info = "f0f1f2f3f4f5f6f7f8f9"; 52 | vector.expected = "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"; 53 | validateVector(vector); 54 | } 55 | 56 | /** 57 | * Test vector data is from RFC 5869, appendix A.2. (Test Case 2) 58 | */ 59 | @Test 60 | public void testHkdf2() { 61 | TestVector vector = new TestVector(); 62 | vector.key = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b" + 63 | "2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"; 64 | vector.salt = "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8" + 65 | "b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf"; 66 | vector.info = "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dad" + 67 | "bdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; 68 | vector.expected = "b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271c" + 69 | "b41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f"; 70 | validateVector(vector); 71 | } 72 | 73 | /** 74 | * Test vector data is from RFC 5869, appendix A.3. (Test Case 3) 75 | */ 76 | @Test 77 | public void testHkdf3() { 78 | TestVector vector = new TestVector(); 79 | vector.key = "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"; 80 | vector.salt = ""; 81 | vector.info = ""; 82 | vector.expected = "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8"; 83 | validateVector(vector); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /nifty-ssl/src/test/java/com/facebook/nifty/ssl/ThreadLocalSslBufferPoolTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.ssl; 17 | 18 | import org.jboss.netty.handler.ssl.SslBufferPool; 19 | import org.testng.Assert; 20 | import org.testng.annotations.Test; 21 | 22 | import java.nio.ByteBuffer; 23 | 24 | public class ThreadLocalSslBufferPoolTest { 25 | @Test 26 | public void testMultipleThreads() { 27 | int numThreads = 5; 28 | int maxPoolSize = ThreadLocalSslBufferPool.getBufferSize() * numThreads; 29 | SslBufferPool pool = new ThreadLocalSslBufferPool(maxPoolSize, true, true, numThreads); 30 | Assert.assertEquals(pool.getMaxPoolSize(), ThreadLocalSslBufferPool.getBufferSize()); 31 | Assert.assertEquals(pool.getUnacquiredPoolSize(), ThreadLocalSslBufferPool.getBufferSize()); 32 | } 33 | 34 | @Test 35 | public void testPreallocated() { 36 | int maxPoolSize = ThreadLocalSslBufferPool.getBufferSize() * 5; 37 | SslBufferPool pool = new ThreadLocalSslBufferPool(maxPoolSize, true, true, 1); 38 | Assert.assertEquals(pool.getMaxPoolSize(), maxPoolSize); 39 | Assert.assertEquals(pool.getUnacquiredPoolSize(), maxPoolSize); 40 | 41 | ByteBuffer buf = null; 42 | try { 43 | buf = pool.acquireBuffer(); 44 | Assert.assertEquals(buf.capacity(), ThreadLocalSslBufferPool.getBufferSize()); 45 | Assert.assertEquals(pool.getUnacquiredPoolSize(), maxPoolSize - ThreadLocalSslBufferPool.getBufferSize()); 46 | } finally { 47 | pool.releaseBuffer(buf); 48 | } 49 | } 50 | 51 | @Test 52 | public void testNonPreallocated() { 53 | int maxPoolSize = ThreadLocalSslBufferPool.getBufferSize() * 5; 54 | SslBufferPool pool = new ThreadLocalSslBufferPool(maxPoolSize, false, true, 1); 55 | Assert.assertEquals(pool.getMaxPoolSize(), maxPoolSize); 56 | Assert.assertEquals(pool.getUnacquiredPoolSize(), 0); 57 | 58 | ByteBuffer buf = null; 59 | try { 60 | buf = pool.acquireBuffer(); 61 | Assert.assertEquals(buf.capacity(), ThreadLocalSslBufferPool.getBufferSize()); 62 | Assert.assertEquals(pool.getUnacquiredPoolSize(), 0); 63 | } finally { 64 | pool.releaseBuffer(buf); 65 | } 66 | Assert.assertEquals(pool.getUnacquiredPoolSize(), ThreadLocalSslBufferPool.getBufferSize()); 67 | } 68 | 69 | @Test 70 | public void testNonBlockingAcquireBuffer() { 71 | SslBufferPool pool = new ThreadLocalSslBufferPool(1, true, true, 1); 72 | 73 | ByteBuffer buf1 = null; 74 | ByteBuffer buf2 = null; 75 | try { 76 | buf1 = pool.acquireBuffer(); 77 | Assert.assertEquals(pool.getUnacquiredPoolSize(), 0); 78 | // Try to acquire buffer. Unlike SslBufferPool, this should not block and will return another buffer. 79 | buf2 = pool.acquireBuffer(); 80 | } finally { 81 | pool.releaseBuffer(buf1); 82 | pool.releaseBuffer(buf2); 83 | } 84 | } 85 | 86 | @Test(expectedExceptions = IllegalArgumentException.class) 87 | public void testInvalidMaxPoolSize() { 88 | SslBufferPool pool = new ThreadLocalSslBufferPool(0, true, true, 1); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /nifty-ssl/src/test/java/com/facebook/nifty/ssl/TicketSeedFileParserTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.facebook.nifty.ssl; 17 | 18 | import com.fasterxml.jackson.core.JsonParseException; 19 | import org.apache.tomcat.jni.SessionTicketKey; 20 | import org.testng.Assert; 21 | import org.testng.annotations.Test; 22 | 23 | import java.io.File; 24 | import java.io.IOException; 25 | import java.util.List; 26 | 27 | public class TicketSeedFileParserTest { 28 | 29 | @Test 30 | public void testParseSeeds() throws IOException { 31 | List keys = new TicketSeedFileParser().parse( 32 | new File(TicketSeedFileParserTest.class.getResource("/good_seeds.json").getFile())); 33 | Assert.assertEquals(6, keys.size()); 34 | 35 | // The seeds in the file are arranged so that every 2 are the same, and adjacent ones are not. 36 | for (int i = 0; i < keys.size() / 2; i += 2) { 37 | Assert.assertEquals(keys.get(i).getHmacKey(), keys.get(i + 2).getHmacKey(), "HMAC keys not equal"); 38 | Assert.assertEquals(keys.get(i).getName(), keys.get(i + 2).getName(), "key names not equal"); 39 | Assert.assertEquals(keys.get(i).getAesKey(), keys.get(i + 2).getAesKey(), "AES keys not equal"); 40 | } 41 | for (int i = 0; i < keys.size() - 1; i++) { 42 | Assert.assertNotEquals(keys.get(i).getHmacKey(), keys.get(i + 1).getHmacKey()); 43 | Assert.assertNotEquals(keys.get(i).getName(), keys.get(i + 1).getName()); 44 | Assert.assertNotEquals(keys.get(i).getAesKey(), keys.get(i + 1).getAesKey()); 45 | } 46 | 47 | List keys2 = new TicketSeedFileParser().parse( 48 | new File(TicketSeedFileParserTest.class.getResource("/good_seeds.json").getFile())); 49 | Assert.assertEquals(keys.size(), keys2.size()); 50 | for (int i = 0; i < keys.size(); ++i) { 51 | Assert.assertEquals(keys.get(i).getAesKey(), keys2.get(i).getAesKey(), "AES keys not equal"); 52 | Assert.assertEquals(keys.get(i).getName(), keys2.get(i).getName(), "key names not equal"); 53 | Assert.assertEquals(keys.get(i).getHmacKey(), keys2.get(i).getHmacKey(), "HMAC keys not equal"); 54 | } 55 | } 56 | 57 | @Test 58 | public void testParseCurrentSeeds() throws IOException { 59 | List keys = new TicketSeedFileParser().parse( 60 | new File(TicketSeedFileParserTest.class.getResource("/seeds_with_only_current.json").getFile())); 61 | Assert.assertEquals(2, keys.size()); 62 | } 63 | 64 | @Test(expectedExceptions = IllegalArgumentException.class, 65 | expectedExceptionsMessageRegExp = "current seeds must not be empty") 66 | public void testParseNoCurrentSeeds() throws IOException { 67 | new TicketSeedFileParser().parse( 68 | new File(TicketSeedFileParserTest.class.getResource("/seeds_with_no_current.json").getFile())); 69 | } 70 | 71 | @Test(expectedExceptions = JsonParseException.class) 72 | public void testParseBadJson() throws IOException { 73 | new TicketSeedFileParser().parse( 74 | new File(TicketSeedFileParserTest.class.getResource("/seeds_bad_json.json").getFile())); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /nifty-ssl/src/test/resources/good_seeds.json: -------------------------------------------------------------------------------- 1 | { 2 | "old": ["aaaaaaaa", "bbbbbbbbbb"], 3 | "new": ["aaaaaaaa", "bbbbbbbbbb"], 4 | "current": ["aaaaaaaa", "bbbbbbbbbb"] 5 | } 6 | -------------------------------------------------------------------------------- /nifty-ssl/src/test/resources/seeds_bad_json.json: -------------------------------------------------------------------------------- 1 | { 2 | "old": ["aaaaaaaa", "bbbbbbbbbb"], 3 | "new": ["aaaaaaaa", "bbbbbbbbbb"], 4 | } 5 | -------------------------------------------------------------------------------- /nifty-ssl/src/test/resources/seeds_with_no_current.json: -------------------------------------------------------------------------------- 1 | { 2 | "old": ["aaaaaaaa", "bbbbbbbbbb"], 3 | "new": ["aaaaaaaa", "bbbbbbbbbb"] 4 | } 5 | -------------------------------------------------------------------------------- /nifty-ssl/src/test/resources/seeds_with_only_current.json: -------------------------------------------------------------------------------- 1 | { 2 | "current": ["aaaaaaaa", "bbbbbbbbbb"] 3 | } 4 | -------------------------------------------------------------------------------- /src/findbugs/findbugs-exclude-filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 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 | -------------------------------------------------------------------------------- /src/license/LICENSE-HEADER.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) ${inceptionYear}-${year} Facebook, Inc. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | 15 | 16 | --------------------------------------------------------------------------------