├── .gitignore ├── .travis.yml ├── CHANGES.md ├── LICENSE ├── README.md ├── build.gradle ├── codequality ├── HEADER └── checkstyle.xml ├── gradle.properties ├── gradle ├── buildViaTravis.sh └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── rxnetty-common ├── .gitignore ├── build.gradle └── src │ ├── main │ └── java │ │ └── io │ │ └── reactivex │ │ └── netty │ │ ├── HandlerNames.java │ │ ├── RxNetty.java │ │ ├── channel │ │ ├── AbstractConnectionToChannelBridge.java │ │ ├── AllocatingTransformer.java │ │ ├── AppendTransformerEvent.java │ │ ├── AutoReleaseOperator.java │ │ ├── BackpressureManagingHandler.java │ │ ├── BytesInspector.java │ │ ├── ChannelOperations.java │ │ ├── ChannelSubscriberEvent.java │ │ ├── Connection.java │ │ ├── ConnectionCreationFailedEvent.java │ │ ├── ConnectionImpl.java │ │ ├── ConnectionInputSubscriberEvent.java │ │ ├── ConnectionInputSubscriberReplaceEvent.java │ │ ├── ConnectionInputSubscriberResetEvent.java │ │ ├── ConnectionSubscriberEvent.java │ │ ├── ContentSource.java │ │ ├── DefaultChannelOperations.java │ │ ├── DetachedChannelPipeline.java │ │ ├── DisposableContentSource.java │ │ ├── EmitConnectionEvent.java │ │ ├── FlushSelectorOperator.java │ │ ├── MarkAwarePipeline.java │ │ ├── SubscriberToChannelFutureBridge.java │ │ ├── WriteTransformations.java │ │ ├── WriteTransformer.java │ │ └── events │ │ │ ├── ConnectionEventListener.java │ │ │ └── ConnectionEventPublisher.java │ │ ├── client │ │ ├── ChannelProvider.java │ │ ├── ChannelProviderFactory.java │ │ ├── ClientConnectionToChannelBridge.java │ │ ├── ClientState.java │ │ ├── ConnectionProvider.java │ │ ├── ConnectionProviderFactory.java │ │ ├── ConnectionRequest.java │ │ ├── Host.java │ │ ├── HostConnector.java │ │ ├── events │ │ │ └── ClientEventListener.java │ │ ├── internal │ │ │ └── SingleHostConnectionProvider.java │ │ ├── loadbalancer │ │ │ ├── AbstractP2CStrategy.java │ │ │ ├── HostCollector.java │ │ │ ├── HostHolder.java │ │ │ ├── LoadBalancerFactory.java │ │ │ ├── LoadBalancingStrategy.java │ │ │ ├── NoBufferHostCollector.java │ │ │ └── NoHostsAvailableException.java │ │ └── pool │ │ │ ├── CompositePoolLimitDeterminationStrategy.java │ │ │ ├── FIFOIdleConnectionsHolder.java │ │ │ ├── IdleConnectionsHolder.java │ │ │ ├── MaxConnectionsBasedStrategy.java │ │ │ ├── PoolConfig.java │ │ │ ├── PoolExhaustedException.java │ │ │ ├── PoolLimitDeterminationStrategy.java │ │ │ ├── PooledConnection.java │ │ │ ├── PooledConnectionProvider.java │ │ │ ├── PooledConnectionProviderImpl.java │ │ │ ├── PreferCurrentEventLoopHolder.java │ │ │ ├── SingleHostPoolingProviderFactory.java │ │ │ └── UnboundedPoolLimitDeterminationStrategy.java │ │ ├── events │ │ ├── Clock.java │ │ ├── EventAttributeKeys.java │ │ ├── EventListener.java │ │ ├── EventPublisher.java │ │ ├── EventSource.java │ │ ├── ListenerInvocationException.java │ │ ├── ListenersHolder.java │ │ └── internal │ │ │ └── SafeEventListener.java │ │ ├── internal │ │ ├── ExecuteInEventloopAction.java │ │ ├── InternalReadTimeoutHandler.java │ │ └── VoidToAnythingCast.java │ │ ├── server │ │ └── ServerState.java │ │ ├── ssl │ │ ├── DefaultSslCodec.java │ │ └── SslCodec.java │ │ ├── threads │ │ ├── PreferCurrentEventLoopGroup.java │ │ ├── RxDefaultThreadFactory.java │ │ ├── RxEventLoopProvider.java │ │ ├── RxJavaEventloopScheduler.java │ │ ├── RxJavaNettyBasedSchedulersHook.java │ │ └── SingleNioLoopProvider.java │ │ └── util │ │ ├── CollectBytes.java │ │ ├── LineReader.java │ │ ├── LoggingHandlerFactory.java │ │ ├── StringLineDecoder.java │ │ └── UnicastBufferingSubject.java │ └── test │ ├── java │ └── io │ │ └── reactivex │ │ └── netty │ │ ├── channel │ │ ├── AbstractConnectionToChannelBridgeTest.java │ │ ├── BackpressureManagingHandlerTest.java │ │ ├── BytesWriteInterceptorTest.java │ │ ├── ConnectionImplTest.java │ │ ├── ContentSourceRule.java │ │ ├── ContentSourceTest.java │ │ ├── DefaultChannelOperationsTest.java │ │ ├── DetachedChannelPipelineTest.java │ │ ├── ReadProducerTest.java │ │ ├── SubscriberToChannelFutureBridgeTest.java │ │ ├── WriteStreamSubscriberTest.java │ │ ├── WriteTransformerTest.java │ │ └── events │ │ │ └── ConnectionEventPublisherTest.java │ │ ├── client │ │ ├── ClientStateTest.java │ │ ├── loadbalancer │ │ │ ├── AbstractP2CStrategyTest.java │ │ │ └── LoadBalancerFactoryTest.java │ │ └── pool │ │ │ ├── FIFOIdleConnectionsHolderTest.java │ │ │ ├── PoolLimitStrategyTest.java │ │ │ ├── PooledConnectionProviderImplTest.java │ │ │ └── PreferCurrentEventLoopHolderTest.java │ │ ├── events │ │ ├── ListenersHolderRule.java │ │ └── ListenersHolderTest.java │ │ ├── test │ │ └── util │ │ │ ├── FlushSelector.java │ │ │ ├── InboundRequestFeeder.java │ │ │ ├── MockClientEventListener.java │ │ │ ├── MockConnectionEventListener.java │ │ │ ├── MockEventListener.java │ │ │ ├── MockEventPublisher.java │ │ │ ├── MockPoolLimitDeterminationStrategy.java │ │ │ ├── MockProducer.java │ │ │ ├── TrackableMetricEventsListener.java │ │ │ └── embedded │ │ │ ├── EmbeddedChannelPipelineDelegate.java │ │ │ ├── EmbeddedChannelProvider.java │ │ │ ├── EmbeddedChannelWithFeeder.java │ │ │ └── EmbeddedConnectionProvider.java │ │ ├── threads │ │ ├── PreferCurrentEventLoopGroupTest.java │ │ └── RxJavaEventloopSchedulerTest.java │ │ └── util │ │ ├── CollectBytesTest.java │ │ ├── LineReaderTest.java │ │ └── UnicastBufferingSubjectTest.java │ └── resources │ └── log4j.properties ├── rxnetty-examples ├── HTTP.md ├── README.md ├── TCP.md ├── WS.md ├── bin │ ├── WEB-INF │ │ └── index.html │ ├── document.txt │ ├── io │ │ └── reactivex │ │ │ └── netty │ │ │ └── examples │ │ │ ├── http │ │ │ ├── chunk │ │ │ │ └── README.md │ │ │ ├── cpuintensive │ │ │ │ └── README.md │ │ │ ├── helloworld │ │ │ │ └── README.md │ │ │ ├── logtail │ │ │ │ └── README.md │ │ │ ├── plaintext │ │ │ │ └── README.md │ │ │ ├── post │ │ │ │ └── README.md │ │ │ ├── sse │ │ │ │ └── README.md │ │ │ ├── ssl │ │ │ │ └── README.md │ │ │ └── wordcounter │ │ │ │ └── README.md │ │ │ ├── tcp │ │ │ ├── cpuintensive │ │ │ │ └── README.md │ │ │ ├── echo │ │ │ │ └── README.md │ │ │ ├── event │ │ │ │ └── README.md │ │ │ ├── interval │ │ │ │ └── README.md │ │ │ └── ssl │ │ │ │ └── README.md │ │ │ └── udp │ │ │ └── README.md │ └── log4j.properties ├── build.gradle └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── reactivex │ │ │ └── netty │ │ │ └── examples │ │ │ ├── ExamplesEnvironment.java │ │ │ ├── http │ │ │ ├── helloworld │ │ │ │ ├── HelloWorldClient.java │ │ │ │ └── HelloWorldServer.java │ │ │ ├── interceptors │ │ │ │ ├── simple │ │ │ │ │ ├── InterceptingClient.java │ │ │ │ │ └── InterceptingServer.java │ │ │ │ └── transformation │ │ │ │ │ ├── InterceptingClient.java │ │ │ │ │ └── TransformingInterceptorsServer.java │ │ │ ├── loadbalancing │ │ │ │ ├── HttpLoadBalancer.java │ │ │ │ └── HttpLoadBalancingClient.java │ │ │ ├── perf │ │ │ │ ├── PerfHelloWorldClient.java │ │ │ │ └── PerfHelloWorldServer.java │ │ │ ├── proxy │ │ │ │ ├── ProxyClient.java │ │ │ │ └── ProxyServer.java │ │ │ ├── secure │ │ │ │ ├── SecureDefaultHttpClient.java │ │ │ │ ├── SecureHelloWorldClient.java │ │ │ │ └── SecureHelloWorldServer.java │ │ │ ├── sse │ │ │ │ ├── HelloSseClient.java │ │ │ │ └── HelloSseServer.java │ │ │ ├── streaming │ │ │ │ ├── StreamingClient.java │ │ │ │ └── StreamingServer.java │ │ │ └── ws │ │ │ │ ├── echo │ │ │ │ ├── WebSocketEchoClient.java │ │ │ │ └── WebSocketEchoServer.java │ │ │ │ └── messaging │ │ │ │ ├── AcceptOnlyBinaryFramesFilter.java │ │ │ │ ├── MessageFrame.java │ │ │ │ ├── MessageProducer.java │ │ │ │ ├── MessagingClient.java │ │ │ │ ├── MessagingServer.java │ │ │ │ └── PendingMessageTracker.java │ │ │ ├── local │ │ │ └── LocalEcho.java │ │ │ └── tcp │ │ │ ├── echo │ │ │ ├── EchoClient.java │ │ │ └── EchoServer.java │ │ │ ├── interceptors │ │ │ ├── simple │ │ │ │ ├── InterceptingClient.java │ │ │ │ └── InterceptingServer.java │ │ │ └── transformation │ │ │ │ ├── InterceptingClient.java │ │ │ │ └── TransformingInterceptorsServer.java │ │ │ ├── loadbalancing │ │ │ ├── AbstractLoadBalancer.java │ │ │ ├── TcpLoadBalancer.java │ │ │ └── TcpLoadBalancingClient.java │ │ │ ├── proxy │ │ │ ├── ProxyClient.java │ │ │ └── ProxyServer.java │ │ │ ├── secure │ │ │ ├── SecureEchoClient.java │ │ │ └── SecureEchoServer.java │ │ │ └── streaming │ │ │ ├── StreamingClient.java │ │ │ └── StreamingServer.java │ └── resources │ │ └── log4j.properties │ └── test │ ├── java │ └── io │ │ └── reactivex │ │ └── netty │ │ ├── examples │ │ ├── ExamplesMockLogger.java │ │ ├── ExamplesTestUtil.java │ │ ├── http │ │ │ ├── helloworld │ │ │ │ └── HelloWorldTest.java │ │ │ ├── interceptors │ │ │ │ ├── simple │ │ │ │ │ └── SimpleInterceptorTest.java │ │ │ │ └── transformation │ │ │ │ │ └── TransformingInterceptorTest.java │ │ │ ├── loadbalancing │ │ │ │ └── LoadBalancingTest.java │ │ │ ├── perf │ │ │ │ └── PerfTest.java │ │ │ ├── proxy │ │ │ │ └── ProxyTest.java │ │ │ ├── secure │ │ │ │ └── SecureHelloWorldTest.java │ │ │ ├── sse │ │ │ │ └── ServerSentEventsTest.java │ │ │ ├── streaming │ │ │ │ └── StreamingTest.java │ │ │ └── ws │ │ │ │ ├── echo │ │ │ │ └── WebSocketEchoTest.java │ │ │ │ └── messaging │ │ │ │ └── MessagingTest.java │ │ ├── local │ │ │ └── LocalEchoTest.java │ │ └── tcp │ │ │ ├── echo │ │ │ └── EchoTest.java │ │ │ ├── interceptors │ │ │ ├── simple │ │ │ │ └── SimpleInterceptorTest.java │ │ │ └── transformation │ │ │ │ └── TransformingInterceptorTest.java │ │ │ ├── loadbalancing │ │ │ └── LoadBalancingTest.java │ │ │ ├── proxy │ │ │ └── ProxyTest.java │ │ │ ├── secure │ │ │ └── SecureEchoTest.java │ │ │ └── streaming │ │ │ └── StreamingTest.java │ │ └── spectator │ │ └── http │ │ └── ResponseCodesHolderTest.java │ └── resources │ └── log4j.properties ├── rxnetty-http ├── .gitignore ├── build.gradle └── src │ ├── main │ └── java │ │ └── io │ │ └── reactivex │ │ └── netty │ │ └── protocol │ │ └── http │ │ ├── CookiesHolder.java │ │ ├── HttpHandlerNames.java │ │ ├── TrailingHeaders.java │ │ ├── client │ │ ├── HttpClient.java │ │ ├── HttpClientImpl.java │ │ ├── HttpClientInterceptorChain.java │ │ ├── HttpClientInterceptorChainImpl.java │ │ ├── HttpClientRequest.java │ │ ├── HttpClientResponse.java │ │ ├── HttpRedirectException.java │ │ ├── InterceptingHttpClient.java │ │ ├── InterceptingHttpClientImpl.java │ │ ├── Interceptor.java │ │ ├── RequestProvider.java │ │ ├── TransformingInterceptor.java │ │ ├── events │ │ │ ├── HttpClientEventPublisher.java │ │ │ ├── HttpClientEventsListener.java │ │ │ └── SafeHttpClientEventsListener.java │ │ ├── internal │ │ │ ├── HttpChannelProvider.java │ │ │ ├── HttpChannelProviderFactory.java │ │ │ ├── HttpClientRequestImpl.java │ │ │ ├── HttpClientResponseImpl.java │ │ │ ├── HttpClientToConnectionBridge.java │ │ │ ├── RawRequest.java │ │ │ ├── Redirector.java │ │ │ └── UnusableConnection.java │ │ └── loadbalancer │ │ │ └── EWMABasedP2CStrategy.java │ │ ├── internal │ │ ├── AbstractHttpConnectionBridge.java │ │ ├── HttpContentSubscriberEvent.java │ │ ├── HttpMessageFormatter.java │ │ ├── OperatorTrailer.java │ │ └── UnsafeEmptySubscriber.java │ │ ├── server │ │ ├── ContentWriterImpl.java │ │ ├── FailedContentWriter.java │ │ ├── HttpConnectionHandler.java │ │ ├── HttpServer.java │ │ ├── HttpServerImpl.java │ │ ├── HttpServerInterceptorChain.java │ │ ├── HttpServerRequest.java │ │ ├── HttpServerRequestImpl.java │ │ ├── HttpServerResponse.java │ │ ├── HttpServerResponseImpl.java │ │ ├── HttpServerToConnectionBridge.java │ │ ├── RequestHandler.java │ │ ├── ResponseContentWriter.java │ │ ├── UriInfoHolder.java │ │ └── events │ │ │ ├── HttpServerEventPublisher.java │ │ │ ├── HttpServerEventsListener.java │ │ │ └── SafeHttpServerEventsListener.java │ │ ├── sse │ │ ├── ServerSentEvent.java │ │ ├── client │ │ │ └── ServerSentEventDecoder.java │ │ └── server │ │ │ └── ServerSentEventEncoder.java │ │ ├── util │ │ └── HttpContentStringLineDecoder.java │ │ └── ws │ │ ├── WebSocketConnection.java │ │ ├── client │ │ ├── OperatorCacheSingleWebsocketConnection.java │ │ ├── WebSocketRequest.java │ │ ├── WebSocketResponse.java │ │ ├── Ws7To13UpgradeHandler.java │ │ └── internal │ │ │ ├── WebSocketRequestImpl.java │ │ │ └── WebSocketResponseImpl.java │ │ ├── internal │ │ └── WsUtils.java │ │ └── server │ │ ├── V7to13Handshaker.java │ │ ├── WebSocketHandler.java │ │ ├── WebSocketHandlers.java │ │ ├── WebSocketHandshaker.java │ │ └── Ws7To13UpgradeHandler.java │ └── test │ ├── java │ └── io │ │ └── reactivex │ │ └── netty │ │ ├── client │ │ └── SslClientTest.java │ │ ├── protocol │ │ └── http │ │ │ ├── CookiesHolderTest.java │ │ │ ├── client │ │ │ ├── EventListenerTest.java │ │ │ ├── HttpClientPoolTest.java │ │ │ ├── HttpClientRule.java │ │ │ ├── HttpClientTest.java │ │ │ ├── HttpRedirectTest.java │ │ │ ├── RedirectOperatorTest.java │ │ │ ├── events │ │ │ │ ├── HttpClientEventPublisherTest.java │ │ │ │ ├── HttpClientEventsListenerImpl.java │ │ │ │ └── HttpClientEventsTest.java │ │ │ └── internal │ │ │ │ └── HttpClientRequestImplTest.java │ │ │ ├── internal │ │ │ └── AbstractHttpConnectionBridgeTest.java │ │ │ ├── server │ │ │ ├── CookieTest.java │ │ │ ├── Http10Test.java │ │ │ ├── HttpEndToEndTest.java │ │ │ ├── HttpServerRequestUriTest.java │ │ │ ├── HttpServerRule.java │ │ │ ├── HttpServerTest.java │ │ │ ├── HttpServerToConnectionBridgeTest.java │ │ │ ├── PipeliningTest.java │ │ │ └── events │ │ │ │ ├── HttpServerEventPublisherTest.java │ │ │ │ └── HttpServerEventsListenerImpl.java │ │ │ ├── sse │ │ │ ├── ServerSentEventEndToEndTest.java │ │ │ ├── SseTestUtil.java │ │ │ ├── client │ │ │ │ └── ServerSentEventDecoderTest.java │ │ │ └── server │ │ │ │ └── ServerSentEventEncoderTest.java │ │ │ └── ws │ │ │ ├── client │ │ │ └── OperatorCacheSingleWebsocketConnectionTest.java │ │ │ └── server │ │ │ └── WSEagerInputSubscriptionHandlerTest.java │ │ └── test │ │ └── util │ │ ├── MockTcpServerEventListener.java │ │ └── TcpConnectionRequestMock.java │ └── resources │ └── log4j.properties ├── rxnetty-spectator-http ├── README.md ├── build.gradle └── src │ └── main │ └── java │ └── io │ └── reactivex │ └── netty │ └── spectator │ └── http │ ├── HttpClientListener.java │ ├── HttpServerListener.java │ └── internal │ └── ResponseCodesHolder.java ├── rxnetty-spectator-tcp ├── README.md ├── build.gradle └── src │ └── main │ └── java │ └── io │ └── reactivex │ └── netty │ └── spectator │ ├── internal │ ├── EventMetric.java │ └── SpectatorUtils.java │ └── tcp │ ├── TcpClientListener.java │ └── TcpServerListener.java ├── rxnetty-tcp ├── .gitignore ├── build.gradle └── src │ ├── main │ └── java │ │ └── io │ │ └── reactivex │ │ └── netty │ │ └── protocol │ │ └── tcp │ │ ├── TcpHandlerNames.java │ │ ├── client │ │ ├── ConnectionRequestImpl.java │ │ ├── InterceptingTcpClient.java │ │ ├── InterceptingTcpClientImpl.java │ │ ├── Interceptor.java │ │ ├── TcpClient.java │ │ ├── TcpClientImpl.java │ │ ├── TcpClientInterceptorChain.java │ │ ├── TcpClientInterceptorChainImpl.java │ │ ├── TransformingInterceptor.java │ │ ├── events │ │ │ ├── SafeTcpClientEventListener.java │ │ │ ├── TcpClientEventListener.java │ │ │ └── TcpClientEventPublisher.java │ │ └── internal │ │ │ ├── TcpChannelProvider.java │ │ │ └── TcpChannelProviderFactory.java │ │ └── server │ │ ├── ConnectionHandler.java │ │ ├── TcpServer.java │ │ ├── TcpServerConnectionToChannelBridge.java │ │ ├── TcpServerImpl.java │ │ ├── TcpServerInterceptorChain.java │ │ ├── TcpServerState.java │ │ └── events │ │ ├── SafeTcpServerEventListener.java │ │ ├── TcpServerEventListener.java │ │ └── TcpServerEventPublisher.java │ └── test │ ├── java │ └── io │ │ └── reactivex │ │ └── netty │ │ ├── client │ │ └── ClientStateTest.java │ │ ├── protocol │ │ └── tcp │ │ │ ├── client │ │ │ ├── EventListenerTest.java │ │ │ ├── MockTcpClientEventListener.java │ │ │ ├── PoolingWithRealChannelTest.java │ │ │ ├── TcpClientImplTest.java │ │ │ ├── TcpClientRule.java │ │ │ └── events │ │ │ │ ├── TcpClientEventPublisherTest.java │ │ │ │ └── TcpClientEventsTest.java │ │ │ └── server │ │ │ ├── UnexpectedConnectionHandlerErrorsTest.java │ │ │ └── events │ │ │ └── TcpServerEventPublisherTest.java │ │ └── test │ │ └── util │ │ └── MockTcpServerEventListener.java │ └── resources │ └── log4j.properties └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled source # 2 | ################### 3 | *.com 4 | *.class 5 | *.dll 6 | *.exe 7 | *.o 8 | *.so 9 | 10 | # Packages # 11 | ############ 12 | # it's better to unpack these files and commit the raw source 13 | # git has its own built in compression methods 14 | *.7z 15 | *.dmg 16 | *.gz 17 | *.iso 18 | *.jar 19 | *.rar 20 | *.tar 21 | *.zip 22 | 23 | # Logs and databases # 24 | ###################### 25 | *.log 26 | 27 | # OS generated files # 28 | ###################### 29 | .DS_Store* 30 | ehthumbs.db 31 | Icon? 32 | Thumbs.db 33 | 34 | # Editor Files # 35 | ################ 36 | *~ 37 | *.swp 38 | 39 | # Gradle Files # 40 | ################ 41 | .gradle 42 | .gradletasknamecache 43 | .m2 44 | 45 | # Build output directies 46 | target/ 47 | build/ 48 | 49 | # IntelliJ specific files/directories 50 | out 51 | .idea 52 | *.ipr 53 | *.iws 54 | *.iml 55 | atlassian-ide-plugin.xml 56 | 57 | # Eclipse specific files/directories 58 | .classpath 59 | .project 60 | .settings 61 | .metadata 62 | bin/ 63 | 64 | # NetBeans specific files/directories 65 | .nbattrs 66 | /.nb-gradle/profiles/private/ 67 | .nb-gradle-properties 68 | 69 | # Scala build 70 | *.cache 71 | /.nb-gradle/private/ 72 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | sudo: false 5 | script: gradle/buildViaTravis.sh 6 | env: 7 | global: 8 | - secure: JjyE1E+adlM+CitIVpwb9HewJDjY3ZVjDgu8eYcTY+wXRNAvpcNH3gtUUClisXLZ3X4Kd8f875XH7/vUuOtJqMvQDQfUWPbCinE5GDzoRl2S5ZHoRA0H584bqilO7CXjjGMfTBlbw8A5auZ6Vf+n4zTZxgJNvDtple6WRoz/hzg= 9 | - secure: WcCL4StO7AWOit9MIi0Z7jBnd7axCq2M18FW3kdt/N/D1+AoYGq9vguknhJyQomzsmfpcKY4v10XiGOCX2Wh6YvEaD5TXK59baCPqu8xD4T7MHQLddIdjU95+Y8LYWSD1ARzJL6uwMQW77/GKZJCoRxxr8fgs/LmjUWpkPdgbBQ= 10 | - secure: ImKGKP+KwPffBBteqP0NnAan94xL1psVFCZo9XdstJ6X/0ykT9GOR39BX5wP4WXC7Z0L6qhh7nRw4MaL82ll7otPz0/7Oi0C3ZUbYR812IsHJO7JxUdgdTnBIFyn7RJ6d3qx99mgPmZ9dFCMnJy7ivjJfvV3BR0sHKz4PX47xmg= 11 | - secure: oGPp8Lt6nI43N5lM0e5cS1IM6fVM2pBQnaQAfLarXHGo2bJtBnfVkgLIAuI/EoTp5gi1HEIsGd2CF9O2KxeTmw9zTWp84UX9Rw0cO5DaVnG+xL0JFpzdMEzTXEhmeNuo+h9ppU3eSH6656w5vuYfHIGC5RRyVuEYRinq2EHwXWo= 12 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | buildscript { 18 | repositories { jcenter() } 19 | dependencies { 20 | classpath 'com.netflix.nebula:gradle-rxjava-project-plugin:4.0.0' 21 | classpath 'com.netflix.nebula:gradle-extra-configurations-plugin:3.1.0' 22 | } 23 | } 24 | 25 | description = 'RxNetty: Reactive Extensions for Netty' 26 | 27 | apply plugin: 'nebula.rxjava-project' 28 | 29 | subprojects { 30 | apply plugin: 'nebula.optional-base' 31 | apply plugin: 'nebula.rxjava-project' 32 | apply plugin: 'java' 33 | 34 | sourceCompatibility = JavaVersion.VERSION_1_7 35 | targetCompatibility = JavaVersion.VERSION_1_7 36 | 37 | dependencies { 38 | compile "io.reactivex:rxjava:1.2.+" 39 | 40 | testCompile 'junit:junit:4.12' 41 | testCompile "org.hamcrest:hamcrest-library:1.3" 42 | testCompile "org.mockito:mockito-core:1.10.19" 43 | testRuntime "org.slf4j:slf4j-log4j12:${slf4j_version}" 44 | } 45 | 46 | test { 47 | testLogging { 48 | showStandardStreams = true 49 | } 50 | } 51 | } 52 | 53 | // support for snapshot/final releases with the various branches RxJava uses 54 | nebulaRelease { 55 | addReleaseBranchPattern(/\d+\.\d+\.\d+/) 56 | addReleaseBranchPattern('HEAD') 57 | } 58 | 59 | if (project.hasProperty('release.useLastTag')) { 60 | tasks.prepare.enabled = false 61 | } 62 | -------------------------------------------------------------------------------- /codequality/HEADER: -------------------------------------------------------------------------------- 1 | Copyright ${year} Netflix, 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 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2015 Netflix, 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 | netty_version=4.1.5.Final 17 | slf4j_version=1.7.6 18 | -------------------------------------------------------------------------------- /gradle/buildViaTravis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script will build the project. 3 | 4 | if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then 5 | echo -e "Build Pull Request #$TRAVIS_PULL_REQUEST => Branch [$TRAVIS_BRANCH]" 6 | ./gradlew -Prelease.useLastTag=true build 7 | elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" == "" ]; then 8 | echo -e 'Build Branch with Snapshot => Branch ['$TRAVIS_BRANCH']' 9 | ./gradlew -Prelease.travisci=true -PbintrayUser="${bintrayUser}" -PbintrayKey="${bintrayKey}" -PsonatypeUsername="${sonatypeUsername}" -PsonatypePassword="${sonatypePassword}" build snapshot --stacktrace 10 | elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" != "" ]; then 11 | echo -e 'Build Branch for Release => Branch ['$TRAVIS_BRANCH'] Tag ['$TRAVIS_TAG']' 12 | ./gradlew -Prelease.travisci=true -Prelease.useLastTag=true -PbintrayUser="${bintrayUser}" -PbintrayKey="${bintrayKey}" -PsonatypeUsername="${sonatypeUsername}" -PsonatypePassword="${sonatypePassword}" final --stacktrace 13 | else 14 | echo -e 'WARN: Should not be here => Branch ['$TRAVIS_BRANCH'] Tag ['$TRAVIS_TAG'] Pull Request ['$TRAVIS_PULL_REQUEST']' 15 | ./gradlew -Prelease.useLastTag=true build 16 | fi 17 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactiveX/RxNetty/a7ca9a9c1d544a79c82f7b17036daf6958bf1cd6/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon May 23 10:20:35 PDT 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip 7 | -------------------------------------------------------------------------------- /rxnetty-common/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactiveX/RxNetty/a7ca9a9c1d544a79c82f7b17036daf6958bf1cd6/rxnetty-common/.gitignore -------------------------------------------------------------------------------- /rxnetty-common/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | plugins { 18 | id "com.github.hauner.jarTest" version "1.0" 19 | } 20 | 21 | dependencies { 22 | compile "io.netty:netty-handler:${netty_version}" 23 | compile "io.netty:netty-transport-native-epoll:${netty_version}", optional 24 | compile "org.slf4j:slf4j-api:${slf4j_version}" 25 | } 26 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/HandlerNames.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | package io.reactivex.netty; 18 | 19 | /** 20 | * A list of all handler names added by the framework. This is just to ensure consistency in naming. 21 | */ 22 | public enum HandlerNames { 23 | 24 | SslHandler("ssl-handler"), 25 | SslConnectionEmissionHandler("ssl-connection-emitter"), 26 | WireLogging("wire-logging-handler"), 27 | WriteTransformer("write-transformer"), 28 | ClientReadTimeoutHandler("client-read-timeout-handler"), 29 | ClientChannelActiveBufferingHandler("client-channel-active-buffer-handler"), 30 | ; 31 | 32 | private final String name; 33 | 34 | HandlerNames(String name) { 35 | this.name = qualify(name); 36 | } 37 | 38 | public String getName() { 39 | return name; 40 | } 41 | 42 | private static String qualify(String name) { 43 | return "_rx_netty_" + name; 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/channel/AppendTransformerEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.channel; 19 | 20 | /** 21 | * An event to register a custom transformer of data written on a channel. 22 | * 23 | * @param Source type for the transformer. 24 | * @param Target type for the transformer. 25 | */ 26 | public final class AppendTransformerEvent { 27 | 28 | private final AllocatingTransformer transformer; 29 | 30 | public AppendTransformerEvent(AllocatingTransformer transformer) { 31 | if (null == transformer) { 32 | throw new NullPointerException("Transformer can not be null."); 33 | } 34 | this.transformer = transformer; 35 | } 36 | 37 | public AllocatingTransformer getTransformer() { 38 | return transformer; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/channel/AutoReleaseOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.channel; 19 | 20 | import io.netty.util.ReferenceCountUtil; 21 | import rx.Observable.Operator; 22 | import rx.Subscriber; 23 | 24 | class AutoReleaseOperator implements Operator { 25 | 26 | @Override 27 | public Subscriber call(final Subscriber subscriber) { 28 | return new Subscriber(subscriber) { 29 | @Override 30 | public void onCompleted() { 31 | subscriber.onCompleted(); 32 | } 33 | 34 | @Override 35 | public void onError(Throwable e) { 36 | subscriber.onError(e); 37 | } 38 | 39 | @Override 40 | public void onNext(T t) { 41 | try { 42 | subscriber.onNext(t); 43 | } finally { 44 | ReferenceCountUtil.release(t); 45 | } 46 | } 47 | }; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/channel/ChannelSubscriberEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.channel; 18 | 19 | import io.netty.channel.Channel; 20 | import rx.Subscriber; 21 | 22 | /** 23 | * An event to communicate the subscriber of a new channel created by {@link AbstractConnectionToChannelBridge}. 24 | * 25 | *

Connection reuse

26 | * 27 | * For cases, where the {@link Connection} is pooled, reuse should be indicated explicitly via 28 | * {@link ConnectionInputSubscriberResetEvent}. There can be multiple {@link ConnectionInputSubscriberResetEvent}s 29 | * sent to the same channel and hence the same instance of {@link AbstractConnectionToChannelBridge}. 30 | * 31 | * @param Type read from the connection held by the event. 32 | * @param Type written to the connection held by the event. 33 | */ 34 | public class ChannelSubscriberEvent { 35 | 36 | private final Subscriber subscriber; 37 | 38 | public ChannelSubscriberEvent(Subscriber subscriber) { 39 | this.subscriber = subscriber; 40 | } 41 | 42 | public Subscriber getSubscriber() { 43 | return subscriber; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/channel/ConnectionCreationFailedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.channel; 18 | 19 | import io.netty.channel.ChannelHandlerContext; 20 | import io.netty.channel.ChannelInboundHandler; 21 | 22 | /** 23 | * An event to indicate to {@link AbstractConnectionToChannelBridge} that the subscriber as published by 24 | * {@link ChannelSubscriberEvent} should be informed of a connection creation failure, instead of a new connection. 25 | * 26 | *

Why do we need this?

27 | * 28 | * Since, emitting a connection can include a handshake for protocols such as TLS/SSL, it is not so that a new 29 | * {@link io.reactivex.netty.channel.Connection} should be emitted as soon as the channel is active (i.e. inside 30 | * {@link ChannelInboundHandler#channelActive(ChannelHandlerContext)}). 31 | * For this reason, this event leaves it to the pipeline or any other entity outside to decide, when is the rite time to 32 | * determine that a connection for a channel has failed creation. 33 | */ 34 | public final class ConnectionCreationFailedEvent { 35 | 36 | private final Throwable throwable; 37 | 38 | public ConnectionCreationFailedEvent(Throwable throwable) { 39 | this.throwable = throwable; 40 | } 41 | 42 | public Throwable getThrowable() { 43 | return throwable; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/channel/ConnectionInputSubscriberEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.channel; 18 | 19 | import io.netty.util.ReferenceCountUtil; 20 | import rx.Subscriber; 21 | import rx.functions.Action1; 22 | import rx.observers.Subscribers; 23 | 24 | /** 25 | * An event to communicate the subscriber of the associated connection input stream created by 26 | * {@link AbstractConnectionToChannelBridge}. 27 | * 28 | *

Multiple events on the same channel

29 | * 30 | * Multiple instance of this event can be sent on the same channel, provided that there is a 31 | * {@link ConnectionInputSubscriberResetEvent} between two consecutive {@link ConnectionInputSubscriberEvent}s 32 | * 33 | * @param Type read from the connection held by the event. 34 | * @param Type written to the connection held by the event. 35 | */ 36 | public final class ConnectionInputSubscriberEvent { 37 | 38 | private final Subscriber subscriber; 39 | 40 | public ConnectionInputSubscriberEvent(Subscriber subscriber) { 41 | if (null == subscriber) { 42 | throw new NullPointerException("Subscriber can not be null"); 43 | } 44 | this.subscriber = subscriber; 45 | } 46 | 47 | public Subscriber getSubscriber() { 48 | return subscriber; 49 | } 50 | 51 | public static ConnectionInputSubscriberEvent discardAllInput() { 52 | return new ConnectionInputSubscriberEvent<>(Subscribers.create(new Action1() { 53 | @Override 54 | public void call(II msg) { 55 | ReferenceCountUtil.release(msg); 56 | } 57 | }, new Action1() { 58 | @Override 59 | public void call(Throwable throwable) { 60 | // Empty as we are discarding input anyways. 61 | } 62 | })); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/channel/ConnectionInputSubscriberReplaceEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.channel; 18 | 19 | /** 20 | * This event is an indication to atomically replace existing connection input subscriber, if any, with another. 21 | */ 22 | public class ConnectionInputSubscriberReplaceEvent { 23 | 24 | private final ConnectionInputSubscriberEvent newSubEvent; 25 | 26 | public ConnectionInputSubscriberReplaceEvent(ConnectionInputSubscriberEvent newSubEvent) { 27 | this.newSubEvent = newSubEvent; 28 | } 29 | 30 | public ConnectionInputSubscriberEvent getNewSubEvent() { 31 | return newSubEvent; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/channel/ConnectionInputSubscriberResetEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.channel; 18 | 19 | /** 20 | * This event is an indication that there will be multiple subscribers to the connection input stream. This event 21 | * must be sent as many times as the subscribers to the input. This typically will be the case for client-side 22 | * connections when a channel is pooled and reused. 23 | */ 24 | public interface ConnectionInputSubscriberResetEvent { 25 | 26 | } 27 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/channel/ConnectionSubscriberEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.channel; 18 | 19 | import rx.Subscriber; 20 | 21 | /** 22 | * An event to communicate the subscriber of a new connection created by {@link AbstractConnectionToChannelBridge}. 23 | * 24 | *

Connection reuse

25 | * 26 | * For cases, where the {@link Connection} is pooled, reuse should be indicated explicitly via 27 | * {@link ConnectionInputSubscriberResetEvent}. There can be multiple {@link ConnectionInputSubscriberResetEvent}s 28 | * sent to the same channel and hence the same instance of {@link AbstractConnectionToChannelBridge}. 29 | * 30 | * @param Type read from the connection held by the event. 31 | * @param Type written to the connection held by the event. 32 | */ 33 | public class ConnectionSubscriberEvent { 34 | 35 | private final Subscriber> subscriber; 36 | 37 | public ConnectionSubscriberEvent(Subscriber> subscriber) { 38 | this.subscriber = subscriber; 39 | } 40 | 41 | public Subscriber> getSubscriber() { 42 | return subscriber; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/channel/EmitConnectionEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.channel; 18 | 19 | import io.netty.channel.ChannelHandlerContext; 20 | import io.netty.channel.ChannelInboundHandler; 21 | 22 | /** 23 | * An event to indicate to {@link AbstractConnectionToChannelBridge} that the channel is ready to emit a new 24 | * {@link io.reactivex.netty.channel.Connection} to the subscriber as published by {@link ChannelSubscriberEvent} 25 | * 26 | *

Why do we need this?

27 | * 28 | * Since, emitting a connection can include a handshake for protocols such as TLS/SSL, it is not so that a new 29 | * {@link io.reactivex.netty.channel.Connection} should be emitted as soon as the channel is active (i.e. inside 30 | * {@link ChannelInboundHandler#channelActive(ChannelHandlerContext)}). 31 | * For this reason, this event leaves it to the pipeline or any other entity outside to decide, when is the rite time to 32 | * emit a connection. 33 | */ 34 | public final class EmitConnectionEvent { 35 | 36 | public static final EmitConnectionEvent INSTANCE = new EmitConnectionEvent(); 37 | 38 | private EmitConnectionEvent() { 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/channel/FlushSelectorOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.channel; 18 | 19 | import rx.Observable.Operator; 20 | import rx.Subscriber; 21 | import rx.functions.Func1; 22 | 23 | public class FlushSelectorOperator implements Operator { 24 | 25 | private final Func1 flushSelector; 26 | private final ChannelOperations channelOps; 27 | 28 | public FlushSelectorOperator(Func1 flushSelector, ChannelOperations channelOps) { 29 | this.flushSelector = flushSelector; 30 | this.channelOps = channelOps; 31 | } 32 | 33 | @Override 34 | public Subscriber call(final Subscriber subscriber) { 35 | 36 | return new Subscriber(subscriber) { 37 | @Override 38 | public void onCompleted() { 39 | subscriber.onCompleted(); 40 | } 41 | 42 | @Override 43 | public void onError(Throwable e) { 44 | subscriber.onError(e); 45 | } 46 | 47 | @Override 48 | public void onNext(T next) { 49 | subscriber.onNext(next); 50 | /*Call the selector _after_ writing an element*/ 51 | if (flushSelector.call(next)) { 52 | channelOps.flush(); 53 | } 54 | } 55 | }; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/client/ChannelProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.client; 19 | 20 | import io.netty.channel.Channel; 21 | import rx.Observable; 22 | 23 | public interface ChannelProvider { 24 | 25 | Observable newChannel(Observable input); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/client/ChannelProviderFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.client; 19 | 20 | import io.reactivex.netty.client.events.ClientEventListener; 21 | import io.reactivex.netty.events.EventPublisher; 22 | import io.reactivex.netty.events.EventSource; 23 | 24 | public interface ChannelProviderFactory { 25 | 26 | ChannelProvider newProvider(Host host, EventSource eventSource, 27 | EventPublisher publisher, ClientEventListener clientPublisher); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/client/ConnectionProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.client; 19 | 20 | import io.reactivex.netty.channel.Connection; 21 | import rx.Observable; 22 | 23 | /** 24 | * A contract to control how connections are established from a client. 25 | * 26 | * @param The type of objects written on the connections created by this provider. 27 | * @param The type of objects read from the connections created by this provider. 28 | */ 29 | public interface ConnectionProvider { 30 | 31 | /** 32 | * Returns an {@code Observable} that emits a single connection every time it is subscribed. 33 | * 34 | * @return An {@code Observable} that emits a single connection every time it is subscribed. 35 | */ 36 | Observable> newConnectionRequest(); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/client/ConnectionProviderFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.client; 19 | 20 | import rx.Observable; 21 | 22 | public interface ConnectionProviderFactory { 23 | 24 | ConnectionProvider newProvider(Observable> hosts); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/client/ConnectionRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | package io.reactivex.netty.client; 18 | 19 | import io.reactivex.netty.channel.Connection; 20 | import rx.Observable; 21 | 22 | /** 23 | * A connection request that is used to create connections for different protocols. 24 | * 25 | *

Mutations

26 | * 27 | * All mutations to this request that creates a brand new instance. 28 | * 29 | *

Inititating connections

30 | * 31 | * A new connection is initiated every time {@link ConnectionRequest#subscribe()} is called and is the only way of 32 | * creating connections. 33 | * 34 | * @param The type of the objects that are written to the connection created by this request. 35 | * @param The type of objects that are read from the connection created by this request. 36 | */ 37 | public abstract class ConnectionRequest extends Observable> { 38 | 39 | protected ConnectionRequest(OnSubscribe> f) { 40 | super(f); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/client/Host.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.client; 19 | 20 | import rx.Observable; 21 | 22 | import java.net.SocketAddress; 23 | 24 | public final class Host { 25 | 26 | private final SocketAddress host; 27 | private final Observable closeNotifier; 28 | 29 | public Host(SocketAddress host) { 30 | this(host, Observable.never()); 31 | } 32 | 33 | public Host(SocketAddress host, Observable closeNotifier) { 34 | this.host = host; 35 | this.closeNotifier = closeNotifier; 36 | } 37 | 38 | public SocketAddress getHost() { 39 | return host; 40 | } 41 | 42 | public Observable getCloseNotifier() { 43 | return closeNotifier; 44 | } 45 | 46 | @Override 47 | public boolean equals(Object o) { 48 | if (this == o) { 49 | return true; 50 | } 51 | if (!(o instanceof Host)) { 52 | return false; 53 | } 54 | 55 | Host host1 = (Host) o; 56 | 57 | if (host != null? !host.equals(host1.host) : host1.host != null) { 58 | return false; 59 | } 60 | return closeNotifier != null? closeNotifier.equals(host1.closeNotifier) : host1.closeNotifier == null; 61 | 62 | } 63 | 64 | @Override 65 | public int hashCode() { 66 | int result = host != null? host.hashCode() : 0; 67 | result = 31 * result + (closeNotifier != null? closeNotifier.hashCode() : 0); 68 | return result; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/client/loadbalancer/HostCollector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.client.loadbalancer; 19 | 20 | import rx.Single; 21 | import rx.functions.Func1; 22 | 23 | import java.util.List; 24 | 25 | public interface HostCollector { 26 | 27 | Func1, Single>>> newCollector(); 28 | 29 | final class HostUpdate { 30 | 31 | public enum Action{ Add, Remove } 32 | 33 | private final Action action; 34 | private final HostHolder hostHolder; 35 | 36 | public HostUpdate(Action action, HostHolder hostHolder) { 37 | this.action = action; 38 | this.hostHolder = hostHolder; 39 | } 40 | 41 | public Action getAction() { 42 | return action; 43 | } 44 | 45 | public HostHolder getHostHolder() { 46 | return hostHolder; 47 | } 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/client/loadbalancer/HostHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.client.loadbalancer; 19 | 20 | import io.reactivex.netty.client.HostConnector; 21 | import io.reactivex.netty.client.events.ClientEventListener; 22 | 23 | public class HostHolder { 24 | 25 | private final HostConnector connector; 26 | private final ClientEventListener eventListener; 27 | 28 | public HostHolder(HostConnector connector, ClientEventListener eventListener) { 29 | this.connector = connector; 30 | this.eventListener = eventListener; 31 | } 32 | 33 | public HostConnector getConnector() { 34 | return connector; 35 | } 36 | 37 | public ClientEventListener getEventListener() { 38 | return eventListener; 39 | } 40 | 41 | @Override 42 | public boolean equals(Object o) { 43 | if (this == o) { 44 | return true; 45 | } 46 | if (!(o instanceof HostHolder)) { 47 | return false; 48 | } 49 | 50 | HostHolder that = (HostHolder) o; 51 | 52 | if (connector != null? !connector.equals(that.connector) : that.connector != null) { 53 | return false; 54 | } 55 | return eventListener != null? eventListener.equals(that.eventListener) : that.eventListener == null; 56 | 57 | } 58 | 59 | @Override 60 | public int hashCode() { 61 | int result = connector != null? connector.hashCode() : 0; 62 | result = 31 * result + (eventListener != null? eventListener.hashCode() : 0); 63 | return result; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/client/loadbalancer/LoadBalancingStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.client.loadbalancer; 19 | 20 | import io.reactivex.netty.client.ConnectionProvider; 21 | import io.reactivex.netty.client.HostConnector; 22 | 23 | import java.util.List; 24 | 25 | public interface LoadBalancingStrategy { 26 | 27 | ConnectionProvider newStrategy(List> hosts); 28 | 29 | HostHolder toHolder(HostConnector connector); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/client/loadbalancer/NoHostsAvailableException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.client.loadbalancer; 19 | 20 | import io.netty.util.internal.EmptyArrays; 21 | 22 | /** 23 | * Exception raised when there are no eligible hosts available to a load balancer. 24 | */ 25 | public class NoHostsAvailableException extends RuntimeException { 26 | 27 | private static final long serialVersionUID = 7993688893506534768L; 28 | 29 | @SuppressWarnings("ThrowableInstanceNeverThrown") 30 | public static final NoHostsAvailableException EMPTY_INSTANCE = new NoHostsAvailableException(); 31 | 32 | static { 33 | EMPTY_INSTANCE.setStackTrace(EmptyArrays.EMPTY_STACK_TRACE); 34 | } 35 | 36 | public NoHostsAvailableException() { 37 | } 38 | 39 | public NoHostsAvailableException(String message) { 40 | super(message); 41 | } 42 | 43 | public NoHostsAvailableException(String message, Throwable cause) { 44 | super(message, cause); 45 | } 46 | 47 | public NoHostsAvailableException(Throwable cause) { 48 | super(cause); 49 | } 50 | 51 | public NoHostsAvailableException(String message, Throwable cause, boolean enableSuppression, 52 | boolean writableStackTrace) { 53 | super(message, cause, enableSuppression, writableStackTrace); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/client/pool/PoolExhaustedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.client.pool; 18 | 19 | public class PoolExhaustedException extends Exception { 20 | 21 | private static final long serialVersionUID = -6299997509113653123L; 22 | 23 | public PoolExhaustedException() { 24 | } 25 | 26 | public PoolExhaustedException(Throwable cause) { 27 | super(cause); 28 | } 29 | 30 | public PoolExhaustedException(String message) { 31 | super(message); 32 | } 33 | 34 | public PoolExhaustedException(String message, Throwable cause) { 35 | super(message, cause); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/client/pool/PoolLimitDeterminationStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.client.pool; 19 | 20 | import java.util.concurrent.TimeUnit; 21 | 22 | /** 23 | * A strategy to delegate the decision pertaining to connection pool size limits. 24 | */ 25 | public interface PoolLimitDeterminationStrategy { 26 | 27 | /** 28 | * Attempts to acquire a creation permit. 29 | * 30 | * @param acquireStartTime The start time for the acquire process in milliseconds since epoch. 31 | * @param timeUnit The timeunit for the acquire start time. 32 | * 33 | * @return {@code true} if the permit was acquired, {@code false} otherwise. 34 | */ 35 | boolean acquireCreationPermit(long acquireStartTime, TimeUnit timeUnit); 36 | 37 | /** 38 | * Returns the number of creation permits available. 39 | * 40 | * @return The number of creation permits available. 41 | */ 42 | int getAvailablePermits(); 43 | 44 | /** 45 | * Release a previously acquired permit. 46 | */ 47 | void releasePermit(); 48 | } 49 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/client/pool/SingleHostPoolingProviderFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.client.pool; 19 | 20 | import io.reactivex.netty.client.ConnectionProvider; 21 | import io.reactivex.netty.client.ConnectionProviderFactory; 22 | import io.reactivex.netty.client.HostConnector; 23 | import io.reactivex.netty.client.internal.SingleHostConnectionProvider; 24 | import rx.Observable; 25 | import rx.functions.Func1; 26 | 27 | /** 28 | * A {@link ConnectionProviderFactory} that must only be used for a client that operates on a single host. 29 | */ 30 | public class SingleHostPoolingProviderFactory implements ConnectionProviderFactory { 31 | 32 | private final PoolConfig config; 33 | 34 | private SingleHostPoolingProviderFactory(PoolConfig config) { 35 | this.config = config; 36 | } 37 | 38 | @Override 39 | public ConnectionProvider newProvider(Observable> hosts) { 40 | return new SingleHostConnectionProvider<>(hosts.map(new Func1, HostConnector>() { 41 | @Override 42 | public HostConnector call(HostConnector hc) { 43 | return new HostConnector<>(hc, PooledConnectionProvider.create(config, hc)); 44 | } 45 | })); 46 | } 47 | 48 | public static SingleHostPoolingProviderFactory createUnbounded() { 49 | return create(new PoolConfig()); 50 | } 51 | 52 | public static SingleHostPoolingProviderFactory createBounded(int maxConnections) { 53 | return create(new PoolConfig().maxConnections(maxConnections)); 54 | } 55 | 56 | public static SingleHostPoolingProviderFactory create(final PoolConfig config) { 57 | return new SingleHostPoolingProviderFactory<>(config); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/client/pool/UnboundedPoolLimitDeterminationStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.client.pool; 18 | 19 | import java.util.concurrent.TimeUnit; 20 | 21 | public class UnboundedPoolLimitDeterminationStrategy implements PoolLimitDeterminationStrategy { 22 | 23 | public static final PoolLimitDeterminationStrategy INSTANCE = new UnboundedPoolLimitDeterminationStrategy(); 24 | 25 | private UnboundedPoolLimitDeterminationStrategy() { } 26 | 27 | @Override 28 | public boolean acquireCreationPermit(long acquireStartTime, TimeUnit timeUnit) { 29 | return true; 30 | } 31 | 32 | @Override 33 | public int getAvailablePermits() { 34 | return Integer.MAX_VALUE; 35 | } 36 | 37 | @Override 38 | public void releasePermit() { 39 | // No Op, no limit. 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/events/EventAttributeKeys.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.events; 19 | 20 | import io.netty.util.AttributeKey; 21 | import io.reactivex.netty.channel.events.ConnectionEventListener; 22 | import io.reactivex.netty.client.events.ClientEventListener; 23 | 24 | /** 25 | * A set of {@link AttributeKey} that are used by the event infrastructure. 26 | */ 27 | public final class EventAttributeKeys { 28 | 29 | private EventAttributeKeys() { 30 | } 31 | 32 | public static final AttributeKey EVENT_PUBLISHER = 33 | AttributeKey.valueOf("rxnetty_client_event_publisher"); 34 | public static final AttributeKey CLIENT_EVENT_LISTENER = 35 | AttributeKey.valueOf("rxnetty_client_event_listener"); 36 | public static final AttributeKey CONNECTION_EVENT_LISTENER = 37 | AttributeKey.valueOf("rxnetty_client_conn_event_listener"); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/events/EventPublisher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.events; 18 | 19 | /** 20 | * A contract for any publisher of events. 21 | */ 22 | public interface EventPublisher { 23 | 24 | /** 25 | * Returns {@code true} if event publishing is enabled. This is primarily used to short-circuit event publishing 26 | * if the publishing is not enabled. Event publishing will be disabled if there are no active listeners or has 27 | * been explicitly disabled using {@link io.reactivex.netty.RxNetty#disableEventPublishing()} 28 | * 29 | * @return {@code true} if event publishing is enabled. 30 | */ 31 | boolean publishingEnabled(); 32 | } 33 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/events/EventSource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.events; 18 | 19 | import rx.Subscription; 20 | 21 | /** 22 | * An event source to which {@link EventListener}s can subscribe to receive events. 23 | */ 24 | public interface EventSource { 25 | 26 | /** 27 | * Subscribes the passed {@code listener} for events published by this source. 28 | * 29 | * @param listener Listener for events published by this source. 30 | * 31 | * @return Subscription, from which one can unsubscribe to stop receiving events. 32 | */ 33 | Subscription subscribe(T listener); 34 | } 35 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/events/ListenerInvocationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.events; 18 | 19 | import java.io.ByteArrayOutputStream; 20 | import java.io.PrintStream; 21 | import java.util.Collections; 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | public class ListenerInvocationException extends RuntimeException { 26 | 27 | private Map exceptions; 28 | private String message; 29 | 30 | private static final long serialVersionUID = -4381062024201397997L; 31 | 32 | @SuppressWarnings("rawtypes") 33 | protected ListenerInvocationException() { 34 | super("Metric event listener invocation failed."); 35 | exceptions = new HashMap<>(); 36 | message = super.getMessage(); 37 | } 38 | 39 | protected void addException(EventListener listener, Throwable error) { 40 | exceptions.put(listener, error); 41 | } 42 | 43 | protected void finish() { 44 | exceptions = Collections.unmodifiableMap(exceptions); 45 | StringBuilder msgBuilder = new StringBuilder(getMessage()).append(". Errors: \n"); 46 | for (Map.Entry exceptionEntry : exceptions.entrySet()) { 47 | msgBuilder.append("Listener: "); 48 | msgBuilder.append(exceptionEntry.getKey().getClass().getSimpleName()); 49 | msgBuilder.append("\n Error:"); 50 | ByteArrayOutputStream stackTraceStream = new ByteArrayOutputStream(); 51 | exceptionEntry.getValue().printStackTrace(new PrintStream(stackTraceStream)); 52 | msgBuilder.append(stackTraceStream.toString()); 53 | } 54 | message = msgBuilder.toString(); 55 | } 56 | 57 | public Map getExceptions() { 58 | return exceptions; 59 | } 60 | 61 | @Override 62 | public String getMessage() { 63 | return message; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/events/internal/SafeEventListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.events.internal; 18 | 19 | import io.reactivex.netty.events.EventListener; 20 | 21 | /** 22 | * A marker interface to indicate that the {@link EventListener} is safe to be invoked multiple times but the wrapped 23 | * listener will only be invoked once. 24 | */ 25 | public interface SafeEventListener extends EventListener { 26 | } 27 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/internal/ExecuteInEventloopAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.internal; 19 | 20 | import io.netty.channel.Channel; 21 | import rx.functions.Action0; 22 | 23 | public abstract class ExecuteInEventloopAction implements Action0, Runnable { 24 | 25 | private final Channel channel; 26 | 27 | protected ExecuteInEventloopAction(Channel channel) { 28 | this.channel = channel; 29 | } 30 | 31 | @Override 32 | public void call() { 33 | if (channel.eventLoop().inEventLoop()) { 34 | run(); 35 | } else { 36 | channel.eventLoop().execute(this); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/internal/VoidToAnythingCast.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | package io.reactivex.netty.internal; 18 | 19 | import rx.Observable; 20 | import rx.functions.Func1; 21 | 22 | /** 23 | * A function to be used in place of {@link Observable#cast(Class)} to support nested generics. 24 | * 25 | * @param Target type. 26 | */ 27 | public class VoidToAnythingCast implements Func1 { 28 | 29 | @Override 30 | public T call(Void aVoid) { 31 | return null; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/ssl/DefaultSslCodec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.ssl; 18 | 19 | import io.netty.buffer.ByteBufAllocator; 20 | import io.netty.channel.ChannelPipeline; 21 | import io.netty.handler.ssl.SslHandler; 22 | import rx.functions.Func1; 23 | 24 | import javax.net.ssl.SSLEngine; 25 | 26 | /** 27 | * Default implementation of {@link SslCodec} that uses a statically created {@link SSLEngine} or a provided factory to 28 | * create one dynamically. 29 | * 30 | * No custom configurations are applied to the created {@link SslHandler} unless done so explicity by overriding 31 | * {@link #configureHandler(SslHandler)} 32 | */ 33 | public class DefaultSslCodec extends SslCodec { 34 | 35 | private final Func1 engineFactory; 36 | 37 | public DefaultSslCodec(Func1 engineFactory) { 38 | this.engineFactory = engineFactory; 39 | } 40 | 41 | public DefaultSslCodec(final SSLEngine sslEngine) { 42 | this(new Func1() { 43 | @Override 44 | public SSLEngine call(ByteBufAllocator allocator) { 45 | return sslEngine; 46 | } 47 | }); 48 | } 49 | 50 | @Override 51 | protected SslHandler newSslHandler(ChannelPipeline pipeline) { 52 | SslHandler toReturn = new SslHandler(engineFactory.call(pipeline.channel().alloc())); 53 | configureHandler(toReturn); 54 | return toReturn; 55 | } 56 | 57 | /** 58 | * An optional method that can be overridden to add any custom configurations to the {@link SslHandler} returned 59 | * by {@link #newSslHandler(ChannelPipeline)} 60 | * 61 | * @param handler Handler to configure. 62 | */ 63 | protected void configureHandler(@SuppressWarnings("unused")SslHandler handler) { 64 | // No Op .. 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/threads/RxDefaultThreadFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.threads; 18 | 19 | import io.netty.util.concurrent.DefaultThreadFactory; 20 | 21 | public class RxDefaultThreadFactory extends DefaultThreadFactory { 22 | 23 | public RxDefaultThreadFactory(String threadNamePrefix) { 24 | super(threadNamePrefix, true); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/threads/RxJavaNettyBasedSchedulersHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.threads; 19 | 20 | import io.netty.channel.EventLoopGroup; 21 | import rx.Scheduler; 22 | import rx.annotations.Beta; 23 | import rx.plugins.RxJavaSchedulersHook; 24 | import rx.schedulers.Schedulers; 25 | 26 | /** 27 | * A scheduler hook for RxJava, to override the computation scheduler, as retrieved via {@link Schedulers#computation()}, 28 | * with a scheduler to use netty's {@link EventLoopGroup}. The computation scheduler implementation is as provided as an 29 | * {@link RxJavaEventloopScheduler} instance.

30 | * 31 | * This is to be used as

32 | {@code 33 | RxJavaPlugins.getInstance().registerSchedulersHook(hook); 34 | } 35 | at startup. 36 | */ 37 | @Beta 38 | public class RxJavaNettyBasedSchedulersHook extends RxJavaSchedulersHook { 39 | 40 | private final RxJavaEventloopScheduler computationScheduler; 41 | 42 | public RxJavaNettyBasedSchedulersHook(RxJavaEventloopScheduler computationScheduler) { 43 | this.computationScheduler = computationScheduler; 44 | } 45 | 46 | @Override 47 | public Scheduler getComputationScheduler() { 48 | return computationScheduler; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /rxnetty-common/src/main/java/io/reactivex/netty/util/StringLineDecoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | package io.reactivex.netty.util; 18 | 19 | import io.netty.buffer.ByteBuf; 20 | import io.netty.channel.ChannelHandlerContext; 21 | import io.netty.handler.codec.ByteToMessageDecoder; 22 | 23 | import java.util.List; 24 | 25 | /** 26 | * A decoder that breaks an incoming {@link ByteBuf}s into a list of strings delimited by a new line. 27 | */ 28 | public class StringLineDecoder extends ByteToMessageDecoder { 29 | 30 | private final LineReader lineReader = new LineReader(); 31 | 32 | @Override 33 | protected void handlerRemoved0(ChannelHandlerContext ctx) throws Exception { 34 | lineReader.dispose(); 35 | super.handlerRemoved0(ctx); 36 | } 37 | 38 | @Override 39 | protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { 40 | lineReader.decode(in, out, ctx.alloc()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /rxnetty-common/src/test/java/io/reactivex/netty/test/util/FlushSelector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.test.util; 18 | 19 | import rx.functions.Func1; 20 | 21 | public class FlushSelector implements Func1 { 22 | 23 | private final int flushEvery; 24 | private int count; 25 | 26 | public FlushSelector(int flushEvery) { 27 | this.flushEvery = flushEvery; 28 | } 29 | 30 | @Override 31 | public Boolean call(T o) { 32 | return ++count % flushEvery == 0; 33 | } 34 | 35 | public int getFlushEvery() { 36 | return flushEvery; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /rxnetty-common/src/test/java/io/reactivex/netty/test/util/MockEventPublisher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.test.util; 19 | 20 | import io.reactivex.netty.events.EventListener; 21 | import io.reactivex.netty.events.EventPublisher; 22 | import io.reactivex.netty.events.EventSource; 23 | import rx.Subscription; 24 | import rx.subscriptions.Subscriptions; 25 | 26 | public class MockEventPublisher implements EventPublisher, EventSource { 27 | 28 | private static final MockEventPublisher DISABLED_EVENT_PUBLISHER = new MockEventPublisher(true); 29 | private static final MockEventPublisher ENABLED_EVENT_PUBLISHER = new MockEventPublisher(false); 30 | 31 | private final boolean disable; 32 | 33 | private MockEventPublisher(boolean disable) { 34 | this.disable = disable; 35 | } 36 | 37 | public static MockEventPublisher disabled() { 38 | @SuppressWarnings("unchecked") 39 | MockEventPublisher t = (MockEventPublisher) DISABLED_EVENT_PUBLISHER; 40 | return t; 41 | } 42 | 43 | public static MockEventPublisher enabled() { 44 | @SuppressWarnings("unchecked") 45 | MockEventPublisher t = (MockEventPublisher) ENABLED_EVENT_PUBLISHER; 46 | return t; 47 | } 48 | 49 | @Override 50 | public boolean publishingEnabled() { 51 | return !disable; 52 | } 53 | 54 | @Override 55 | public Subscription subscribe(T listener) { 56 | return Subscriptions.empty(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /rxnetty-common/src/test/java/io/reactivex/netty/test/util/MockPoolLimitDeterminationStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.test.util; 18 | 19 | import io.reactivex.netty.client.pool.MaxConnectionsBasedStrategy; 20 | import io.reactivex.netty.client.pool.PoolLimitDeterminationStrategy; 21 | 22 | import java.util.concurrent.TimeUnit; 23 | import java.util.concurrent.atomic.AtomicInteger; 24 | 25 | public class MockPoolLimitDeterminationStrategy implements PoolLimitDeterminationStrategy { 26 | 27 | private final MaxConnectionsBasedStrategy delegate; 28 | private final AtomicInteger acquireCount = new AtomicInteger(); 29 | private final AtomicInteger releaseCount = new AtomicInteger(); 30 | 31 | public MockPoolLimitDeterminationStrategy(int maxPermits) { 32 | delegate = new MaxConnectionsBasedStrategy(maxPermits); 33 | } 34 | 35 | @Override 36 | public boolean acquireCreationPermit(long acquireStartTime, TimeUnit timeUnit) { 37 | acquireCount.incrementAndGet(); 38 | return delegate.acquireCreationPermit(acquireStartTime, timeUnit); 39 | } 40 | 41 | @Override 42 | public int getAvailablePermits() { 43 | return delegate.getAvailablePermits(); 44 | } 45 | 46 | @Override 47 | public void releasePermit() { 48 | releaseCount.incrementAndGet(); 49 | delegate.releasePermit(); 50 | } 51 | 52 | public int getAcquireCount() { 53 | return acquireCount.get(); 54 | } 55 | 56 | public int getReleaseCount() { 57 | return releaseCount.get(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /rxnetty-common/src/test/java/io/reactivex/netty/test/util/MockProducer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.test.util; 18 | 19 | import rx.Producer; 20 | 21 | import java.util.concurrent.atomic.AtomicInteger; 22 | import java.util.concurrent.atomic.AtomicLong; 23 | 24 | public class MockProducer implements Producer { 25 | 26 | private final AtomicLong requested = new AtomicLong(); 27 | private final AtomicInteger negativeRequestCount = new AtomicInteger(); 28 | private final AtomicInteger maxValueRequestedCount = new AtomicInteger(); 29 | 30 | @Override 31 | public void request(long n) { 32 | if (Long.MAX_VALUE == n) { 33 | requested.set(Long.MAX_VALUE); 34 | maxValueRequestedCount.incrementAndGet(); 35 | } else if (n <= 0) { 36 | negativeRequestCount.incrementAndGet(); 37 | } 38 | requested.addAndGet(n); 39 | } 40 | 41 | public long getRequested() { 42 | return requested.get(); 43 | } 44 | 45 | public void assertIllegalRequest() { 46 | final int negReqCnt = negativeRequestCount.get(); 47 | if (negReqCnt != 0) { 48 | throw new AssertionError("Negative items requested " + negReqCnt + " times."); 49 | } 50 | } 51 | 52 | public void assertBackpressureRequested() { 53 | final int maxValReqCnt = maxValueRequestedCount.get(); 54 | if (maxValReqCnt != 0) { 55 | throw new AssertionError("Backpressure disabled " + maxValReqCnt + " times."); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /rxnetty-common/src/test/java/io/reactivex/netty/test/util/embedded/EmbeddedChannelWithFeeder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | package io.reactivex.netty.test.util.embedded; 18 | 19 | import io.netty.channel.embedded.EmbeddedChannel; 20 | import io.reactivex.netty.client.events.ClientEventListener; 21 | import io.reactivex.netty.events.EventSource; 22 | import io.reactivex.netty.test.util.MockEventPublisher; 23 | import io.reactivex.netty.test.util.InboundRequestFeeder; 24 | 25 | public class EmbeddedChannelWithFeeder { 26 | 27 | private final EmbeddedChannel channel; 28 | private final InboundRequestFeeder feeder; 29 | private final EventSource tcpEventSource; 30 | 31 | public EmbeddedChannelWithFeeder(EmbeddedChannel channel, InboundRequestFeeder feeder) { 32 | this(channel, feeder, MockEventPublisher.disabled()); 33 | } 34 | 35 | public EmbeddedChannelWithFeeder(EmbeddedChannel channel, InboundRequestFeeder feeder, 36 | EventSource tcpEventSource) { 37 | this.channel = channel; 38 | this.feeder = feeder; 39 | this.tcpEventSource = tcpEventSource; 40 | } 41 | 42 | public EmbeddedChannel getChannel() { 43 | return channel; 44 | } 45 | 46 | public InboundRequestFeeder getFeeder() { 47 | return feeder; 48 | } 49 | 50 | public EventSource getTcpEventSource() { 51 | return tcpEventSource; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /rxnetty-common/src/test/java/io/reactivex/netty/test/util/embedded/EmbeddedConnectionProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.test.util.embedded; 19 | 20 | import io.netty.channel.Channel; 21 | import io.reactivex.netty.channel.Connection; 22 | import io.reactivex.netty.channel.ConnectionImpl; 23 | import io.reactivex.netty.client.ConnectionProvider; 24 | import io.reactivex.netty.client.ConnectionProviderFactory; 25 | import io.reactivex.netty.client.HostConnector; 26 | import rx.Observable; 27 | import rx.functions.Func1; 28 | 29 | public class EmbeddedConnectionProvider implements ConnectionProvider { 30 | 31 | private final EmbeddedChannelProvider channelProvider; 32 | 33 | public EmbeddedConnectionProvider() { 34 | this(new EmbeddedChannelProvider()); 35 | } 36 | 37 | public EmbeddedConnectionProvider(EmbeddedChannelProvider channelProvider) { 38 | this.channelProvider = channelProvider; 39 | } 40 | 41 | @Override 42 | public Observable> newConnectionRequest() { 43 | return channelProvider.newChannel(Observable.empty()) 44 | .map(new Func1>() { 45 | @Override 46 | public Connection call(Channel channel) { 47 | return ConnectionImpl.fromChannel(channel); 48 | } 49 | }); 50 | } 51 | 52 | public EmbeddedChannelProvider getChannelProvider() { 53 | return channelProvider; 54 | } 55 | 56 | public ConnectionProviderFactory asFactory() { 57 | return new ConnectionProviderFactory() { 58 | @Override 59 | public ConnectionProvider newProvider(Observable> hosts) { 60 | return EmbeddedConnectionProvider.this; 61 | } 62 | }; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /rxnetty-common/src/test/java/io/reactivex/netty/threads/PreferCurrentEventLoopGroupTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.threads; 18 | 19 | import io.netty.channel.nio.NioEventLoopGroup; 20 | import io.netty.util.concurrent.EventExecutor; 21 | import io.netty.util.concurrent.Future; 22 | import org.junit.Test; 23 | 24 | import java.util.Set; 25 | import java.util.concurrent.Callable; 26 | import java.util.concurrent.TimeUnit; 27 | 28 | import static org.junit.Assert.*; 29 | 30 | public class PreferCurrentEventLoopGroupTest { 31 | 32 | @Test(timeout = 60000) 33 | public void testNextInEventloop() throws Exception { 34 | final PreferCurrentEventLoopGroup group = new PreferCurrentEventLoopGroup(new NioEventLoopGroup(4)); 35 | for (EventExecutor child : group) { 36 | Future future = child.submit(new Callable() { 37 | @Override 38 | public Boolean call() throws Exception { 39 | return group.next().inEventLoop(); 40 | } 41 | }); 42 | assertTrue("Current eventloop was not preferred.", future.get(1, TimeUnit.MINUTES)); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /rxnetty-common/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2015 Netflix, 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 | log4j.rootLogger=INFO, stdout 18 | 19 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 20 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 21 | log4j.appender.stdout.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss,SSS} %5p [%t] (%F:%L) - %m%n -------------------------------------------------------------------------------- /rxnetty-examples/README.md: -------------------------------------------------------------------------------- 1 | 2 | This module contains examples for various usecases that `RxNetty` to act as a "Getting Started" guide to use `RxNetty`. 3 | The examples are not exhaustive in terms of the features `RxNetty` provides but are representative of different 4 | usecases that one can achieve using `RxNetty` 5 | 6 | Catalog 7 | ================ 8 | 9 | The catalog is categorized with protocol as well as the user level like Beginner, Intermediate, Advanced, for you to get 10 | to the correct example when using `RxNetty`. The following protocol based categorization links to the elaborate examples 11 | per protocol. 12 | 13 | ### TCP 14 | 15 | [This catalog](TCP.md) contains all examples for TCP. 16 | 17 | ### HTTP 18 | 19 | [This catalog](HTTP.md) contains all examples for HTTP. 20 | 21 | ### WebSockets 22 | 23 | [This catalog](WS.md) contains all examples for HTTP. 24 | 25 | Using the examples 26 | =============== 27 | 28 | All examples have a `Server` and `Client` class, both of which can be run independently from their `main` methods. 29 | 30 | ### Server 31 | 32 | All servers use ephemeral ports and when started outputs the port it is using. The server code is usually useful when 33 | you are trying to understand how to write a server for that usecase. If you are only interested in the client, then you 34 | can safely ignore the server part as the client is standalone. 35 | 36 | ### Client 37 | 38 | All clients can be executed in 3 different ways: 39 | 40 | - __Default__: This internally starts the server required by the client and uses the ephermal port used by the server. 41 | This is the easiest way to run any example. 42 | 43 | 44 | - __Use an already started server__: In this mode, the client does not try to start a server by itself. For running in 45 | this mode, you should pass the port as a program argument while running the client, eg: 46 | 47 | ``` 48 | java io.reactivex.netty.examples.http.helloworld.HelloWorldClient [server port] 49 | ``` 50 | 51 | - __Use an external server__: In this mode, the client does not try to start a server by itself. For running in 52 | this mode, you should pass server host & port as a program argument while running the client, eg: 53 | 54 | ``` 55 | java io.reactivex.netty.examples.http.helloworld.HelloWorldClient [server port] [server host] 56 | ``` 57 | -------------------------------------------------------------------------------- /rxnetty-examples/WS.md: -------------------------------------------------------------------------------- 1 | WebSockets Examples 2 | ============== 3 | 4 | The following WebSockets examples are available: 5 | 6 | - __Echo__: A WebSockets echo example where the client sends a set of pre-defined WebSocket frames and expects the server to 7 | echo the same frames back. This example constitutes of an 8 | [Echo Client](src/main/java/io/reactivex/netty/examples/http/ws/echo/WebSocketEchoClient.java) 9 | and an [Echo Server](src/main/java/io/reactivex/netty/examples/http/ws/echo/WebSocketEchoServer.java) 10 | 11 | - __Messaging__: An example to demonstrate how to use a websocket connection for atleast once message delivery. This 12 | example constitutes of a 13 | [Messaging Client](src/main/java/io/reactivex/netty/examples/http/ws/messaging/MessagingClient.java) 14 | and a [Messaging Server](src/main/java/io/reactivex/netty/examples/http/ws/messaging/MessagingServer.java) 15 | -------------------------------------------------------------------------------- /rxnetty-examples/bin/WEB-INF/index.html: -------------------------------------------------------------------------------- 1 | 16 |

Hello RxNetty!!!

-------------------------------------------------------------------------------- /rxnetty-examples/bin/document.txt: -------------------------------------------------------------------------------- 1 | Lets count some words. Lets count some words. Lets count some words. Lets count some words. 2 | Lets count some words. Lets count some words. Lets count some words. Lets count some words. 3 | Lets count some words. Lets count some words. Lets count some words. Lets count some words. 4 | Lets count some words. Lets count some words. Lets count some words. Lets count some words. -------------------------------------------------------------------------------- /rxnetty-examples/bin/io/reactivex/netty/examples/http/cpuintensive/README.md: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | An example of how to write a server which does some CPU intensive or Blocking work and hence is not suitable for running 5 | the request processing in the channel's event loop. 6 | This is achieved by using netty's [`EventExecutorGroup`](https://github.com/netty/netty/blob/master/common/src/main/java/io/netty/util/concurrent/EventExecutorGroup.java) 7 | as a threadpool. 8 | `RxNetty` makes sure that the [`RequestHandler`](https://github.com/Netflix/RxNetty/blob/master/rxnetty/src/main/java/io/reactivex/netty/protocol/http/server/RequestHandler.java) 9 | as well as the subscribers of `HttpServerRequest`'s content happens on this executor. 10 | 11 | Running 12 | ======= 13 | 14 | To run the example execute: 15 | 16 | ``` 17 | $ cd RxNetty/rxnetty-examples 18 | $ ../gradlew runCpuIntensiveHttpServer 19 | ``` 20 | 21 | and in another console: 22 | 23 | ``` 24 | $ cd RxNetty/rxnetty-examples 25 | $ ../gradlew runCpuIntensiveHttpClient 26 | ``` 27 | -------------------------------------------------------------------------------- /rxnetty-examples/bin/io/reactivex/netty/examples/http/logtail/README.md: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | Log tail example aims to illustrate how SOA application, consisting of multiple level service hierarchy could be 5 | implemented with RxNetty. The key service here is log aggregator (LogAggregator class) that taps to multiple 6 | lower-level services (log producers), and processes/filters the received log entries prior to sending it further 7 | to a client. 8 | 9 | Running 10 | ======= 11 | 12 | You can run multiple log producers, but they have to have consecutive port numbers: 13 | 14 | ``` 15 | $ cd RxNetty/rxnetty-examples 16 | $ ../gradlew runLogTailProducer -Pport= -Pinterval= > logProducer1.log & 17 | $ ../gradlew runLogTailProducer -Pport= -Pinterval= > logProducer2.log & 18 | ... 19 | $ ../gradlew runLogTailProducer -Pport= -Pinterval= > logProducerM.log & 20 | ``` 21 | 22 | next log aggregator has to be started: 23 | 24 | ``` 25 | $ cd RxNetty/rxnetty-examples 26 | $ ../gradlew runLogTailAggregator -PportFrom= -PportTo= 27 | ``` 28 | 29 | and the last one is the client: 30 | 31 | ``` 32 | $ cd RxNetty/rxnetty-examples 33 | $ ../gradlew runLogTailClient 34 | ``` 35 | -------------------------------------------------------------------------------- /rxnetty-examples/bin/io/reactivex/netty/examples/http/plaintext/README.md: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | This example is intended to be a sample used for "helloworld" performance tests for RxNetty and has optimizations specific 5 | for helloworld kind of tests. 6 | 7 | The following are the primary differences over the [HelloWorld example](../helloworld) 8 | 9 | - This example does NOT aggregate HTTP requests. 10 | - This example does NOT print the request headers. 11 | 12 | Running 13 | ======= 14 | 15 | To run the example execute: 16 | 17 | ``` 18 | $ cd RxNetty/rxnetty-examples 19 | $ ../gradlew runPlainTextServer 20 | ``` 21 | 22 | and in another console: 23 | 24 | ``` 25 | $ cd RxNetty/rxnetty-examples 26 | $ ../gradlew runPlainTextClient 27 | ``` 28 | -------------------------------------------------------------------------------- /rxnetty-examples/bin/io/reactivex/netty/examples/http/ssl/README.md: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | TO enable HTTPS connection, configure ```io.reactivex.netty.pipeline.ssl.SSLEngineFactory``` using 5 | HttpClientBuilder. For testing purposes ```io.reactivex.netty.pipeline.ssl.DefaultFactories``` class is provided 6 | that makes it easy to build SSLEngineFactory instances for client and server endpoints. These are good only for testing environment. 7 | 8 | Running 9 | ======= 10 | 11 | To run the example execute: 12 | 13 | ``` 14 | $ cd RxNetty/rxnetty-examples 15 | $ ../gradlew runSslHelloWorldServer 16 | ``` 17 | 18 | and in another console: 19 | 20 | ``` 21 | $ cd RxNetty/rxnetty-examples 22 | $ ../gradlew runSslHelloWorldClient 23 | ``` 24 | 25 | HTTP client 26 | =========== 27 | 28 | Here is the snippet from [SslHelloWordClient](SslHelloWorldClient.java): 29 | 30 | ```java 31 | public HttpResponseStatus sendHelloRequest() throws Exception { 32 | HttpClient rxClient = RxNetty.newHttpClientBuilder("localhost", port) 33 | .withSslEngineFactory(DefaultFactories.trustAll()) 34 | .build(); 35 | 36 | HttpResponseStatus statusCode = rxClient.submit(HttpClientRequest.createGet("/hello")) 37 | ... 38 | } 39 | } 40 | ``` 41 | 42 | The client code is identical to its non-encrypted counterpart ([HelloWorldClient](../helloworld/README.md)), except 43 | the HTTPClient creation step. The predefined DefaultFactories.trustAll() SSLEngineFactory used in the example 44 | will accept all certificates without validation. It is good only for testing purposes. 45 | 46 | HTTP server 47 | =========== 48 | 49 | Here is the snippet from [SslHelloWordClient](SslHelloWorldServer.java): 50 | 51 | ```java 52 | public HttpServer createServer() throws CertificateException, SSLException { 53 | HttpServer server = RxNetty.newHttpServerBuilder(port, new RequestHandler() { 54 | @Override 55 | public Observable handle(HttpServerRequest request, final HttpServerResponse response) { 56 | response.writeStringAndFlush("Welcome!!"); 57 | return response.close(); 58 | } 59 | }).withSslEngineFactory(DefaultFactories.selfSigned()).build(); 60 | ... 61 | } 62 | ``` 63 | 64 | On the server side, SSLEngineFactory is configured with a temporary self signed certificate/private key generated automatically. 65 | It will be accepted on the client side, since in it is configured to trusts all certificates. 66 | This setup should NEVER be used in the production deployment. Its usage is limited to test code/examples. 67 | -------------------------------------------------------------------------------- /rxnetty-examples/bin/io/reactivex/netty/examples/tcp/cpuintensive/README.md: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | An example of how to write a server which does some CPU intensive or Blocking work and hence is not suitable for running 5 | the connection processing in the channel's event loop. 6 | This is achieved by using netty's [`EventExecutorGroup`](https://github.com/netty/netty/blob/master/common/src/main/java/io/netty/util/concurrent/EventExecutorGroup.java) 7 | as a threadpool. 8 | `RxNetty` makes sure that the [`ConnectionHandler`](https://github.com/Netflix/RxNetty/blob/master/rxnetty/src/main/java/io/reactivex/netty/channel/ConnectionHandler.java) 9 | as well as the subscribers of `ObservableConnection`'s content happens on this executor. 10 | 11 | Running 12 | ======= 13 | 14 | To run the example execute: 15 | 16 | ``` 17 | $ cd RxNetty/rxnetty-examples 18 | $ ../gradlew runCpuIntensiveTcpServer 19 | ``` 20 | 21 | and in another console: 22 | 23 | ``` 24 | $ cd RxNetty/rxnetty-examples 25 | $ ../gradlew runCpuIntensiveTcpClient 26 | ``` -------------------------------------------------------------------------------- /rxnetty-examples/bin/io/reactivex/netty/examples/tcp/echo/README.md: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | It is basic TCP client/server example with String content encoder/decoder. 5 | 6 | Running 7 | ======= 8 | 9 | To run the example execute: 10 | 11 | ``` 12 | $ cd RxNetty/rxnetty-examples 13 | $ ../gradlew runTcpEchoServer 14 | ``` 15 | 16 | and in another console: 17 | 18 | ``` 19 | $ cd RxNetty/rxnetty-examples 20 | $ ../gradlew runTcpEchoClient 21 | ``` 22 | -------------------------------------------------------------------------------- /rxnetty-examples/bin/io/reactivex/netty/examples/tcp/event/README.md: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | In this example TCP server sends a sequence of events to the client at 10ms intervals. The client is started 5 | with configurable processing delay and a number of events to collect. Once the required number of events is collected 6 | client terminates. 7 | 8 | By setting client side processing delay to larger value then server side send interval, there is an unbounded amount 9 | of unfinished work accumulated in the transport layer, which will eventually result in server crashing with 10 | OutOfMemory exception. 11 | 12 | Running 13 | ======= 14 | 15 | To run the example execute: 16 | 17 | ``` 18 | $ cd RxNetty/rxnetty-examples 19 | $ ../gradlew runTcpEventStreamServer 20 | ``` 21 | 22 | and in another console: 23 | 24 | ``` 25 | $ cd RxNetty/rxnetty-examples 26 | $ ../gradlew runTcpEventStreamClient -Pdelay= -Pevents= 27 | ``` 28 | -------------------------------------------------------------------------------- /rxnetty-examples/bin/io/reactivex/netty/examples/tcp/interval/README.md: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | This example illustrates simple client/server protocol implementation. The protocol sequence includes the following 5 | steps: 6 | 7 | ``` 8 | client server 9 | | subscribe | 10 | |-------------------->| 11 | | event 1 | 12 | |<--------------------| 13 | | event 2 | 14 | |<--------------------| 15 | | ... | 16 | | event N | 17 | |<--------------------| 18 | | unsubscribe | 19 | |-------------------->| 20 | | | 21 | ``` 22 | 23 | On the client side first subscribe event is sent, which triggers sending of unbounded sequence of events from 24 | server at configured interval. The client consumes a configurable number of events and terminates. Alternatively 25 | it could send unsubscribe event to server which would result in connection termination on the server side. 26 | 27 | Running 28 | ======= 29 | 30 | To run the example execute: 31 | 32 | ``` 33 | $ cd RxNetty/rxnetty-examples 34 | $ ../gradlew runTcpIntervalServer -Pinterval= 35 | ``` 36 | 37 | and in another console: 38 | 39 | ``` 40 | $ cd RxNetty/rxnetty-examples 41 | $ ../gradlew runTcpIntervalClient -P 42 | ``` 43 | -------------------------------------------------------------------------------- /rxnetty-examples/bin/io/reactivex/netty/examples/tcp/ssl/README.md: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | This example is a small modification of [TCP echo](../echo/README.md) example that demonstrates how to setup SSL connection. 5 | More detailed explanation of SSL handling is provided with the [SSL HelloWorld](../../ssl/README.md) example. 6 | 7 | Running 8 | ======= 9 | 10 | To run the example execute: 11 | 12 | ``` 13 | $ cd RxNetty/rxnetty-examples 14 | $ ../gradlew runSslTcpEchoServer 15 | ``` 16 | 17 | and in another console: 18 | 19 | ``` 20 | $ cd RxNetty/rxnetty-examples 21 | $ ../gradlew runSslTcpEchoClient 22 | ``` 23 | -------------------------------------------------------------------------------- /rxnetty-examples/bin/io/reactivex/netty/examples/udp/README.md: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | It is basic UDP client/server example. 5 | 6 | Running 7 | ======= 8 | 9 | To run the example execute: 10 | 11 | ``` 12 | $ cd RxNetty/rxnetty-examples 13 | $ ../gradlew runUdpClient 14 | ``` 15 | 16 | and in another console: 17 | 18 | ``` 19 | $ cd RxNetty/rxnetty-examples 20 | $ ../gradlew runUdpServer 21 | ``` 22 | -------------------------------------------------------------------------------- /rxnetty-examples/bin/log4j.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2014 Netflix, 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 | log4j.rootLogger=INFO, stdout 17 | 18 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 19 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 20 | log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n -------------------------------------------------------------------------------- /rxnetty-examples/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | // examples are in Java 8 while rest of projects is Java 7 19 | sourceCompatibility = JavaVersion.VERSION_1_8 20 | targetCompatibility = JavaVersion.VERSION_1_8 21 | 22 | dependencies { 23 | compile project(':rxnetty-http') 24 | compile project(':rxnetty-spectator-http') 25 | compile project(':rxnetty-tcp') 26 | compile project(':rxnetty-common') 27 | compile "io.reactivex:rxjava-string:1.0.0" 28 | compile "org.slf4j:slf4j-log4j12:${slf4j_version}" 29 | } 30 | -------------------------------------------------------------------------------- /rxnetty-examples/src/main/java/io/reactivex/netty/examples/http/helloworld/HelloWorldServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.examples.http.helloworld; 19 | 20 | import io.netty.buffer.ByteBuf; 21 | import io.reactivex.netty.examples.ExamplesEnvironment; 22 | import io.reactivex.netty.protocol.http.server.HttpServer; 23 | 24 | import static rx.Observable.*; 25 | 26 | /** 27 | * An HTTP "Hello World" server. 28 | * 29 | * This server sends a response with "Hello World" as the content for any request that it recieves. 30 | */ 31 | public final class HelloWorldServer { 32 | 33 | public static void main(final String[] args) { 34 | 35 | ExamplesEnvironment env = ExamplesEnvironment.newEnvironment(HelloWorldServer.class); 36 | 37 | HttpServer server; 38 | 39 | server = HttpServer.newServer() 40 | .start((req, resp) -> 41 | resp.writeString(just("Hello World!")) 42 | ); 43 | 44 | /*Wait for shutdown if not called from the client (passed an arg)*/ 45 | if (env.shouldWaitForShutdown(args)) { 46 | server.awaitShutdown(); 47 | } 48 | 49 | /*If not waiting for shutdown, assign the ephemeral port used to a field so that it can be read and used by 50 | the caller, if any.*/ 51 | env.registerServerAddress(server.getServerAddress()); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /rxnetty-examples/src/main/java/io/reactivex/netty/examples/http/proxy/ProxyClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.examples.http.proxy; 19 | 20 | import io.netty.handler.logging.LogLevel; 21 | import io.reactivex.netty.examples.ExamplesEnvironment; 22 | import io.reactivex.netty.examples.http.helloworld.HelloWorldClient; 23 | import io.reactivex.netty.protocol.http.client.HttpClient; 24 | import org.slf4j.Logger; 25 | 26 | import java.net.SocketAddress; 27 | import java.nio.charset.Charset; 28 | 29 | /** 30 | * A client to test {@link ProxyServer}. This client is provided here only for completeness of the example, 31 | * otherwise, it is exactly the same as {@link HelloWorldClient}. 32 | */ 33 | public final class ProxyClient { 34 | 35 | public static void main(String[] args) { 36 | 37 | ExamplesEnvironment env = ExamplesEnvironment.newEnvironment(ProxyClient.class); 38 | Logger logger = env.getLogger(); 39 | 40 | /* 41 | * Retrieves the server address, using the following algorithm: 42 | *
    43 |
  • If any arguments are passed, then use the first argument as the server port.
  • 44 |
  • If available, use the second argument as the server host, else default to localhost
  • 45 |
  • Otherwise, start the passed server class and use that address.
  • 46 |
47 | */ 48 | SocketAddress serverAddress = env.getServerAddress(ProxyServer.class, args); 49 | 50 | HttpClient.newClient(serverAddress) 51 | .enableWireLogging("proxy-client", LogLevel.DEBUG) 52 | .createGet("/hello") 53 | .doOnNext(resp -> logger.info(resp.toString())) 54 | .flatMap(resp -> resp.getContent() 55 | .map(bb -> bb.toString(Charset.defaultCharset())) 56 | ) 57 | .toBlocking() 58 | .forEach(logger::info); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /rxnetty-examples/src/main/java/io/reactivex/netty/examples/http/secure/SecureHelloWorldServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.examples.http.secure; 19 | 20 | import io.netty.buffer.ByteBuf; 21 | import io.netty.handler.logging.LogLevel; 22 | import io.reactivex.netty.examples.ExamplesEnvironment; 23 | import io.reactivex.netty.protocol.http.server.HttpServer; 24 | 25 | import static rx.Observable.*; 26 | 27 | /** 28 | * An HTTPS "Hello World" server. 29 | * 30 | * This server only accepts HTTPs requests and sends a response with "Hello World" as the content for all requests. 31 | */ 32 | public final class SecureHelloWorldServer { 33 | 34 | public static void main(final String[] args) { 35 | 36 | ExamplesEnvironment env = ExamplesEnvironment.newEnvironment(SecureHelloWorldServer.class); 37 | HttpServer server; 38 | 39 | server = HttpServer.newServer() 40 | .enableWireLogging("hello-server", LogLevel.DEBUG) 41 | /*Enable HTTPS for demo purpose only, for real apps, use secure() methods instead.*/ 42 | .unsafeSecure() 43 | .start((req, resp) -> 44 | resp.writeString(just("Hello World!")) 45 | ); 46 | 47 | /*Wait for shutdown if not called from the client (passed an arg)*/ 48 | if (env.shouldWaitForShutdown(args)) { 49 | server.awaitShutdown(); 50 | } 51 | 52 | /*If not waiting for shutdown, assign the ephemeral port used to a field so that it can be read and used by 53 | the caller, if any.*/ 54 | env.registerServerAddress(server.getServerAddress()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /rxnetty-examples/src/main/java/io/reactivex/netty/examples/http/streaming/StreamingServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.examples.http.streaming; 19 | 20 | import io.netty.buffer.ByteBuf; 21 | import io.netty.handler.logging.LogLevel; 22 | import io.reactivex.netty.examples.ExamplesEnvironment; 23 | import io.reactivex.netty.protocol.http.server.HttpServer; 24 | import rx.Observable; 25 | 26 | import java.util.concurrent.TimeUnit; 27 | 28 | /** 29 | * An HTTP server that sends an infinite HTTP chunked response emitting a number every second. 30 | */ 31 | public final class StreamingServer { 32 | 33 | public static void main(final String[] args) { 34 | 35 | ExamplesEnvironment env = ExamplesEnvironment.newEnvironment(StreamingServer.class); 36 | 37 | HttpServer server; 38 | 39 | server = HttpServer.newServer() 40 | .enableWireLogging("streaming-server", LogLevel.DEBUG) 41 | .start((req, resp) -> 42 | resp.writeStringAndFlushOnEach( 43 | Observable.interval(10, TimeUnit.MILLISECONDS) 44 | .onBackpressureBuffer(10) 45 | .map(aLong -> "Interval =>" + aLong) 46 | ) 47 | ); 48 | 49 | /*Wait for shutdown if not called from the client (passed an arg)*/ 50 | if (env.shouldWaitForShutdown(args)) { 51 | server.awaitShutdown(); 52 | } 53 | 54 | /*If not waiting for shutdown, assign the ephemeral port used to a field so that it can be read and used by 55 | the caller, if any.*/ 56 | env.registerServerAddress(server.getServerAddress()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /rxnetty-examples/src/main/java/io/reactivex/netty/examples/http/ws/messaging/AcceptOnlyBinaryFramesFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.examples.http.ws.messaging; 19 | 20 | import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; 21 | import io.netty.handler.codec.http.websocketx.WebSocketFrame; 22 | import rx.functions.Func1; 23 | 24 | public class AcceptOnlyBinaryFramesFilter implements Func1 { 25 | 26 | public static final AcceptOnlyBinaryFramesFilter INSTANCE = new AcceptOnlyBinaryFramesFilter(); 27 | 28 | private AcceptOnlyBinaryFramesFilter() { 29 | } 30 | 31 | @Override 32 | public Boolean call(WebSocketFrame f) { 33 | if (f instanceof BinaryWebSocketFrame) { 34 | return true; 35 | } else { 36 | f.release(); 37 | return false; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /rxnetty-examples/src/main/java/io/reactivex/netty/examples/http/ws/messaging/PendingMessageTracker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.examples.http.ws.messaging; 19 | 20 | import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; 21 | import io.netty.handler.codec.http.websocketx.WebSocketFrame; 22 | import io.reactivex.netty.examples.http.ws.messaging.MessageFrame.MessageType; 23 | import io.reactivex.netty.util.UnicastBufferingSubject; 24 | import rx.Observable; 25 | 26 | import java.util.concurrent.ConcurrentLinkedQueue; 27 | import java.util.concurrent.TimeUnit; 28 | 29 | public class PendingMessageTracker { 30 | 31 | private final ConcurrentLinkedQueue unacknowledgedIds; 32 | 33 | public PendingMessageTracker(UnicastBufferingSubject sender) { 34 | unacknowledgedIds = new ConcurrentLinkedQueue<>(); 35 | Observable.interval(10, TimeUnit.SECONDS) 36 | .forEach(aTick -> { 37 | Long unacked; 38 | while ((unacked = unacknowledgedIds.poll()) != null) { 39 | sender.onNext(new MessageFrame(MessageType.Message, unacked)); 40 | } 41 | }); 42 | } 43 | 44 | public MessageFrame addPendingMessage(MessageFrame messageFrame) { 45 | unacknowledgedIds.add(messageFrame.getId()); 46 | return messageFrame; 47 | } 48 | 49 | public MessageFrame removePendingMessage(BinaryWebSocketFrame bFrame) { 50 | MessageFrame mf = new MessageFrame(bFrame.content()); 51 | unacknowledgedIds.remove(mf.getId()); 52 | return mf; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /rxnetty-examples/src/main/java/io/reactivex/netty/examples/tcp/loadbalancing/TcpLoadBalancer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | package io.reactivex.netty.examples.tcp.loadbalancing; 18 | 19 | import io.reactivex.netty.client.events.ClientEventListener; 20 | import io.reactivex.netty.protocol.tcp.client.events.TcpClientEventListener; 21 | 22 | import java.util.concurrent.TimeUnit; 23 | 24 | /** 25 | * This is an implementation of {@link AbstractLoadBalancer} for TCP clients. 26 | * 27 | * This load balancer uses a naive failure detector that removes the host on the first connection failure. The 28 | * intention here is just to demonstrate how to write complex load balancing logic using lower level constructs in the 29 | * client. 30 | * 31 | * @param Type of Objects written on the connections created by this load balancer. 32 | * @param Type of Objects read from the connections created by this load balancer. 33 | */ 34 | public class TcpLoadBalancer extends AbstractLoadBalancer { 35 | 36 | public TcpLoadBalancer() { 37 | super(); 38 | } 39 | 40 | @Override 41 | protected ClientEventListener newListener() { 42 | 43 | return new ClientEventListenerImpl(); 44 | } 45 | 46 | @Override 47 | protected long getWeight(ClientEventListener eventListener) { 48 | return ((ClientEventListenerImpl)eventListener).weight; 49 | } 50 | 51 | private static class ClientEventListenerImpl extends TcpClientEventListener { 52 | 53 | private volatile long weight = Long.MAX_VALUE; 54 | 55 | @Override 56 | public void onConnectFailed(long duration, TimeUnit timeUnit, Throwable throwable) { 57 | weight = Long.MIN_VALUE; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /rxnetty-examples/src/main/java/io/reactivex/netty/examples/tcp/streaming/StreamingServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.examples.tcp.streaming; 19 | 20 | import io.netty.buffer.ByteBuf; 21 | import io.netty.handler.logging.LogLevel; 22 | import io.reactivex.netty.examples.ExamplesEnvironment; 23 | import io.reactivex.netty.protocol.tcp.server.TcpServer; 24 | import rx.Observable; 25 | 26 | import java.util.concurrent.TimeUnit; 27 | 28 | /** 29 | * A TCP server that sends an infinite stream of new-line separated strings to all accepted connections. 30 | */ 31 | public final class StreamingServer { 32 | 33 | public static void main(final String[] args) { 34 | 35 | ExamplesEnvironment env = ExamplesEnvironment.newEnvironment(StreamingServer.class); 36 | 37 | TcpServer server; 38 | 39 | server = TcpServer.newServer() 40 | .enableWireLogging("streaming-server", LogLevel.DEBUG) 41 | .start(connection -> 42 | connection.writeStringAndFlushOnEach( 43 | Observable.interval(10, TimeUnit.MILLISECONDS) 44 | .onBackpressureBuffer() 45 | .map(aLong -> "Interval =>" + aLong + '\n') 46 | ) 47 | ); 48 | 49 | if (env.shouldWaitForShutdown(args)) { 50 | /*When testing the args are set, to avoid blocking till shutdown*/ 51 | server.awaitShutdown(); 52 | } 53 | 54 | env.registerServerAddress(server.getServerAddress()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /rxnetty-examples/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2015 Netflix, 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 | log4j.rootLogger=INFO, stdout 17 | 18 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 19 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 20 | log4j.appender.stdout.layout.ConversionPattern=%c %d{dd MMM yyyy HH:mm:ss,SSS} %5p [%t] (%F:%L) - %m%n -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/ExamplesMockLogger.java: -------------------------------------------------------------------------------- 1 | package io.reactivex.netty.examples; 2 | 3 | import org.mockito.Mockito; 4 | import org.mockito.invocation.InvocationOnMock; 5 | import org.mockito.stubbing.Answer; 6 | import org.slf4j.Logger; 7 | 8 | import java.util.Queue; 9 | import java.util.concurrent.ConcurrentLinkedQueue; 10 | 11 | import static org.mockito.Matchers.*; 12 | 13 | public class ExamplesMockLogger { 14 | 15 | private final Logger mock; 16 | private final Queue logMessages; 17 | 18 | public ExamplesMockLogger(Class exampleClass) { 19 | mock = Mockito.mock(Logger.class); 20 | logMessages = new ConcurrentLinkedQueue<>(); 21 | 22 | Mockito.doAnswer(new TeeLogsAnswer(logMessages)).when(mock).error(anyString()); 23 | Mockito.doAnswer(new TeeLogsAnswer(logMessages)).when(mock).debug(anyString()); 24 | Mockito.doAnswer(new TeeLogsAnswer(logMessages)).when(mock).info(anyString()); 25 | Mockito.doAnswer(new TeeLogsAnswer(logMessages)).when(mock).warn(anyString()); 26 | } 27 | 28 | public Logger getMock() { 29 | return mock; 30 | } 31 | 32 | public Queue getLogMessages() { 33 | return logMessages; 34 | } 35 | 36 | private static class TeeLogsAnswer implements Answer { 37 | 38 | private final Queue output; 39 | 40 | public TeeLogsAnswer(Queue output) { 41 | this.output = output; 42 | } 43 | 44 | @Override 45 | public Void answer(InvocationOnMock invocation) throws Throwable { 46 | String logged = (String) invocation.getArguments()[0]; 47 | System.out.println(logged); 48 | output.add(logged); 49 | return null; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/ExamplesTestUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 io.reactivex.netty.examples; 17 | 18 | import java.util.Queue; 19 | 20 | public final class ExamplesTestUtil { 21 | 22 | private ExamplesTestUtil() { 23 | } 24 | 25 | public static Queue runClientInMockedEnvironment(Class exampleClass) { 26 | ExamplesMockLogger mockLogger = new ExamplesMockLogger(exampleClass); 27 | Queue output = mockLogger.getLogMessages(); 28 | ExamplesEnvironment.overrideEnvironment(exampleClass, 29 | new ExamplesEnvironment(exampleClass, mockLogger.getMock())); 30 | ExamplesEnvironment.invokeExample(exampleClass, new String[0]); 31 | return output; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/http/helloworld/HelloWorldTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.examples.http.helloworld; 19 | 20 | import io.netty.handler.codec.http.DefaultHttpResponse; 21 | import io.netty.handler.codec.http.HttpHeaderNames; 22 | import io.netty.handler.codec.http.HttpHeaderValues; 23 | import io.netty.handler.codec.http.HttpResponse; 24 | import io.netty.handler.codec.http.HttpResponseStatus; 25 | import io.netty.handler.codec.http.HttpVersion; 26 | import io.reactivex.netty.examples.ExamplesTestUtil; 27 | import io.reactivex.netty.protocol.http.internal.HttpMessageFormatter; 28 | import org.junit.Test; 29 | 30 | import java.lang.reflect.InvocationTargetException; 31 | import java.util.Queue; 32 | 33 | import static org.hamcrest.MatcherAssert.*; 34 | import static org.hamcrest.Matchers.*; 35 | 36 | public class HelloWorldTest { 37 | 38 | @Test(timeout = 60000) 39 | public void testHelloWorld() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { 40 | 41 | Queue output = ExamplesTestUtil.runClientInMockedEnvironment(HelloWorldClient.class); 42 | 43 | HttpResponse expectedHeader = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); 44 | expectedHeader.headers().add(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED); 45 | String expectedHeaderString = HttpMessageFormatter.formatResponse(expectedHeader.protocolVersion(), 46 | expectedHeader.status(), 47 | expectedHeader.headers().iteratorCharSequence()); 48 | 49 | assertThat("Unexpected number of messages echoed", output, hasSize(2)); 50 | 51 | assertThat("Unexpected response.", output, contains(expectedHeaderString, "Hello World!")); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/http/interceptors/transformation/TransformingInterceptorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.examples.http.interceptors.transformation; 19 | 20 | import io.netty.handler.codec.http.DefaultHttpResponse; 21 | import io.netty.handler.codec.http.HttpHeaderNames; 22 | import io.netty.handler.codec.http.HttpHeaderValues; 23 | import io.netty.handler.codec.http.HttpResponse; 24 | import io.netty.handler.codec.http.HttpResponseStatus; 25 | import io.netty.handler.codec.http.HttpVersion; 26 | import io.reactivex.netty.examples.ExamplesTestUtil; 27 | import io.reactivex.netty.protocol.http.internal.HttpMessageFormatter; 28 | import org.junit.Test; 29 | 30 | import java.util.Queue; 31 | 32 | import static org.hamcrest.MatcherAssert.*; 33 | import static org.hamcrest.Matchers.*; 34 | 35 | public class TransformingInterceptorTest { 36 | 37 | @Test(timeout = 60000) 38 | public void testTransformingInterceptor() throws Exception { 39 | 40 | Queue output = ExamplesTestUtil.runClientInMockedEnvironment(InterceptingClient.class); 41 | 42 | HttpResponse expectedHeader = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); 43 | expectedHeader.headers().add(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED); 44 | String expectedHeaderString = HttpMessageFormatter.formatResponse(expectedHeader.protocolVersion(), 45 | expectedHeader.status(), 46 | expectedHeader.headers().iteratorCharSequence()); 47 | 48 | assertThat("Unexpected number of messages echoed", output, hasSize(3)); 49 | 50 | assertThat("Unexpected response.", output, contains(expectedHeaderString, "1", "2")); 51 | } 52 | } -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/http/loadbalancing/LoadBalancingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 io.reactivex.netty.examples.http.loadbalancing; 17 | 18 | import io.reactivex.netty.examples.ExamplesTestUtil; 19 | import org.junit.Test; 20 | 21 | import java.util.Queue; 22 | 23 | import static org.hamcrest.MatcherAssert.*; 24 | import static org.hamcrest.Matchers.*; 25 | 26 | public class LoadBalancingTest { 27 | 28 | @Test(timeout = 60000) 29 | public void testLoadBalancing() throws Exception { 30 | Queue output = ExamplesTestUtil.runClientInMockedEnvironment(HttpLoadBalancingClient.class); 31 | 32 | assertThat("Unexpected number of messages echoed", output, hasSize(5)); 33 | 34 | assertThat("Unexpected status.", output.poll(), anyOf(containsString("HTTP/1.1 200 OK"), 35 | containsString("HTTP/1.1 503 Service Unavailable"))); 36 | assertThat("Unexpected status.", output.poll(), anyOf(containsString("HTTP/1.1 200 OK"), 37 | containsString("HTTP/1.1 503 Service Unavailable"))); 38 | assertThat("Unexpected status.", output.poll(), anyOf(containsString("HTTP/1.1 200 OK"), 39 | containsString("HTTP/1.1 503 Service Unavailable"))); 40 | assertThat("Unexpected status.", output.poll(), anyOf(containsString("HTTP/1.1 200 OK"), 41 | containsString("HTTP/1.1 503 Service Unavailable"))); 42 | assertThat("Unexpected status.", output.poll(), anyOf(containsString("HTTP/1.1 200 OK"), 43 | containsString("HTTP/1.1 503 Service Unavailable"))); 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/http/proxy/ProxyTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.examples.http.proxy; 19 | 20 | import io.netty.handler.codec.http.DefaultHttpResponse; 21 | import io.netty.handler.codec.http.HttpHeaderNames; 22 | import io.netty.handler.codec.http.HttpHeaderValues; 23 | import io.netty.handler.codec.http.HttpResponse; 24 | import io.netty.handler.codec.http.HttpResponseStatus; 25 | import io.netty.handler.codec.http.HttpVersion; 26 | import io.reactivex.netty.examples.ExamplesTestUtil; 27 | import io.reactivex.netty.protocol.http.internal.HttpMessageFormatter; 28 | import org.junit.Test; 29 | 30 | import java.lang.reflect.InvocationTargetException; 31 | import java.util.Queue; 32 | 33 | import static org.hamcrest.MatcherAssert.*; 34 | import static org.hamcrest.Matchers.*; 35 | 36 | public class ProxyTest { 37 | 38 | @Test(timeout = 60000) 39 | public void testProxy() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { 40 | 41 | Queue output = ExamplesTestUtil.runClientInMockedEnvironment(ProxyClient.class); 42 | 43 | HttpResponse expectedHeader = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); 44 | expectedHeader.headers().add((CharSequence)"X-Proxied-By", "RxNetty"); 45 | expectedHeader.headers().add(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED); 46 | String expectedHeaderString = HttpMessageFormatter.formatResponse(expectedHeader.protocolVersion(), 47 | expectedHeader.status(), 48 | expectedHeader.headers().iteratorCharSequence()); 49 | 50 | assertThat("Unexpected number of messages echoed", output, hasSize(2)); 51 | 52 | assertThat("Unexpected response.", output, contains(expectedHeaderString, "HelloWorld!")); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/http/secure/SecureHelloWorldTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.examples.http.secure; 19 | 20 | import io.netty.handler.codec.http.DefaultHttpResponse; 21 | import io.netty.handler.codec.http.HttpHeaderNames; 22 | import io.netty.handler.codec.http.HttpHeaderValues; 23 | import io.netty.handler.codec.http.HttpResponse; 24 | import io.netty.handler.codec.http.HttpResponseStatus; 25 | import io.netty.handler.codec.http.HttpVersion; 26 | import io.reactivex.netty.examples.ExamplesTestUtil; 27 | import io.reactivex.netty.protocol.http.internal.HttpMessageFormatter; 28 | import org.junit.Test; 29 | 30 | import java.lang.reflect.InvocationTargetException; 31 | import java.util.Queue; 32 | 33 | import static org.hamcrest.MatcherAssert.*; 34 | import static org.hamcrest.Matchers.*; 35 | 36 | public class SecureHelloWorldTest { 37 | 38 | @Test(timeout = 60000) 39 | public void testHelloWorld() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { 40 | 41 | Queue output = ExamplesTestUtil.runClientInMockedEnvironment(SecureHelloWorldClient.class); 42 | 43 | HttpResponse expectedHeader = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); 44 | expectedHeader.headers().add(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED); 45 | String expectedHeaderString = HttpMessageFormatter.formatResponse(expectedHeader.protocolVersion(), 46 | expectedHeader.status(), 47 | expectedHeader.headers().iteratorCharSequence()); 48 | 49 | assertThat("Unexpected number of messages echoed", output, hasSize(2)); 50 | 51 | assertThat("Unexpected response.", output, contains(expectedHeaderString, "Hello World!")); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/http/ws/echo/WebSocketEchoTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.examples.http.ws.echo; 18 | 19 | import io.netty.handler.codec.http.HttpHeaderNames; 20 | import io.netty.handler.codec.http.HttpHeaderValues; 21 | import io.reactivex.netty.examples.ExamplesTestUtil; 22 | import org.junit.Test; 23 | 24 | import java.lang.reflect.InvocationTargetException; 25 | import java.util.Queue; 26 | 27 | import static org.hamcrest.MatcherAssert.*; 28 | import static org.hamcrest.Matchers.*; 29 | 30 | public class WebSocketEchoTest { 31 | 32 | @Test(timeout = 60000) 33 | public void testWebSocketHello() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { 34 | 35 | Queue output = ExamplesTestUtil.runClientInMockedEnvironment(WebSocketEchoClient.class); 36 | String[] content = new String[10]; 37 | for (int i = 0; i < 10; i++) { 38 | content[i] = "Interval " + (i + 1); 39 | } 40 | 41 | assertThat("Unexpected number of messages echoed", output, hasSize(content.length + 1)); 42 | 43 | final String headerString = output.poll(); 44 | assertThat("Unexpected HTTP initial line of response.", headerString, 45 | containsString("HTTP/1.1 101 Switching Protocols")); 46 | assertThat("WebSocket accept header not found in response.", headerString, 47 | containsString(HttpHeaderNames.SEC_WEBSOCKET_ACCEPT + ":")); 48 | assertThat("Unexpected connection header.", headerString, 49 | containsString(HttpHeaderNames.CONNECTION + ": " + HttpHeaderValues.UPGRADE)); 50 | 51 | assertThat("Unexpected content", output, contains(content)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/http/ws/messaging/MessagingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.examples.http.ws.messaging; 19 | 20 | import io.netty.handler.codec.http.HttpHeaderNames; 21 | import io.netty.handler.codec.http.HttpHeaderValues; 22 | import io.reactivex.netty.examples.ExamplesTestUtil; 23 | import org.junit.Test; 24 | 25 | import java.lang.reflect.InvocationTargetException; 26 | import java.util.Queue; 27 | 28 | import static org.hamcrest.MatcherAssert.*; 29 | import static org.hamcrest.Matchers.*; 30 | 31 | public class MessagingTest { 32 | 33 | @Test(timeout = 60000) 34 | public void testMessaging() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { 35 | 36 | Queue output = ExamplesTestUtil.runClientInMockedEnvironment(MessagingClient.class); 37 | 38 | String[] content = new String[10]; 39 | for (int i = 0; i < 10; i++) { 40 | content[i] = "Received acknowledgment for message id => " + i; 41 | } 42 | 43 | assertThat("Unexpected number of messages echoed", output, hasSize(content.length + 1)); 44 | 45 | final String headerString = output.poll(); 46 | assertThat("Unexpected HTTP initial line of response.", headerString, 47 | containsString("HTTP/1.1 101 Switching Protocols")); 48 | assertThat("WebSocket accept header not found in response.", headerString, 49 | containsString(HttpHeaderNames.SEC_WEBSOCKET_ACCEPT + ":")); 50 | assertThat("Unexpected connection header.", headerString, 51 | containsString(HttpHeaderNames.CONNECTION + ": " + HttpHeaderValues.UPGRADE)); 52 | 53 | assertThat("Unexpected content", output, contains(content)); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/local/LocalEchoTest.java: -------------------------------------------------------------------------------- 1 | package io.reactivex.netty.examples.local; 2 | 3 | import io.reactivex.netty.examples.ExamplesTestUtil; 4 | import org.junit.Ignore; 5 | import org.junit.Test; 6 | 7 | import java.util.Queue; 8 | 9 | import static org.hamcrest.MatcherAssert.*; 10 | import static org.hamcrest.Matchers.*; 11 | 12 | @Ignore("travis doesn't like me") 13 | public class LocalEchoTest { 14 | 15 | @Test(timeout = 60000) 16 | public void testEcho() throws Exception { 17 | Queue output = ExamplesTestUtil.runClientInMockedEnvironment(LocalEcho.class); 18 | 19 | assertThat("Unexpected number of messages echoed", output, hasSize(1)); 20 | assertThat("Unexpected number of messages echoed", output, contains("echo => Hello World!")); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/tcp/echo/EchoTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.examples.tcp.echo; 18 | 19 | import io.reactivex.netty.examples.ExamplesTestUtil; 20 | import org.junit.Test; 21 | 22 | import java.util.Queue; 23 | 24 | import static org.hamcrest.MatcherAssert.*; 25 | import static org.hamcrest.Matchers.*; 26 | 27 | public class EchoTest { 28 | 29 | @Test(timeout = 60000) 30 | public void testEcho() throws Exception { 31 | Queue output = ExamplesTestUtil.runClientInMockedEnvironment(EchoClient.class); 32 | 33 | assertThat("Unexpected number of messages echoed", output, hasSize(1)); 34 | assertThat("Unexpected number of messages echoed", output, contains("echo => Hello World!")); 35 | } 36 | } -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/tcp/interceptors/simple/SimpleInterceptorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.examples.tcp.interceptors.simple; 19 | 20 | import io.reactivex.netty.examples.ExamplesTestUtil; 21 | import org.junit.Test; 22 | 23 | import java.util.Queue; 24 | 25 | import static org.hamcrest.MatcherAssert.*; 26 | import static org.hamcrest.Matchers.*; 27 | 28 | public class SimpleInterceptorTest { 29 | 30 | @Test(timeout = 60000) 31 | public void testSimpleInterceptor() throws Exception { 32 | 33 | Queue output = ExamplesTestUtil.runClientInMockedEnvironment(InterceptingClient.class); 34 | 35 | assertThat("Unexpected number of messages echoed", output, hasSize(1)); 36 | assertThat("Unexpected number of messages echoed", output, contains("echo => Hello World!")); 37 | } 38 | } -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/tcp/interceptors/transformation/TransformingInterceptorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.examples.tcp.interceptors.transformation; 19 | 20 | import io.reactivex.netty.examples.ExamplesTestUtil; 21 | import org.junit.Test; 22 | 23 | import java.util.Queue; 24 | 25 | import static org.hamcrest.MatcherAssert.*; 26 | import static org.hamcrest.Matchers.*; 27 | 28 | public class TransformingInterceptorTest { 29 | 30 | @Test(timeout = 60000) 31 | public void testTransformingInterceptor() throws Exception { 32 | 33 | Queue output = ExamplesTestUtil.runClientInMockedEnvironment(InterceptingClient.class); 34 | 35 | assertThat("Unexpected number of messages echoed", output, hasSize(2)); 36 | assertThat("Unexpected number of messages echoed", output, contains("2", "3")); 37 | } 38 | } -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/tcp/loadbalancing/LoadBalancingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.examples.tcp.loadbalancing; 19 | 20 | import io.reactivex.netty.examples.ExamplesTestUtil; 21 | import org.junit.Test; 22 | 23 | import java.util.HashMap; 24 | import java.util.Map; 25 | import java.util.Queue; 26 | 27 | import static org.hamcrest.MatcherAssert.*; 28 | import static org.hamcrest.Matchers.*; 29 | 30 | public class LoadBalancingTest { 31 | 32 | @Test(timeout = 60000) 33 | public void testLoadBalancing() throws Exception { 34 | Queue output = ExamplesTestUtil.runClientInMockedEnvironment(TcpLoadBalancingClient.class); 35 | 36 | assertThat("Unexpected number of messages echoed", output, hasSize(10)); 37 | 38 | Map hostsVsCount = new HashMap<>(); 39 | 40 | for (int i = 0; i < 5; i++) { 41 | String hostUsed = output.poll(); 42 | Integer existingCount = hostsVsCount.get(hostUsed); 43 | if (null == existingCount) { 44 | hostsVsCount.put(hostUsed, 1); 45 | } else { 46 | hostsVsCount.put(hostUsed, existingCount + 1); 47 | } 48 | assertThat("Unexpected content.", hostUsed, startsWith("Using host:")); 49 | assertThat("Unexpected content.", output.poll(), equalTo("Hello World!")); 50 | } 51 | 52 | assertThat("Unexpected number of hosts used.", hostsVsCount.entrySet(), hasSize(2)); 53 | } 54 | } -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/tcp/proxy/ProxyTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.examples.tcp.proxy; 18 | 19 | import io.reactivex.netty.examples.ExamplesTestUtil; 20 | import org.junit.Test; 21 | 22 | import java.util.Queue; 23 | 24 | import static org.hamcrest.MatcherAssert.*; 25 | import static org.hamcrest.Matchers.*; 26 | 27 | public class ProxyTest { 28 | 29 | @Test(timeout = 60000) 30 | public void testProxy() throws Exception { 31 | 32 | Queue output = ExamplesTestUtil.runClientInMockedEnvironment(ProxyClient.class); 33 | 34 | assertThat("Unexpected number of messages echoed", output, hasSize(1)); 35 | assertThat("Unexpected number of messages echoed", output, contains("proxy => echo => Hello World!")); 36 | } 37 | } -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/tcp/secure/SecureEchoTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.examples.tcp.secure; 18 | 19 | import io.reactivex.netty.examples.ExamplesTestUtil; 20 | import org.junit.Test; 21 | 22 | import java.util.Queue; 23 | 24 | import static org.hamcrest.MatcherAssert.*; 25 | import static org.hamcrest.Matchers.*; 26 | 27 | public class SecureEchoTest { 28 | 29 | @Test(timeout = 60000) 30 | public void testSecureEcho() throws Exception { 31 | 32 | Queue output = ExamplesTestUtil.runClientInMockedEnvironment(SecureEchoClient.class); 33 | 34 | assertThat("Unexpected number of messages echoed", output, hasSize(1)); 35 | assertThat("Unexpected number of messages echoed", output, contains("echo => Hello World!")); 36 | } 37 | } -------------------------------------------------------------------------------- /rxnetty-examples/src/test/java/io/reactivex/netty/examples/tcp/streaming/StreamingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.examples.tcp.streaming; 18 | 19 | import io.reactivex.netty.examples.ExamplesTestUtil; 20 | import org.junit.Test; 21 | 22 | import java.util.Queue; 23 | 24 | import static org.hamcrest.MatcherAssert.*; 25 | import static org.hamcrest.Matchers.*; 26 | 27 | public class StreamingTest { 28 | 29 | @Test(timeout = 60000) 30 | public void testStreaming() throws Exception { 31 | 32 | Queue output = ExamplesTestUtil.runClientInMockedEnvironment(StreamingClient.class); 33 | 34 | assertThat("Unexpected number of messages echoed", output, hasSize(10)); 35 | 36 | String[] content = new String[10]; 37 | for (int i = 0; i < 10; i++) { 38 | content[i] = "Interval =>" + i; 39 | } 40 | 41 | assertThat("Unexpected content", output, contains(content)); 42 | } 43 | } -------------------------------------------------------------------------------- /rxnetty-examples/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2015 Netflix, 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 | log4j.rootLogger=INFO, stdout 18 | 19 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 20 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 21 | log4j.appender.stdout.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss,SSS} %5p [%t] (%F:%L) - %m%n -------------------------------------------------------------------------------- /rxnetty-http/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactiveX/RxNetty/a7ca9a9c1d544a79c82f7b17036daf6958bf1cd6/rxnetty-http/.gitignore -------------------------------------------------------------------------------- /rxnetty-http/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | dependencies { 18 | compile project(':rxnetty-common') 19 | compile project(':rxnetty-tcp') 20 | compile "io.netty:netty-codec-http:${netty_version}" 21 | 22 | testCompile project(path: ':rxnetty-common', configuration: 'testArchives') 23 | } 24 | -------------------------------------------------------------------------------- /rxnetty-http/src/main/java/io/reactivex/netty/protocol/http/HttpHandlerNames.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.protocol.http; 18 | 19 | /** 20 | * A list of all handler names added by for HTTP. This is just to ensure consistency in naming. 21 | */ 22 | public enum HttpHandlerNames { 23 | 24 | HttpClientCodec("http-client-codec"), 25 | HttpServerDecoder("http-server-request-decoder"), 26 | HttpServerEncoder("http-server-response-encoder"), 27 | WsServerDecoder("ws-server-request-decoder"), 28 | WsServerEncoder("ws-server-response-encoder"), 29 | WsServerUpgradeHandler("ws-server-upgrade-handler"), 30 | WsClientDecoder("ws-client-request-decoder"), 31 | WsClientEncoder("ws-client-response-encoder"), 32 | WsClientUpgradeHandler("ws-client-upgrade-handler"), 33 | SseClientCodec("sse-client-codec"), 34 | SseServerCodec("sse-server-codec"), 35 | ; 36 | 37 | private final String name; 38 | 39 | HttpHandlerNames(String name) { 40 | this.name = qualify(name); 41 | } 42 | 43 | public String getName() { 44 | return name; 45 | } 46 | 47 | private static String qualify(String name) { 48 | return "_rx_netty_" + name; 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /rxnetty-http/src/main/java/io/reactivex/netty/protocol/http/client/HttpClientInterceptorChainImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.protocol.http.client; 19 | 20 | import io.reactivex.netty.protocol.http.client.events.HttpClientEventPublisher; 21 | 22 | final class HttpClientInterceptorChainImpl implements HttpClientInterceptorChain { 23 | 24 | private final RequestProvider rp; 25 | private final HttpClientEventPublisher cep; 26 | 27 | HttpClientInterceptorChainImpl(RequestProvider rp, HttpClientEventPublisher cep) { 28 | this.rp = rp; 29 | this.cep = cep; 30 | } 31 | 32 | @Override 33 | public HttpClientInterceptorChain next(Interceptor i) { 34 | return new HttpClientInterceptorChainImpl<>(i.intercept(rp), cep); 35 | } 36 | 37 | @Override 38 | public HttpClientInterceptorChain nextWithReadTransform(TransformingInterceptor i) { 39 | return new HttpClientInterceptorChainImpl<>(i.intercept(rp), cep); 40 | } 41 | 42 | @Override 43 | public HttpClientInterceptorChain nextWithWriteTransform(TransformingInterceptor i) { 44 | return new HttpClientInterceptorChainImpl<>(i.intercept(rp), cep); 45 | } 46 | 47 | @Override 48 | public HttpClientInterceptorChain nextWithTransform(TransformingInterceptor i) { 49 | return new HttpClientInterceptorChainImpl<>(i.intercept(rp), cep); 50 | } 51 | 52 | @Override 53 | public InterceptingHttpClient finish() { 54 | return new InterceptingHttpClientImpl<>(rp, cep); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /rxnetty-http/src/main/java/io/reactivex/netty/protocol/http/client/HttpRedirectException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.protocol.http.client; 18 | 19 | /** 20 | * An exception signifying a failed HTTP redirects. Every exception has an encapsulated {@link Reason} retrievable via 21 | * {@link #getReason()} 22 | */ 23 | public class HttpRedirectException extends RuntimeException { 24 | 25 | private static final long serialVersionUID = 612647744832660373L; 26 | private final Reason reason; 27 | 28 | public enum Reason { 29 | RedirectLoop, 30 | TooManyRedirects, 31 | InvalidRedirect 32 | } 33 | 34 | public HttpRedirectException(Reason reason) { 35 | this.reason = reason; 36 | } 37 | 38 | public HttpRedirectException(Reason reason, Throwable cause) { 39 | super(getMsgWithReason(reason), cause); 40 | this.reason = reason; 41 | } 42 | 43 | public HttpRedirectException(Reason reason, String message) { 44 | super(getMsgWithReason(reason, message)); 45 | this.reason = reason; 46 | } 47 | 48 | public HttpRedirectException(Reason reason, String message, Throwable cause) { 49 | super(getMsgWithReason(reason, message), cause); 50 | this.reason = reason; 51 | } 52 | 53 | public Reason getReason() { 54 | return reason; 55 | } 56 | 57 | private static String getMsgWithReason(Reason reason) { 58 | return "Redirect failed. Reason: " + reason; 59 | } 60 | 61 | private static String getMsgWithReason(Reason reason, String message) { 62 | return getMsgWithReason(reason) + ". Error: " + message; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /rxnetty-http/src/main/java/io/reactivex/netty/protocol/http/client/Interceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.protocol.http.client; 19 | 20 | /** 21 | * An interceptor that preserves the type of client request and response content. 22 | * 23 | * @param The type of the content of request. 24 | * @param The type of the content of response. 25 | */ 26 | public interface Interceptor { 27 | 28 | /** 29 | * Intercepts and optionally changes the passed {@code RequestProvider}. 30 | * 31 | * @param provider Provider to intercept. 32 | * 33 | * @return Provider to use after this transformation. 34 | */ 35 | RequestProvider intercept(RequestProvider provider); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /rxnetty-http/src/main/java/io/reactivex/netty/protocol/http/client/RequestProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.protocol.http.client; 19 | 20 | import io.netty.handler.codec.http.HttpMethod; 21 | import io.netty.handler.codec.http.HttpVersion; 22 | 23 | /** 24 | * An abstraction that creates new instance of {@link HttpClientRequest}. 25 | * 26 | * @param The type of the content of request. 27 | * @param The type of the content of response. 28 | */ 29 | public interface RequestProvider { 30 | 31 | /** 32 | * Creates a new {@link HttpClientRequest} with the provided {@code version}, {@code method} and {@code uri} 33 | * 34 | * @param version HTTP version. 35 | * @param method HTTP method. 36 | * @param uri URI. 37 | * 38 | * @return A new instance of {@code HttpClientRequest} 39 | */ 40 | HttpClientRequest createRequest(HttpVersion version, HttpMethod method, String uri); 41 | } 42 | -------------------------------------------------------------------------------- /rxnetty-http/src/main/java/io/reactivex/netty/protocol/http/client/TransformingInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.protocol.http.client; 19 | 20 | /** 21 | * An interceptor that preserves the type of client request and response content. 22 | * 23 | * @param The type of the content of request. 24 | * @param The type of the content of response. 25 | */ 26 | public interface TransformingInterceptor { 27 | 28 | /** 29 | * Intercepts and changes the passed {@code RequestProvider}. 30 | * 31 | * @param provider Provider to intercept. 32 | * 33 | * @return Provider to use after this transformation. 34 | */ 35 | RequestProvider intercept(RequestProvider provider); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /rxnetty-http/src/main/java/io/reactivex/netty/protocol/http/client/internal/HttpChannelProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.protocol.http.client.internal; 19 | 20 | import io.netty.channel.Channel; 21 | import io.netty.util.AttributeKey; 22 | import io.reactivex.netty.client.ChannelProvider; 23 | import io.reactivex.netty.protocol.http.client.events.HttpClientEventPublisher; 24 | import io.reactivex.netty.protocol.http.client.events.HttpClientEventsListener; 25 | import rx.Observable; 26 | import rx.functions.Func1; 27 | 28 | public class HttpChannelProvider implements ChannelProvider { 29 | 30 | public static final AttributeKey HTTP_CLIENT_EVENT_LISTENER = 31 | AttributeKey.valueOf("rxnetty_http_client_event_listener"); 32 | 33 | private final HttpClientEventPublisher hostEventPublisher; 34 | private final ChannelProvider delegate; 35 | 36 | public HttpChannelProvider(HttpClientEventPublisher hostEventPublisher, ChannelProvider delegate) { 37 | this.hostEventPublisher = hostEventPublisher; 38 | this.delegate = delegate; 39 | } 40 | 41 | @Override 42 | public Observable newChannel(Observable input) { 43 | if (null != delegate) { 44 | input = delegate.newChannel(input); 45 | } 46 | return input.map(new Func1() { 47 | @Override 48 | public Channel call(Channel channel) { 49 | channel.attr(HTTP_CLIENT_EVENT_LISTENER).set(hostEventPublisher); 50 | return channel; 51 | } 52 | }); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /rxnetty-http/src/main/java/io/reactivex/netty/protocol/http/internal/HttpContentSubscriberEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.protocol.http.internal; 18 | 19 | import rx.Subscriber; 20 | 21 | public class HttpContentSubscriberEvent { 22 | 23 | private final Subscriber subscriber; 24 | 25 | public HttpContentSubscriberEvent(Subscriber subscriber) { 26 | this.subscriber = subscriber; 27 | } 28 | 29 | public Subscriber getSubscriber() { 30 | return subscriber; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /rxnetty-http/src/main/java/io/reactivex/netty/protocol/http/internal/UnsafeEmptySubscriber.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.protocol.http.internal; 19 | 20 | import io.netty.util.ReferenceCountUtil; 21 | import org.slf4j.Logger; 22 | import org.slf4j.LoggerFactory; 23 | import rx.Subscriber; 24 | import rx.observers.SafeSubscriber; 25 | 26 | /** 27 | * A subscriber that can be reused if and only if not wrapped in a {@link SafeSubscriber}. 28 | */ 29 | final class UnsafeEmptySubscriber extends Subscriber { 30 | 31 | private static final Logger logger = LoggerFactory.getLogger(UnsafeEmptySubscriber.class); 32 | 33 | private final String msg; 34 | 35 | protected UnsafeEmptySubscriber(String msg) { 36 | this.msg = msg; 37 | } 38 | 39 | @Override 40 | public void onCompleted() { 41 | } 42 | 43 | @Override 44 | public void onError(Throwable e) { 45 | logger.error(msg, e); 46 | } 47 | 48 | @Override 49 | public void onNext(T o) { 50 | ReferenceCountUtil.release(o); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /rxnetty-http/src/main/java/io/reactivex/netty/protocol/http/server/RequestHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.protocol.http.server; 18 | 19 | import rx.Observable; 20 | 21 | /** 22 | * A handler for an {@link HttpServerRequest} to produce a {@link HttpServerResponse} 23 | * 24 | * @param The type of objects received as content from the request. 25 | * @param The type of objects written as content from the response. 26 | */ 27 | public interface RequestHandler { 28 | 29 | /** 30 | * Provides a request and response pair to process. 31 | * 32 | * @param request Http request to process. 33 | * @param response Http response to populate after processing the request. 34 | * 35 | * @return An {@link Observable} that represents the processing of the request. Subscribing to this should start 36 | * the request processing and unsubscribing should cancel the processing. 37 | */ 38 | Observable handle(HttpServerRequest request, HttpServerResponse response); 39 | } 40 | -------------------------------------------------------------------------------- /rxnetty-http/src/main/java/io/reactivex/netty/protocol/http/util/HttpContentStringLineDecoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.protocol.http.util; 19 | 20 | import io.netty.channel.ChannelHandlerContext; 21 | import io.netty.handler.codec.MessageToMessageDecoder; 22 | import io.netty.handler.codec.http.DefaultLastHttpContent; 23 | import io.netty.handler.codec.http.HttpContent; 24 | import io.netty.handler.codec.http.LastHttpContent; 25 | import io.reactivex.netty.util.LineReader; 26 | import io.reactivex.netty.util.StringLineDecoder; 27 | 28 | import java.util.List; 29 | 30 | /** 31 | * A handler just like {@link StringLineDecoder} but works on {@link HttpContent}. This handler will decode the HTTP 32 | * content as lines, separated by a new line. 33 | */ 34 | public class HttpContentStringLineDecoder extends MessageToMessageDecoder { 35 | 36 | private final LineReader reader = new LineReader(); 37 | 38 | @Override 39 | public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { 40 | reader.dispose(); 41 | super.handlerRemoved(ctx); 42 | } 43 | 44 | @Override 45 | protected void decode(ChannelHandlerContext ctx, HttpContent msg, List out) throws Exception { 46 | if (msg instanceof LastHttpContent) { 47 | reader.decodeLast(msg.content(), out, ctx.alloc()); 48 | out.add(LastHttpContent.EMPTY_LAST_CONTENT); 49 | } else { 50 | reader.decode(msg.content(), out, ctx.alloc()); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /rxnetty-http/src/main/java/io/reactivex/netty/protocol/http/ws/client/WebSocketRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.protocol.http.ws.client; 18 | 19 | import rx.Observable; 20 | 21 | /** 22 | * A WebSocket upgrade HTTP request that will generate a {@link WebSocketResponse} 23 | * 24 | * @param The type of the content received in the HTTP response, in case, the upgrade was rejected by the server. 25 | */ 26 | public abstract class WebSocketRequest extends Observable> { 27 | 28 | protected WebSocketRequest(OnSubscribe> f) { 29 | super(f); 30 | } 31 | 32 | /** 33 | * Specify any sub protocols that are to be requested to the server as specified by the 34 | * specifications 35 | * 36 | * @param subProtocols Sub protocols to request. 37 | * 38 | * @return A new instance of {@link WebSocketRequest} with the sub protocols requested. 39 | */ 40 | public abstract WebSocketRequest requestSubProtocols(String... subProtocols); 41 | 42 | /** 43 | * By default, the websocket request made is for the latest version in the specifications, however, if an earlier 44 | * version is required, it can be updated by this method. 45 | * 46 | * @param version WebSocket version. 47 | * 48 | * @return A new instance of {@link WebSocketRequest} with the version requested. 49 | */ 50 | public abstract WebSocketRequest version(int version); 51 | } 52 | -------------------------------------------------------------------------------- /rxnetty-http/src/main/java/io/reactivex/netty/protocol/http/ws/client/WebSocketResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.protocol.http.ws.client; 18 | 19 | import io.netty.handler.codec.http.HttpHeaderNames; 20 | import io.netty.handler.codec.http.HttpHeaderValues; 21 | import io.netty.handler.codec.http.HttpResponseStatus; 22 | import io.reactivex.netty.protocol.http.client.HttpClientResponse; 23 | import io.reactivex.netty.protocol.http.ws.WebSocketConnection; 24 | import rx.Observable; 25 | 26 | import static io.netty.handler.codec.http.HttpHeaderNames.*; 27 | import static io.netty.handler.codec.http.HttpHeaderValues.*; 28 | 29 | public abstract class WebSocketResponse extends HttpClientResponse { 30 | 31 | public abstract Observable getWebSocketConnection(); 32 | 33 | public String getAcceptedSubProtocol() { 34 | return getHeader(SEC_WEBSOCKET_PROTOCOL); 35 | } 36 | 37 | public boolean isUpgraded() { 38 | return getStatus().equals(HttpResponseStatus.SWITCHING_PROTOCOLS) 39 | && containsHeader(CONNECTION, HttpHeaderValues.UPGRADE, true) 40 | && containsHeader(HttpHeaderNames.UPGRADE, WEBSOCKET, true) 41 | && containsHeader(SEC_WEBSOCKET_ACCEPT); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /rxnetty-http/src/main/java/io/reactivex/netty/protocol/http/ws/server/WebSocketHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.protocol.http.ws.server; 18 | 19 | import io.reactivex.netty.protocol.http.ws.WebSocketConnection; 20 | import rx.Observable; 21 | 22 | /** 23 | * A handler for {@link WebSocketConnection} upon a successful upgrade from an HTTP request. 24 | */ 25 | public interface WebSocketHandler { 26 | 27 | /** 28 | * Processes the passed connection. 29 | * 30 | * @param wsConnection Connection to process. 31 | * 32 | * @return {@code Observable} representing the processing termination. 33 | */ 34 | Observable handle(WebSocketConnection wsConnection); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /rxnetty-http/src/main/java/io/reactivex/netty/protocol/http/ws/server/WebSocketHandlers.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.protocol.http.ws.server; 18 | 19 | import io.netty.handler.codec.http.HttpResponseStatus; 20 | import io.reactivex.netty.protocol.http.server.HttpServerRequest; 21 | import io.reactivex.netty.protocol.http.server.HttpServerResponse; 22 | import io.reactivex.netty.protocol.http.server.RequestHandler; 23 | import rx.Observable; 24 | 25 | /** 26 | * A utility to provide convenience {@link RequestHandler} implementations for Web Sockets. 27 | */ 28 | public final class WebSocketHandlers { 29 | 30 | private WebSocketHandlers() { 31 | } 32 | 33 | /** 34 | * Returns a {@link RequestHandler} that accepts all WebSocket upgrade requests by delegating it to the passed 35 | * handler but sends an HTTP 404 response for all other requests. 36 | * 37 | * @param handler Web Socket handler for all web socket upgrade requests. 38 | * 39 | * @return request handler. 40 | */ 41 | public static RequestHandler acceptAllUpgrades(final WebSocketHandler handler) { 42 | return new RequestHandler() { 43 | @Override 44 | public Observable handle(HttpServerRequest request, HttpServerResponse response) { 45 | if (request.isWebSocketUpgradeRequested()) { 46 | return response.acceptWebSocketUpgrade(handler); 47 | } 48 | 49 | return response.setStatus(HttpResponseStatus.NOT_FOUND) 50 | .write(Observable.empty()); 51 | } 52 | }; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /rxnetty-http/src/test/java/io/reactivex/netty/protocol/http/server/HttpServerToConnectionBridgeTest.java: -------------------------------------------------------------------------------- 1 | package io.reactivex.netty.protocol.http.server; 2 | 3 | import io.reactivex.netty.protocol.http.internal.AbstractHttpConnectionBridge; 4 | import io.reactivex.netty.protocol.http.internal.AbstractHttpConnectionBridgeTest.AbstractHttpConnectionBridgeMock; 5 | import io.reactivex.netty.protocol.http.internal.AbstractHttpConnectionBridgeTest.HandlerRule; 6 | import io.reactivex.netty.protocol.http.internal.HttpContentSubscriberEvent; 7 | import io.reactivex.netty.protocol.http.server.events.HttpServerEventPublisher; 8 | import io.reactivex.netty.protocol.tcp.server.events.TcpServerEventPublisher; 9 | import org.junit.Rule; 10 | import org.junit.Test; 11 | import rx.observers.TestSubscriber; 12 | 13 | import java.nio.channels.ClosedChannelException; 14 | 15 | public class HttpServerToConnectionBridgeTest { 16 | 17 | @Rule 18 | public final HandlerRule handlerRule = new HandlerRule() { 19 | @Override 20 | protected AbstractHttpConnectionBridge newAbstractHttpConnectionBridgeMock() { 21 | return new HttpServerToConnectionBridge<>(new HttpServerEventPublisher(new TcpServerEventPublisher())); 22 | } 23 | }; 24 | 25 | @Test(timeout = 60000) 26 | public void testPendingContentSubscriber() throws Exception { 27 | handlerRule.setupAndAssertConnectionInputSub(); 28 | handlerRule.simulateHeaderReceive(); /*Simulate header receive, required for content sub.*/ 29 | TestSubscriber subscriber = new TestSubscriber<>(); 30 | handlerRule.getChannel().pipeline().fireUserEventTriggered(new HttpContentSubscriberEvent<>(subscriber)); 31 | TestSubscriber subscriber1 = new TestSubscriber<>(); 32 | handlerRule.getChannel().pipeline().fireUserEventTriggered(new HttpContentSubscriberEvent<>(subscriber1)); 33 | 34 | subscriber.assertNoErrors(); 35 | subscriber1.assertNoErrors(); 36 | subscriber.unsubscribe(); 37 | 38 | subscriber.assertUnsubscribed(); 39 | 40 | handlerRule.getChannel().close().await(); 41 | 42 | subscriber.assertNoErrors(); 43 | subscriber1.assertError(ClosedChannelException.class); 44 | } 45 | } -------------------------------------------------------------------------------- /rxnetty-http/src/test/java/io/reactivex/netty/test/util/TcpConnectionRequestMock.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | package io.reactivex.netty.test.util; 18 | 19 | import io.reactivex.netty.channel.Connection; 20 | import io.reactivex.netty.client.ConnectionRequest; 21 | import rx.Observable; 22 | import rx.Subscriber; 23 | 24 | public class TcpConnectionRequestMock extends ConnectionRequest { 25 | 26 | public TcpConnectionRequestMock(final Observable> connections) { 27 | super(new OnSubscribe>() { 28 | @Override 29 | public void call(Subscriber> subscriber) { 30 | connections.unsafeSubscribe(subscriber); 31 | } 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /rxnetty-http/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2015 Netflix, 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 | log4j.rootLogger=INFO, stdout 18 | 19 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 20 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 21 | log4j.appender.stdout.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss,SSS} %5p [%t] (%F:%L) - %m%n -------------------------------------------------------------------------------- /rxnetty-spectator-http/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | // spectator requires java 8 19 | sourceCompatibility = JavaVersion.VERSION_1_8 20 | targetCompatibility = JavaVersion.VERSION_1_8 21 | 22 | dependencies { 23 | compile project(':rxnetty-http') 24 | compile project(':rxnetty-spectator-tcp') 25 | compile project(':rxnetty-common') 26 | } 27 | -------------------------------------------------------------------------------- /rxnetty-spectator-tcp/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | // spectator requires java 8 19 | sourceCompatibility = JavaVersion.VERSION_1_8 20 | targetCompatibility = JavaVersion.VERSION_1_8 21 | 22 | dependencies { 23 | compile project(':rxnetty-tcp') 24 | compile project(':rxnetty-common') 25 | compile 'com.netflix.spectator:spectator-api:0.50.0' 26 | compile 'com.netflix.numerus:numerus:1.1' 27 | } 28 | -------------------------------------------------------------------------------- /rxnetty-spectator-tcp/src/main/java/io/reactivex/netty/spectator/internal/EventMetric.java: -------------------------------------------------------------------------------- 1 | package io.reactivex.netty.spectator.internal; 2 | 3 | import com.netflix.spectator.api.Counter; 4 | import com.netflix.spectator.api.Registry; 5 | import com.netflix.spectator.api.histogram.PercentileTimer; 6 | 7 | import java.util.concurrent.TimeUnit; 8 | 9 | import static io.reactivex.netty.spectator.internal.SpectatorUtils.*; 10 | 11 | public class EventMetric { 12 | 13 | private final Counter start; 14 | private final PercentileTimer startLatency; 15 | 16 | private final Counter success; 17 | private final PercentileTimer successLatency; 18 | 19 | private final Counter failed; 20 | private final PercentileTimer failureLatency; 21 | 22 | public EventMetric(Registry registry, String name, String monitorId, String... tags) { 23 | start = newCounter(registry, name, monitorId, mergeTags(tags, "rtype", "count", "state", "start")); 24 | startLatency = newPercentileTimer(registry, name, monitorId, mergeTags(tags, "rtype", "latency", 25 | "state", "start")); 26 | success = newCounter(registry, name, monitorId, mergeTags(tags, "rtype", "count", "state", "success")); 27 | successLatency = newPercentileTimer(registry, name, monitorId, mergeTags(tags, "rtype", "latency", 28 | "state", "success")); 29 | failed = newCounter(registry, name, monitorId, mergeTags(tags, "rtype", "count", "state", "failed")); 30 | failureLatency = newPercentileTimer(registry, name, monitorId, mergeTags(tags, "rtype", "latency", 31 | "state", "failed")); 32 | } 33 | 34 | public void start() { 35 | start.increment(); 36 | } 37 | 38 | public void start(long duration, TimeUnit timeUnit) { 39 | start.increment(); 40 | startLatency.record(duration, timeUnit); 41 | } 42 | 43 | public void success() { 44 | success.increment(); 45 | } 46 | 47 | public void success(long duration, TimeUnit timeUnit) { 48 | success.increment(); 49 | successLatency.record(duration, timeUnit); 50 | } 51 | 52 | public void failure() { 53 | failed.increment(); 54 | } 55 | 56 | public void failure(long duration, TimeUnit timeUnit) { 57 | failed.increment(); 58 | failureLatency.record(duration, timeUnit); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /rxnetty-tcp/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactiveX/RxNetty/a7ca9a9c1d544a79c82f7b17036daf6958bf1cd6/rxnetty-tcp/.gitignore -------------------------------------------------------------------------------- /rxnetty-tcp/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | dependencies { 18 | compile project(':rxnetty-common') 19 | 20 | testCompile project(path: ':rxnetty-common', configuration: 'testArchives') 21 | } 22 | -------------------------------------------------------------------------------- /rxnetty-tcp/src/main/java/io/reactivex/netty/protocol/tcp/TcpHandlerNames.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.protocol.tcp; 18 | 19 | /** 20 | * A list of all handler names added for TCP. This is just to ensure consistency in naming. 21 | */ 22 | public enum TcpHandlerNames { 23 | 24 | ClientReadTimeoutHandler("client-read-timeout-handler"), 25 | ; 26 | 27 | private final String name; 28 | 29 | TcpHandlerNames(String name) { 30 | this.name = qualify(name); 31 | } 32 | 33 | public String getName() { 34 | return name; 35 | } 36 | 37 | private static String qualify(String name) { 38 | return "_rx_netty_" + name; 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /rxnetty-tcp/src/main/java/io/reactivex/netty/protocol/tcp/client/ConnectionRequestImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | package io.reactivex.netty.protocol.tcp.client; 18 | 19 | import io.reactivex.netty.channel.Connection; 20 | import io.reactivex.netty.client.ConnectionProvider; 21 | import io.reactivex.netty.client.ConnectionRequest; 22 | import rx.Subscriber; 23 | 24 | final class ConnectionRequestImpl extends ConnectionRequest { 25 | 26 | ConnectionRequestImpl(final ConnectionProvider cp) { 27 | super(new OnSubscribe>() { 28 | @Override 29 | public void call(final Subscriber> subscriber) { 30 | cp.newConnectionRequest().unsafeSubscribe(subscriber); 31 | } 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /rxnetty-tcp/src/main/java/io/reactivex/netty/protocol/tcp/client/InterceptingTcpClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.protocol.tcp.client; 19 | 20 | import io.reactivex.netty.client.ConnectionRequest; 21 | import io.reactivex.netty.events.EventSource; 22 | import io.reactivex.netty.protocol.tcp.client.events.TcpClientEventListener; 23 | 24 | public abstract class InterceptingTcpClient implements EventSource { 25 | 26 | /** 27 | * Creates a new {@link ConnectionRequest} which should be subscribed to actually connect to the target server. 28 | * 29 | * @return A new {@link ConnectionRequest} which either can be subscribed directly or altered in various ways 30 | * before subscription. 31 | */ 32 | public abstract ConnectionRequest createConnectionRequest(); 33 | 34 | /** 35 | * Starts the process of adding interceptors to this client. Interceptors help in achieving various usecases of 36 | * instrumenting and transforming connections. 37 | * 38 | * @return A new interceptor chain to add the various interceptors. 39 | */ 40 | public abstract TcpClientInterceptorChain intercept(); 41 | } 42 | -------------------------------------------------------------------------------- /rxnetty-tcp/src/main/java/io/reactivex/netty/protocol/tcp/client/InterceptingTcpClientImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.protocol.tcp.client; 19 | 20 | import io.reactivex.netty.client.ConnectionProvider; 21 | import io.reactivex.netty.client.ConnectionRequest; 22 | import io.reactivex.netty.protocol.tcp.client.events.TcpClientEventListener; 23 | import io.reactivex.netty.protocol.tcp.client.events.TcpClientEventPublisher; 24 | import rx.Subscription; 25 | 26 | public class InterceptingTcpClientImpl extends InterceptingTcpClient { 27 | 28 | private final ConnectionProvider cp; 29 | private final TcpClientEventPublisher eventPublisher; 30 | private final ConnectionRequest connectionRequest; 31 | 32 | public InterceptingTcpClientImpl(ConnectionProvider cp, TcpClientEventPublisher ep) { 33 | this.cp = cp; 34 | this.eventPublisher = ep; 35 | connectionRequest = new ConnectionRequestImpl<>(this.cp); 36 | 37 | } 38 | 39 | @Override 40 | public ConnectionRequest createConnectionRequest() { 41 | return connectionRequest; 42 | } 43 | 44 | @Override 45 | public TcpClientInterceptorChain intercept() { 46 | return new TcpClientInterceptorChainImpl<>(cp, eventPublisher); 47 | } 48 | 49 | @Override 50 | public Subscription subscribe(TcpClientEventListener listener) { 51 | return eventPublisher.subscribe(listener); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /rxnetty-tcp/src/main/java/io/reactivex/netty/protocol/tcp/client/Interceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.protocol.tcp.client; 19 | 20 | import io.reactivex.netty.client.ConnectionProvider; 21 | 22 | /** 23 | * An interceptor that preserves the type of objects read and written to the connection. 24 | * 25 | * @param Type of objects read from the connection handled by this interceptor. 26 | * @param Type of objects written to the connection handled by this interceptor. 27 | */ 28 | public interface Interceptor { 29 | 30 | /** 31 | * Intercepts and optionally changes the passed {@code ConnectionProvider}. 32 | * 33 | * @param provider Provider to intercept. 34 | * 35 | * @return Provider to use after this transformation. 36 | */ 37 | ConnectionProvider intercept(ConnectionProvider provider); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /rxnetty-tcp/src/main/java/io/reactivex/netty/protocol/tcp/client/TcpClientInterceptorChainImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.protocol.tcp.client; 19 | 20 | import io.reactivex.netty.client.ConnectionProvider; 21 | import io.reactivex.netty.protocol.tcp.client.events.TcpClientEventPublisher; 22 | 23 | public class TcpClientInterceptorChainImpl implements TcpClientInterceptorChain { 24 | 25 | private ConnectionProvider connectionProvider; 26 | private final TcpClientEventPublisher eventPublisher; 27 | 28 | public TcpClientInterceptorChainImpl(ConnectionProvider cp, TcpClientEventPublisher ep) { 29 | connectionProvider = cp; 30 | this.eventPublisher = ep; 31 | } 32 | 33 | @Override 34 | public TcpClientInterceptorChain next(Interceptor i) { 35 | connectionProvider = i.intercept(connectionProvider); 36 | return this; 37 | } 38 | 39 | @Override 40 | public TcpClientInterceptorChain nextWithReadTransform(TransformingInterceptor i) { 41 | return new TcpClientInterceptorChainImpl<>(i.intercept(connectionProvider), eventPublisher); 42 | } 43 | 44 | @Override 45 | public TcpClientInterceptorChain nextWithWriteTransform(TransformingInterceptor i) { 46 | return new TcpClientInterceptorChainImpl<>(i.intercept(connectionProvider), eventPublisher); 47 | } 48 | 49 | @Override 50 | public TcpClientInterceptorChain nextWithTransform(TransformingInterceptor i) { 51 | return new TcpClientInterceptorChainImpl<>(i.intercept(connectionProvider), eventPublisher); 52 | } 53 | 54 | @Override 55 | public InterceptingTcpClient finish() { 56 | return new InterceptingTcpClientImpl<>(connectionProvider, eventPublisher); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /rxnetty-tcp/src/main/java/io/reactivex/netty/protocol/tcp/client/TransformingInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | 18 | package io.reactivex.netty.protocol.tcp.client; 19 | 20 | import io.reactivex.netty.client.ConnectionProvider; 21 | 22 | /** 23 | * An interceptor that changes the type of objects read and written to the connection. 24 | * 25 | * @param Type of objects read from the connection before applying this interceptor. 26 | * @param Type of objects written to the connection before applying this interceptor. 27 | * @param Type of objects read from the connection after applying this interceptor. 28 | * @param Type of objects written to the connection after applying this interceptor. 29 | */ 30 | public interface TransformingInterceptor { 31 | 32 | /** 33 | * Intercepts and changes the passed {@code ConnectionProvider}. 34 | * 35 | * @param provider Provider to intercept. 36 | * 37 | * @return Provider to use after this transformation. 38 | */ 39 | ConnectionProvider intercept(ConnectionProvider provider); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /rxnetty-tcp/src/main/java/io/reactivex/netty/protocol/tcp/client/events/TcpClientEventListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.protocol.tcp.client.events; 18 | 19 | import io.reactivex.netty.client.events.ClientEventListener; 20 | import io.reactivex.netty.protocol.tcp.client.TcpClient; 21 | 22 | /** 23 | * A listener for all events published by {@link TcpClient} 24 | */ 25 | public abstract class TcpClientEventListener extends ClientEventListener { 26 | 27 | } 28 | -------------------------------------------------------------------------------- /rxnetty-tcp/src/main/java/io/reactivex/netty/protocol/tcp/client/internal/TcpChannelProviderFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | 18 | package io.reactivex.netty.protocol.tcp.client.internal; 19 | 20 | import io.reactivex.netty.channel.DetachedChannelPipeline; 21 | import io.reactivex.netty.client.ChannelProvider; 22 | import io.reactivex.netty.client.ChannelProviderFactory; 23 | import io.reactivex.netty.client.Host; 24 | import io.reactivex.netty.client.events.ClientEventListener; 25 | import io.reactivex.netty.events.EventPublisher; 26 | import io.reactivex.netty.events.EventSource; 27 | 28 | public class TcpChannelProviderFactory implements ChannelProviderFactory { 29 | 30 | private final DetachedChannelPipeline channelPipeline; 31 | private final ChannelProviderFactory delegate; 32 | 33 | public TcpChannelProviderFactory(DetachedChannelPipeline channelPipeline, ChannelProviderFactory delegate) { 34 | this.channelPipeline = channelPipeline; 35 | this.delegate = delegate instanceof TcpChannelProviderFactory ? ((TcpChannelProviderFactory) delegate).delegate 36 | : delegate; 37 | } 38 | 39 | @Override 40 | public ChannelProvider newProvider(Host host, EventSource hostEventSource, 41 | EventPublisher publisher, ClientEventListener hostEventPublisher) { 42 | ChannelProvider delegate = this.delegate.newProvider(host, hostEventSource, publisher, hostEventPublisher); 43 | return new TcpChannelProvider(channelPipeline, delegate, publisher, hostEventPublisher); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /rxnetty-tcp/src/main/java/io/reactivex/netty/protocol/tcp/server/ConnectionHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.protocol.tcp.server; 18 | 19 | import io.reactivex.netty.channel.Connection; 20 | import rx.Observable; 21 | 22 | /** 23 | * A connection handler invoked for every new connection is established by {@link TcpServer} 24 | * 25 | * @param The type of the object that is read from a new connection. 26 | * @param The type of objects that are written to a new connection. 27 | */ 28 | public interface ConnectionHandler { 29 | 30 | /** 31 | * Invoked whenever a new connection is established. 32 | * 33 | * @param newConnection Newly established connection. 34 | * 35 | * @return An {@link Observable}, unsubscribe from which should cancel the handling. 36 | */ 37 | Observable handle(Connection newConnection); 38 | } 39 | -------------------------------------------------------------------------------- /rxnetty-tcp/src/main/java/io/reactivex/netty/protocol/tcp/server/events/TcpServerEventListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, 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 | package io.reactivex.netty.protocol.tcp.server.events; 18 | 19 | import io.reactivex.netty.channel.events.ConnectionEventListener; 20 | import io.reactivex.netty.protocol.tcp.server.TcpServer; 21 | 22 | import java.util.concurrent.TimeUnit; 23 | 24 | /** 25 | * A listener for all events published by {@link TcpServer} 26 | */ 27 | public abstract class TcpServerEventListener extends ConnectionEventListener { 28 | 29 | /** 30 | * Event whenever a new client connection is accepted. 31 | */ 32 | public void onNewClientConnected() { } 33 | 34 | /** 35 | * Event when any connection handling starts. 36 | * 37 | * @param duration Time between a client connection is accepted to when it is handled by the connection handler. 38 | * @param timeUnit Time unit for the duration. 39 | */ 40 | @SuppressWarnings("unused") 41 | public void onConnectionHandlingStart(long duration, TimeUnit timeUnit) { } 42 | 43 | /** 44 | * Event when any connection handling is successfully completed. 45 | * 46 | * @param duration Time taken for connection handling. 47 | * @param timeUnit Time unit for the duration. 48 | */ 49 | @SuppressWarnings("unused") 50 | public void onConnectionHandlingSuccess(long duration, TimeUnit timeUnit) {} 51 | 52 | /** 53 | * Event when any connection handling completes with an error. 54 | * 55 | * @param duration Time taken for connection handling. 56 | * @param timeUnit Time unit for the duration. 57 | */ 58 | @SuppressWarnings("unused") 59 | public void onConnectionHandlingFailed(long duration, TimeUnit timeUnit, Throwable throwable) { } 60 | } 61 | -------------------------------------------------------------------------------- /rxnetty-tcp/src/test/java/io/reactivex/netty/protocol/tcp/client/events/TcpClientEventsTest.java: -------------------------------------------------------------------------------- 1 | package io.reactivex.netty.protocol.tcp.client.events; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.reactivex.netty.client.pool.PooledConnection; 5 | import io.reactivex.netty.protocol.tcp.client.MockTcpClientEventListener; 6 | import io.reactivex.netty.protocol.tcp.client.TcpClientRule; 7 | import io.reactivex.netty.test.util.MockClientEventListener.ClientEvent; 8 | import io.reactivex.netty.test.util.MockConnectionEventListener.Event; 9 | import org.junit.Rule; 10 | import org.junit.Test; 11 | import rx.Observable; 12 | import rx.observers.TestSubscriber; 13 | 14 | public class TcpClientEventsTest { 15 | 16 | @Rule 17 | public final TcpClientRule clientRule = new TcpClientRule(); 18 | 19 | @Test(timeout = 60000) 20 | public void testEventsPublished() throws Exception { 21 | MockTcpClientEventListener listener = sendRequests(); 22 | 23 | listener.assertMethodCalled(ClientEvent.AcquireStart); 24 | listener.assertMethodCalled(ClientEvent.AcquireSuccess); 25 | listener.assertMethodCalled(ClientEvent.ConnectStart); 26 | listener.assertMethodCalled(ClientEvent.ConnectSuccess); 27 | listener.assertMethodCalled(Event.WriteStart); 28 | listener.assertMethodCalled(Event.WriteSuccess); 29 | listener.assertMethodCalled(Event.FlushStart); 30 | listener.assertMethodCalled(Event.FlushSuccess); 31 | listener.assertMethodCalled(Event.BytesRead); 32 | } 33 | 34 | protected MockTcpClientEventListener sendRequests() { 35 | clientRule.startServer(10); 36 | MockTcpClientEventListener listener = new MockTcpClientEventListener(); 37 | clientRule.getClient().subscribe(listener); 38 | PooledConnection connection = clientRule.connect(); 39 | TestSubscriber testSubscriber = new TestSubscriber<>(); 40 | connection.writeStringAndFlushOnEach(Observable.just("Hello")) 41 | .toCompletable() 42 | .toObservable() 43 | .concatWith(connection.getInput()) 44 | .take(1) 45 | .subscribe(testSubscriber); 46 | 47 | testSubscriber.awaitTerminalEvent(); 48 | testSubscriber.assertNoErrors(); 49 | return listener; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /rxnetty-tcp/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2015 Netflix, 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 | log4j.rootLogger=INFO, stdout 18 | 19 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 20 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 21 | log4j.appender.stdout.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss,SSS} %5p [%t] (%F:%L) - %m%n -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, 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 | rootProject.name='RxNetty' 18 | include 'rxnetty-common' 19 | include 'rxnetty-tcp' 20 | include 'rxnetty-spectator-tcp' 21 | include 'rxnetty-http' 22 | include 'rxnetty-spectator-http' 23 | include 'rxnetty-examples' 24 | 25 | --------------------------------------------------------------------------------