├── .github └── workflows │ ├── gradle-wrapper-validation.yml │ ├── nebula-ci.yml │ ├── nebula-publish.yml │ └── nebula-snapshot.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── OSSMETADATA ├── README.md ├── build.gradle ├── codequality └── checkstyle.xml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── ribbon-archaius ├── build.gradle └── src │ └── main │ ├── java │ └── com │ │ └── netflix │ │ ├── client │ │ ├── SimpleVipAddressResolver.java │ │ └── config │ │ │ ├── ArchaiusClientConfigFactory.java │ │ │ ├── ArchaiusPropertyResolver.java │ │ │ └── DefaultClientConfigImpl.java │ │ └── utils │ │ └── ScheduledThreadPoolExectuorWithDynamicSize.java │ └── resources │ └── META-INF │ └── services │ └── com.netflix.client.config.ClientConfigFactory ├── ribbon-core ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── netflix │ │ └── client │ │ ├── ClientException.java │ │ ├── ClientRequest.java │ │ ├── DefaultLoadBalancerRetryHandler.java │ │ ├── IClient.java │ │ ├── IClientConfigAware.java │ │ ├── IResponse.java │ │ ├── RequestSpecificRetryHandler.java │ │ ├── RetryHandler.java │ │ ├── Utils.java │ │ ├── VipAddressResolver.java │ │ ├── config │ │ ├── AbstractDefaultClientConfigImpl.java │ │ ├── ClientConfigFactory.java │ │ ├── CommonClientConfigKey.java │ │ ├── FallbackProperty.java │ │ ├── IClientConfig.java │ │ ├── IClientConfigKey.java │ │ ├── Property.java │ │ ├── PropertyResolver.java │ │ ├── PropertyUtils.java │ │ ├── ReloadableClientConfig.java │ │ └── UnboxedIntProperty.java │ │ ├── http │ │ └── UnexpectedHttpResponseException.java │ │ ├── ssl │ │ ├── AbstractSslContextFactory.java │ │ ├── ClientSslSocketFactoryException.java │ │ └── URLSslContextFactory.java │ │ └── util │ │ └── Resources.java │ ├── resources │ └── META-INF │ │ └── services │ │ └── com.netflix.client.config.ClientConfigFactory │ └── test │ ├── java │ └── com │ │ └── netflix │ │ └── client │ │ └── config │ │ ├── ArchaiusPropertyResolverTest.java │ │ ├── ClientConfigTest.java │ │ ├── CommonClientConfigKeyTest.java │ │ ├── DefaultClientConfigImplTest.java │ │ └── ReloadableClientConfigTest.java │ └── resources │ └── log4j.properties ├── ribbon-eureka ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── netflix │ │ └── niws │ │ └── loadbalancer │ │ ├── DiscoveryEnabledNIWSServerList.java │ │ ├── DiscoveryEnabledServer.java │ │ ├── EurekaNotificationServerListUpdater.java │ │ ├── LegacyEurekaClientProvider.java │ │ └── NIWSDiscoveryPing.java │ └── test │ ├── java │ └── com │ │ └── netflix │ │ ├── loadbalancer │ │ └── EurekaDynamicServerListLoadBalancerTest.java │ │ └── niws │ │ └── loadbalancer │ │ ├── DefaultNIWSServerListFilterTest.java │ │ ├── DiscoveryEnabledLoadBalancerSupportsPortOverrideTest.java │ │ ├── DiscoveryEnabledLoadBalancerSupportsUseIpAddrTest.java │ │ ├── EurekaNotificationServerListUpdaterTest.java │ │ ├── LBBuilderTest.java │ │ └── LoadBalancerTestUtils.java │ └── resources │ └── log4j.properties ├── ribbon-evcache ├── build.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── ribbon │ │ │ ├── evache │ │ │ ├── CacheFaultException.java │ │ │ ├── CacheMissException.java │ │ │ ├── EvCacheOptions.java │ │ │ └── EvCacheProvider.java │ │ │ └── proxy │ │ │ ├── annotation │ │ │ └── EvCache.java │ │ │ └── processor │ │ │ └── EVCacheAnnotationProcessor.java │ └── resources │ │ └── META-INF │ │ └── services │ │ └── com.netflix.ribbon.proxy.processor.AnnotationProcessor │ └── test │ └── java │ └── com │ └── netflix │ └── ribbon │ ├── evache │ ├── EvCacheProviderTest.java │ └── ServiceLoaderTest.java │ └── proxy │ ├── EvCacheAnnotationTest.java │ └── sample │ ├── EvCacheClasses.java │ ├── HystrixHandlers.java │ ├── Movie.java │ ├── MovieServiceInterfaces.java │ ├── MovieTransformer.java │ ├── ResourceGroupClasses.java │ ├── SampleCacheProviderFactory.java │ └── SampleMovieServiceWithEVCache.java ├── ribbon-examples ├── build.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── ribbon │ │ │ └── examples │ │ │ ├── ExampleAppWithLocalResource.java │ │ │ ├── loadbalancer │ │ │ └── URLConnectionLoadBalancer.java │ │ │ ├── netty │ │ │ └── http │ │ │ │ ├── LoadBalancingExample.java │ │ │ │ └── SimpleGet.java │ │ │ ├── restclient │ │ │ └── SampleApp.java │ │ │ ├── rx │ │ │ ├── AbstractRxMovieClient.java │ │ │ ├── README.md │ │ │ ├── RxMovieServer.java │ │ │ ├── common │ │ │ │ ├── InMemoryCacheProviderFactory.java │ │ │ │ ├── Movie.java │ │ │ │ ├── RecommendationServiceFallbackHandler.java │ │ │ │ ├── RecommendationServiceResponseValidator.java │ │ │ │ ├── Recommendations.java │ │ │ │ └── RxMovieTransformer.java │ │ │ ├── proxy │ │ │ │ ├── MovieService.java │ │ │ │ └── RxMovieProxyExample.java │ │ │ ├── template │ │ │ │ └── RxMovieTemplateExample.java │ │ │ └── transport │ │ │ │ └── RxMovieTransportExample.java │ │ │ └── server │ │ │ └── ServerResources.java │ └── resources │ │ └── sample-client.properties │ └── test │ └── java │ └── com │ └── netflix │ └── ribbon │ └── examples │ └── rx │ ├── RxMovieClientTestBase.java │ ├── RxMovieServerTest.java │ ├── common │ ├── MovieTest.java │ └── RecommendationsTest.java │ ├── proxy │ └── RxMovieProxyExampleTest.java │ ├── template │ └── RxMovieTemplateExampleTest.java │ └── transport │ └── RxMovieTransportExampleTest.java ├── ribbon-guice ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── netflix │ │ └── ribbon │ │ └── guice │ │ ├── RibbonModule.java │ │ └── RibbonResourceProvider.java │ └── test │ └── java │ └── com │ └── netflix │ └── ribbon │ └── examples │ └── rx │ ├── RibbonModuleTest.java │ ├── RxMovieClientTestBase.java │ ├── RxMovieProxyExampleTest.java │ └── proxy │ └── RxMovieProxyExample.java ├── ribbon-httpclient ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── netflix │ │ ├── client │ │ └── http │ │ │ ├── CaseInsensitiveMultiMap.java │ │ │ ├── HttpHeaders.java │ │ │ ├── HttpRequest.java │ │ │ └── HttpResponse.java │ │ ├── http4 │ │ ├── ConnectionPoolCleaner.java │ │ ├── MonitoredConnectionManager.java │ │ ├── NFHttpClient.java │ │ ├── NFHttpClientFactory.java │ │ ├── NFHttpMethodRetryHandler.java │ │ ├── NamedConnectionPool.java │ │ └── ssl │ │ │ ├── AcceptAllSocketFactory.java │ │ │ └── KeyStoreAwareSocketFactory.java │ │ ├── loadbalancer │ │ └── PingUrl.java │ │ └── niws │ │ └── client │ │ └── http │ │ ├── HttpClientLoadBalancerErrorHandler.java │ │ ├── HttpClientRequest.java │ │ ├── HttpClientResponse.java │ │ ├── HttpPrimeConnection.java │ │ └── RestClient.java │ └── test │ ├── java │ └── com │ │ └── netflix │ │ ├── client │ │ ├── ClientFactoryTest.java │ │ ├── ManyShortLivedRequestsSurvivorTest.java │ │ ├── samples │ │ │ └── SampleApp.java │ │ └── testutil │ │ │ └── SimpleSSLTestServer.java │ │ ├── http4 │ │ ├── NFHttpClientTest.java │ │ └── NamedConnectionPoolTest.java │ │ └── niws │ │ └── client │ │ └── http │ │ ├── FollowRedirectTest.java │ │ ├── GetPostTest.java │ │ ├── PrimeConnectionsTest.java │ │ ├── ResponseTimeWeightedRuleTest.java │ │ ├── RestClientTest.java │ │ ├── RetryTest.java │ │ ├── SecureAcceptAllGetTest.java │ │ ├── SecureGetTest.java │ │ ├── SecureRestClientKeystoreTest.java │ │ ├── TestObject.java │ │ └── TestResource.java │ └── resources │ ├── log4j.properties │ └── sample-client.properties ├── ribbon-loadbalancer ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── netflix │ │ ├── client │ │ ├── AbstractLoadBalancerAwareClient.java │ │ ├── ClientFactory.java │ │ ├── IPrimeConnection.java │ │ └── PrimeConnections.java │ │ └── loadbalancer │ │ ├── AbstractLoadBalancer.java │ │ ├── AbstractLoadBalancerPing.java │ │ ├── AbstractLoadBalancerRule.java │ │ ├── AbstractServerList.java │ │ ├── AbstractServerListFilter.java │ │ ├── AbstractServerPredicate.java │ │ ├── AvailabilityFilteringRule.java │ │ ├── AvailabilityPredicate.java │ │ ├── BaseLoadBalancer.java │ │ ├── BestAvailableRule.java │ │ ├── ClientConfigEnabledRoundRobinRule.java │ │ ├── CompositePredicate.java │ │ ├── ConfigurationBasedServerList.java │ │ ├── DummyPing.java │ │ ├── DynamicServerListLoadBalancer.java │ │ ├── ILoadBalancer.java │ │ ├── IPing.java │ │ ├── IPingStrategy.java │ │ ├── IRule.java │ │ ├── InterruptTask.java │ │ ├── LoadBalancerBuilder.java │ │ ├── LoadBalancerContext.java │ │ ├── LoadBalancerStats.java │ │ ├── NoOpLoadBalancer.java │ │ ├── NoOpPing.java │ │ ├── PingConstant.java │ │ ├── PollingServerListUpdater.java │ │ ├── PredicateBasedRule.java │ │ ├── PredicateKey.java │ │ ├── RandomRule.java │ │ ├── ResponseTimeWeightedRule.java │ │ ├── RetryRule.java │ │ ├── RoundRobinRule.java │ │ ├── Server.java │ │ ├── ServerComparator.java │ │ ├── ServerList.java │ │ ├── ServerListChangeListener.java │ │ ├── ServerListFilter.java │ │ ├── ServerListSubsetFilter.java │ │ ├── ServerListUpdater.java │ │ ├── ServerStats.java │ │ ├── ServerStatusChangeListener.java │ │ ├── WeightedResponseTimeRule.java │ │ ├── ZoneAffinityPredicate.java │ │ ├── ZoneAffinityServerListFilter.java │ │ ├── ZoneAvoidancePredicate.java │ │ ├── ZoneAvoidanceRule.java │ │ ├── ZoneAwareLoadBalancer.java │ │ ├── ZoneSnapshot.java │ │ ├── ZoneStats.java │ │ └── reactive │ │ ├── ExecutionContext.java │ │ ├── ExecutionContextListenerInvoker.java │ │ ├── ExecutionInfo.java │ │ ├── ExecutionListener.java │ │ ├── LoadBalancerCommand.java │ │ └── ServerOperation.java │ └── test │ ├── java │ └── com │ │ └── netflix │ │ ├── client │ │ ├── SimpleVipAddressResolverTest.java │ │ └── testutil │ │ │ └── MockHttpServer.java │ │ └── loadbalancer │ │ ├── BestAvailableRuleTest.java │ │ ├── ConfigurationBasedServerListTest.java │ │ ├── DynamicServerListLoadBalancerTest.java │ │ ├── LoadBalancerCommandTest.java │ │ ├── LoadBalancerContextTest.java │ │ ├── MockServerList.java │ │ ├── PollingServerListUpdaterTest.java │ │ ├── PredicatesTest.java │ │ ├── RandomLBTest.java │ │ ├── ServerListChangeListenerTest.java │ │ ├── ServerListLoabBalancerTest.java │ │ ├── ServerStatsTest.java │ │ ├── ServerStatusChangeListenerTest.java │ │ ├── ServerTest.java │ │ ├── SimpleRoundRobinLBTest.java │ │ ├── SimpleRoundRobinWithRetryLBTest.java │ │ ├── SubsetFilterTest.java │ │ ├── WeightedResponseTimeRuleTest.java │ │ ├── ZoneAwareLoadBalancerTest.java │ │ └── reactive │ │ └── ExecutionContextTest.java │ └── resources │ └── log4j.properties ├── ribbon-test ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── netflix │ ├── ribbon │ ├── test │ │ └── resources │ │ │ └── EmbeddedResources.java │ └── testutils │ │ ├── MockedDiscoveryServerListTest.java │ │ └── TestUtils.java │ └── serialization │ ├── Deserializer.java │ ├── JacksonCodec.java │ ├── SerializationUtils.java │ ├── Serializer.java │ ├── StringDeserializer.java │ └── TypeDef.java ├── ribbon-transport ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── netflix │ │ └── ribbon │ │ ├── RibbonTransportFactory.java │ │ └── transport │ │ └── netty │ │ ├── DynamicPropertyBasedPoolStrategy.java │ │ ├── LoadBalancingRxClient.java │ │ ├── LoadBalancingRxClientWithPoolOptions.java │ │ ├── RibbonTransport.java │ │ ├── http │ │ ├── DefaultResponseToErrorPolicy.java │ │ ├── LoadBalancingHttpClient.java │ │ ├── NettyHttpLoadBalancerErrorHandler.java │ │ └── SSEClient.java │ │ ├── tcp │ │ └── LoadBalancingTcpClient.java │ │ └── udp │ │ └── LoadBalancingUdpClient.java │ └── test │ ├── java │ └── com │ │ └── netflix │ │ ├── client │ │ └── netty │ │ │ └── udp │ │ │ └── HelloUdpServerExternalResource.java │ │ └── ribbon │ │ └── transport │ │ └── netty │ │ ├── DynamicPropertyBasedPoolStrategyTest.java │ │ ├── MyUDPClient.java │ │ ├── http │ │ ├── DiscoveryLoadBalancerTest.java │ │ ├── ListenerTest.java │ │ ├── NettyClientTest.java │ │ ├── ObserverWithLatch.java │ │ ├── ServerListRefreshTest.java │ │ └── TestExecutionListener.java │ │ └── udp │ │ ├── HelloUdpServer.java │ │ └── UdpClientTest.java │ └── resources │ └── log4j.properties ├── ribbon ├── README.md ├── build.gradle └── src │ ├── examples │ └── java │ │ └── com │ │ └── netflix │ │ └── ribbon │ │ └── RibbonExamples.java │ ├── main │ └── java │ │ └── com │ │ └── netflix │ │ └── ribbon │ │ ├── CacheProvider.java │ │ ├── CacheProviderFactory.java │ │ ├── ClientOptions.java │ │ ├── DefaultResourceFactory.java │ │ ├── RequestTemplate.java │ │ ├── RequestWithMetaData.java │ │ ├── ResourceGroup.java │ │ ├── ResponseValidator.java │ │ ├── Ribbon.java │ │ ├── RibbonRequest.java │ │ ├── RibbonResourceFactory.java │ │ ├── RibbonResponse.java │ │ ├── ServerError.java │ │ ├── UnsuccessfulResponseException.java │ │ ├── http │ │ ├── HttpMetaRequest.java │ │ ├── HttpMetaResponse.java │ │ ├── HttpRequest.java │ │ ├── HttpRequestBuilder.java │ │ ├── HttpRequestTemplate.java │ │ ├── HttpResourceGroup.java │ │ ├── HttpResourceObservableCommand.java │ │ └── HttpResponseValidator.java │ │ ├── hystrix │ │ ├── CacheObservableCommand.java │ │ ├── FallbackHandler.java │ │ ├── HystrixObservableCommandChain.java │ │ └── ResultCommandPair.java │ │ ├── proxy │ │ ├── ClassTemplate.java │ │ ├── MethodTemplate.java │ │ ├── MethodTemplateExecutor.java │ │ ├── ProxyAnnotationException.java │ │ ├── ProxyHttpResourceGroupFactory.java │ │ ├── ProxyLifeCycle.java │ │ ├── RibbonDynamicProxy.java │ │ ├── RibbonProxyException.java │ │ ├── Utils.java │ │ ├── annotation │ │ │ ├── CacheProvider.java │ │ │ ├── ClientProperties.java │ │ │ ├── Content.java │ │ │ ├── ContentTransformerClass.java │ │ │ ├── Http.java │ │ │ ├── Hystrix.java │ │ │ ├── ResourceGroup.java │ │ │ ├── TemplateName.java │ │ │ └── Var.java │ │ └── processor │ │ │ ├── AnnotationProcessor.java │ │ │ ├── AnnotationProcessorsProvider.java │ │ │ ├── CacheProviderAnnotationProcessor.java │ │ │ ├── ClientPropertiesProcessor.java │ │ │ ├── HttpAnnotationProcessor.java │ │ │ └── HystrixAnnotationProcessor.java │ │ └── template │ │ ├── MatrixVar.java │ │ ├── ParsedTemplate.java │ │ ├── PathVar.java │ │ ├── TemplateParser.java │ │ ├── TemplateParsingException.java │ │ └── TemplateVar.java │ └── test │ ├── java │ └── com │ │ └── netflix │ │ └── ribbon │ │ ├── DiscoveryEnabledServerListTest.java │ │ ├── RibbonTest.java │ │ ├── http │ │ └── TemplateBuilderTest.java │ │ ├── hystrix │ │ └── HystrixCommandChainTest.java │ │ └── proxy │ │ ├── ClassTemplateTest.java │ │ ├── ClientPropertiesTest.java │ │ ├── HttpResourceGroupFactoryTest.java │ │ ├── MethodTemplateExecutorTest.java │ │ ├── MethodTemplateTest.java │ │ ├── RibbonDynamicProxyTest.java │ │ ├── ShutDownTest.java │ │ ├── UtilsTest.java │ │ └── sample │ │ ├── HystrixHandlers.java │ │ ├── Movie.java │ │ ├── MovieServiceInterfaces.java │ │ ├── MovieTransformer.java │ │ ├── ResourceGroupClasses.java │ │ └── SampleCacheProviderFactory.java │ └── resources │ └── log4j.properties └── settings.gradle /.github/workflows/gradle-wrapper-validation.yml: -------------------------------------------------------------------------------- 1 | name: "Gradle Wrapper" 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | validation: 6 | name: "validation" 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - uses: gradle/wrapper-validation-action@v1 11 | -------------------------------------------------------------------------------- /.github/workflows/nebula-ci.yml: -------------------------------------------------------------------------------- 1 | name: "CI" 2 | on: 3 | push: 4 | branches: 5 | - '*' 6 | tags-ignore: 7 | - '*' 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | strategy: 14 | matrix: 15 | # test against JDK 8 16 | java: [ 8 ] 17 | name: CI with Java ${{ matrix.java }} 18 | steps: 19 | - uses: actions/checkout@v1 20 | - name: Setup jdk 21 | uses: actions/setup-java@v1 22 | with: 23 | java-version: ${{ matrix.java }} 24 | - uses: actions/cache@v4 25 | id: gradle-cache 26 | with: 27 | path: ~/.gradle/caches 28 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/gradle/dependency-locks/*.lockfile') }} 29 | restore-keys: | 30 | - ${{ runner.os }}-gradle- 31 | - uses: actions/cache@v4 32 | id: gradle-wrapper-cache 33 | with: 34 | path: ~/.gradle/wrapper 35 | key: ${{ runner.os }}-gradlewrapper-${{ hashFiles('gradle/wrapper/*') }} 36 | restore-keys: | 37 | - ${{ runner.os }}-gradlewrapper- 38 | - name: Build with Gradle 39 | run: ./gradlew --info --stacktrace build 40 | env: 41 | CI_NAME: github_actions 42 | CI_BUILD_NUMBER: ${{ github.sha }} 43 | CI_BUILD_URL: 'https://github.com/${{ github.repository }}' 44 | CI_BRANCH: ${{ github.ref }} 45 | COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} 46 | -------------------------------------------------------------------------------- /.github/workflows/nebula-publish.yml: -------------------------------------------------------------------------------- 1 | name: "Publish candidate/release to NetflixOSS and Maven Central" 2 | on: 3 | push: 4 | tags: 5 | - v*.*.* 6 | - v*.*.*-rc.* 7 | release: 8 | types: 9 | - published 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: Setup jdk 8 17 | uses: actions/setup-java@v1 18 | with: 19 | java-version: 1.8 20 | - uses: actions/cache@v4 21 | id: gradle-cache 22 | with: 23 | path: ~/.gradle/caches 24 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/gradle/dependency-locks/*.lockfile') }} 25 | restore-keys: | 26 | - ${{ runner.os }}-gradle- 27 | - uses: actions/cache@v4 28 | id: gradle-wrapper-cache 29 | with: 30 | path: ~/.gradle/wrapper 31 | key: ${{ runner.os }}-gradlewrapper-${{ hashFiles('gradle/wrapper/*') }} 32 | restore-keys: | 33 | - ${{ runner.os }}-gradlewrapper- 34 | - name: Publish candidate 35 | if: contains(github.ref, '-rc.') 36 | run: ./gradlew --info --stacktrace -Prelease.useLastTag=true candidate 37 | env: 38 | NETFLIX_OSS_SIGNING_KEY: ${{ secrets.ORG_SIGNING_KEY }} 39 | NETFLIX_OSS_SIGNING_PASSWORD: ${{ secrets.ORG_SIGNING_PASSWORD }} 40 | NETFLIX_OSS_REPO_USERNAME: ${{ secrets.ORG_NETFLIXOSS_USERNAME }} 41 | NETFLIX_OSS_REPO_PASSWORD: ${{ secrets.ORG_NETFLIXOSS_PASSWORD }} 42 | - name: Publish release 43 | if: (!contains(github.ref, '-rc.')) 44 | run: ./gradlew --info -Prelease.useLastTag=true final 45 | env: 46 | NETFLIX_OSS_SONATYPE_USERNAME: ${{ secrets.ORG_SONATYPE_USERNAME }} 47 | NETFLIX_OSS_SONATYPE_PASSWORD: ${{ secrets.ORG_SONATYPE_PASSWORD }} 48 | NETFLIX_OSS_SIGNING_KEY: ${{ secrets.ORG_SIGNING_KEY }} 49 | NETFLIX_OSS_SIGNING_PASSWORD: ${{ secrets.ORG_SIGNING_PASSWORD }} 50 | NETFLIX_OSS_REPO_USERNAME: ${{ secrets.ORG_NETFLIXOSS_USERNAME }} 51 | NETFLIX_OSS_REPO_PASSWORD: ${{ secrets.ORG_NETFLIXOSS_PASSWORD }} 52 | -------------------------------------------------------------------------------- /.github/workflows/nebula-snapshot.yml: -------------------------------------------------------------------------------- 1 | name: "Publish snapshot to NetflixOSS and Maven Central" 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | with: 14 | fetch-depth: 0 15 | - name: Set up JDK 16 | uses: actions/setup-java@v1 17 | with: 18 | java-version: 8 19 | - uses: actions/cache@v4 20 | id: gradle-cache 21 | with: 22 | path: | 23 | ~/.gradle/caches 24 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} 25 | - uses: actions/cache@v4 26 | id: gradle-wrapper-cache 27 | with: 28 | path: | 29 | ~/.gradle/wrapper 30 | key: ${{ runner.os }}-gradlewrapper-${{ hashFiles('gradle/wrapper/*') }} 31 | - name: Build 32 | run: ./gradlew build snapshot 33 | env: 34 | NETFLIX_OSS_SIGNING_KEY: ${{ secrets.ORG_SIGNING_KEY }} 35 | NETFLIX_OSS_SIGNING_PASSWORD: ${{ secrets.ORG_SIGNING_PASSWORD }} 36 | NETFLIX_OSS_REPO_USERNAME: ${{ secrets.ORG_NETFLIXOSS_USERNAME }} 37 | NETFLIX_OSS_REPO_PASSWORD: ${{ secrets.ORG_NETFLIXOSS_PASSWORD }} 38 | -------------------------------------------------------------------------------- /.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 | 43 | # Build output directies 44 | /target 45 | */target 46 | /build 47 | */build 48 | */bin 49 | 50 | # IntelliJ specific files/directories 51 | out 52 | .idea 53 | *.ipr 54 | *.iws 55 | *.iml 56 | atlassian-ide-plugin.xml 57 | 58 | # Eclipse specific files/directories 59 | .classpath 60 | .project 61 | .settings 62 | .metadata 63 | 64 | # NetBeans specific files/directories 65 | .nbattrs 66 | 67 | # publishing secrets 68 | secrets/signing-key 69 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### Version 0.3.4 2 | 3 | https://github.com/Netflix/ribbon/pull/62 4 | * Fix Issue #61: FollowRedirects impossible to turn off. 5 | 6 | ### Version 0.3.3 7 | 8 | https://github.com/Netflix/ribbon/pull/60 9 | * add hook for custom ssl factory and AcceptAllSocketFactory implementation 10 | 11 | ### Version 0.3.2 12 | 13 | [pull request 57](https://github.com/Netflix/ribbon/pull/57) 14 | * Make sure NamedConnectionPool instances register with Servo with unique names. 15 | 16 | ### Version 0.3.1 17 | 18 | [pull request 56](https://github.com/Netflix/ribbon/pull/56) 19 | * Fix connection leak when RestClient throws exception on server throttle 20 | 21 | 22 | ### Version 0.3.0 23 | 24 | [pull request 51](https://github.com/Netflix/ribbon/pull/51) 25 | * Added asynchronous client based on Apache's HttpAsyncClient 26 | * API to support async cancellable back up requests 27 | * Support Observable APIs from https://github.com/Netflix/RxJava 28 | * Created unified serialization interface to be used by all clients 29 | * Builders for async clients 30 | * ribbion-examples sub-project created 31 | * refactoring of load balancer APIs 32 | * Unify the request and response object used by RestClient to be the same as RibbonHttpAsyncClient 33 | * Replaced dependency on jersey-bundle with jersey-client. 34 | 35 | [pull request 54](https://github.com/Netflix/ribbon/pull/54) 36 | * Changed the dependency of HttpAsyncClient to be 4.0 GA 37 | * Enhanced JUnit tests 38 | 39 | -------------------------------------------------------------------------------- /OSSMETADATA: -------------------------------------------------------------------------------- 1 | osslifecycle=maintenance 2 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.netflix.nebula.netflixoss' version '11.3.2' 3 | } 4 | 5 | // Establish version and status 6 | ext.githubProjectName = rootProject.name // Change if github project name is not the same as the root project's name 7 | 8 | subprojects { 9 | apply plugin: 'com.netflix.nebula.netflixoss' 10 | apply plugin: 'java-library' 11 | 12 | java { 13 | toolchain { 14 | languageVersion = JavaLanguageVersion.of(8) 15 | } 16 | } 17 | 18 | 19 | group = "com.netflix.${githubProjectName}" // TEMPLATE: Set to organization of project 20 | 21 | repositories { 22 | mavenCentral() 23 | } 24 | 25 | if (project.hasProperty('useMavenLocal')) { 26 | repositories { 27 | mavenLocal() 28 | } 29 | } 30 | if (project.getProperty('status').equals("snapshot")) { 31 | repositories { 32 | maven { url 'https://artifactory-oss.prod.netflix.net/artifactory/maven-oss-snapshots' } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | rx_java_version=1.0.9 2 | rx_netty_version=0.4.9 3 | servo_version=0.10.1 4 | hystrix_version=1.4.3 5 | guava_version=19.0 6 | archaius_version=0.7.6 7 | eureka_version=1.7.2 8 | jersey_version=1.19.1 9 | slf4j_version=1.7.2 10 | 11 | junit_version=4.12 12 | powermock_version=1.6.2 13 | easymock_version=3.2 -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/ribbon/45e59260c1e0b8834d4cc960895ba59ecbda7f63/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /ribbon-archaius/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api "org.slf4j:slf4j-api:${slf4j_version}" 3 | api 'com.google.code.findbugs:annotations:2.0.0' 4 | api "com.google.guava:guava:${guava_version}" 5 | api 'commons-configuration:commons-configuration:1.8' 6 | api 'commons-lang:commons-lang:2.6' 7 | api "com.netflix.archaius:archaius-core:${archaius_version}" 8 | 9 | api project(':ribbon-core') 10 | 11 | testImplementation 'junit:junit:4.11' 12 | } 13 | -------------------------------------------------------------------------------- /ribbon-archaius/src/main/java/com/netflix/client/config/ArchaiusClientConfigFactory.java: -------------------------------------------------------------------------------- 1 | package com.netflix.client.config; 2 | 3 | public class ArchaiusClientConfigFactory implements ClientConfigFactory { 4 | @Override 5 | public IClientConfig newConfig() { 6 | return new DefaultClientConfigImpl(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ribbon-archaius/src/main/resources/META-INF/services/com.netflix.client.config.ClientConfigFactory: -------------------------------------------------------------------------------- 1 | com.netflix.client.config.ArchaiusClientConfigFactory -------------------------------------------------------------------------------- /ribbon-core/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api "org.slf4j:slf4j-api:${slf4j_version}" 3 | api 'com.google.code.findbugs:annotations:2.0.0' 4 | api "com.google.guava:guava:${guava_version}" 5 | api 'commons-lang:commons-lang:2.6' 6 | 7 | testImplementation 'junit:junit:4.11' 8 | testImplementation "org.slf4j:slf4j-log4j12:${slf4j_version}" 9 | testImplementation project(":ribbon-archaius") 10 | } 11 | -------------------------------------------------------------------------------- /ribbon-core/src/main/java/com/netflix/client/IClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.client; 19 | 20 | import com.netflix.client.config.IClientConfig; 21 | 22 | 23 | /** 24 | * A client that can execute a single request. 25 | * 26 | * @author awang 27 | * 28 | */ 29 | public interface IClient { 30 | 31 | /** 32 | * Execute the request and return the response. It is expected that there is no retry and all exceptions 33 | * are thrown directly. 34 | */ 35 | public T execute(S request, IClientConfig requestConfig) throws Exception; 36 | } 37 | -------------------------------------------------------------------------------- /ribbon-core/src/main/java/com/netflix/client/IClientConfigAware.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.client; 19 | 20 | import com.netflix.client.config.IClientConfig; 21 | 22 | /** 23 | * There are multiple classes (and components) that need access to the configuration. 24 | * Its easier to do this by using {@link IClientConfig} as the object that carries these configurations 25 | * and to define a common interface that components that need this can implement and hence be aware of. 26 | * 27 | * @author stonse 28 | * @author awang 29 | * 30 | */ 31 | public interface IClientConfigAware { 32 | interface Factory { 33 | Object create(String type, IClientConfig config) throws InstantiationException, IllegalAccessException, ClassNotFoundException; 34 | } 35 | 36 | /** 37 | * Concrete implementation should implement this method so that the configuration set via 38 | * {@link IClientConfig} (which in turn were set via Archaius properties) will be taken into consideration 39 | * 40 | * @param clientConfig 41 | */ 42 | default void initWithNiwsConfig(IClientConfig clientConfig) { 43 | } 44 | 45 | default void initWithNiwsConfig(IClientConfig clientConfig, Factory factory) { 46 | initWithNiwsConfig(clientConfig); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /ribbon-core/src/main/java/com/netflix/client/IResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.client; 19 | 20 | import java.io.Closeable; 21 | import java.net.URI; 22 | import java.util.Map; 23 | 24 | /** 25 | * Response interface for the client framework. 26 | * 27 | */ 28 | public interface IResponse extends Closeable 29 | { 30 | 31 | /** 32 | * Returns the raw entity if available from the response 33 | */ 34 | public Object getPayload() throws ClientException; 35 | 36 | /** 37 | * A "peek" kinda API. Use to check if your service returned a response with an Entity 38 | */ 39 | public boolean hasPayload(); 40 | 41 | /** 42 | * @return true if the response is deemed success, for example, 200 response code for http protocol. 43 | */ 44 | public boolean isSuccess(); 45 | 46 | 47 | /** 48 | * Return the Request URI that generated this response 49 | */ 50 | public URI getRequestedURI(); 51 | 52 | /** 53 | * 54 | * @return Headers if any in the response. 55 | */ 56 | public Map getHeaders(); 57 | } 58 | -------------------------------------------------------------------------------- /ribbon-core/src/main/java/com/netflix/client/Utils.java: -------------------------------------------------------------------------------- 1 | package com.netflix.client; 2 | 3 | import java.util.Collection; 4 | 5 | public class Utils { 6 | public static boolean isPresentAsCause(Throwable throwableToSearchIn, 7 | Collection> throwableToSearchFor) { 8 | int infiniteLoopPreventionCounter = 10; 9 | while (throwableToSearchIn != null && infiniteLoopPreventionCounter > 0) { 10 | infiniteLoopPreventionCounter--; 11 | for (Class c: throwableToSearchFor) { 12 | if (c.isAssignableFrom(throwableToSearchIn.getClass())) { 13 | return true; 14 | } 15 | } 16 | throwableToSearchIn = throwableToSearchIn.getCause(); 17 | } 18 | return false; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ribbon-core/src/main/java/com/netflix/client/VipAddressResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.client; 19 | 20 | import com.netflix.client.config.IClientConfig; 21 | 22 | /** 23 | * A "VipAddress" is a logical name for a Target Server farm. 24 | * 25 | * @author stonse 26 | * 27 | */ 28 | public interface VipAddressResolver { 29 | public String resolve(String vipAddress, IClientConfig niwsClientConfig); 30 | } 31 | -------------------------------------------------------------------------------- /ribbon-core/src/main/java/com/netflix/client/config/ClientConfigFactory.java: -------------------------------------------------------------------------------- 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 | package com.netflix.client.config; 17 | 18 | 19 | import java.util.Comparator; 20 | import java.util.ServiceLoader; 21 | import java.util.stream.StreamSupport; 22 | 23 | /** 24 | * Created by awang on 7/18/14. 25 | */ 26 | public interface ClientConfigFactory { 27 | IClientConfig newConfig(); 28 | 29 | ClientConfigFactory DEFAULT = findDefaultConfigFactory(); 30 | 31 | default int getPriority() { return 0; } 32 | 33 | static ClientConfigFactory findDefaultConfigFactory() { 34 | return StreamSupport.stream(ServiceLoader.load(ClientConfigFactory.class).spliterator(), false) 35 | .sorted(Comparator 36 | .comparingInt(ClientConfigFactory::getPriority) 37 | .thenComparing(f -> f.getClass().getCanonicalName()) 38 | .reversed()) 39 | .findFirst() 40 | .orElseGet(() -> { 41 | throw new IllegalStateException("Expecting at least one implementation of ClientConfigFactory discoverable via the ServiceLoader"); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ribbon-core/src/main/java/com/netflix/client/config/FallbackProperty.java: -------------------------------------------------------------------------------- 1 | package com.netflix.client.config; 2 | 3 | import java.util.Optional; 4 | import java.util.function.Consumer; 5 | 6 | public final class FallbackProperty implements Property { 7 | private final Property primary; 8 | private final Property fallback; 9 | 10 | public FallbackProperty(Property primary, Property fallback) { 11 | this.primary = primary; 12 | this.fallback = fallback; 13 | } 14 | 15 | @Override 16 | public void onChange(Consumer consumer) { 17 | primary.onChange(ignore -> consumer.accept(getOrDefault())); 18 | fallback.onChange(ignore -> consumer.accept(getOrDefault())); 19 | } 20 | 21 | @Override 22 | public Optional get() { 23 | Optional value = primary.get(); 24 | if (value.isPresent()) { 25 | return value; 26 | } 27 | return fallback.get(); 28 | } 29 | 30 | @Override 31 | public T getOrDefault() { 32 | return primary.get().orElseGet(fallback::getOrDefault); 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return String.valueOf(get()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ribbon-core/src/main/java/com/netflix/client/config/Property.java: -------------------------------------------------------------------------------- 1 | package com.netflix.client.config; 2 | 3 | import java.util.Optional; 4 | import java.util.function.Consumer; 5 | 6 | /** 7 | * Ribbon specific encapsulation of a dynamic configuration property 8 | * @param 9 | */ 10 | public interface Property { 11 | /** 12 | * Register a consumer to be called when the configuration changes 13 | * @param consumer 14 | */ 15 | void onChange(Consumer consumer); 16 | 17 | /** 18 | * @return Get the current value. Can be null if not set 19 | */ 20 | Optional get(); 21 | 22 | /** 23 | * @return Get the current value or the default value if not set 24 | */ 25 | T getOrDefault(); 26 | 27 | default Property fallbackWith(Property fallback) { 28 | return new FallbackProperty<>(this, fallback); 29 | } 30 | 31 | static Property of(T value) { 32 | return new Property() { 33 | @Override 34 | public void onChange(Consumer consumer) { 35 | // It's a static property so no need to track the consumer 36 | } 37 | 38 | @Override 39 | public Optional get() { 40 | return Optional.ofNullable(value); 41 | } 42 | 43 | @Override 44 | public T getOrDefault() { 45 | return value; 46 | } 47 | 48 | @Override 49 | public String toString( ){ 50 | return String.valueOf(value); 51 | } 52 | }; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ribbon-core/src/main/java/com/netflix/client/config/PropertyResolver.java: -------------------------------------------------------------------------------- 1 | package com.netflix.client.config; 2 | 3 | import java.util.Optional; 4 | import java.util.function.BiConsumer; 5 | 6 | /** 7 | * Internal abstraction to decouple the property source from Ribbon's internal configuration. 8 | */ 9 | public interface PropertyResolver { 10 | /** 11 | * @return Get the value of a property or Optional.empty() if not set 12 | */ 13 | Optional get(String key, Class type); 14 | 15 | /** 16 | * Iterate through all properties with the specified prefix 17 | */ 18 | void forEach(String prefix, BiConsumer consumer); 19 | 20 | /** 21 | * Provide action to invoke when config changes 22 | * @param action 23 | */ 24 | void onChange(Runnable action); 25 | } 26 | -------------------------------------------------------------------------------- /ribbon-core/src/main/java/com/netflix/client/config/PropertyUtils.java: -------------------------------------------------------------------------------- 1 | package com.netflix.client.config; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import java.lang.reflect.Method; 7 | import java.util.Map; 8 | import java.util.Optional; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | public class PropertyUtils { 12 | private static Logger LOG = LoggerFactory.getLogger(PropertyUtils.class); 13 | 14 | private PropertyUtils() {} 15 | 16 | /** 17 | * Returns the internal property to the desiredn type 18 | */ 19 | private static Map, Optional> valueOfMethods = new ConcurrentHashMap<>(); 20 | 21 | public static Optional resolveWithValueOf(Class type, String value) { 22 | return valueOfMethods.computeIfAbsent(type, ignore -> { 23 | try { 24 | return Optional.of(type.getDeclaredMethod("valueOf", String.class)); 25 | } catch (NoSuchMethodException e) { 26 | return Optional.empty(); 27 | } catch (Exception e) { 28 | LOG.warn("Unable to determine if type " + type + " has a valueOf() static method", e); 29 | return Optional.empty(); 30 | } 31 | }).map(method -> { 32 | try { 33 | return (T)method.invoke(null, value); 34 | } catch (Exception e) { 35 | throw new RuntimeException(e); 36 | } 37 | }); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /ribbon-core/src/main/java/com/netflix/client/config/UnboxedIntProperty.java: -------------------------------------------------------------------------------- 1 | package com.netflix.client.config; 2 | 3 | public class UnboxedIntProperty { 4 | private volatile int value; 5 | 6 | public UnboxedIntProperty(Property delegate) { 7 | this.value = delegate.getOrDefault(); 8 | 9 | delegate.onChange(newValue -> this.value = newValue); 10 | } 11 | 12 | public UnboxedIntProperty(int constantValue) { 13 | this.value = constantValue; 14 | } 15 | 16 | public int get() { 17 | return value; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ribbon-core/src/main/java/com/netflix/client/http/UnexpectedHttpResponseException.java: -------------------------------------------------------------------------------- 1 | package com.netflix.client.http; 2 | 3 | public class UnexpectedHttpResponseException extends Exception { 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = 1L; 9 | 10 | private final int statusCode; 11 | private final String line; 12 | 13 | public UnexpectedHttpResponseException(int statusCode, String statusLine) { 14 | super(statusLine); 15 | this.statusCode = statusCode; 16 | this.line = statusLine; 17 | } 18 | 19 | public int getStatusCode() { 20 | return statusCode; 21 | } 22 | 23 | public String getStatusLine() { 24 | return this.line; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ribbon-core/src/main/java/com/netflix/client/ssl/ClientSslSocketFactoryException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.client.ssl; 19 | 20 | /** 21 | * Reports problems detected by the ClientSslSocketFactory class. 22 | * 23 | * @author pstout@netflix.com (Peter D. Stout) 24 | */ 25 | public class ClientSslSocketFactoryException extends Exception { 26 | /** Serial version identifier for this class. */ 27 | private static final long serialVersionUID = 1L; 28 | 29 | /** Constructs a new instance with the specified message and cause. */ 30 | public ClientSslSocketFactoryException(final String message, final Throwable cause) { 31 | super(message, cause); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ribbon-core/src/main/java/com/netflix/client/util/Resources.java: -------------------------------------------------------------------------------- 1 | package com.netflix.client.util; 2 | 3 | import java.io.File; 4 | import java.net.URL; 5 | import java.net.URLDecoder; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | public abstract class Resources { 11 | private static final Logger logger = LoggerFactory.getLogger(Resources.class); 12 | 13 | public static URL getResource(String resourceName) { 14 | URL url = null; 15 | // attempt to load from the context classpath 16 | ClassLoader loader = Thread.currentThread().getContextClassLoader(); 17 | if (loader != null) { 18 | url = loader.getResource(resourceName); 19 | } 20 | if (url == null) { 21 | // attempt to load from the system classpath 22 | url = ClassLoader.getSystemResource(resourceName); 23 | } 24 | if (url == null) { 25 | try { 26 | resourceName = URLDecoder.decode(resourceName, "UTF-8"); 27 | url = (new File(resourceName)).toURI().toURL(); 28 | } catch (Exception e) { 29 | logger.error("Problem loading resource", e); 30 | } 31 | } 32 | return url; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ribbon-core/src/resources/META-INF/services/com.netflix.client.config.ClientConfigFactory: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/ribbon/45e59260c1e0b8834d4cc960895ba59ecbda7f63/ribbon-core/src/resources/META-INF/services/com.netflix.client.config.ClientConfigFactory -------------------------------------------------------------------------------- /ribbon-core/src/test/java/com/netflix/client/config/ArchaiusPropertyResolverTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.client.config; 2 | 3 | import com.netflix.config.ConfigurationManager; 4 | import org.apache.commons.configuration.AbstractConfiguration; 5 | import org.junit.Assert; 6 | import org.junit.Rule; 7 | import org.junit.Test; 8 | import org.junit.rules.TestName; 9 | 10 | import java.util.Map; 11 | import java.util.TreeMap; 12 | 13 | public class ArchaiusPropertyResolverTest { 14 | @Rule 15 | public TestName testName = new TestName(); 16 | 17 | @Test 18 | public void mapFromPrefixedKeys() { 19 | final String prefix = "client.ribbon." + testName.getMethodName(); 20 | 21 | final AbstractConfiguration config = ConfigurationManager.getConfigInstance(); 22 | 23 | config.setProperty(prefix + ".a", "1"); 24 | config.setProperty(prefix + ".b", "2"); 25 | config.setProperty(prefix + ".c", "3"); 26 | 27 | final ArchaiusPropertyResolver resolver = ArchaiusPropertyResolver.INSTANCE; 28 | 29 | final Map map = new TreeMap<>(); 30 | 31 | resolver.forEach(prefix, map::put); 32 | 33 | final Map expected = new TreeMap<>(); 34 | expected.put("a", "1"); 35 | expected.put("b", "2"); 36 | expected.put("c", "3"); 37 | 38 | Assert.assertEquals(expected, map); 39 | } 40 | 41 | @Test 42 | public void noCallbackIfNoValues() { 43 | final String prefix = "client.ribbon." + testName.getMethodName(); 44 | 45 | final ArchaiusPropertyResolver resolver = ArchaiusPropertyResolver.INSTANCE; 46 | 47 | final Map map = new TreeMap<>(); 48 | 49 | resolver.forEach(prefix, map::put); 50 | 51 | Assert.assertTrue(map.toString(), map.isEmpty()); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ribbon-core/src/test/java/com/netflix/client/config/CommonClientConfigKeyTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.client.config; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import org.junit.Test; 6 | 7 | import com.google.common.collect.Sets; 8 | 9 | public class CommonClientConfigKeyTest { 10 | 11 | @Test 12 | public void testCommonKeys() { 13 | IClientConfigKey[] keys = CommonClientConfigKey.values(); 14 | assertTrue(keys.length > 30); 15 | assertEquals(Sets.newHashSet(keys), CommonClientConfigKey.keys()); 16 | assertTrue(CommonClientConfigKey.keys().contains(CommonClientConfigKey.ConnectTimeout)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ribbon-core/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootCategory=INFO,stdout 2 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d %-5p %C:%L [%t] [%M] %m%n 5 | 6 | log4j.logger.com.netflix.client.config=DEBUG -------------------------------------------------------------------------------- /ribbon-eureka/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api project(':ribbon-core') 3 | api project(':ribbon-loadbalancer') 4 | api "com.netflix.eureka:eureka-client:${eureka_version}" 5 | api "com.netflix.archaius:archaius-core:0.7.5" 6 | api "commons-configuration:commons-configuration:1.8" 7 | api "javax.inject:javax.inject:1" 8 | api 'com.google.code.findbugs:annotations:2.0.0' 9 | api "org.slf4j:slf4j-api:${slf4j_version}" 10 | 11 | testImplementation project(":ribbon-archaius") 12 | testImplementation "org.slf4j:slf4j-log4j12:${slf4j_version}" 13 | testImplementation "junit:junit:${junit_version}" 14 | testImplementation "org.powermock:powermock-easymock-release-full:${powermock_version}" 15 | testImplementation "org.powermock:powermock-mockito-release-full:${powermock_version}" 16 | testImplementation "org.easymock:easymock:${easymock_version}" 17 | testImplementation "com.netflix.eureka:eureka-test-utils:${eureka_version}" 18 | } 19 | -------------------------------------------------------------------------------- /ribbon-eureka/src/main/java/com/netflix/niws/loadbalancer/LegacyEurekaClientProvider.java: -------------------------------------------------------------------------------- 1 | package com.netflix.niws.loadbalancer; 2 | 3 | import com.netflix.discovery.DiscoveryManager; 4 | import com.netflix.discovery.EurekaClient; 5 | 6 | import javax.inject.Provider; 7 | 8 | /** 9 | * A legacy class to provide eurekaclient via static singletons 10 | */ 11 | class LegacyEurekaClientProvider implements Provider { 12 | 13 | private volatile EurekaClient eurekaClient; 14 | 15 | @Override 16 | public synchronized EurekaClient get() { 17 | if (eurekaClient == null) { 18 | eurekaClient = DiscoveryManager.getInstance().getDiscoveryClient(); 19 | } 20 | 21 | return eurekaClient; 22 | } 23 | } -------------------------------------------------------------------------------- /ribbon-eureka/src/test/java/com/netflix/niws/loadbalancer/LoadBalancerTestUtils.java: -------------------------------------------------------------------------------- 1 | package com.netflix.niws.loadbalancer; 2 | 3 | import com.netflix.appinfo.DataCenterInfo; 4 | import com.netflix.appinfo.InstanceInfo; 5 | import com.netflix.appinfo.MyDataCenterInfo; 6 | import com.netflix.discovery.DefaultEurekaClientConfig; 7 | import com.netflix.discovery.DiscoveryClient; 8 | import com.netflix.discovery.DiscoveryManager; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | import static org.easymock.EasyMock.expect; 14 | import static org.powermock.api.easymock.PowerMock.createMock; 15 | 16 | public class LoadBalancerTestUtils 17 | { 18 | static List getDummyInstanceInfo(String appName, String host, String ipAddr, int port){ 19 | List list = new ArrayList(); 20 | 21 | InstanceInfo info = InstanceInfo.Builder.newBuilder().setAppName(appName) 22 | .setHostName(host) 23 | .setIPAddr(ipAddr) 24 | .setPort(port) 25 | .setDataCenterInfo(new MyDataCenterInfo(DataCenterInfo.Name.MyOwn)) 26 | .build(); 27 | 28 | list.add(info); 29 | 30 | return list; 31 | } 32 | 33 | static DiscoveryClient mockDiscoveryClient() 34 | { 35 | DiscoveryClient mockedDiscoveryClient = createMock(DiscoveryClient.class); 36 | expect(mockedDiscoveryClient.getEurekaClientConfig()).andReturn(new DefaultEurekaClientConfig()).anyTimes(); 37 | return mockedDiscoveryClient; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ribbon-eureka/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootCategory=INFO,stdout 2 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d %-5p %C:%L [%t] [%M] %m%n 5 | -------------------------------------------------------------------------------- /ribbon-evcache/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api project(':ribbon') 3 | api 'com.netflix.evcache:evcache-client:1.0.5' 4 | api "io.reactivex:rxjava:${rx_java_version}" 5 | api "org.slf4j:slf4j-api:${slf4j_version}" 6 | testImplementation project(':ribbon-test') 7 | testImplementation "junit:junit:${junit_version}" 8 | testImplementation "org.powermock:powermock-easymock-release-full:${powermock_version}" 9 | testImplementation "org.easymock:easymock:${easymock_version}" 10 | } 11 | -------------------------------------------------------------------------------- /ribbon-evcache/src/main/java/com/netflix/ribbon/evache/CacheFaultException.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.evache; 18 | 19 | /** 20 | * @author Tomasz Bak 21 | */ 22 | public class CacheFaultException extends RuntimeException { 23 | private static final long serialVersionUID = -1672764803141328757L; 24 | 25 | public CacheFaultException(String message) { 26 | super(message); 27 | } 28 | 29 | public CacheFaultException(String message, Throwable cause) { 30 | super(message, cause); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ribbon-evcache/src/main/java/com/netflix/ribbon/evache/CacheMissException.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.evache; 18 | 19 | /** 20 | * @author Tomasz Bak 21 | */ 22 | public class CacheMissException extends RuntimeException { 23 | } 24 | -------------------------------------------------------------------------------- /ribbon-evcache/src/main/java/com/netflix/ribbon/evache/EvCacheOptions.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.evache; 18 | 19 | import com.netflix.evcache.EVCacheTranscoder; 20 | 21 | /** 22 | * @author Tomasz Bak 23 | */ 24 | public class EvCacheOptions { 25 | private final String appName; 26 | private final String cacheName; 27 | private final boolean enableZoneFallback; 28 | private final int timeToLive; 29 | private final EVCacheTranscoder transcoder; 30 | private final String cacheKeyTemplate; 31 | 32 | public EvCacheOptions(String appName, String cacheName, boolean enableZoneFallback, int timeToLive, 33 | EVCacheTranscoder transcoder, String cacheKeyTemplate) { 34 | this.appName = appName; 35 | this.cacheName = cacheName; 36 | this.enableZoneFallback = enableZoneFallback; 37 | this.timeToLive = timeToLive; 38 | this.transcoder = transcoder; 39 | this.cacheKeyTemplate = cacheKeyTemplate; 40 | } 41 | 42 | public String getAppName() { 43 | return appName; 44 | } 45 | 46 | public String getCacheName() { 47 | return cacheName; 48 | } 49 | 50 | public boolean isEnableZoneFallback() { 51 | return enableZoneFallback; 52 | } 53 | 54 | public int getTimeToLive() { 55 | return timeToLive; 56 | } 57 | 58 | public EVCacheTranscoder getTranscoder() { 59 | return transcoder; 60 | } 61 | 62 | public String getCacheKeyTemplate() { 63 | return cacheKeyTemplate; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /ribbon-evcache/src/main/java/com/netflix/ribbon/proxy/annotation/EvCache.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.proxy.annotation; 18 | 19 | import com.netflix.evcache.EVCacheTranscoder; 20 | 21 | import java.lang.annotation.ElementType; 22 | import java.lang.annotation.Retention; 23 | import java.lang.annotation.RetentionPolicy; 24 | import java.lang.annotation.Target; 25 | 26 | @Target(ElementType.METHOD) 27 | @Retention(RetentionPolicy.RUNTIME) 28 | public @interface EvCache { 29 | 30 | String name(); 31 | 32 | String appName(); 33 | 34 | String key(); 35 | 36 | int ttl() default 100; 37 | 38 | boolean enableZoneFallback() default true; 39 | 40 | Class>[] transcoder() default {}; 41 | } 42 | -------------------------------------------------------------------------------- /ribbon-evcache/src/main/resources/META-INF/services/com.netflix.ribbon.proxy.processor.AnnotationProcessor: -------------------------------------------------------------------------------- 1 | com.netflix.ribbon.proxy.processor.EVCacheAnnotationProcessor 2 | -------------------------------------------------------------------------------- /ribbon-evcache/src/test/java/com/netflix/ribbon/evache/ServiceLoaderTest.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.evache; 17 | 18 | import com.netflix.ribbon.proxy.processor.AnnotationProcessor; 19 | import com.netflix.ribbon.proxy.processor.AnnotationProcessorsProvider; 20 | import com.netflix.ribbon.proxy.processor.EVCacheAnnotationProcessor; 21 | import org.junit.Test; 22 | 23 | import java.util.List; 24 | 25 | import static junit.framework.TestCase.assertTrue; 26 | 27 | /** 28 | * @author Allen Wang 29 | */ 30 | public class ServiceLoaderTest { 31 | @Test 32 | public void testServiceLoader() { 33 | AnnotationProcessorsProvider annotations = AnnotationProcessorsProvider.DEFAULT; 34 | List processors = annotations.getProcessors(); 35 | boolean hasEVCacheProcessor = false; 36 | for (AnnotationProcessor processor: processors) { 37 | Class clazz = processor.getClass(); 38 | if (clazz.equals(EVCacheAnnotationProcessor.class)) { 39 | hasEVCacheProcessor = true; 40 | break; 41 | } 42 | } 43 | assertTrue(hasEVCacheProcessor); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ribbon-evcache/src/test/java/com/netflix/ribbon/proxy/sample/EvCacheClasses.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.proxy.sample; 18 | 19 | import com.netflix.evcache.EVCacheTranscoder; 20 | import net.spy.memcached.CachedData; 21 | 22 | /** 23 | * @author Tomasz Bak 24 | */ 25 | public class EvCacheClasses { 26 | 27 | public static class SampleEVCacheTranscoder implements EVCacheTranscoder { 28 | 29 | @Override 30 | public boolean asyncDecode(CachedData d) { 31 | return false; 32 | } 33 | 34 | @Override 35 | public CachedData encode(Object o) { 36 | return null; 37 | } 38 | 39 | @Override 40 | public Object decode(CachedData d) { 41 | return null; 42 | } 43 | 44 | @Override 45 | public int getMaxSize() { 46 | return 0; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ribbon-evcache/src/test/java/com/netflix/ribbon/proxy/sample/HystrixHandlers.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.proxy.sample; 18 | 19 | import com.netflix.hystrix.HystrixInvokableInfo; 20 | import com.netflix.ribbon.ServerError; 21 | import com.netflix.ribbon.UnsuccessfulResponseException; 22 | import com.netflix.ribbon.http.HttpResponseValidator; 23 | import com.netflix.ribbon.hystrix.FallbackHandler; 24 | import io.netty.buffer.ByteBuf; 25 | import io.reactivex.netty.protocol.http.client.HttpClientResponse; 26 | import rx.Observable; 27 | 28 | import java.util.Map; 29 | 30 | /** 31 | * @author Tomasz Bak 32 | */ 33 | public class HystrixHandlers { 34 | 35 | public static class SampleHttpResponseValidator implements HttpResponseValidator { 36 | 37 | @Override 38 | public void validate(HttpClientResponse response) throws UnsuccessfulResponseException, ServerError { 39 | } 40 | } 41 | 42 | public static class MovieFallbackHandler implements FallbackHandler { 43 | 44 | @Override 45 | public Observable getFallback(HystrixInvokableInfo hystrixInfo, Map requestProperties) { 46 | return null; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ribbon-evcache/src/test/java/com/netflix/ribbon/proxy/sample/Movie.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.proxy.sample; 2 | 3 | /** 4 | * @author Tomasz Bak 5 | */ 6 | public class Movie { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /ribbon-evcache/src/test/java/com/netflix/ribbon/proxy/sample/MovieTransformer.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.proxy.sample; 18 | 19 | import io.netty.buffer.ByteBuf; 20 | import io.netty.buffer.ByteBufAllocator; 21 | import io.reactivex.netty.channel.ContentTransformer; 22 | 23 | /** 24 | * @author Tomasz Bak 25 | */ 26 | public class MovieTransformer implements ContentTransformer { 27 | @Override 28 | public ByteBuf call(MovieTransformer toTransform, ByteBufAllocator byteBufAllocator) { 29 | return null; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ribbon-evcache/src/test/java/com/netflix/ribbon/proxy/sample/ResourceGroupClasses.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.proxy.sample; 2 | 3 | import com.netflix.ribbon.http.HttpResourceGroup; 4 | 5 | /** 6 | * @author Tomasz Bak 7 | */ 8 | public class ResourceGroupClasses { 9 | public static class SampleHttpResourceGroup extends HttpResourceGroup { 10 | public SampleHttpResourceGroup() { 11 | super("myTestGroup"); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ribbon-evcache/src/test/java/com/netflix/ribbon/proxy/sample/SampleCacheProviderFactory.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.proxy.sample; 18 | 19 | import com.netflix.ribbon.CacheProvider; 20 | import com.netflix.ribbon.CacheProviderFactory; 21 | import rx.Observable; 22 | 23 | import java.util.Map; 24 | 25 | /** 26 | * @author Tomasz Bak 27 | */ 28 | public class SampleCacheProviderFactory implements CacheProviderFactory { 29 | 30 | @Override 31 | public CacheProvider createCacheProvider() { 32 | return new SampleCacheProvider(); 33 | } 34 | 35 | public static class SampleCacheProvider implements CacheProvider { 36 | 37 | @Override 38 | public Observable get(String key, Map requestProperties) { 39 | return null; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ribbon-examples/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api project(':ribbon-core') 3 | api project(':ribbon-httpclient') 4 | api project(':ribbon-transport') 5 | api project(':ribbon-loadbalancer') 6 | api project(':ribbon') 7 | api "io.reactivex:rxjava:${rx_java_version}" 8 | api "io.reactivex:rxnetty:${rx_netty_version}" 9 | api "com.netflix.hystrix:hystrix-core:${hystrix_version}" 10 | api 'javax.ws.rs:jsr311-api:1.1.1' 11 | api 'com.google.code.findbugs:annotations:2.0.0' 12 | api 'org.codehaus.jackson:jackson-mapper-asl:1.9.11' 13 | api 'com.thoughtworks.xstream:xstream:1.4.5' 14 | api "com.sun.jersey:jersey-server:${jersey_version}" 15 | api "com.google.guava:guava:${guava_version}" 16 | api "com.netflix.archaius:archaius-core:${archaius_version}" 17 | testImplementation 'junit:junit:4.11' 18 | } 19 | -------------------------------------------------------------------------------- /ribbon-examples/src/main/java/com/netflix/ribbon/examples/ExampleAppWithLocalResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.ribbon.examples; 19 | 20 | import java.util.Random; 21 | import java.util.concurrent.ExecutorService; 22 | import java.util.concurrent.Executors; 23 | 24 | import com.sun.jersey.api.container.httpserver.HttpServerFactory; 25 | import com.sun.jersey.api.core.PackagesResourceConfig; 26 | import com.sun.net.httpserver.HttpServer; 27 | 28 | /** 29 | * A base class for some sample applications that starts and stops a local server 30 | * 31 | * @author awang 32 | * 33 | */ 34 | public abstract class ExampleAppWithLocalResource { 35 | 36 | public int port = (new Random()).nextInt(1000) + 4000; 37 | public String SERVICE_URI = "http://localhost:" + port + "/"; 38 | HttpServer server = null; 39 | 40 | public abstract void run() throws Exception; 41 | 42 | @edu.umd.cs.findbugs.annotations.SuppressWarnings 43 | public final void runApp() throws Exception { 44 | PackagesResourceConfig resourceConfig = new PackagesResourceConfig("com.netflix.ribbon.examples.server"); 45 | ExecutorService service = Executors.newFixedThreadPool(50); 46 | try{ 47 | server = HttpServerFactory.create(SERVICE_URI, resourceConfig); 48 | server.setExecutor(service); 49 | server.start(); 50 | run(); 51 | } finally { 52 | System.err.println("Shut down server ..."); 53 | if (server != null) { 54 | server.stop(1); 55 | } 56 | service.shutdownNow(); 57 | } 58 | System.exit(0); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ribbon-examples/src/main/java/com/netflix/ribbon/examples/netty/http/LoadBalancingExample.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.examples.netty.http; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.reactivex.netty.protocol.http.client.HttpClientRequest; 5 | import io.reactivex.netty.protocol.http.client.HttpClientResponse; 6 | 7 | import java.util.List; 8 | import java.util.concurrent.CountDownLatch; 9 | 10 | import rx.Observer; 11 | 12 | import com.google.common.collect.Lists; 13 | import com.netflix.ribbon.transport.netty.RibbonTransport; 14 | import com.netflix.ribbon.transport.netty.http.LoadBalancingHttpClient; 15 | import com.netflix.loadbalancer.BaseLoadBalancer; 16 | import com.netflix.loadbalancer.LoadBalancerBuilder; 17 | import com.netflix.loadbalancer.Server; 18 | 19 | 20 | public class LoadBalancingExample { 21 | public static void main(String[] args) throws Exception { 22 | List servers = Lists.newArrayList(new Server("www.google.com:80"), new Server("www.examples.com:80"), new Server("www.wikipedia.org:80")); 23 | BaseLoadBalancer lb = LoadBalancerBuilder.newBuilder() 24 | .buildFixedServerListLoadBalancer(servers); 25 | 26 | LoadBalancingHttpClient client = RibbonTransport.newHttpClient(lb); 27 | final CountDownLatch latch = new CountDownLatch(servers.size()); 28 | Observer> observer = new Observer>() { 29 | @Override 30 | public void onCompleted() { 31 | } 32 | 33 | @Override 34 | public void onError(Throwable e) { 35 | e.printStackTrace(); 36 | } 37 | 38 | @Override 39 | public void onNext(HttpClientResponse args) { 40 | latch.countDown(); 41 | System.out.println("Got response: " + args.getStatus()); 42 | } 43 | }; 44 | for (int i = 0; i < servers.size(); i++) { 45 | HttpClientRequest request = HttpClientRequest.createGet("/"); 46 | client.submit(request).subscribe(observer); 47 | } 48 | latch.await(); 49 | System.out.println(lb.getLoadBalancerStats()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ribbon-examples/src/main/java/com/netflix/ribbon/examples/netty/http/SimpleGet.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.examples.netty.http; 2 | 3 | import com.netflix.ribbon.transport.netty.RibbonTransport; 4 | import com.netflix.ribbon.transport.netty.http.LoadBalancingHttpClient; 5 | import io.netty.buffer.ByteBuf; 6 | import io.reactivex.netty.protocol.http.client.HttpClientRequest; 7 | import io.reactivex.netty.protocol.http.client.HttpClientResponse; 8 | import rx.functions.Action1; 9 | 10 | import java.nio.charset.Charset; 11 | import java.util.concurrent.CountDownLatch; 12 | import java.util.concurrent.TimeUnit; 13 | 14 | public class SimpleGet { 15 | @edu.umd.cs.findbugs.annotations.SuppressWarnings 16 | public static void main(String[] args) throws Exception { 17 | LoadBalancingHttpClient client = RibbonTransport.newHttpClient(); 18 | HttpClientRequest request = HttpClientRequest.createGet("http://www.google.com/"); 19 | final CountDownLatch latch = new CountDownLatch(1); 20 | client.submit(request) 21 | .toBlocking() 22 | .forEach(new Action1>() { 23 | @Override 24 | public void call(HttpClientResponse t1) { 25 | System.out.println("Status code: " + t1.getStatus()); 26 | t1.getContent().subscribe(new Action1() { 27 | 28 | @Override 29 | public void call(ByteBuf content) { 30 | System.out.println("Response content: " + content.toString(Charset.defaultCharset())); 31 | latch.countDown(); 32 | } 33 | 34 | }); 35 | } 36 | }); 37 | latch.await(2, TimeUnit.SECONDS); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ribbon-examples/src/main/java/com/netflix/ribbon/examples/rx/README.md: -------------------------------------------------------------------------------- 1 | This example contains implementation of a simple movie service. Three different clients are implemented with 2 | equivalent functionality, but on top of different Ribbon API layers: 3 | 4 | Example | Description 5 | --------|------------- 6 | [RxMovieProxyExample](proxy) | Ribbon proxy based implementation. 7 | [RxMovieTemplateExample](template) | Ribbon template based implementation. 8 | [RxMovieTransportExample](transport) | An implementation using directly RxNetty load balancing HTTP client. 9 | 10 | Before running any of those examples, [RxMovieServer](RxMovieServer.java) must be started first. 11 | -------------------------------------------------------------------------------- /ribbon-examples/src/main/java/com/netflix/ribbon/examples/rx/common/InMemoryCacheProviderFactory.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.examples.rx.common; 18 | 19 | import com.netflix.ribbon.CacheProvider; 20 | import com.netflix.ribbon.CacheProviderFactory; 21 | import rx.Observable; 22 | 23 | import java.util.Map; 24 | import java.util.concurrent.ConcurrentHashMap; 25 | 26 | /** 27 | * @author Tomasz Bak 28 | */ 29 | public class InMemoryCacheProviderFactory implements CacheProviderFactory { 30 | 31 | @Override 32 | public CacheProvider createCacheProvider() { 33 | return new InMemoryCacheProvider(); 34 | } 35 | 36 | public static class InMemoryCacheProvider implements CacheProvider { 37 | private final Map cacheMap = new ConcurrentHashMap(); 38 | 39 | @Override 40 | public Observable get(String key, Map requestProperties) { 41 | return null; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ribbon-examples/src/main/java/com/netflix/ribbon/examples/rx/common/RecommendationServiceFallbackHandler.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.examples.rx.common; 18 | 19 | import com.netflix.hystrix.HystrixInvokableInfo; 20 | import com.netflix.ribbon.hystrix.FallbackHandler; 21 | import io.netty.buffer.ByteBuf; 22 | import io.netty.buffer.UnpooledByteBufAllocator; 23 | import rx.Observable; 24 | 25 | import java.nio.charset.Charset; 26 | import java.util.Map; 27 | 28 | /** 29 | * @author Tomasz Bak 30 | */ 31 | public class RecommendationServiceFallbackHandler implements FallbackHandler { 32 | @Override 33 | public Observable getFallback(HystrixInvokableInfo hystrixInfo, Map requestProperties) { 34 | byte[] bytes = Movie.ORANGE_IS_THE_NEW_BLACK.toString().getBytes(Charset.defaultCharset()); 35 | ByteBuf byteBuf = UnpooledByteBufAllocator.DEFAULT.buffer(bytes.length); 36 | byteBuf.writeBytes(bytes); 37 | return Observable.just(byteBuf); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ribbon-examples/src/main/java/com/netflix/ribbon/examples/rx/common/RecommendationServiceResponseValidator.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.examples.rx.common; 18 | 19 | import com.netflix.ribbon.ServerError; 20 | import com.netflix.ribbon.UnsuccessfulResponseException; 21 | import com.netflix.ribbon.http.HttpResponseValidator; 22 | import io.netty.buffer.ByteBuf; 23 | import io.reactivex.netty.protocol.http.client.HttpClientResponse; 24 | 25 | /** 26 | * @author Tomasz Bak 27 | */ 28 | public class RecommendationServiceResponseValidator implements HttpResponseValidator { 29 | @Override 30 | public void validate(HttpClientResponse response) throws UnsuccessfulResponseException, ServerError { 31 | if (response.getStatus().code() / 100 != 2) { 32 | throw new UnsuccessfulResponseException("Unexpected HTTP status code " + response.getStatus()); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ribbon-examples/src/main/java/com/netflix/ribbon/examples/rx/common/RxMovieTransformer.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.examples.rx.common; 18 | 19 | import io.netty.buffer.ByteBuf; 20 | import io.netty.buffer.ByteBufAllocator; 21 | import io.reactivex.netty.channel.ContentTransformer; 22 | 23 | import java.nio.charset.Charset; 24 | 25 | /** 26 | * @author Tomasz Bak 27 | */ 28 | public class RxMovieTransformer implements ContentTransformer { 29 | @Override 30 | public ByteBuf call(Movie movie, ByteBufAllocator byteBufAllocator) { 31 | byte[] bytes = movie.toString().getBytes(Charset.defaultCharset()); 32 | ByteBuf byteBuf = byteBufAllocator.buffer(bytes.length); 33 | byteBuf.writeBytes(bytes); 34 | return byteBuf; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ribbon-examples/src/main/resources/sample-client.properties: -------------------------------------------------------------------------------- 1 | # Max number of retries on the same server (excluding the first try) 2 | sample-client.ribbon.MaxAutoRetries=1 3 | 4 | # Max number of next servers to retry (excluding the first server) 5 | sample-client.ribbon.MaxAutoRetriesNextServer=1 6 | 7 | # Whether all operations can be retried for this client 8 | sample-client.ribbon.OkToRetryOnAllOperations=true 9 | 10 | # Interval to refresh the server list from the source 11 | sample-client.ribbon.ServerListRefreshInterval=2000 12 | 13 | # Connect timeout used by Apache HttpClient 14 | sample-client.ribbon.ConnectTimeout=3000 15 | 16 | # Read timeout used by Apache HttpClient 17 | sample-client.ribbon.ReadTimeout=3000 18 | 19 | # Initial list of servers, can be changed via Archaius dynamic property at runtime 20 | sample-client.ribbon.listOfServers=www.microsoft.com:80,www.yahoo.com:80,www.google.com:80 21 | 22 | sample-client.ribbon.EnablePrimeConnections=true 23 | 24 | -------------------------------------------------------------------------------- /ribbon-examples/src/test/java/com/netflix/ribbon/examples/rx/RxMovieClientTestBase.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.examples.rx; 17 | 18 | import io.netty.buffer.ByteBuf; 19 | import io.reactivex.netty.protocol.http.server.HttpServer; 20 | 21 | import org.junit.After; 22 | import org.junit.Before; 23 | 24 | /** 25 | * @author Tomasz Bak 26 | */ 27 | public class RxMovieClientTestBase { 28 | protected int port = 0; 29 | 30 | private RxMovieServer movieServer; 31 | 32 | private HttpServer httpServer; 33 | 34 | @Before 35 | public void setUp() throws Exception { 36 | movieServer = new RxMovieServer(port); 37 | httpServer = movieServer.createServer().start(); 38 | port = httpServer.getServerPort(); 39 | } 40 | 41 | @After 42 | public void tearDown() throws Exception { 43 | httpServer.shutdown(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ribbon-examples/src/test/java/com/netflix/ribbon/examples/rx/common/MovieTest.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.examples.rx.common; 18 | 19 | import org.junit.Test; 20 | 21 | import static com.netflix.ribbon.examples.rx.common.Movie.*; 22 | import static org.junit.Assert.*; 23 | 24 | /** 25 | * @author Tomasz Bak 26 | */ 27 | public class MovieTest { 28 | 29 | @Test 30 | public void testStringParsing() { 31 | Movie fromString = Movie.from(ORANGE_IS_THE_NEW_BLACK.toString()); 32 | assertEquals(ORANGE_IS_THE_NEW_BLACK, fromString); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ribbon-examples/src/test/java/com/netflix/ribbon/examples/rx/common/RecommendationsTest.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.examples.rx.common; 18 | 19 | import org.junit.Test; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | import static junit.framework.Assert.*; 25 | 26 | /** 27 | * @author Tomasz Bak 28 | */ 29 | public class RecommendationsTest { 30 | 31 | @Test 32 | public void testStringParsing() throws Exception { 33 | List movies = new ArrayList(); 34 | movies.add(Movie.ORANGE_IS_THE_NEW_BLACK); 35 | movies.add(Movie.BREAKING_BAD); 36 | Recommendations recommendations = new Recommendations(movies); 37 | Recommendations fromString = Recommendations.from(recommendations.toString()); 38 | assertEquals(recommendations, fromString); 39 | } 40 | } -------------------------------------------------------------------------------- /ribbon-examples/src/test/java/com/netflix/ribbon/examples/rx/proxy/RxMovieProxyExampleTest.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.examples.rx.proxy; 17 | 18 | import com.netflix.ribbon.examples.rx.RxMovieClientTestBase; 19 | import org.junit.Test; 20 | 21 | import static junit.framework.Assert.*; 22 | 23 | /** 24 | * @author Tomasz Bak 25 | */ 26 | public class RxMovieProxyExampleTest extends RxMovieClientTestBase { 27 | 28 | @Test 29 | public void testProxyExample() throws Exception { 30 | assertTrue(new RxMovieProxyExample(port).runExample()); 31 | } 32 | } -------------------------------------------------------------------------------- /ribbon-examples/src/test/java/com/netflix/ribbon/examples/rx/template/RxMovieTemplateExampleTest.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.examples.rx.template; 17 | 18 | import com.netflix.ribbon.examples.rx.RxMovieClientTestBase; 19 | import org.junit.Test; 20 | 21 | import static junit.framework.Assert.*; 22 | 23 | /** 24 | * @author Tomasz Bak 25 | */ 26 | public class RxMovieTemplateExampleTest extends RxMovieClientTestBase { 27 | 28 | @Test 29 | public void testTemplateExample() throws Exception { 30 | assertTrue(new RxMovieTemplateExample(port).runExample()); 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /ribbon-examples/src/test/java/com/netflix/ribbon/examples/rx/transport/RxMovieTransportExampleTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.examples.rx.transport; 2 | 3 | import com.netflix.ribbon.examples.rx.RxMovieClientTestBase; 4 | import org.junit.Test; 5 | 6 | import static junit.framework.Assert.*; 7 | 8 | /** 9 | * @author Tomasz Bak 10 | */ 11 | public class RxMovieTransportExampleTest extends RxMovieClientTestBase { 12 | 13 | @Test 14 | public void testTemplateExample() throws Exception { 15 | assertTrue(new RxMovieTransportExample(port).runExample()); 16 | } 17 | } -------------------------------------------------------------------------------- /ribbon-guice/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api project(':ribbon-core') 3 | api project(':ribbon-transport') 4 | api project(':ribbon') 5 | api 'com.google.inject:guice:4.0' 6 | api 'com.google.inject.extensions:guice-multibindings:4.0' 7 | testImplementation 'junit:junit:4.11' 8 | testImplementation "io.reactivex:rxjava:${rx_java_version}" 9 | testImplementation "io.reactivex:rxnetty:${rx_netty_version}" 10 | testImplementation (project(':ribbon-examples')) {transitive=false} 11 | testImplementation "com.netflix.archaius:archaius-core:${archaius_version}" 12 | } 13 | -------------------------------------------------------------------------------- /ribbon-guice/src/main/java/com/netflix/ribbon/guice/RibbonModule.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.guice; 17 | 18 | import com.google.inject.AbstractModule; 19 | import com.google.inject.Scopes; 20 | import com.netflix.client.config.ClientConfigFactory; 21 | import com.netflix.ribbon.DefaultResourceFactory; 22 | import com.netflix.ribbon.RibbonResourceFactory; 23 | import com.netflix.ribbon.RibbonTransportFactory; 24 | import com.netflix.ribbon.RibbonTransportFactory.DefaultRibbonTransportFactory; 25 | import com.netflix.ribbon.proxy.processor.AnnotationProcessorsProvider; 26 | import com.netflix.ribbon.proxy.processor.AnnotationProcessorsProvider.DefaultAnnotationProcessorsProvider; 27 | 28 | /** 29 | * Default bindings for Ribbon 30 | * 31 | * @author elandau 32 | * 33 | */ 34 | public class RibbonModule extends AbstractModule { 35 | @Override 36 | protected void configure() { 37 | bind(ClientConfigFactory.class).toInstance(ClientConfigFactory.DEFAULT); 38 | bind(RibbonTransportFactory.class).to(DefaultRibbonTransportFactory.class).in(Scopes.SINGLETON); 39 | bind(AnnotationProcessorsProvider.class).to(DefaultAnnotationProcessorsProvider.class).in(Scopes.SINGLETON); 40 | bind(RibbonResourceFactory.class).to(DefaultResourceFactory.class).in(Scopes.SINGLETON); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ribbon-guice/src/main/java/com/netflix/ribbon/guice/RibbonResourceProvider.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.guice; 17 | 18 | import com.google.inject.Inject; 19 | import com.google.inject.spi.BindingTargetVisitor; 20 | import com.google.inject.spi.ProviderInstanceBinding; 21 | import com.google.inject.spi.ProviderWithExtensionVisitor; 22 | import com.google.inject.spi.Toolable; 23 | import com.netflix.ribbon.RibbonResourceFactory; 24 | 25 | /** 26 | * Guice Provider extension to create a ribbon resource from an injectable 27 | * RibbonResourceFactory. 28 | * 29 | * @author elandau 30 | * 31 | * @param Type of the client API interface class 32 | */ 33 | public class RibbonResourceProvider implements ProviderWithExtensionVisitor { 34 | 35 | private RibbonResourceFactory factory; 36 | private final Class contract; 37 | 38 | public RibbonResourceProvider(Class contract) { 39 | this.contract = contract; 40 | } 41 | 42 | @Override 43 | public T get() { 44 | // TODO: Get name from annotations (not only class name of contract) 45 | return factory.from(contract); 46 | } 47 | 48 | /** 49 | * This is needed for 'initialize(injector)' below to be called so the provider 50 | * can get the injector after it is instantiated. 51 | */ 52 | @Override 53 | public V acceptExtensionVisitor( 54 | BindingTargetVisitor visitor, 55 | ProviderInstanceBinding binding) { 56 | return visitor.visit(binding); 57 | } 58 | 59 | @Inject 60 | @Toolable 61 | protected void initialize(RibbonResourceFactory factory) { 62 | this.factory = factory; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /ribbon-guice/src/test/java/com/netflix/ribbon/examples/rx/RxMovieClientTestBase.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.examples.rx; 17 | 18 | import io.netty.buffer.ByteBuf; 19 | import io.reactivex.netty.protocol.http.server.HttpServer; 20 | 21 | import org.junit.After; 22 | import org.junit.Before; 23 | 24 | /** 25 | * @author Tomasz Bak 26 | */ 27 | public class RxMovieClientTestBase { 28 | protected int port = 0; 29 | 30 | private RxMovieServer movieServer; 31 | 32 | private HttpServer httpServer; 33 | 34 | @Before 35 | public void setUp() throws Exception { 36 | movieServer = new RxMovieServer(port); 37 | httpServer = movieServer.createServer().start(); 38 | port = httpServer.getServerPort(); 39 | } 40 | 41 | @After 42 | public void tearDown() throws Exception { 43 | httpServer.shutdown(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ribbon-guice/src/test/java/com/netflix/ribbon/examples/rx/proxy/RxMovieProxyExample.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.examples.rx.proxy; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | 5 | import javax.inject.Inject; 6 | 7 | import rx.Observable; 8 | 9 | import com.google.inject.Singleton; 10 | import com.netflix.ribbon.examples.rx.AbstractRxMovieClient; 11 | import com.netflix.ribbon.examples.rx.common.Movie; 12 | import com.netflix.ribbon.examples.rx.proxy.MovieService; 13 | import com.netflix.ribbon.proxy.ProxyLifeCycle; 14 | 15 | @Singleton 16 | public class RxMovieProxyExample extends AbstractRxMovieClient { 17 | 18 | private final MovieService movieService; 19 | 20 | @Inject 21 | public RxMovieProxyExample(MovieService movieService) { 22 | this.movieService = movieService; 23 | } 24 | 25 | @SuppressWarnings("unchecked") 26 | @Override 27 | protected Observable[] triggerMoviesRegistration() { 28 | return new Observable[]{ 29 | movieService.registerMovie(Movie.ORANGE_IS_THE_NEW_BLACK).toObservable(), 30 | movieService.registerMovie(Movie.BREAKING_BAD).toObservable(), 31 | movieService.registerMovie(Movie.HOUSE_OF_CARDS).toObservable() 32 | }; 33 | } 34 | 35 | @SuppressWarnings("unchecked") 36 | @Override 37 | protected Observable[] triggerRecommendationsUpdate() { 38 | return new Observable[]{ 39 | movieService.updateRecommendations(TEST_USER, Movie.ORANGE_IS_THE_NEW_BLACK.getId()).toObservable(), 40 | movieService.updateRecommendations(TEST_USER, Movie.BREAKING_BAD.getId()).toObservable() 41 | }; 42 | } 43 | 44 | @SuppressWarnings("unchecked") 45 | @Override 46 | protected Observable[] triggerRecommendationsSearch() { 47 | return new Observable[]{ 48 | movieService.recommendationsByUserId(TEST_USER).toObservable(), 49 | movieService.recommendationsBy("Drama", "Adults").toObservable() 50 | }; 51 | } 52 | 53 | @Override 54 | public void shutdown() { 55 | super.shutdown(); 56 | ((ProxyLifeCycle) movieService).shutdown(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ribbon-httpclient/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api project(':ribbon-core') 3 | api project(':ribbon-loadbalancer') 4 | api 'commons-collections:commons-collections:3.2.2' 5 | api 'org.apache.httpcomponents:httpclient:4.2.1' 6 | api 'com.google.code.findbugs:annotations:2.0.0' 7 | api "com.sun.jersey:jersey-client:${jersey_version}" 8 | api "com.sun.jersey.contribs:jersey-apache-client4:${jersey_version}" 9 | api "org.slf4j:slf4j-api:${slf4j_version}" 10 | api "com.netflix.servo:servo-core:${servo_version}" 11 | api "com.google.guava:guava:${guava_version}" 12 | api 'com.netflix.netflix-commons:netflix-commons-util:0.1.1' 13 | testImplementation 'junit:junit:4.11' 14 | testImplementation "org.slf4j:slf4j-log4j12:${slf4j_version}" 15 | testImplementation 'commons-io:commons-io:2.0.1' 16 | testImplementation "com.sun.jersey:jersey-server:${jersey_version}" 17 | testImplementation 'com.google.mockwebserver:mockwebserver:20130505' 18 | testImplementation 'com.fasterxml.jackson.core:jackson-databind:2.4.3' 19 | testImplementation project(':ribbon-archaius') 20 | testImplementation project(":ribbon-loadbalancer").sourceSets.test.output 21 | } 22 | -------------------------------------------------------------------------------- /ribbon-httpclient/src/main/java/com/netflix/client/http/HttpHeaders.java: -------------------------------------------------------------------------------- 1 | package com.netflix.client.http; 2 | 3 | import java.util.List; 4 | import java.util.Map.Entry; 5 | 6 | public interface HttpHeaders { 7 | 8 | public String getFirstValue(String headerName); 9 | 10 | public List getAllValues(String headerName); 11 | 12 | public List> getAllHeaders(); 13 | 14 | public boolean containsHeader(String name); 15 | } 16 | -------------------------------------------------------------------------------- /ribbon-httpclient/src/main/java/com/netflix/client/http/HttpResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.client.http; 19 | 20 | import com.google.common.reflect.TypeToken; 21 | import com.netflix.client.IResponse; 22 | 23 | import java.io.Closeable; 24 | import java.io.InputStream; 25 | import java.lang.reflect.Type; 26 | import java.util.Collection; 27 | import java.util.Map; 28 | 29 | /** 30 | * Response for HTTP communication. 31 | * 32 | * @author awang 33 | * 34 | */ 35 | public interface HttpResponse extends IResponse, Closeable { 36 | /** 37 | * Get the HTTP status code. 38 | */ 39 | public int getStatus(); 40 | 41 | /** 42 | * Get the reason phrase of HTTP status 43 | */ 44 | public String getStatusLine(); 45 | 46 | /** 47 | * @see #getHttpHeaders() 48 | */ 49 | @Override 50 | @Deprecated 51 | public Map> getHeaders(); 52 | 53 | public HttpHeaders getHttpHeaders(); 54 | 55 | public void close(); 56 | 57 | public InputStream getInputStream(); 58 | 59 | public boolean hasEntity(); 60 | 61 | public T getEntity(Class type) throws Exception; 62 | 63 | public T getEntity(Type type) throws Exception; 64 | 65 | /** 66 | * @deprecated use {@link #getEntity(Type)} 67 | */ 68 | @Deprecated 69 | public T getEntity(TypeToken type) throws Exception; 70 | } 71 | -------------------------------------------------------------------------------- /ribbon-httpclient/src/test/java/com/netflix/niws/client/http/TestObject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.niws.client.http; 19 | 20 | import javax.xml.bind.annotation.XmlRootElement; 21 | 22 | @XmlRootElement 23 | public class TestObject { 24 | public String name; 25 | } 26 | -------------------------------------------------------------------------------- /ribbon-httpclient/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootCategory=INFO,stdout 2 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d %-5p %C:%L [%t] [%M] %m%n 5 | -------------------------------------------------------------------------------- /ribbon-httpclient/src/test/resources/sample-client.properties: -------------------------------------------------------------------------------- 1 | # Max number of retries on the same server (excluding the first try) 2 | sample-client.ribbon.MaxAutoRetries=1 3 | 4 | # Max number of next servers to retry (excluding the first server) 5 | sample-client.ribbon.MaxAutoRetriesNextServer=1 6 | 7 | # Whether all operations can be retried for this client 8 | sample-client.ribbon.OkToRetryOnAllOperations=true 9 | 10 | # Interval to refresh the server list from the source 11 | sample-client.ribbon.ServerListRefreshInterval=2000 12 | 13 | # Connect timeout used by Apache HttpClient 14 | sample-client.ribbon.ConnectTimeout=3000 15 | 16 | # Read timeout used by Apache HttpClient 17 | sample-client.ribbon.ReadTimeout=3000 18 | 19 | # Initial list of servers, can be changed via Archaius dynamic property at runtime 20 | sample-client.ribbon.listOfServers=www.microsoft.com:80,www.yahoo.com:80,www.google.com:80 21 | 22 | sample-client.ribbon.EnablePrimeConnections=true 23 | 24 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api project(':ribbon-core') 3 | api 'com.netflix.netflix-commons:netflix-statistics:0.1.1' 4 | api "io.reactivex:rxjava:${rx_java_version}" 5 | api "org.slf4j:slf4j-api:${slf4j_version}" 6 | api "com.netflix.servo:servo-core:${servo_version}" 7 | api "com.google.guava:guava:${guava_version}" 8 | api 'com.netflix.netflix-commons:netflix-commons-util:0.1.1' 9 | 10 | testImplementation project(":ribbon-archaius") 11 | testImplementation 'junit:junit:4.11' 12 | testImplementation 'org.mockito:mockito-core:2.13.0' 13 | testImplementation 'org.awaitility:awaitility:3.0.0' 14 | testImplementation "org.slf4j:slf4j-log4j12:${slf4j_version}" 15 | testImplementation "com.sun.jersey:jersey-server:${jersey_version}" 16 | } 17 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/client/IPrimeConnection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.client; 19 | 20 | import com.netflix.loadbalancer.Server; 21 | 22 | /** 23 | * Interface that defines operation for priming a connection. 24 | * 25 | * @author awang 26 | * 27 | */ 28 | public interface IPrimeConnection extends IClientConfigAware { 29 | 30 | /** 31 | * Sub classes should implement protocol specific operation to connect 32 | * to a server. 33 | * 34 | * @param server Server to connect 35 | * @param uriPath URI to use in server connection 36 | * @return if the priming is successful 37 | * @throws Exception Any network errors 38 | */ 39 | public boolean connect(Server server, String uriPath) throws Exception; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/AbstractLoadBalancer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | import java.util.List; 21 | 22 | /** 23 | * AbstractLoadBalancer contains features required for most loadbalancing 24 | * implementations. 25 | * 26 | * An anatomy of a typical LoadBalancer consists of 1. A List of Servers (nodes) 27 | * that are potentially bucketed based on a specific criteria. 2. A Class that 28 | * defines and implements a LoadBalacing Strategy via IRule 3. A 29 | * Class that defines and implements a mechanism to determine the 30 | * suitability/availability of the nodes/servers in the List. 31 | * 32 | * 33 | * @author stonse 34 | * 35 | */ 36 | public abstract class AbstractLoadBalancer implements ILoadBalancer { 37 | 38 | public enum ServerGroup{ 39 | ALL, 40 | STATUS_UP, 41 | STATUS_NOT_UP 42 | } 43 | 44 | /** 45 | * delegate to {@link #chooseServer(Object)} with parameter null. 46 | */ 47 | public Server chooseServer() { 48 | return chooseServer(null); 49 | } 50 | 51 | 52 | /** 53 | * List of servers that this Loadbalancer knows about 54 | * 55 | * @param serverGroup Servers grouped by status, e.g., {@link ServerGroup#STATUS_UP} 56 | */ 57 | public abstract List getServerList(ServerGroup serverGroup); 58 | 59 | /** 60 | * Obtain LoadBalancer related Statistics 61 | */ 62 | public abstract LoadBalancerStats getLoadBalancerStats(); 63 | } 64 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/AbstractLoadBalancerPing.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | import com.netflix.client.IClientConfigAware; 21 | 22 | /** 23 | * Class that provides the basic implementation of detmerining the "liveness" or 24 | * suitability of a Server (a node) 25 | * 26 | * @author stonse 27 | * 28 | */ 29 | public abstract class AbstractLoadBalancerPing implements IPing, IClientConfigAware{ 30 | 31 | AbstractLoadBalancer lb; 32 | 33 | @Override 34 | public boolean isAlive(Server server) { 35 | return true; 36 | } 37 | 38 | public void setLoadBalancer(AbstractLoadBalancer lb){ 39 | this.lb = lb; 40 | } 41 | 42 | public AbstractLoadBalancer getLoadBalancer(){ 43 | return lb; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/AbstractLoadBalancerRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | import com.netflix.client.IClientConfigAware; 21 | 22 | /** 23 | * Class that provides a default implementation for setting and getting load balancer 24 | * @author stonse 25 | * 26 | */ 27 | public abstract class AbstractLoadBalancerRule implements IRule, IClientConfigAware { 28 | 29 | private ILoadBalancer lb; 30 | 31 | @Override 32 | public void setLoadBalancer(ILoadBalancer lb){ 33 | this.lb = lb; 34 | } 35 | 36 | @Override 37 | public ILoadBalancer getLoadBalancer(){ 38 | return lb; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/AbstractServerListFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | 21 | /** 22 | * Class that is responsible to Filter out list of servers from the ones 23 | * currently available in the Load Balancer 24 | * @author stonse 25 | * 26 | * @param 27 | */ 28 | public abstract class AbstractServerListFilter implements ServerListFilter { 29 | 30 | private volatile LoadBalancerStats stats; 31 | 32 | public void setLoadBalancerStats(LoadBalancerStats stats) { 33 | this.stats = stats; 34 | } 35 | 36 | public LoadBalancerStats getLoadBalancerStats() { 37 | return stats; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/ClientConfigEnabledRoundRobinRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | import com.netflix.client.config.IClientConfig; 21 | 22 | /** 23 | * This class essentially contains the RoundRobinRule class defined in the 24 | * loadbalancer package 25 | * 26 | * @author stonse 27 | * 28 | */ 29 | public class ClientConfigEnabledRoundRobinRule extends AbstractLoadBalancerRule { 30 | 31 | RoundRobinRule roundRobinRule = new RoundRobinRule(); 32 | 33 | @Override 34 | public void initWithNiwsConfig(IClientConfig clientConfig) { 35 | roundRobinRule = new RoundRobinRule(); 36 | } 37 | 38 | @Override 39 | public void setLoadBalancer(ILoadBalancer lb) { 40 | super.setLoadBalancer(lb); 41 | roundRobinRule.setLoadBalancer(lb); 42 | } 43 | 44 | @Override 45 | public Server choose(Object key) { 46 | if (roundRobinRule != null) { 47 | return roundRobinRule.choose(key); 48 | } else { 49 | throw new IllegalArgumentException( 50 | "This class has not been initialized with the RoundRobinRule class"); 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/DummyPing.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | import com.netflix.client.config.IClientConfig; 21 | 22 | /** 23 | * Default simple implementation that marks the liveness of a Server 24 | * 25 | * @author stonse 26 | * 27 | */ 28 | public class DummyPing extends AbstractLoadBalancerPing { 29 | 30 | public DummyPing() { 31 | } 32 | 33 | public boolean isAlive(Server server) { 34 | return true; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/IPing.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | /** 21 | * Interface that defines how we "ping" a server to check if its alive 22 | * @author stonse 23 | * 24 | */ 25 | public interface IPing { 26 | 27 | /** 28 | * Checks whether the given Server is "alive" i.e. should be 29 | * considered a candidate while loadbalancing 30 | * 31 | */ 32 | public boolean isAlive(Server server); 33 | } 34 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/IPingStrategy.java: -------------------------------------------------------------------------------- 1 | package com.netflix.loadbalancer; 2 | 3 | /** 4 | * Defines the strategy, used to ping all servers, registered in 5 | * com.netflix.loadbalancer.BaseLoadBalancer. You would 6 | * typically create custom implementation of this interface, if you 7 | * want your servers to be pinged in parallel. Please note, 8 | * that implementations of this interface should be immutable. 9 | * 10 | * @author Dmitry_Cherkas 11 | * @see Server 12 | * @see IPing 13 | */ 14 | public interface IPingStrategy { 15 | 16 | boolean[] pingServers(IPing ping, Server[] servers); 17 | } 18 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/IRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | /** 21 | * Interface that defines a "Rule" for a LoadBalancer. A Rule can be thought of 22 | * as a Strategy for loadbalacing. Well known loadbalancing strategies include 23 | * Round Robin, Response Time based etc. 24 | * 25 | * @author stonse 26 | * 27 | */ 28 | public interface IRule{ 29 | /* 30 | * choose one alive server from lb.allServers or 31 | * lb.upServers according to key 32 | * 33 | * @return choosen Server object. NULL is returned if none 34 | * server is available 35 | */ 36 | 37 | public Server choose(Object key); 38 | 39 | public void setLoadBalancer(ILoadBalancer lb); 40 | 41 | public ILoadBalancer getLoadBalancer(); 42 | } 43 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/InterruptTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | import java.util.Timer; 21 | import java.util.TimerTask; 22 | 23 | public class InterruptTask extends TimerTask { 24 | 25 | static Timer timer = new Timer("InterruptTimer", true); 26 | 27 | protected Thread target = null; 28 | 29 | public InterruptTask(long millis) { 30 | target = Thread.currentThread(); 31 | timer.schedule(this, millis); 32 | } 33 | 34 | 35 | /* Auto-scheduling constructor */ 36 | public InterruptTask(Thread target, long millis) { 37 | this.target = target; 38 | timer.schedule(this, millis); 39 | } 40 | 41 | 42 | public boolean cancel() { 43 | try { 44 | /* This shouldn't throw exceptions, but... */ 45 | return super.cancel(); 46 | } catch (Exception e) { 47 | return false; 48 | } 49 | } 50 | 51 | public void run() { 52 | if ((target != null) && (target.isAlive())) { 53 | target.interrupt(); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/NoOpLoadBalancer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | 26 | /** 27 | * A noOp Loadbalancer 28 | * i.e. doesnt do anything "loadbalancer like" 29 | * 30 | * @author stonse 31 | * 32 | */ 33 | public class NoOpLoadBalancer extends AbstractLoadBalancer { 34 | 35 | static final Logger logger = LoggerFactory.getLogger(NoOpLoadBalancer.class); 36 | 37 | 38 | @Override 39 | public void addServers(List newServers) { 40 | logger.info("addServers to NoOpLoadBalancer ignored"); 41 | } 42 | 43 | @Override 44 | public Server chooseServer(Object key) { 45 | return null; 46 | } 47 | 48 | @Override 49 | public LoadBalancerStats getLoadBalancerStats() { 50 | return null; 51 | } 52 | 53 | 54 | @Override 55 | public List getServerList(ServerGroup serverGroup) { 56 | return Collections.emptyList(); 57 | } 58 | 59 | @Override 60 | public void markServerDown(Server server) { 61 | logger.info("markServerDown to NoOpLoadBalancer ignored"); 62 | } 63 | 64 | @Override 65 | public List getServerList(boolean availableOnly) { 66 | // TODO Auto-generated method stub 67 | return null; 68 | } 69 | 70 | @Override 71 | public List getReachableServers() { 72 | return null; 73 | 74 | } 75 | 76 | @Override 77 | public List getAllServers() { 78 | return null; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/NoOpPing.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | /** 21 | * No Op Ping 22 | * @author stonse 23 | * 24 | */ 25 | public class NoOpPing implements IPing { 26 | 27 | @Override 28 | public boolean isAlive(Server server) { 29 | return true; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/PingConstant.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | /** 21 | * A utility Ping Implementation that returns whatever its been set to return 22 | * (alive or dead) 23 | * @author stonse 24 | * 25 | */ 26 | public class PingConstant implements IPing { 27 | boolean constant = true; 28 | 29 | public void setConstant(String constantStr) { 30 | constant = (constantStr != null) && (constantStr.toLowerCase().equals("true")); 31 | } 32 | 33 | public void setConstant(boolean constant) { 34 | this.constant = constant; 35 | } 36 | 37 | public boolean getConstant() { 38 | return constant; 39 | } 40 | 41 | public boolean isAlive(Server server) { 42 | return constant; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/PredicateBasedRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | import com.google.common.base.Optional; 21 | 22 | /** 23 | * A rule which delegates the server filtering logic to an instance of {@link AbstractServerPredicate}. 24 | * After filtering, a server is returned from filtered list in a round robin fashion. 25 | * 26 | * 27 | * @author awang 28 | * 29 | */ 30 | public abstract class PredicateBasedRule extends ClientConfigEnabledRoundRobinRule { 31 | 32 | /** 33 | * Method that provides an instance of {@link AbstractServerPredicate} to be used by this class. 34 | * 35 | */ 36 | public abstract AbstractServerPredicate getPredicate(); 37 | 38 | /** 39 | * Get a server by calling {@link AbstractServerPredicate#chooseRandomlyAfterFiltering(java.util.List, Object)}. 40 | * The performance for this method is O(n) where n is number of servers to be filtered. 41 | */ 42 | @Override 43 | public Server choose(Object key) { 44 | ILoadBalancer lb = getLoadBalancer(); 45 | Optional server = getPredicate().chooseRoundRobinAfterFiltering(lb.getAllServers(), key); 46 | if (server.isPresent()) { 47 | return server.get(); 48 | } else { 49 | return null; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/PredicateKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | /** 21 | * The input object of predicates of class {@link AbstractServerPredicate}. 22 | * It includes Server and an Object as load balancer key used in {@link IRule#choose(Object)}, 23 | * which might be null. 24 | * 25 | * @author awang 26 | * 27 | */ 28 | public class PredicateKey { 29 | private Object loadBalancerKey; 30 | private Server server; 31 | 32 | public PredicateKey(Object loadBalancerKey, Server server) { 33 | this.loadBalancerKey = loadBalancerKey; 34 | this.server = server; 35 | } 36 | 37 | public PredicateKey(Server server) { 38 | this(null, server); 39 | } 40 | 41 | public final Object getLoadBalancerKey() { 42 | return loadBalancerKey; 43 | } 44 | 45 | public final Server getServer() { 46 | return server; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/ServerComparator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | import java.io.Serializable; 21 | import java.util.Comparator; 22 | 23 | /** 24 | * Class to help establishing equality for Hash/Key operations. 25 | * 26 | * @author stonse 27 | * 28 | */ 29 | public class ServerComparator implements Comparator, Serializable { 30 | /** 31 | * 32 | */ 33 | private static final long serialVersionUID = 1L; 34 | 35 | public int compare(Server s1, Server s2) { 36 | return s1.getHostPort().compareTo(s2.getId()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/ServerList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | import java.util.List; 21 | 22 | /** 23 | * Interface that defines the methods sed to obtain the List of Servers 24 | * @author stonse 25 | * 26 | * @param 27 | */ 28 | public interface ServerList { 29 | 30 | public List getInitialListOfServers(); 31 | 32 | /** 33 | * Return updated list of servers. This is called say every 30 secs 34 | * (configurable) by the Loadbalancer's Ping cycle 35 | * 36 | */ 37 | public List getUpdatedListOfServers(); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/ServerListChangeListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2014 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | import java.util.List; 21 | 22 | public interface ServerListChangeListener { 23 | /** 24 | * Invoked by {@link BaseLoadBalancer} when server list is changed 25 | */ 26 | public void serverListChanged(List oldList, List newList); 27 | } 28 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/ServerListFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | import java.util.List; 21 | 22 | /** 23 | * This interface allows for filtering the configured or dynamically obtained 24 | * List of candidate servers with desirable characteristics. 25 | * 26 | * @author stonse 27 | * 28 | * @param 29 | */ 30 | public interface ServerListFilter { 31 | 32 | public List getFilteredListOfServers(List servers); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/ServerListUpdater.java: -------------------------------------------------------------------------------- 1 | package com.netflix.loadbalancer; 2 | 3 | /** 4 | * strategy for {@link com.netflix.loadbalancer.DynamicServerListLoadBalancer} to use for different ways 5 | * of doing dynamic server list updates. 6 | * 7 | * @author David Liu 8 | */ 9 | public interface ServerListUpdater { 10 | 11 | /** 12 | * an interface for the updateAction that actually executes a server list update 13 | */ 14 | public interface UpdateAction { 15 | void doUpdate(); 16 | } 17 | 18 | 19 | /** 20 | * start the serverList updater with the given update action 21 | * This call should be idempotent. 22 | * 23 | * @param updateAction 24 | */ 25 | void start(UpdateAction updateAction); 26 | 27 | /** 28 | * stop the serverList updater. This call should be idempotent 29 | */ 30 | void stop(); 31 | 32 | /** 33 | * @return the last update timestamp as a {@link java.util.Date} string 34 | */ 35 | String getLastUpdate(); 36 | 37 | /** 38 | * @return the number of ms that has elapsed since last update 39 | */ 40 | long getDurationSinceLastUpdateMs(); 41 | 42 | /** 43 | * @return the number of update cycles missed, if valid 44 | */ 45 | int getNumberMissedCycles(); 46 | 47 | /** 48 | * @return the number of threads used, if vaid 49 | */ 50 | int getCoreThreads(); 51 | } 52 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/ServerStatusChangeListener.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 com.netflix.loadbalancer; 17 | 18 | import java.util.Collection; 19 | 20 | public interface ServerStatusChangeListener { 21 | 22 | /** 23 | * Invoked by {@link BaseLoadBalancer} when server status has changed (e.g. when marked as down or found dead by ping). 24 | * 25 | * @param servers the servers that had their status changed, never {@code null} 26 | */ 27 | public void serverStatusChanged(Collection servers); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/ZoneAffinityPredicate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | /** 21 | * A predicate the filters out servers that are not in the same zone as the client's current 22 | * zone. 23 | * 24 | * @author awang 25 | * 26 | */ 27 | public class ZoneAffinityPredicate extends AbstractServerPredicate { 28 | 29 | private final String zone; 30 | 31 | public ZoneAffinityPredicate(String zone) { 32 | this.zone = zone; 33 | } 34 | 35 | @Override 36 | public boolean apply(PredicateKey input) { 37 | Server s = input.getServer(); 38 | String az = s.getZone(); 39 | if (az != null && zone != null && az.toLowerCase().equals(zone.toLowerCase())) { 40 | return true; 41 | } else { 42 | return false; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/ZoneSnapshot.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | /** 21 | * Captures the metrics on a Per Zone basis (Zone is modeled after the Amazon Availability Zone) 22 | * @author awang 23 | * 24 | */ 25 | public class ZoneSnapshot { 26 | final int instanceCount; 27 | final double loadPerServer; 28 | final int circuitTrippedCount; 29 | final int activeRequestsCount; 30 | 31 | public ZoneSnapshot() { 32 | this(0, 0, 0, 0d); 33 | } 34 | 35 | public ZoneSnapshot(int instanceCount, int circuitTrippedCount, int activeRequestsCount, double loadPerServer) { 36 | this.instanceCount = instanceCount; 37 | this.loadPerServer = loadPerServer; 38 | this.circuitTrippedCount = circuitTrippedCount; 39 | this.activeRequestsCount = activeRequestsCount; 40 | } 41 | 42 | public final int getInstanceCount() { 43 | return instanceCount; 44 | } 45 | 46 | public final double getLoadPerServer() { 47 | return loadPerServer; 48 | } 49 | 50 | public final int getCircuitTrippedCount() { 51 | return circuitTrippedCount; 52 | } 53 | 54 | public final int getActiveRequestsCount() { 55 | return activeRequestsCount; 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return "ZoneSnapshot [instanceCount=" + instanceCount 61 | + ", loadPerServer=" + loadPerServer + ", circuitTrippedCount=" 62 | + circuitTrippedCount + ", activeRequestsCount=" 63 | + activeRequestsCount + "]"; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/reactive/ServerOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2014 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer.reactive; 19 | 20 | import rx.Observable; 21 | import rx.functions.Func1; 22 | 23 | import com.netflix.loadbalancer.Server; 24 | 25 | /** 26 | * Provide the {@link rx.Observable} for a specified server. Used by {@link com.netflix.loadbalancer.reactive.LoadBalancerCommand} 27 | * 28 | * @param Output type 29 | */ 30 | public interface ServerOperation extends Func1> { 31 | /** 32 | * @return A lazy {@link Observable} for the server supplied. It is expected 33 | * that the actual execution is not started until the returned {@link Observable} is subscribed to. 34 | */ 35 | @Override 36 | public Observable call(Server server); 37 | } 38 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/test/java/com/netflix/client/SimpleVipAddressResolverTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.client; 19 | 20 | import static org.junit.Assert.*; 21 | 22 | import org.junit.Test; 23 | 24 | import com.netflix.config.ConfigurationManager; 25 | 26 | public class SimpleVipAddressResolverTest { 27 | @Test 28 | public void test() { 29 | ConfigurationManager.getConfigInstance().setProperty("foo", "abc"); 30 | ConfigurationManager.getConfigInstance().setProperty("bar", "xyz"); 31 | SimpleVipAddressResolver resolver = new SimpleVipAddressResolver(); 32 | String resolved = resolver.resolve("www.${foo}.com,myserver,${bar}", null); 33 | assertEquals("www.abc.com,myserver,xyz", resolved); 34 | } 35 | 36 | @Test 37 | public void testNoMacro() { 38 | ConfigurationManager.getConfigInstance().setProperty("foo", "abc"); 39 | ConfigurationManager.getConfigInstance().setProperty("bar", "xyz"); 40 | SimpleVipAddressResolver resolver = new SimpleVipAddressResolver(); 41 | String resolved = resolver.resolve("www.foo.com,myserver,bar", null); 42 | assertEquals("www.foo.com,myserver,bar", resolved); 43 | } 44 | 45 | @Test 46 | public void testUndefinedProp() { 47 | ConfigurationManager.getConfigInstance().setProperty("bar", "xyz"); 48 | SimpleVipAddressResolver resolver = new SimpleVipAddressResolver(); 49 | String resolved = resolver.resolve("www.${var}.com,myserver,${bar}", null); 50 | assertEquals("www.${var}.com,myserver,xyz", resolved); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/test/java/com/netflix/loadbalancer/BestAvailableRuleTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2014 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | 21 | import static org.junit.Assert.*; 22 | 23 | import java.util.List; 24 | 25 | import org.junit.Test; 26 | 27 | import com.google.common.collect.Lists; 28 | 29 | public class BestAvailableRuleTest { 30 | 31 | @Test 32 | public void testRule() { 33 | List servers = Lists.newArrayList(); 34 | for (int i = 0; i < 10; i++) { 35 | servers.add(new Server(String.valueOf(i), 80)); 36 | } 37 | IRule rule = new BestAvailableRule(); 38 | BaseLoadBalancer lb = LoadBalancerBuilder.newBuilder().withRule(rule).buildFixedServerListLoadBalancer(servers); 39 | for (int i = 0; i < 10; i++) { 40 | ServerStats stats = lb.getLoadBalancerStats().getSingleServerStat(servers.get(i)); 41 | for (int j = 0; j < 10 - i; j++) { 42 | stats.incrementActiveRequestsCount(); 43 | } 44 | } 45 | Server server = lb.chooseServer(); 46 | assertEquals(servers.get(9), server); 47 | ServerStats stats = lb.getLoadBalancerStats().getSingleServerStat(servers.get(9)); 48 | for (int i = 0; i < 3; i++) { 49 | stats.incrementSuccessiveConnectionFailureCount(); 50 | } 51 | server = lb.chooseServer(); 52 | // server 9 has tripped circuit breaker 53 | assertEquals(servers.get(8), server); 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/test/java/com/netflix/loadbalancer/ConfigurationBasedServerListTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | import static org.junit.Assert.*; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | import org.junit.Test; 26 | 27 | import com.netflix.client.config.DefaultClientConfigImpl; 28 | import com.netflix.config.ConfigurationManager; 29 | 30 | public class ConfigurationBasedServerListTest { 31 | 32 | @Test 33 | public void testList() { 34 | ConfigurationBasedServerList list = new ConfigurationBasedServerList(); 35 | DefaultClientConfigImpl config = DefaultClientConfigImpl.getClientConfigWithDefaultValues("junit1"); 36 | list.initWithNiwsConfig(config); 37 | assertTrue(list.getInitialListOfServers().isEmpty()); 38 | ConfigurationManager.getConfigInstance().setProperty("junit1.ribbon.listOfServers", "abc.com:80,microsoft.com,1.2.3.4:8080"); 39 | List servers = list.getUpdatedListOfServers(); 40 | List expected = new ArrayList(); 41 | expected.add(new Server("abc.com:80")); 42 | expected.add(new Server("microsoft.com:80")); 43 | expected.add(new Server("1.2.3.4:8080")); 44 | assertEquals(expected, servers); 45 | ConfigurationManager.getConfigInstance().setProperty("junit1.ribbon.listOfServers", ""); 46 | assertTrue(list.getUpdatedListOfServers().isEmpty()); 47 | ConfigurationManager.getConfigInstance().clearProperty("junit1.ribbon.listOfServers"); 48 | assertTrue(list.getUpdatedListOfServers().isEmpty()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/test/java/com/netflix/loadbalancer/MockServerList.java: -------------------------------------------------------------------------------- 1 | package com.netflix.loadbalancer; 2 | 3 | import java.util.List; 4 | 5 | import com.google.common.collect.Lists; 6 | import com.netflix.client.config.IClientConfig; 7 | 8 | public class MockServerList extends AbstractServerList { 9 | 10 | private List serverList = Lists.newArrayList(); 11 | 12 | public void setServerList(List serverList) { 13 | this.serverList = serverList; 14 | } 15 | 16 | @Override 17 | public List getInitialListOfServers() { 18 | return serverList; 19 | } 20 | 21 | @Override 22 | public List getUpdatedListOfServers() { 23 | return serverList; 24 | } 25 | 26 | @Override 27 | public void initWithNiwsConfig(IClientConfig clientConfig) { 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/test/java/com/netflix/loadbalancer/PollingServerListUpdaterTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.loadbalancer; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.concurrent.CountDownLatch; 6 | import java.util.concurrent.TimeUnit; 7 | import java.util.concurrent.atomic.AtomicLong; 8 | 9 | import static org.junit.Assert.assertTrue; 10 | 11 | /** 12 | * @author David Liu 13 | */ 14 | public class PollingServerListUpdaterTest { 15 | 16 | private final long updateIntervalMs = 50; 17 | 18 | @Test 19 | public void testUpdating() throws Exception { 20 | PollingServerListUpdater serverListUpdater = new PollingServerListUpdater(0, updateIntervalMs); 21 | 22 | try { 23 | final AtomicLong lastUpdateTimestamp = new AtomicLong(); 24 | final CountDownLatch countDownLatch = new CountDownLatch(2); 25 | serverListUpdater.start(new ServerListUpdater.UpdateAction() { 26 | @Override 27 | public void doUpdate() { 28 | countDownLatch.countDown(); 29 | lastUpdateTimestamp.set(System.currentTimeMillis()); 30 | } 31 | }); 32 | 33 | assertTrue(countDownLatch.await(2, TimeUnit.SECONDS)); 34 | assertTrue(serverListUpdater.getDurationSinceLastUpdateMs() <= updateIntervalMs); 35 | } finally { 36 | serverListUpdater.stop(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/test/java/com/netflix/loadbalancer/ServerListChangeListenerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2014 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | import static org.junit.Assert.assertEquals; 21 | import static org.junit.Assert.assertTrue; 22 | 23 | import java.util.List; 24 | 25 | import org.junit.Test; 26 | 27 | import com.google.common.collect.Lists; 28 | 29 | public class ServerListChangeListenerTest { 30 | 31 | private volatile List oldList; 32 | private volatile List newList; 33 | 34 | @Test 35 | public void testListener() { 36 | BaseLoadBalancer lb = new BaseLoadBalancer(); 37 | lb.addServerListChangeListener(new ServerListChangeListener() { 38 | @Override 39 | public void serverListChanged(List oldList, List newList) { 40 | ServerListChangeListenerTest.this.oldList = oldList; 41 | ServerListChangeListenerTest.this.newList = newList; 42 | } 43 | }); 44 | List list1 = Lists.newArrayList(new Server("server1"), new Server("server2")); 45 | List list2 = Lists.newArrayList(new Server("server3"), new Server("server4")); 46 | lb.setServersList(list1); 47 | assertTrue(oldList.isEmpty()); 48 | assertEquals(list1, newList); 49 | lb.setServersList(list2); 50 | assertEquals(list1, oldList); 51 | assertEquals(list2, newList); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/test/java/com/netflix/loadbalancer/ServerStatsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer; 19 | 20 | import static org.junit.Assert.*; 21 | 22 | import org.junit.Test; 23 | 24 | import com.netflix.servo.monitor.Monitors; 25 | 26 | public class ServerStatsTest { 27 | 28 | @Test 29 | public void testRegisterWithServo() { 30 | // Make sure annotations are correct: 31 | // https://github.com/Netflix/ribbon/issues/191 32 | // Monitors.registerObject(new ServerStats()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/test/java/com/netflix/loadbalancer/reactive/ExecutionContextTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2014 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.loadbalancer.reactive; 19 | 20 | import com.netflix.client.RetryHandler; 21 | import com.netflix.client.config.DefaultClientConfigImpl; 22 | import org.junit.Test; 23 | 24 | import static org.junit.Assert.assertEquals; 25 | import static org.junit.Assert.assertNull; 26 | import static org.junit.Assert.assertSame; 27 | 28 | /** 29 | * @author Allen Wang 30 | */ 31 | public class ExecutionContextTest { 32 | @Test 33 | public void testSubContext() { 34 | ExecutionContext context = new ExecutionContext("hello", DefaultClientConfigImpl.getEmptyConfig(), 35 | DefaultClientConfigImpl.getClientConfigWithDefaultValues(), RetryHandler.DEFAULT); 36 | ExecutionContext subContext1 = context.getChildContext("foo"); 37 | ExecutionContext subContext2 = context.getChildContext("bar"); 38 | assertSame(context, context.getGlobalContext()); 39 | context.put("dummy", "globalValue"); 40 | context.put("dummy2", "globalValue"); 41 | subContext1.put("dummy", "context1Value"); 42 | subContext2.put("dummy", "context2Value"); 43 | assertEquals("context1Value", subContext1.get("dummy")); 44 | assertEquals("context2Value", subContext2.get("dummy")); 45 | assertEquals("globalValue", subContext1.getGlobalContext().get("dummy")); 46 | assertNull(subContext1.get("dummy2")); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ribbon-loadbalancer/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootCategory=INFO,stdout 2 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d %-5p %C:%L [%t] [%M] %m%n 5 | -------------------------------------------------------------------------------- /ribbon-test/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api project(':ribbon-core') 3 | api project(':ribbon-loadbalancer') 4 | api project(':ribbon-eureka') 5 | api 'org.codehaus.jackson:jackson-mapper-asl:1.9.11' 6 | api "com.netflix.eureka:eureka-client:${eureka_version}" 7 | api "io.reactivex:rxjava:${rx_java_version}" 8 | api 'javax.ws.rs:jsr311-api:1.1.1' 9 | api "com.google.guava:guava:${guava_version}" 10 | api "junit:junit:${junit_version}" 11 | api "org.powermock:powermock-easymock-release-full:${powermock_version}" 12 | api "org.easymock:easymock:${easymock_version}" 13 | } 14 | -------------------------------------------------------------------------------- /ribbon-test/src/main/java/com/netflix/serialization/Deserializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.serialization; 19 | 20 | import java.io.IOException; 21 | import java.io.InputStream; 22 | 23 | public interface Deserializer { 24 | public T deserialize(InputStream in, TypeDef type) throws IOException; 25 | } 26 | -------------------------------------------------------------------------------- /ribbon-test/src/main/java/com/netflix/serialization/JacksonCodec.java: -------------------------------------------------------------------------------- 1 | package com.netflix.serialization; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.InputStreamReader; 6 | import java.io.OutputStream; 7 | import java.lang.reflect.Type; 8 | 9 | import org.codehaus.jackson.map.ObjectMapper; 10 | import org.codehaus.jackson.map.ObjectWriter; 11 | import org.codehaus.jackson.type.TypeReference; 12 | 13 | import com.google.common.base.Charsets; 14 | import com.google.common.io.CharStreams; 15 | 16 | public class JacksonCodec implements Serializer, Deserializer { 17 | 18 | private static final JacksonCodec instance = new JacksonCodec(); 19 | 20 | private final ObjectMapper mapper = new ObjectMapper(); 21 | 22 | @Override 23 | public T deserialize(InputStream in, TypeDef type) 24 | throws IOException { 25 | if (String.class.equals(type.getRawType())) { 26 | return (T) CharStreams.toString(new InputStreamReader(in, Charsets.UTF_8)); 27 | } 28 | return mapper.readValue(in, new TypeTokenBasedReference(type)); 29 | } 30 | 31 | @Override 32 | public void serialize(OutputStream out, T object, TypeDef type) throws IOException { 33 | if (type == null) { 34 | mapper.writeValue(out, object); 35 | } else { 36 | ObjectWriter writer = mapper.writerWithType(new TypeTokenBasedReference(type)); 37 | writer.writeValue(out, object); 38 | } 39 | } 40 | 41 | public static final JacksonCodec getInstance() { 42 | return instance; 43 | } 44 | } 45 | 46 | class TypeTokenBasedReference extends TypeReference { 47 | 48 | final Type type; 49 | public TypeTokenBasedReference(TypeDef typeToken) { 50 | type = typeToken.getType(); 51 | 52 | } 53 | 54 | @Override 55 | public Type getType() { 56 | return type; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ribbon-test/src/main/java/com/netflix/serialization/SerializationUtils.java: -------------------------------------------------------------------------------- 1 | package com.netflix.serialization; 2 | 3 | import java.io.ByteArrayInputStream; 4 | import java.io.ByteArrayOutputStream; 5 | import java.io.IOException; 6 | 7 | import com.google.common.base.Preconditions; 8 | 9 | public class SerializationUtils { 10 | 11 | public static T deserializeFromString(Deserializer deserializer, String content, TypeDef typeDef) 12 | throws IOException { 13 | Preconditions.checkNotNull(deserializer); 14 | ByteArrayInputStream in = new ByteArrayInputStream(content.getBytes("UTF-8")); 15 | return deserializer.deserialize(in, typeDef); 16 | } 17 | 18 | public static String serializeToString(Serializer serializer, T obj, TypeDef typeDef) 19 | throws IOException { 20 | return new String(serializeToBytes(serializer, obj, typeDef), "UTF-8"); 21 | } 22 | 23 | public static byte[] serializeToBytes(Serializer serializer, T obj, TypeDef typeDef) 24 | throws IOException { 25 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 26 | serializer.serialize(out, obj, typeDef); 27 | return out.toByteArray(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ribbon-test/src/main/java/com/netflix/serialization/Serializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2013 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.serialization; 19 | 20 | import java.io.IOException; 21 | import java.io.OutputStream; 22 | 23 | public interface Serializer { 24 | public void serialize(OutputStream out, T object, TypeDef type) throws IOException; 25 | } 26 | -------------------------------------------------------------------------------- /ribbon-test/src/main/java/com/netflix/serialization/StringDeserializer.java: -------------------------------------------------------------------------------- 1 | package com.netflix.serialization; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.InputStreamReader; 6 | 7 | import com.google.common.base.Charsets; 8 | import com.google.common.io.CharStreams; 9 | import com.google.common.io.Closeables; 10 | 11 | public class StringDeserializer implements Deserializer { 12 | 13 | private static final StringDeserializer instance = new StringDeserializer(); 14 | 15 | private StringDeserializer() { 16 | } 17 | 18 | public static final StringDeserializer getInstance() { 19 | return instance; 20 | } 21 | 22 | @Override 23 | public String deserialize(InputStream in, TypeDef type) 24 | throws IOException { 25 | try { 26 | String content = CharStreams.toString(new InputStreamReader(in, Charsets.UTF_8)); 27 | return content; 28 | } finally { 29 | Closeables.close(in, true); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ribbon-test/src/main/java/com/netflix/serialization/TypeDef.java: -------------------------------------------------------------------------------- 1 | package com.netflix.serialization; 2 | 3 | import static com.google.common.base.Preconditions.checkArgument; 4 | 5 | import java.lang.reflect.ParameterizedType; 6 | import java.lang.reflect.Type; 7 | 8 | import com.google.common.reflect.TypeToken; 9 | 10 | public abstract class TypeDef { 11 | 12 | // private final Type runtimeType; 13 | private TypeToken delegate; 14 | 15 | @SuppressWarnings("unchecked") 16 | protected TypeDef() { 17 | Type superclass = getClass().getGenericSuperclass(); 18 | checkArgument(superclass instanceof ParameterizedType, 19 | "%s isn't parameterized", superclass); 20 | Type runtimeType = ((ParameterizedType) superclass).getActualTypeArguments()[0]; 21 | this.delegate = (TypeToken) TypeToken.of(runtimeType); 22 | } 23 | 24 | 25 | public static TypeDef fromClass(Class classType) { 26 | TypeDef spec = new TypeDef() { 27 | }; 28 | spec.delegate = TypeToken.of(classType); 29 | return spec; 30 | } 31 | 32 | public static TypeDef fromType(Type type) { 33 | TypeDef spec = new TypeDef() { 34 | }; 35 | spec.delegate = TypeToken.of(type); 36 | return spec; 37 | } 38 | 39 | public Class getRawType() { 40 | return (Class) delegate.getRawType(); 41 | } 42 | 43 | public Type getType() { 44 | return delegate.getType(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /ribbon-transport/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api project(':ribbon-core') 3 | api project(':ribbon-archaius') 4 | api project(':ribbon-loadbalancer') 5 | api "io.reactivex:rxjava:${rx_java_version}" 6 | api "io.reactivex:rxnetty:${rx_netty_version}" 7 | api "io.reactivex:rxnetty-contexts:${rx_netty_version}" 8 | api "io.reactivex:rxnetty-servo:${rx_netty_version}" 9 | api "io.netty:netty-codec-http:4.0.27.Final" 10 | api 'javax.inject:javax.inject:1' 11 | api "org.slf4j:slf4j-api:${slf4j_version}" 12 | api "com.google.guava:guava:${guava_version}" 13 | testImplementation 'junit:junit:4.11' 14 | testImplementation "org.slf4j:slf4j-log4j12:${slf4j_version}" 15 | testImplementation "com.sun.jersey:jersey-server:${jersey_version}" 16 | testImplementation 'com.google.mockwebserver:mockwebserver:20130706' 17 | testImplementation project(':ribbon-eureka') 18 | testImplementation project(':ribbon-test') 19 | testImplementation project(':ribbon-archaius') 20 | } 21 | -------------------------------------------------------------------------------- /ribbon-transport/src/main/java/com/netflix/ribbon/transport/netty/DynamicPropertyBasedPoolStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2014 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.ribbon.transport.netty; 19 | 20 | import com.netflix.config.DynamicProperty; 21 | 22 | import io.reactivex.netty.client.MaxConnectionsBasedStrategy; 23 | 24 | /** 25 | * A {@link MaxConnectionsBasedStrategy} that resize itself based on callbacks from 26 | * {@link DynamicProperty} 27 | * 28 | * @author awang 29 | * 30 | */ 31 | public class DynamicPropertyBasedPoolStrategy extends MaxConnectionsBasedStrategy { 32 | 33 | private final DynamicProperty poolSizeProperty; 34 | 35 | public DynamicPropertyBasedPoolStrategy(final int maxConnections, String propertyName) { 36 | super(maxConnections); 37 | poolSizeProperty = DynamicProperty.getInstance(propertyName); 38 | setMaxConnections(poolSizeProperty.getInteger(maxConnections)); 39 | poolSizeProperty.addCallback(new Runnable() { 40 | @Override 41 | public void run() { 42 | setMaxConnections(poolSizeProperty.getInteger(maxConnections)); 43 | }; 44 | }); 45 | } 46 | 47 | protected void setMaxConnections(int max) { 48 | int diff = max - getMaxConnections(); 49 | incrementMaxConnections(diff); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ribbon-transport/src/main/java/com/netflix/ribbon/transport/netty/http/DefaultResponseToErrorPolicy.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.transport.netty.http; 2 | 3 | import io.netty.handler.codec.http.HttpResponseStatus; 4 | import io.reactivex.netty.protocol.http.client.HttpClientResponse; 5 | 6 | import java.util.concurrent.TimeUnit; 7 | 8 | import rx.Observable; 9 | import rx.functions.Func1; 10 | import rx.functions.Func2; 11 | 12 | import com.netflix.client.ClientException; 13 | 14 | public class DefaultResponseToErrorPolicy implements Func2, Integer, Observable>> { 15 | @Override 16 | public Observable> call(HttpClientResponse t1, Integer backoff) { 17 | if (t1.getStatus().equals(HttpResponseStatus.INTERNAL_SERVER_ERROR)) { 18 | return Observable.error(new ClientException(ClientException.ErrorType.GENERAL)); 19 | } 20 | if (t1.getStatus().equals(HttpResponseStatus.SERVICE_UNAVAILABLE) || 21 | t1.getStatus().equals(HttpResponseStatus.BAD_GATEWAY) || 22 | t1.getStatus().equals(HttpResponseStatus.GATEWAY_TIMEOUT)) { 23 | if (backoff > 0) { 24 | return Observable.timer(backoff, TimeUnit.MILLISECONDS) 25 | .concatMap(new Func1>>() { 26 | @Override 27 | public Observable> call(Long t1) { 28 | return Observable.error(new ClientException(ClientException.ErrorType.SERVER_THROTTLED)); 29 | } 30 | }); 31 | } 32 | else { 33 | return Observable.error(new ClientException(ClientException.ErrorType.SERVER_THROTTLED)); 34 | } 35 | } 36 | return Observable.just(t1); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ribbon-transport/src/test/java/com/netflix/ribbon/transport/netty/DynamicPropertyBasedPoolStrategyTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2014 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.ribbon.transport.netty; 19 | 20 | import static org.junit.Assert.*; 21 | 22 | import org.junit.Test; 23 | 24 | import com.netflix.config.ConfigurationManager; 25 | 26 | public class DynamicPropertyBasedPoolStrategyTest { 27 | @Test 28 | public void testResize() { 29 | ConfigurationManager.getConfigInstance().setProperty("foo", "150"); 30 | DynamicPropertyBasedPoolStrategy strategy = new DynamicPropertyBasedPoolStrategy(100, "foo"); 31 | assertEquals(150, strategy.getMaxConnections()); 32 | ConfigurationManager.getConfigInstance().setProperty("foo", "200"); 33 | assertEquals(200, strategy.getMaxConnections()); 34 | ConfigurationManager.getConfigInstance().setProperty("foo", "50"); 35 | assertEquals(50, strategy.getMaxConnections()); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /ribbon-transport/src/test/java/com/netflix/ribbon/transport/netty/http/ObserverWithLatch.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2014 Netflix, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package com.netflix.ribbon.transport.netty.http; 19 | 20 | import rx.Observer; 21 | 22 | import java.util.concurrent.CountDownLatch; 23 | import java.util.concurrent.TimeUnit; 24 | import java.util.concurrent.atomic.AtomicInteger; 25 | 26 | import static org.junit.Assert.fail; 27 | 28 | 29 | public class ObserverWithLatch implements Observer { 30 | public volatile T obj; 31 | public volatile Throwable error; 32 | 33 | private CountDownLatch latch = new CountDownLatch(1); 34 | public AtomicInteger nextCounter = new AtomicInteger(); 35 | public AtomicInteger errorCounter = new AtomicInteger(); 36 | 37 | @Override 38 | public void onCompleted() { 39 | latch.countDown(); 40 | } 41 | 42 | @Override 43 | public void onError(Throwable e) { 44 | this.error = e; 45 | errorCounter.incrementAndGet(); 46 | latch.countDown(); 47 | } 48 | 49 | @Override 50 | public void onNext(T obj) { 51 | this.obj = obj; 52 | nextCounter.incrementAndGet(); 53 | } 54 | 55 | public void await() { 56 | boolean completed = false; 57 | try { 58 | completed = latch.await(10, TimeUnit.SECONDS); 59 | } catch (Exception e) { // NOPMD 60 | } 61 | if (!completed) { 62 | fail("Observer not completed"); 63 | } 64 | if (nextCounter.get() == 0 && errorCounter.get() == 0) { 65 | fail("onNext() or onError() is not called"); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /ribbon-transport/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootCategory=INFO,stdout 2 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d %-5p %C:%L [%t] [%M] %m%n 5 | -------------------------------------------------------------------------------- /ribbon/README.md: -------------------------------------------------------------------------------- 1 | # Ribbon Module 2 | 3 | Ribbon module contains APIs that integrate load balancing, fault tolerance, caching/batching on top of other 4 | ribbon modules and [Hystrix](https://github.com/netflix/hystrix). 5 | 6 | # Ribbon Annotations 7 | 8 | A Ribbon client can be created from a Java interface annotated with Ribbon 9 | [annotations](src/main/java/com/netflix/ribbon/proxy/annotation), like in the example below. A dynamic proxy 10 | is created which translates interface methods invocations into Ribbon requests. Method parameters annotated with 11 | ```@Content``` annotation are automatically converted into wire format using provided ```ContentTransformer``` class. 12 | Replies as of now are limited to ```ByteBuf``` type only, which contains exact copy of the HTTP response payload. 13 | This restrictions are imposed by existing RxNetty capabilities and will be solved once RxNetty serialization 14 | framework is complete. 15 | 16 | This code snippet is taken from [ribbon-examples](../ribbon-examples) package and can be found 17 | [here](../ribbon-examples/src/main/java/com/netflix/ribbon/examples/rx/proxy). 18 | 19 | ```java 20 | @ResourceGroup(resourceGroupClass = SampleHttpResourceGroup.class) 21 | public interface MovieService { 22 | @TemplateName("recommendations") 23 | @Http(method = HttpMethod.GET, uri = "/users/{userId}/recommendations") 24 | @Hystrix( validator = RecommendationServiceResponseValidator.class, 25 | fallbackHandler = RecommendationServiceFallbackHandler.class) 26 | @CacheProviders(@Provider(key = "{userId}", provider = InMemoryCacheProviderFactory.class)) 27 | RibbonRequest recommendationsByUserId(@Var("userId") String userId); 28 | 29 | @TemplateName("registerMovie") 30 | @Http( method = HttpMethod.POST, uri = "/movies") 31 | @Hystrix(validator = RecommendationServiceResponseValidator.class) 32 | @ContentTransformerClass(RxMovieTransformer.class) 33 | RibbonRequest registerMovie(@Content Movie movie); 34 | } 35 | 36 | MovieService movieService = Ribbon.from(MovieService.class); 37 | Observable result = movieService.recommendationsByUserId("user1").toObservable(); 38 | ``` 39 | -------------------------------------------------------------------------------- /ribbon/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.netflix.nebula.facet' 2 | 3 | facets { 4 | examples { 5 | parentSourceSet = 'main' 6 | } 7 | } 8 | 9 | build.dependsOn(examplesClasses) 10 | 11 | dependencies { 12 | api project(':ribbon-core') 13 | api project(':ribbon-transport') 14 | api "com.netflix.hystrix:hystrix-core:${hystrix_version}" 15 | api 'javax.inject:javax.inject:1' 16 | api "io.reactivex:rxjava:${rx_java_version}" 17 | api "io.reactivex:rxnetty:${rx_netty_version}" 18 | api 'commons-configuration:commons-configuration:1.8' 19 | api "com.google.guava:guava:${guava_version}" 20 | api "com.netflix.archaius:archaius-core:${archaius_version}" 21 | testImplementation "junit:junit:${junit_version}" 22 | testImplementation "org.powermock:powermock-easymock-release-full:${powermock_version}" 23 | testImplementation "org.easymock:easymock:${easymock_version}" 24 | testImplementation "org.slf4j:slf4j-log4j12:${slf4j_version}" 25 | testImplementation project(':ribbon-eureka') 26 | testImplementation project(':ribbon-test') 27 | testImplementation 'com.google.mockwebserver:mockwebserver:20130706' 28 | } 29 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/CacheProvider.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon; 17 | 18 | import java.util.Map; 19 | 20 | import com.netflix.ribbon.RequestTemplate.RequestBuilder; 21 | 22 | import rx.Observable; 23 | 24 | public interface CacheProvider { 25 | /** 26 | * @param keyTemplate A key template which may contain variable, e.g., /foo/bar/{id}, 27 | * where the variable will be substituted with real value by {@link RequestBuilder} 28 | * 29 | * @param requestProperties Key value pairs provided via {@link RequestBuilder#withRequestProperty(String, Object)} 30 | * 31 | * @return Cache content as a lazy {@link Observable}. It is assumed that 32 | * the actual cache retrieval does not happen until the returned {@link Observable} 33 | * is subscribed to. 34 | */ 35 | Observable get(String keyTemplate, Map requestProperties); 36 | } 37 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/CacheProviderFactory.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon; 18 | 19 | public interface CacheProviderFactory { 20 | CacheProvider createCacheProvider(); 21 | } 22 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/DefaultResourceFactory.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon; 17 | 18 | import com.netflix.client.config.ClientConfigFactory; 19 | import com.netflix.ribbon.proxy.processor.AnnotationProcessorsProvider; 20 | 21 | import javax.inject.Inject; 22 | 23 | public class DefaultResourceFactory extends RibbonResourceFactory { 24 | 25 | @Inject 26 | public DefaultResourceFactory(ClientConfigFactory clientConfigFactory, RibbonTransportFactory transportFactory, 27 | AnnotationProcessorsProvider annotationProcessorsProvider) { 28 | super(clientConfigFactory, transportFactory, annotationProcessorsProvider); 29 | } 30 | 31 | public DefaultResourceFactory(ClientConfigFactory clientConfigFactory, RibbonTransportFactory transportFactory) { 32 | super(clientConfigFactory, transportFactory, AnnotationProcessorsProvider.DEFAULT); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/RequestTemplate.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon; 17 | 18 | /** 19 | * @author awang 20 | * 21 | * @param response entity type 22 | * @param response meta data, e.g. HttpClientResponse 23 | */ 24 | public abstract class RequestTemplate { 25 | 26 | public abstract RequestBuilder requestBuilder(); 27 | 28 | public abstract String name(); 29 | 30 | public abstract RequestTemplate copy(String name); 31 | 32 | 33 | public static abstract class RequestBuilder { 34 | public abstract RequestBuilder withRequestProperty(String key, Object value); 35 | 36 | public abstract RibbonRequest build(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/RequestWithMetaData.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon; 18 | 19 | import java.util.concurrent.Future; 20 | 21 | import rx.Observable; 22 | 23 | /** 24 | * A decorated request object whose response content contains the execution meta data. 25 | * 26 | * @author Allen Wang 27 | * 28 | */ 29 | public interface RequestWithMetaData { 30 | /** 31 | * Non blocking API that returns an {@link Observable} while the execution is started asynchronously. 32 | * Subscribing to the returned {@link Observable} is guaranteed to get the complete sequence from 33 | * the beginning, which might be replayed by the framework. 34 | */ 35 | Observable>> observe(); 36 | 37 | /** 38 | * Non blocking API that returns an Observable. The execution is not started until the returned Observable is subscribed to. 39 | */ 40 | Observable>> toObservable(); 41 | 42 | /** 43 | * Non blocking API that returns a {@link Future}, where its {@link Future#get()} method is blocking and returns a 44 | * single (or last element if there is a sequence of objects from the execution) element 45 | */ 46 | Future> queue(); 47 | 48 | /** 49 | * Blocking API that returns a single (or last element if there is a sequence of objects from the execution) element 50 | */ 51 | RibbonResponse execute(); 52 | } 53 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/ResponseValidator.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon; 17 | 18 | import io.reactivex.netty.protocol.http.client.HttpClientResponse; 19 | 20 | 21 | /** 22 | * 23 | * @author awang 24 | * 25 | * @param Protocol specific response meta data, e.g., HttpClientResponse 26 | */ 27 | public interface ResponseValidator { 28 | /** 29 | * @param response Protocol specific response object, e.g., {@link HttpClientResponse} 30 | * @throws UnsuccessfulResponseException throw if server is able to execute the request, but 31 | * returns an an unsuccessful response. 32 | * For example, HTTP response with 404 status code. This will be treated as a valid 33 | * response and will not trigger Hystrix fallback 34 | * @throws ServerError throw if the response indicates that there is an server error in executing the request. 35 | * For example, HTTP response with 500 status code. This will trigger Hystrix fallback. 36 | */ 37 | public void validate(T response) throws UnsuccessfulResponseException, ServerError; 38 | } 39 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/RibbonResponse.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon; 17 | 18 | 19 | import com.netflix.hystrix.HystrixInvokableInfo; 20 | 21 | /** 22 | * Response object from {@link RequestWithMetaData} that contains the content 23 | * and the meta data from execution. 24 | * 25 | * @author Allen Wang 26 | * 27 | * @param Data type of the returned object 28 | */ 29 | public abstract class RibbonResponse { 30 | public abstract T content(); 31 | 32 | public abstract HystrixInvokableInfo getHystrixInfo(); 33 | } 34 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/ServerError.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon; 17 | 18 | @SuppressWarnings("serial") 19 | public class ServerError extends Exception { 20 | 21 | public ServerError(String message, Throwable cause) { 22 | super(message, cause); 23 | } 24 | 25 | public ServerError(String message) { 26 | super(message); 27 | } 28 | 29 | public ServerError(Throwable cause) { 30 | super(cause); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/UnsuccessfulResponseException.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon; 17 | 18 | @SuppressWarnings("serial") 19 | public class UnsuccessfulResponseException extends Exception { 20 | 21 | public UnsuccessfulResponseException(String arg0, Throwable arg1) { 22 | super(arg0, arg1); 23 | } 24 | 25 | public UnsuccessfulResponseException(String arg0) { 26 | super(arg0); 27 | } 28 | 29 | public UnsuccessfulResponseException(Throwable arg0) { 30 | super(arg0); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/http/HttpMetaResponse.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.http; 17 | 18 | import com.netflix.hystrix.HystrixInvokableInfo; 19 | import com.netflix.ribbon.RibbonResponse; 20 | 21 | class HttpMetaResponse extends RibbonResponse { 22 | 23 | private O content; 24 | private HystrixInvokableInfo hystrixInfo; 25 | 26 | public HttpMetaResponse(O content, HystrixInvokableInfo hystrixInfo) { 27 | this.content = content; 28 | this.hystrixInfo = hystrixInfo; 29 | } 30 | 31 | @Override 32 | public O content() { 33 | return content; 34 | } 35 | 36 | @Override 37 | public HystrixInvokableInfo getHystrixInfo() { 38 | return hystrixInfo; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/http/HttpResponseValidator.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.http; 17 | 18 | import io.netty.buffer.ByteBuf; 19 | import io.reactivex.netty.protocol.http.client.HttpClientResponse; 20 | 21 | import com.netflix.ribbon.ResponseValidator; 22 | 23 | public interface HttpResponseValidator extends ResponseValidator> { 24 | } 25 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/hystrix/CacheObservableCommand.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.hystrix; 2 | 3 | import java.util.Map; 4 | 5 | import rx.Observable; 6 | 7 | import com.netflix.hystrix.HystrixObservableCommand; 8 | import com.netflix.ribbon.CacheProvider; 9 | 10 | /** 11 | * @author Tomasz Bak 12 | */ 13 | public class CacheObservableCommand extends HystrixObservableCommand { 14 | 15 | private final CacheProvider cacheProvider; 16 | private final String key; 17 | private final String hystrixCacheKey; 18 | private final Map requestProperties; 19 | 20 | public CacheObservableCommand( 21 | CacheProvider cacheProvider, 22 | String key, 23 | String hystrixCacheKey, 24 | Map requestProperties, 25 | Setter setter) { 26 | super(setter); 27 | this.cacheProvider = cacheProvider; 28 | this.key = key; 29 | this.hystrixCacheKey = hystrixCacheKey; 30 | this.requestProperties = requestProperties; 31 | } 32 | 33 | @Override 34 | protected String getCacheKey() { 35 | if (hystrixCacheKey == null) { 36 | return super.getCacheKey(); 37 | } else { 38 | return hystrixCacheKey; 39 | } 40 | } 41 | 42 | @Override 43 | protected Observable construct() { 44 | return cacheProvider.get(key, requestProperties); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/hystrix/FallbackHandler.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.hystrix; 17 | 18 | import java.util.Map; 19 | 20 | import com.netflix.hystrix.HystrixInvokableInfo; 21 | 22 | import rx.Observable; 23 | 24 | /** 25 | * 26 | * @author awang 27 | * 28 | * @param Output entity type 29 | */ 30 | public interface FallbackHandler { 31 | public Observable getFallback(HystrixInvokableInfo hystrixInfo, Map requestProperties); 32 | } 33 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/hystrix/ResultCommandPair.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.hystrix; 2 | 3 | import com.netflix.hystrix.HystrixObservableCommand; 4 | 5 | /** 6 | * @author Tomasz Bak 7 | */ 8 | public class ResultCommandPair { 9 | private final T result; 10 | private final HystrixObservableCommand command; 11 | 12 | public ResultCommandPair(T result, HystrixObservableCommand command) { 13 | this.result = result; 14 | this.command = command; 15 | } 16 | 17 | public T getResult() { 18 | return result; 19 | } 20 | 21 | public HystrixObservableCommand getCommand() { 22 | return command; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/ProxyAnnotationException.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.proxy; 18 | 19 | /** 20 | * @author Tomasz Bak 21 | */ 22 | public class ProxyAnnotationException extends RibbonProxyException { 23 | private static final long serialVersionUID = 1584867992816375583L; 24 | 25 | public ProxyAnnotationException(String message) { 26 | super(message); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/ProxyLifeCycle.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.proxy; 18 | 19 | public interface ProxyLifeCycle { 20 | 21 | boolean isShutDown(); 22 | 23 | void shutdown(); 24 | } 25 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/RibbonProxyException.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.proxy; 18 | 19 | /** 20 | * @author Tomasz Bak 21 | */ 22 | public class RibbonProxyException extends RuntimeException { 23 | private static final long serialVersionUID = -1; 24 | 25 | public RibbonProxyException(String message) { 26 | super(message); 27 | } 28 | 29 | public RibbonProxyException(String message, Throwable cause) { 30 | super(message, cause); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/annotation/CacheProvider.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.proxy.annotation; 17 | 18 | import com.netflix.ribbon.CacheProviderFactory; 19 | 20 | import java.lang.annotation.ElementType; 21 | import java.lang.annotation.Retention; 22 | import java.lang.annotation.RetentionPolicy; 23 | import java.lang.annotation.Target; 24 | 25 | @Target(ElementType.METHOD) 26 | @Retention(RetentionPolicy.RUNTIME) 27 | public @interface CacheProvider { 28 | 29 | String key(); 30 | 31 | Class> provider(); 32 | } 33 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/annotation/ClientProperties.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.proxy.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * @author Allen Wang 10 | */ 11 | @Target(ElementType.TYPE) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface ClientProperties { 14 | @interface Property { 15 | String name(); 16 | String value(); 17 | } 18 | 19 | Property[] properties() default {}; 20 | 21 | boolean exportToArchaius() default false; 22 | } 23 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/annotation/Content.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.proxy.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Target(ElementType.PARAMETER) 24 | @Retention(RetentionPolicy.RUNTIME) 25 | public @interface Content { 26 | } 27 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/annotation/ContentTransformerClass.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.proxy.annotation; 18 | 19 | 20 | import io.reactivex.netty.channel.ContentTransformer; 21 | 22 | import java.lang.annotation.ElementType; 23 | import java.lang.annotation.Retention; 24 | import java.lang.annotation.RetentionPolicy; 25 | import java.lang.annotation.Target; 26 | 27 | @Target(ElementType.METHOD) 28 | @Retention(RetentionPolicy.RUNTIME) 29 | public @interface ContentTransformerClass { 30 | Class> value(); 31 | } 32 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/annotation/Http.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.proxy.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | /** 24 | * @author Tomasz Bak 25 | */ 26 | @Target(ElementType.METHOD) 27 | @Retention(RetentionPolicy.RUNTIME) 28 | public @interface Http { 29 | 30 | enum HttpMethod { 31 | DELETE, 32 | GET, 33 | POST, 34 | PATCH, 35 | PUT 36 | } 37 | 38 | HttpMethod method(); 39 | 40 | String uri() default ""; 41 | 42 | Header[] headers() default {}; 43 | 44 | @interface Header { 45 | String name(); 46 | 47 | String value(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/annotation/Hystrix.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.proxy.annotation; 17 | 18 | import com.netflix.ribbon.http.HttpResponseValidator; 19 | import com.netflix.ribbon.hystrix.FallbackHandler; 20 | 21 | import java.lang.annotation.ElementType; 22 | import java.lang.annotation.Retention; 23 | import java.lang.annotation.RetentionPolicy; 24 | import java.lang.annotation.Target; 25 | 26 | @Target({ElementType.TYPE, ElementType.METHOD}) 27 | @Retention(RetentionPolicy.RUNTIME) 28 | public @interface Hystrix { 29 | String cacheKey() default ""; 30 | 31 | Class>[] fallbackHandler() default {}; 32 | 33 | Class[] validator() default {}; 34 | } 35 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/annotation/ResourceGroup.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.proxy.annotation; 17 | 18 | import com.netflix.ribbon.http.HttpResourceGroup; 19 | 20 | import java.lang.annotation.ElementType; 21 | import java.lang.annotation.Retention; 22 | import java.lang.annotation.RetentionPolicy; 23 | import java.lang.annotation.Target; 24 | 25 | @Target(ElementType.TYPE) 26 | @Retention(RetentionPolicy.RUNTIME) 27 | public @interface ResourceGroup { 28 | String name() default ""; 29 | 30 | Class[] resourceGroupClass() default {}; 31 | } 32 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/annotation/TemplateName.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.proxy.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Target(ElementType.METHOD) 24 | @Retention(RetentionPolicy.RUNTIME) 25 | public @interface TemplateName { 26 | String value(); 27 | } 28 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/annotation/Var.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.proxy.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Target(ElementType.PARAMETER) 24 | @Retention(RetentionPolicy.RUNTIME) 25 | public @interface Var { 26 | String value(); 27 | } 28 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/processor/AnnotationProcessor.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.proxy.processor; 2 | 3 | import com.netflix.ribbon.ResourceGroup.GroupBuilder; 4 | import com.netflix.ribbon.ResourceGroup.TemplateBuilder; 5 | import com.netflix.ribbon.RibbonResourceFactory; 6 | 7 | import java.lang.reflect.Method; 8 | 9 | /** 10 | * @author Tomasz Bak 11 | */ 12 | public interface AnnotationProcessor { 13 | 14 | void process(String templateName, S templateBuilder, Method method); 15 | 16 | void process(String groupName, T groupBuilder, RibbonResourceFactory resourceFactory, Class interfaceClass); 17 | } 18 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/processor/AnnotationProcessorsProvider.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.proxy.processor; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | import java.util.ServiceLoader; 6 | import java.util.concurrent.CopyOnWriteArrayList; 7 | 8 | /** 9 | * @author Tomasz Bak 10 | */ 11 | public abstract class AnnotationProcessorsProvider { 12 | 13 | public static final AnnotationProcessorsProvider DEFAULT = new DefaultAnnotationProcessorsProvider(); 14 | private final List processors = new CopyOnWriteArrayList(); 15 | 16 | public static class DefaultAnnotationProcessorsProvider extends AnnotationProcessorsProvider { 17 | protected DefaultAnnotationProcessorsProvider() { 18 | ServiceLoader loader = ServiceLoader.load(AnnotationProcessor.class); 19 | Iterator iterator = loader.iterator(); 20 | while (iterator.hasNext()) { 21 | register(iterator.next()); 22 | } 23 | } 24 | 25 | } 26 | 27 | public void register(AnnotationProcessor processor) { 28 | processors.add(processor); 29 | } 30 | 31 | public List getProcessors() { 32 | return processors; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/processor/CacheProviderAnnotationProcessor.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.proxy.processor; 2 | 3 | import com.netflix.ribbon.CacheProviderFactory; 4 | import com.netflix.ribbon.ResourceGroup.GroupBuilder; 5 | import com.netflix.ribbon.ResourceGroup.TemplateBuilder; 6 | import com.netflix.ribbon.RibbonResourceFactory; 7 | import com.netflix.ribbon.proxy.Utils; 8 | import com.netflix.ribbon.proxy.annotation.CacheProvider; 9 | 10 | import java.lang.reflect.Method; 11 | 12 | /** 13 | * @author Allen Wang 14 | */ 15 | public class CacheProviderAnnotationProcessor implements AnnotationProcessor { 16 | @Override 17 | public void process(String templateName, TemplateBuilder templateBuilder, Method method) { 18 | CacheProvider annotation = method.getAnnotation(CacheProvider.class); 19 | if (annotation != null) { 20 | CacheProviderFactory factory = Utils.newInstance(annotation.provider()); 21 | templateBuilder.withCacheProvider(annotation.key(), factory.createCacheProvider()); 22 | } 23 | } 24 | 25 | @Override 26 | public void process(String groupName, GroupBuilder groupBuilder, RibbonResourceFactory resourceFactory, Class interfaceClass) { 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/proxy/processor/HystrixAnnotationProcessor.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.proxy.processor; 2 | 3 | import com.netflix.ribbon.RibbonResourceFactory; 4 | import com.netflix.ribbon.http.HttpRequestTemplate.Builder; 5 | import com.netflix.ribbon.http.HttpResourceGroup; 6 | import com.netflix.ribbon.http.HttpResponseValidator; 7 | import com.netflix.ribbon.hystrix.FallbackHandler; 8 | import com.netflix.ribbon.proxy.ProxyAnnotationException; 9 | import com.netflix.ribbon.proxy.Utils; 10 | import com.netflix.ribbon.proxy.annotation.Hystrix; 11 | 12 | import java.lang.reflect.Method; 13 | 14 | import static java.lang.String.format; 15 | 16 | /** 17 | * @author Allen Wang 18 | */ 19 | public class HystrixAnnotationProcessor implements AnnotationProcessor { 20 | @Override 21 | public void process(String templateName, Builder templateBuilder, Method method) { 22 | Hystrix annotation = method.getAnnotation(Hystrix.class); 23 | if (annotation == null) { 24 | return; 25 | } 26 | String cacheKey = annotation.cacheKey().trim(); 27 | if (!cacheKey.isEmpty()) { 28 | templateBuilder.withRequestCacheKey(cacheKey); 29 | } 30 | if (annotation.fallbackHandler().length == 1) { 31 | FallbackHandler hystrixFallbackHandler = Utils.newInstance(annotation.fallbackHandler()[0]); 32 | templateBuilder.withFallbackProvider(hystrixFallbackHandler); 33 | } else if (annotation.fallbackHandler().length > 1) { 34 | throw new ProxyAnnotationException(format("more than one fallback handler defined for method %s", method.getName())); 35 | } 36 | if (annotation.validator().length == 1) { 37 | HttpResponseValidator hystrixResponseValidator = Utils.newInstance(annotation.validator()[0]); 38 | templateBuilder.withResponseValidator(hystrixResponseValidator); 39 | } else if (annotation.validator().length > 1) { 40 | throw new ProxyAnnotationException(format("more than one validator defined for method %s", method.getName())); 41 | } 42 | } 43 | 44 | @Override 45 | public void process(String groupName, HttpResourceGroup.Builder groupBuilder, RibbonResourceFactory resourceFactory, Class interfaceClass) { 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/template/MatrixVar.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.template; 17 | 18 | 19 | /** 20 | * MatrixVar is used to represent a matrix parameter in a URI template. eg var in /template{;var} 21 | */ 22 | class MatrixVar extends TemplateVar { 23 | MatrixVar(String val) { 24 | super(val); 25 | } 26 | } -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/template/ParsedTemplate.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.template; 17 | 18 | import java.util.List; 19 | 20 | public class ParsedTemplate { 21 | 22 | private List parsed; 23 | private String template; 24 | 25 | public ParsedTemplate(List parsed, String template) { 26 | super(); 27 | this.parsed = parsed; 28 | this.template = template; 29 | } 30 | 31 | public final List getParsed() { 32 | return parsed; 33 | } 34 | 35 | public final String getTemplate() { 36 | return template; 37 | } 38 | 39 | public static ParsedTemplate create(String template) { 40 | List parsed = TemplateParser.parseTemplate(template); 41 | return new ParsedTemplate(parsed, template); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/template/PathVar.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.template; 17 | 18 | 19 | /** 20 | * PathVar is used to represent a variable path portion of a URI template. eg {var} in /template/{var} 21 | */ 22 | class PathVar extends TemplateVar { 23 | PathVar(String val) { 24 | super(val); 25 | } 26 | } -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/template/TemplateParsingException.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.template; 17 | 18 | public class TemplateParsingException extends Exception { 19 | 20 | /** 21 | * 22 | */ 23 | private static final long serialVersionUID = 1910187667077051723L; 24 | 25 | public TemplateParsingException(String arg0, Throwable arg1) { 26 | super(arg0, arg1); 27 | } 28 | 29 | public TemplateParsingException(String arg0) { 30 | super(arg0); 31 | } 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /ribbon/src/main/java/com/netflix/ribbon/template/TemplateVar.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.template; 17 | 18 | 19 | /** 20 | * TemplateVar is a base type for use in the template parser & URI Fragment builder to isolate template values from 21 | * static values 22 | */ 23 | class TemplateVar { 24 | private final String val; 25 | 26 | TemplateVar(String val) { 27 | this.val = val; 28 | } 29 | 30 | public String toString() { 31 | return val; 32 | } 33 | } -------------------------------------------------------------------------------- /ribbon/src/test/java/com/netflix/ribbon/proxy/UtilsTest.java: -------------------------------------------------------------------------------- 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 | package com.netflix.ribbon.proxy; 17 | 18 | import org.junit.Test; 19 | 20 | import java.io.InputStream; 21 | import java.lang.reflect.Method; 22 | 23 | import static junit.framework.Assert.*; 24 | 25 | /** 26 | * @author Tomasz Bak 27 | */ 28 | public class UtilsTest { 29 | 30 | @Test 31 | public void testMethodByName() throws Exception { 32 | Method source = Utils.methodByName(String.class, "equals"); 33 | assertNotNull(source); 34 | assertEquals("equals", source.getName()); 35 | 36 | assertNull(Utils.methodByName(String.class, "not_equals")); 37 | } 38 | 39 | @Test 40 | public void testExecuteOnInstance() throws Exception { 41 | Method source = Utils.methodByName(String.class, "equals"); 42 | Object obj = new Object(); 43 | assertEquals(Boolean.TRUE, Utils.executeOnInstance(obj, source, new Object[]{obj})); 44 | assertEquals(Boolean.FALSE, Utils.executeOnInstance(obj, source, new Object[]{this})); 45 | } 46 | 47 | @Test(expected = IllegalArgumentException.class) 48 | public void testExecuteNotExistingMethod() throws Exception { 49 | Method source = Utils.methodByName(String.class, "getChars"); 50 | Utils.executeOnInstance(new Object(), source, new Object[]{}); 51 | } 52 | 53 | @Test 54 | public void testNewInstance() throws Exception { 55 | assertNotNull(Utils.newInstance(Object.class)); 56 | } 57 | 58 | @Test(expected = RibbonProxyException.class) 59 | public void testNewInstanceForFailure() throws Exception { 60 | Utils.newInstance(InputStream.class); 61 | } 62 | } -------------------------------------------------------------------------------- /ribbon/src/test/java/com/netflix/ribbon/proxy/sample/HystrixHandlers.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.proxy.sample; 18 | 19 | import com.netflix.hystrix.HystrixInvokableInfo; 20 | import com.netflix.ribbon.ServerError; 21 | import com.netflix.ribbon.UnsuccessfulResponseException; 22 | import com.netflix.ribbon.http.HttpResponseValidator; 23 | import com.netflix.ribbon.hystrix.FallbackHandler; 24 | 25 | import io.netty.buffer.ByteBuf; 26 | import io.reactivex.netty.protocol.http.client.HttpClientResponse; 27 | import rx.Observable; 28 | 29 | import java.util.Map; 30 | 31 | /** 32 | * @author Tomasz Bak 33 | */ 34 | public class HystrixHandlers { 35 | 36 | public static class SampleHttpResponseValidator implements HttpResponseValidator { 37 | 38 | @Override 39 | public void validate(HttpClientResponse response) throws UnsuccessfulResponseException, ServerError { 40 | } 41 | } 42 | 43 | public static class MovieFallbackHandler implements FallbackHandler { 44 | 45 | @Override 46 | public Observable getFallback(HystrixInvokableInfo hystrixInfo, Map requestProperties) { 47 | return null; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ribbon/src/test/java/com/netflix/ribbon/proxy/sample/Movie.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.proxy.sample; 2 | 3 | /** 4 | * @author Tomasz Bak 5 | */ 6 | public class Movie { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /ribbon/src/test/java/com/netflix/ribbon/proxy/sample/MovieTransformer.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.proxy.sample; 18 | 19 | import io.netty.buffer.ByteBuf; 20 | import io.netty.buffer.ByteBufAllocator; 21 | import io.reactivex.netty.channel.ContentTransformer; 22 | 23 | /** 24 | * @author Tomasz Bak 25 | */ 26 | public class MovieTransformer implements ContentTransformer { 27 | @Override 28 | public ByteBuf call(MovieTransformer toTransform, ByteBufAllocator byteBufAllocator) { 29 | return null; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ribbon/src/test/java/com/netflix/ribbon/proxy/sample/ResourceGroupClasses.java: -------------------------------------------------------------------------------- 1 | package com.netflix.ribbon.proxy.sample; 2 | 3 | import com.netflix.ribbon.http.HttpResourceGroup; 4 | 5 | /** 6 | * @author Tomasz Bak 7 | */ 8 | public class ResourceGroupClasses { 9 | public static class SampleHttpResourceGroup extends HttpResourceGroup { 10 | public SampleHttpResourceGroup() { 11 | super("myTestGroup"); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ribbon/src/test/java/com/netflix/ribbon/proxy/sample/SampleCacheProviderFactory.java: -------------------------------------------------------------------------------- 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 | 17 | package com.netflix.ribbon.proxy.sample; 18 | 19 | import com.netflix.ribbon.CacheProvider; 20 | import com.netflix.ribbon.CacheProviderFactory; 21 | 22 | import rx.Observable; 23 | 24 | import java.util.Map; 25 | 26 | /** 27 | * @author Tomasz Bak 28 | */ 29 | public class SampleCacheProviderFactory implements CacheProviderFactory { 30 | 31 | @Override 32 | public CacheProvider createCacheProvider() { 33 | return new SampleCacheProvider(); 34 | } 35 | 36 | public static class SampleCacheProvider implements CacheProvider { 37 | 38 | @Override 39 | public Observable get(String key, Map requestProperties) { 40 | return null; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ribbon/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootCategory=INFO,stdout 2 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d %-5p %C:%L [%t] [%M] %m%n 5 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name='ribbon' 2 | include 'ribbon-core' 3 | include 'ribbon-archaius' 4 | include 'ribbon-loadbalancer' 5 | include 'ribbon-httpclient' 6 | include 'ribbon-eureka' 7 | include 'ribbon-transport' 8 | include 'ribbon-examples' 9 | include 'ribbon-test' 10 | include 'ribbon-guice' 11 | include 'ribbon' 12 | include 'ribbon-evcache' 13 | --------------------------------------------------------------------------------