From 48e1618cddfacbbaee2f004416ab010a239c0e2c Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Tue, 14 Jan 2020 20:32:13 -0500 Subject: [PATCH] Removes modules in maintenance mode. fixes gh-3415 --- docs/pom.xml | 32 +- pom.xml | 36 +- spring-cloud-netflix-archaius/pom.xml | 48 - .../archaius/ArchaiusAutoConfiguration.java | 241 ---- .../ArchaiusDelegatingProxyUtils.java | 56 - .../netflix/archaius/ArchaiusEndpoint.java | 73 -- .../ConfigurableEnvironmentConfiguration.java | 107 -- ...itional-spring-configuration-metadata.json | 10 - .../main/resources/META-INF/spring.factories | 2 - .../ArchaiusAutoConfigurationTests.java | 108 -- .../archaius/ArchaiusEndpointTests.java | 56 - .../archaius/LazyLoadConfigurationTests.java | 50 - .../TestArchaiusExternalConfiguration.java | 41 - .../src/test/resources/config.properties | 2 - .../pom.xml | 2 +- spring-cloud-netflix-core/pom.xml | 47 - .../netflix/core/CoreAutoConfiguration.java | 42 - .../main/resources/META-INF/spring.factories | 2 - spring-cloud-netflix-dependencies/pom.xml | 262 +--- spring-cloud-netflix-eureka-client/pom.xml | 45 +- ...EurekaLoadBalancerClientConfiguration.java | 2 +- .../eureka => eureka/support}/ZoneUtils.java | 2 +- .../ConditionalOnRibbonAndEurekaEnabled.java | 74 -- .../eureka/DomainExtractingServerList.java | 119 -- .../EurekaRibbonClientConfiguration.java | 151 --- .../eureka/EurekaServerIntrospector.java | 51 - .../eureka/RibbonEurekaAutoConfiguration.java | 39 - .../main/resources/META-INF/spring.factories | 1 - .../support}/ZoneUtilsTests.java | 4 +- .../DomainExtractingServerListTests.java | 137 -- ...aDisabledRibbonClientIntegrationTests.java | 96 -- .../EurekaRibbonClientConfigurationTests.java | 131 -- ...bonClientPreprocessorIntegrationTests.java | 90 -- ...lientPropertyOverrideIntegrationTests.java | 88 -- ...bonClientPreprocessorIntegrationTests.java | 124 -- .../RibbonEurekaAutoConfigurationTests.java | 104 -- spring-cloud-netflix-eureka-server/pom.xml | 17 +- .../eureka/server/EurekaController.java | 7 +- .../eureka/server/EurekaServerBootstrap.java | 37 - spring-cloud-netflix-hystrix-contract/pom.xml | 115 -- .../contract/HystrixContractUtils.java | 88 -- .../src/main/resources/stubs/simpleBody.json | 72 -- .../pom.xml | 64 - .../dashboard/EnableHystrixDashboard.java | 36 - .../HystrixDashboardConfiguration.java | 297 ----- .../dashboard/HystrixDashboardController.java | 53 - .../dashboard/HystrixDashboardProperties.java | 57 - .../hystrixCommand/hystrixCommand.css | 200 --- .../hystrixCommand/hystrixCommand.js | 542 -------- .../magnifying-glass-icon-20.png | Bin 863 -> 0 bytes .../hystrixCommand/magnifying-glass-icon.png | Bin 13416 -> 0 bytes .../templates/hystrixCircuit.html | 77 -- .../templates/hystrixCircuitContainer.html | 40 - .../templates/hystrixCircuitProperties.html | 6 - .../hystrixThreadPool/hystrixThreadPool.css | 141 --- .../hystrixThreadPool/hystrixThreadPool.js | 343 ----- .../templates/hystrixThreadPool.html | 33 - .../templates/hystrixThreadPoolContainer.html | 34 - .../resources/static/hystrix/css/global.css | 71 -- .../resources/static/hystrix/css/monitor.css | 105 -- .../resources/static/hystrix/css/resets.css | 102 -- .../hystrix/css/simplegrid/1236_grid.css | 21 - .../hystrix/css/simplegrid/720_grid.css | 33 - .../hystrix/css/simplegrid/986_grid.css | 24 - .../static/hystrix/css/simplegrid/LICENSE.txt | 19 - .../static/hystrix/css/simplegrid/README.txt | 1 - .../css/simplegrid/percentage_grid.css | 27 - .../images/hystrix-logo-tagline-tiny.png | Bin 13315 -> 0 bytes .../static/hystrix/images/hystrix-logo.png | Bin 55931 -> 0 bytes .../static/hystrix/js/jquery.tinysort.min.js | 12 - .../main/resources/static/hystrix/js/tmpl.js | 43 - .../resources/templates/hystrix/index.ftlh | 58 - .../resources/templates/hystrix/monitor.ftlh | 202 --- .../HystrixDashboardConfigurationTests.java | 114 -- .../HystrixDashboardContextTests.java | 103 -- .../HystrixDashboardHomePageTests.java | 85 -- .../dashboard/HystrixDashboardTests.java | 81 -- .../src/test/resources/templates/test.txt | 1 - spring-cloud-netflix-hystrix-stream/pom.xml | 171 --- .../HystrixStreamAutoConfiguration.java | 116 -- .../hystrix/stream/HystrixStreamClient.java | 41 - .../stream/HystrixStreamProperties.java | 124 -- .../hystrix/stream/HystrixStreamTask.java | 394 ------ .../main/resources/META-INF/spring.factories | 2 - ...mAutoConfigurationNoRegistrationTests.java | 64 - .../HystrixStreamAutoConfigurationTests.java | 55 - .../stream/HystrixStreamTaskTests.java | 97 -- .../hystrix/stream/HystrixStreamTests.java | 102 -- .../hystrix/stream/StreamSourceTestBase.java | 242 ---- .../src/test/resources/application.yml | 6 - .../shouldProduceValidMetricsData.groovy | 29 - spring-cloud-netflix-hystrix/pom.xml | 186 --- .../hystrix/AbstractHystrixConfigBuilder.java | 73 -- .../cloud/netflix/hystrix/EnableHystrix.java | 45 - .../hystrix/HystrixAutoConfiguration.java | 130 -- .../hystrix/HystrixCircuitBreaker.java | 56 - ...ystrixCircuitBreakerAutoConfiguration.java | 54 - .../HystrixCircuitBreakerConfiguration.java | 67 - .../hystrix/HystrixCircuitBreakerFactory.java | 73 -- .../netflix/hystrix/HystrixCommands.java | 231 ---- .../netflix/hystrix/HystrixConstants.java | 33 - .../hystrix/HystrixHealthIndicator.java | 68 - .../hystrix/HystrixMetricsProperties.java | 77 -- .../netflix/hystrix/HystrixProperties.java | 43 - .../hystrix/HystrixStreamEndpoint.java | 49 - .../hystrix/HystrixWebfluxEndpoint.java | 47 - .../ReactiveHystrixCircuitBreaker.java | 84 -- ...ystrixCircuitBreakerAutoConfiguration.java | 52 - .../ReactiveHystrixCircuitBreakerFactory.java | 75 -- .../HystrixSecurityAutoConfiguration.java | 111 -- .../SecurityContextConcurrencyStrategy.java | 90 -- ...itional-spring-configuration-metadata.json | 22 - .../main/resources/META-INF/spring.factories | 8 - .../cloud/netflix/AdhocTestSuite.java | 110 -- .../HystrixAutoConfigurationTests.java | 61 - .../HystrixCircuitBreakerIntegrationTest.java | 133 -- .../hystrix/HystrixCircuitBreakerTest.java | 45 - .../netflix/hystrix/HystrixCommandsTests.java | 136 -- .../hystrix/HystrixConfigurationTests.java | 60 - .../netflix/hystrix/HystrixOnlyTests.java | 204 --- .../hystrix/HystrixStreamEndpointTests.java | 132 -- .../hystrix/HystrixWebfluxEndpointTests.java | 99 -- ...eHystrixCircuitBreakerIntegrationTest.java | 155 --- .../ReactiveHystrixCircuitBreakerTest.java | 70 -- .../security/HystrixSecurityApplication.java | 29 - .../HystrixSecurityAutoConfigurationTest.java | 125 -- .../security/HystrixSecurityNoFeignTests.java | 43 - .../app/CustomConcurrenyStrategy.java | 41 - .../security/app/UsernameController.java | 35 - .../resttemplate/RestTemplateRetryTests.java | 314 ----- .../HttpClientStatusCodeExceptionTest.java | 80 -- .../okhttp/OkHttpStatusCodeExceptionTest.java | 58 - .../netflix/test/NoSecurityConfiguration.java | 31 - .../netflix/test/TestAutoConfiguration.java | 71 -- .../test/resources/META-INF/spring.factories | 2 - .../src/test/resources/application.yml | 35 - .../src/test/resources/archaius_db_store.sql | 8 - .../src/test/resources/config.properties.bak | 2 - .../src/test/resources/static/index.html | 28 - spring-cloud-netflix-ribbon/pom.xml | 128 -- .../ribbon/DefaultServerIntrospector.java | 49 - .../netflix/ribbon/PropertiesFactory.java | 84 -- .../ribbon/RestClientRibbonConfiguration.java | 64 - .../RibbonApplicationContextInitializer.java | 57 - .../ribbon/RibbonAutoConfiguration.java | 198 --- .../cloud/netflix/ribbon/RibbonClient.java | 71 -- .../ribbon/RibbonClientConfiguration.java | 226 ---- .../RibbonClientConfigurationRegistrar.java | 89 -- .../RibbonClientHttpRequestFactory.java | 57 - .../netflix/ribbon/RibbonClientName.java | 42 - .../ribbon/RibbonClientSpecification.java | 82 -- .../cloud/netflix/ribbon/RibbonClients.java | 45 - .../ribbon/RibbonEagerLoadProperties.java | 52 - .../netflix/ribbon/RibbonHttpRequest.java | 126 -- .../netflix/ribbon/RibbonHttpResponse.java | 74 -- .../RibbonLoadBalancedRetryFactory.java | 55 - .../ribbon/RibbonLoadBalancedRetryPolicy.java | 178 --- .../ribbon/RibbonLoadBalancerClient.java | 278 ----- .../ribbon/RibbonLoadBalancerContext.java | 66 - .../netflix/ribbon/RibbonProperties.java | 222 ---- .../netflix/ribbon/RibbonStatsRecorder.java | 62 - .../cloud/netflix/ribbon/RibbonUtils.java | 188 --- .../netflix/ribbon/ServerIntrospector.java | 32 - .../ribbon/ServerIntrospectorProperties.java | 65 - .../netflix/ribbon/SpringClientFactory.java | 134 -- .../netflix/ribbon/StaticServerList.java | 49 - .../ZonePreferenceServerListFilter.java | 96 -- .../apache/HttpClientRibbonConfiguration.java | 154 --- .../apache/HttpClientStatusCodeException.java | 54 - .../ribbon/apache/HttpClientUtils.java | 58 - ...etryableRibbonLoadBalancingHttpClient.java | 203 --- .../apache/RibbonApacheHttpRequest.java | 85 -- .../apache/RibbonApacheHttpResponse.java | 173 --- .../apache/RibbonLoadBalancingHttpClient.java | 111 -- .../okhttp/OkHttpLoadBalancingClient.java | 96 -- .../okhttp/OkHttpRibbonConfiguration.java | 126 -- .../ribbon/okhttp/OkHttpRibbonRequest.java | 138 -- .../ribbon/okhttp/OkHttpRibbonResponse.java | 155 --- .../okhttp/OkHttpStatusCodeException.java | 53 - .../RetryableOkHttpLoadBalancingClient.java | 198 --- .../support/AbstractLoadBalancingClient.java | 163 --- .../ribbon/support/ContextAwareRequest.java | 84 -- .../ResettableServletInputStreamWrapper.java | 64 - .../ribbon/support/RibbonCommandContext.java | 245 ---- .../support/RibbonRequestCustomizer.java | 51 - .../ribbon/support/RibbonRetryPolicy.java | 118 -- ...itional-spring-configuration-metadata.json | 28 - .../main/resources/META-INF/spring.factories | 2 - ...DefaultServerIntrospectorDefaultTests.java | 67 - .../DefaultServerIntrospectorTests.java | 68 - ...bonClientPreprocessorIntegrationTests.java | 62 - ...bonApplicationContextInitializerTests.java | 98 -- ...bbonAutoConfigurationIntegrationTests.java | 64 - ...onClientConfigurationIntegrationTests.java | 71 -- .../RibbonClientConfigurationTests.java | 219 ---- .../RibbonClientHttpRequestFactoryTests.java | 219 ---- ...bonClientPreprocessorIntegrationTests.java | 81 -- ...PreprocessorOverridesIntegrationTests.java | 168 --- ...ClientPreprocessorOverridesRetryTests.java | 126 -- ...orPropertiesOverridesIntegrationTests.java | 114 -- ...RibbonClientsEagerInitializationTests.java | 80 -- ...onClientsPreprocessorIntegrationTests.java | 102 -- .../netflix/ribbon/RibbonDisabledTests.java | 47 - .../ribbon/RibbonInterceptorTests.java | 129 -- .../RibbonLoadBalancedRetryFactoryTests.java | 348 ------ .../ribbon/RibbonLoadBalancerClientTests.java | 348 ------ .../netflix/ribbon/RibbonPropertiesTests.java | 39 - .../netflix/ribbon/RibbonUtilsTests.java | 174 --- .../ribbon/SpringClientFactoryTests.java | 130 -- .../ribbon/SpringRetryDisabledTests.java | 60 - .../ribbon/SpringRetryEnabledTests.java | 67 - .../ZonePreferenceServerListFilterTests.java | 71 -- .../apache/RibbonApacheHttpRequestTests.java | 145 --- .../apache/RibbonApacheHttpResponseTests.java | 71 -- .../RibbonLoadBalancingHttpClientTests.java | 1109 ----------------- .../OkHttpLoadBalancingClientTests.java | 202 --- .../okhttp/OkHttpRibbonRequestTests.java | 128 -- .../okhttp/OkHttpRibbonResponseTests.java | 72 -- .../SpringRetryDisableOkHttpClientTests.java | 64 - .../SpringRetryEnabledOkHttpClientTests.java | 186 --- .../support/ContextAwareRequestTests.java | 119 -- .../support/RibbonCommandContextTest.java | 106 -- ...RibbonClientDefaultConfigurationTests.java | 78 -- ...ClientDefaultConfigurationTestsConfig.java | 85 -- .../ribbon/test/TestAutoConfiguration.java | 76 -- .../netflix/ribbon/test/TestLoadBalancer.java | 27 - .../netflix/ribbon/test/TestServerList.java | 50 - .../test/resources/META-INF/spring.factories | 2 - .../src/test/resources/application.yml | 8 - spring-cloud-netflix-sidecar/pom.xml | 104 -- spring-cloud-netflix-sidecar/run-server.sh | 1 - .../cloud/netflix/sidecar/EnableSidecar.java | 40 - .../LocalApplicationHealthCheckHandler.java | 59 - .../LocalApplicationHealthIndicator.java | 72 -- .../sidecar/SidecarAutoConfiguration.java | 204 --- .../netflix/sidecar/SidecarController.java | 66 - .../sidecar/SidecarMarkerConfiguration.java | 40 - .../netflix/sidecar/SidecarProperties.java | 142 --- .../main/resources/META-INF/spring.factories | 2 - .../AcceptAllSslCertificatesContextTests.java | 102 -- ...thPropertiesEurekaTestConfigBeanTests.java | 52 - .../sidecar/EurekaTestConfigBeanTests.java | 52 - ...calApplicationHealthCheckHandlerTests.java | 73 -- ...textPathStatusAndHealthCheckUrlsTests.java | 53 - .../NewPropertyEurekaTestConfigBeanTests.java | 52 - .../netflix/sidecar/PreferIpAddressTests.java | 53 - .../netflix/sidecar/SecurePortEnableds.java | 47 - ...textPathStatusAndHealthCheckUrlsTests.java | 52 - .../netflix/sidecar/SidecarApplication.java | 66 - .../sidecar/SidecarApplicationTests.java | 228 ---- .../src/test/resources/application.yml | 30 - .../src/test/resources/bootstrap.yml | 7 - .../src/test/resources/health.json | 1 - spring-cloud-netflix-turbine-stream/.jdk8 | 0 spring-cloud-netflix-turbine-stream/pom.xml | 140 --- .../turbine/stream/EnableTurbineStream.java | 39 - .../stream/HystrixStreamAggregator.java | 111 -- .../turbine/stream/TurbineApplication.java | 39 - .../turbine/stream/TurbineController.java | 68 - .../TurbineStreamAutoConfiguration.java | 79 -- .../turbine/stream/TurbineStreamClient.java | 36 - .../stream/TurbineStreamConfiguration.java | 53 - .../stream/TurbineStreamProperties.java | 77 -- .../main/resources/META-INF/spring.factories | 2 - .../src/main/resources/turbine.yml | 10 - .../stream/HystrixStreamAggregatorTests.java | 102 -- .../TurbineStreamConfigurationTest.java | 69 - .../turbine/stream/TurbineStreamTests.java | 202 --- spring-cloud-netflix-turbine/pom.xml | 97 -- .../netflix/turbine/ClusterInformation.java | 78 -- .../turbine/CommonsInstanceDiscovery.java | 234 ---- ...igurationBasedTurbineClustersProvider.java | 49 - .../cloud/netflix/turbine/EnableTurbine.java | 36 - .../EurekaBasedTurbineClustersProvider.java | 57 - .../turbine/EurekaInstanceDiscovery.java | 153 --- .../turbine/SpringAggregatorFactory.java | 145 --- .../netflix/turbine/SpringClusterMonitor.java | 127 -- .../turbine/TurbineAggregatorProperties.java | 69 - .../turbine/TurbineClustersProvider.java | 30 - .../netflix/turbine/TurbineController.java | 46 - .../turbine/TurbineHttpConfiguration.java | 125 -- .../turbine/TurbineInformationService.java | 85 -- .../netflix/turbine/TurbineLifecycle.java | 81 -- .../netflix/turbine/TurbineProperties.java | 102 -- .../turbine/AdhocTurbineTestSuite.java | 35 - .../CommonsInstanceDiscoveryTests.java | 191 --- ...ationBasedTurbineClustersProviderTest.java | 49 - ...urekaBasedTurbineClustersProviderTest.java | 61 - .../turbine/EurekaInstanceDiscoveryTests.java | 200 --- .../TurbineAggregatorPropertiesTest.java | 75 -- .../netflix/turbine/TurbineHttpTests.java | 90 -- spring-cloud-netflix-zuul/pom.xml | 128 -- .../cloud/netflix/zuul/EnableZuulProxy.java | 44 - .../cloud/netflix/zuul/EnableZuulServer.java | 44 - .../cloud/netflix/zuul/FiltersEndpoint.java | 69 - .../RibbonCommandFactoryConfiguration.java | 164 --- .../cloud/netflix/zuul/RoutesEndpoint.java | 205 --- .../netflix/zuul/RoutesRefreshedEvent.java | 39 - .../netflix/zuul/ZuulFilterInitializer.java | 97 -- .../zuul/ZuulProxyAutoConfiguration.java | 182 --- .../zuul/ZuulProxyMarkerConfiguration.java | 41 - ...uulRouteApplicationContextInitializer.java | 59 - .../zuul/ZuulServerAutoConfiguration.java | 329 ----- .../zuul/ZuulServerMarkerConfiguration.java | 41 - .../cloud/netflix/zuul/ZuulServletFilter.java | 52 - .../zuul/filters/CompositeRouteLocator.java | 83 -- .../zuul/filters/ProxyRequestHelper.java | 323 ----- .../zuul/filters/RefreshableRouteLocator.java | 28 - .../cloud/netflix/zuul/filters/Route.java | 185 --- .../netflix/zuul/filters/RouteLocator.java | 46 - .../zuul/filters/SimpleRouteLocator.java | 248 ---- .../zuul/filters/TraceProxyRequestHelper.java | 190 --- .../netflix/zuul/filters/ZuulProperties.java | 967 -------------- .../DiscoveryClientRouteLocator.java | 190 --- .../discovery/PatternServiceRouteMapper.java | 91 -- .../filters/discovery/ServiceRouteMapper.java | 34 - .../discovery/SimpleServiceRouteMapper.java | 31 - .../filters/post/LocationRewriteFilter.java | 162 --- .../zuul/filters/post/SendErrorFilter.java | 200 --- .../zuul/filters/post/SendResponseFilter.java | 387 ------ .../netflix/zuul/filters/pre/DebugFilter.java | 72 -- .../filters/pre/FormBodyWrapperFilter.java | 236 ---- .../zuul/filters/pre/PreDecorationFilter.java | 306 ----- .../filters/pre/Servlet30RequestWrapper.java | 45 - .../filters/pre/Servlet30WrapperFilter.java | 87 -- .../filters/pre/ServletDetectionFilter.java | 85 -- .../zuul/filters/route/FallbackProvider.java | 43 - .../route/RestClientRibbonCommand.java | 140 --- .../route/RestClientRibbonCommandFactory.java | 75 -- .../zuul/filters/route/RibbonCommand.java | 28 - .../filters/route/RibbonCommandFactory.java | 30 - .../filters/route/RibbonRoutingFilter.java | 241 ---- .../zuul/filters/route/SendForwardFilter.java | 79 -- .../route/SimpleHostRoutingFilter.java | 490 -------- .../route/apache/HttpClientRibbonCommand.java | 61 - .../HttpClientRibbonCommandFactory.java | 64 - .../route/okhttp/OkHttpRibbonCommand.java | 61 - .../okhttp/OkHttpRibbonCommandFactory.java | 63 - .../route/support/AbstractRibbonCommand.java | 261 ---- .../support/AbstractRibbonCommandFactory.java | 56 - .../zuul/filters/support/FilterConstants.java | 241 ---- .../zuul/metrics/DefaultCounterFactory.java | 41 - .../zuul/metrics/EmptyCounterFactory.java | 32 - .../zuul/metrics/EmptyTracerFactory.java | 48 - .../util/RequestContentDataExtractor.java | 177 --- .../cloud/netflix/zuul/util/RequestUtils.java | 54 - .../zuul/util/ZuulRuntimeException.java | 35 - .../netflix/zuul/web/ZuulController.java | 53 - .../netflix/zuul/web/ZuulHandlerMapping.java | 131 -- ...itional-spring-configuration-metadata.json | 22 - .../main/resources/META-INF/spring.factories | 3 - .../ContextPathZuulProxyApplicationTests.java | 120 -- .../netflix/zuul/FiltersEndpointTests.java | 109 -- .../zuul/FormZuulProxyApplicationTests.java | 318 ----- .../FormZuulServletProxyApplicationTests.java | 236 ---- .../RetryableZuulProxyApplicationTests.java | 162 --- .../zuul/RoutesEndpointDetailsTests.java | 107 -- .../zuul/RoutesEndpointIntegrationTests.java | 131 -- .../netflix/zuul/RoutesEndpointTests.java | 87 -- .../ServletPathZuulProxyApplicationTests.java | 165 --- .../zuul/SimpleZuulProxyApplicationTests.java | 188 --- .../SimpleZuulServerApplicationTests.java | 144 --- .../zuul/ZuulFilterInitializerTests.java | 113 -- .../zuul/ZuulProxyApplicationTests.java | 196 --- .../zuul/ZuulProxyAutoConfigurationTests.java | 65 - .../zuul/ZuulProxyConfigurationTests.java | 84 -- .../ZuulServerAutoConfigurationTests.java | 63 - .../filters/CompositeRouteLocatorTests.java | 112 -- .../filters/CustomHostRoutingFilterTests.java | 269 ---- .../zuul/filters/ProxyRequestHelperTests.java | 434 ------- .../zuul/filters/SimpleRouteLocatorTests.java | 155 --- .../zuul/filters/ZuulPropertiesTests.java | 114 -- .../DiscoveryClientRouteLocatorTests.java | 751 ----------- ...ernServiceRouteMapperIntegrationTests.java | 158 --- .../PatternServiceRouteMapperTests.java | 81 -- ...LocationRewriteFilterIntegrationTests.java | 116 -- .../post/LocationRewriteFilterTests.java | 191 --- .../post/SendErrorFilterIntegrationTests.java | 211 ---- .../filters/post/SendErrorFilterTests.java | 101 -- .../filters/post/SendResponseFilterTests.java | 426 ------- .../pre/FormBodyWrapperFilterTests.java | 223 ---- .../filters/pre/PreDecorationFilterTests.java | 711 ----------- .../EagerLoadOfZuulConfigurationTests.java | 93 -- .../LazyLoadOfZuulConfigurationTests.java | 136 -- .../route/RestClientRibbonCommandTests.java | 183 --- ...FilterLoadBalancerKeyIntegrationTests.java | 196 --- .../route/RibbonRoutingFilterTests.java | 195 --- .../filters/route/SendForwardFilterTests.java | 73 -- ...mpleHostRoutingFilterIntegrationTests.java | 393 ------ .../route/SimpleHostRoutingFilterTests.java | 374 ------ .../HttpClientRibbonCommandFactoryTest.java | 391 ------ .../HttpClientRibbonCommandFallbackTests.java | 45 - ...tpClientRibbonCommandIntegrationTests.java | 229 ---- ...HttpClientRibbonRetryIntegrationTests.java | 83 -- .../OkHttpRibbonCommandFactoryTest.java | 387 ------ .../OkHttpRibbonCommandFallbackTests.java | 47 - .../OkHttpRibbonCommandIntegrationTests.java | 157 --- .../OkHttpRibbonRetryIntegrationTests.java | 74 -- .../RestClientRibbonCommandFallbackTests.java | 44 - ...stClientRibbonCommandIntegrationTests.java | 461 ------- .../NoEncodingFormHttpMessageConverter.java | 69 - ...onCommandCauseFallbackPropagationTest.java | 276 ---- .../support/RibbonCommandFallbackTests.java | 168 --- ...ibbonCommandHystrixThreadPoolKeyTests.java | 136 -- .../RibbonRetryIntegrationTestBase.java | 263 ---- .../route/support/ZuulProxyTestBase.java | 578 --------- .../metrics/DefaultCounterFactoryTests.java | 45 - .../ZuulEmptyMetricsApplicationTests.java | 86 -- .../metrics/ZuulMetricsApplicationTests.java | 109 -- .../netflix/zuul/test/AdhocTestSuite.java | 92 -- .../netflix/zuul/test/AdhocZuulTestSuite.java | 91 -- .../zuul/test/NoSecurityConfiguration.java | 31 - .../zuul/test/TestAutoConfiguration.java | 64 - ...uulApacheHttpClientConfigurationTests.java | 141 --- .../ZuulOkHttpClientConfigurationTests.java | 98 -- .../util/RequestContentDataExtractorTest.java | 168 --- .../zuul/web/ZuulHandlerMappingTests.java | 120 -- .../test/resources/META-INF/spring.factories | 2 - .../src/test/resources/application.yml | 26 - .../pom.xml | 20 +- .../pom.xml | 16 +- spring-cloud-starter-netflix/pom.xml | 25 - .../pom.xml | 39 - .../pom.xml | 35 - .../pom.xml | 55 - .../pom.xml | 61 - .../pom.xml | 75 -- .../pom.xml | 61 - .../spring-cloud-starter-netflix-zuul/pom.xml | 51 - 429 files changed, 24 insertions(+), 47506 deletions(-) delete mode 100644 spring-cloud-netflix-archaius/pom.xml delete mode 100644 spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java delete mode 100644 spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusDelegatingProxyUtils.java delete mode 100644 spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpoint.java delete mode 100644 spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ConfigurableEnvironmentConfiguration.java delete mode 100644 spring-cloud-netflix-archaius/src/main/resources/META-INF/additional-spring-configuration-metadata.json delete mode 100644 spring-cloud-netflix-archaius/src/main/resources/META-INF/spring.factories delete mode 100644 spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java delete mode 100644 spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpointTests.java delete mode 100644 spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/LazyLoadConfigurationTests.java delete mode 100644 spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/TestArchaiusExternalConfiguration.java delete mode 100644 spring-cloud-netflix-archaius/src/test/resources/config.properties delete mode 100644 spring-cloud-netflix-core/pom.xml delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/core/CoreAutoConfiguration.java delete mode 100644 spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories rename spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/{ribbon/eureka => eureka/support}/ZoneUtils.java (95%) delete mode 100644 spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ConditionalOnRibbonAndEurekaEnabled.java delete mode 100644 spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java delete mode 100644 spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfiguration.java delete mode 100644 spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaServerIntrospector.java delete mode 100644 spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfiguration.java rename spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/{ribbon/eureka => eureka/support}/ZoneUtilsTests.java (90%) delete mode 100644 spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerListTests.java delete mode 100644 spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaDisabledRibbonClientIntegrationTests.java delete mode 100644 spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfigurationTests.java delete mode 100644 spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPreprocessorIntegrationTests.java delete mode 100644 spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPropertyOverrideIntegrationTests.java delete mode 100644 spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonClientPreprocessorIntegrationTests.java delete mode 100644 spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfigurationTests.java delete mode 100644 spring-cloud-netflix-hystrix-contract/pom.xml delete mode 100644 spring-cloud-netflix-hystrix-contract/src/main/java/org/springframework/cloud/netflix/hystrix/contract/HystrixContractUtils.java delete mode 100644 spring-cloud-netflix-hystrix-contract/src/main/resources/stubs/simpleBody.json delete mode 100644 spring-cloud-netflix-hystrix-dashboard/pom.xml delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/EnableHystrixDashboard.java delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardController.java delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardProperties.java delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/hystrixCommand.css delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/hystrixCommand.js delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/magnifying-glass-icon-20.png delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/magnifying-glass-icon.png delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuit.html delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuitContainer.html delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuitProperties.html delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/hystrixThreadPool.css delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/hystrixThreadPool.js delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/templates/hystrixThreadPool.html delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/templates/hystrixThreadPoolContainer.html delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/global.css delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/monitor.css delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/resets.css delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/1236_grid.css delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/720_grid.css delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/986_grid.css delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/LICENSE.txt delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/README.txt delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/percentage_grid.css delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/images/hystrix-logo-tagline-tiny.png delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/images/hystrix-logo.png delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/js/jquery.tinysort.min.js delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/js/tmpl.js delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/templates/hystrix/index.ftlh delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/main/resources/templates/hystrix/monitor.ftlh delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfigurationTests.java delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardContextTests.java delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardHomePageTests.java delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardTests.java delete mode 100644 spring-cloud-netflix-hystrix-dashboard/src/test/resources/templates/test.txt delete mode 100644 spring-cloud-netflix-hystrix-stream/pom.xml delete mode 100644 spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfiguration.java delete mode 100644 spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamClient.java delete mode 100644 spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamProperties.java delete mode 100644 spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTask.java delete mode 100644 spring-cloud-netflix-hystrix-stream/src/main/resources/META-INF/spring.factories delete mode 100644 spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfigurationNoRegistrationTests.java delete mode 100644 spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfigurationTests.java delete mode 100644 spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTaskTests.java delete mode 100644 spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTests.java delete mode 100644 spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/StreamSourceTestBase.java delete mode 100644 spring-cloud-netflix-hystrix-stream/src/test/resources/application.yml delete mode 100644 spring-cloud-netflix-hystrix-stream/src/test/resources/contracts/shouldProduceValidMetricsData.groovy delete mode 100644 spring-cloud-netflix-hystrix/pom.xml delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/AbstractHystrixConfigBuilder.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/EnableHystrix.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfiguration.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreaker.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerAutoConfiguration.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerConfiguration.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerFactory.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCommands.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixConstants.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixHealthIndicator.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixMetricsProperties.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixProperties.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpoint.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixWebfluxEndpoint.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreaker.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerAutoConfiguration.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerFactory.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityAutoConfiguration.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/security/SecurityContextConcurrencyStrategy.java delete mode 100644 spring-cloud-netflix-hystrix/src/main/resources/META-INF/additional-spring-configuration-metadata.json delete mode 100644 spring-cloud-netflix-hystrix/src/main/resources/META-INF/spring.factories delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/AdhocTestSuite.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfigurationTests.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerIntegrationTest.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerTest.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCommandsTests.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixConfigurationTests.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixOnlyTests.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpointTests.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixWebfluxEndpointTests.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerIntegrationTest.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerTest.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityApplication.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityAutoConfigurationTest.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityNoFeignTests.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/CustomConcurrenyStrategy.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/UsernameController.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/resttemplate/RestTemplateRetryTests.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientStatusCodeExceptionTest.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpStatusCodeExceptionTest.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/test/NoSecurityConfiguration.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/test/TestAutoConfiguration.java delete mode 100644 spring-cloud-netflix-hystrix/src/test/resources/META-INF/spring.factories delete mode 100644 spring-cloud-netflix-hystrix/src/test/resources/application.yml delete mode 100644 spring-cloud-netflix-hystrix/src/test/resources/archaius_db_store.sql delete mode 100644 spring-cloud-netflix-hystrix/src/test/resources/config.properties.bak delete mode 100644 spring-cloud-netflix-hystrix/src/test/resources/static/index.html delete mode 100644 spring-cloud-netflix-ribbon/pom.xml delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospector.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/PropertiesFactory.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RestClientRibbonConfiguration.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonApplicationContextInitializer.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClient.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationRegistrar.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactory.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientName.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientSpecification.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClients.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonEagerLoadProperties.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonHttpRequest.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonHttpResponse.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryFactory.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicy.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerContext.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonProperties.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonStatsRecorder.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonUtils.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospector.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospectorProperties.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/StaticServerList.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ZonePreferenceServerListFilter.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientRibbonConfiguration.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientStatusCodeException.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientUtils.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RetryableRibbonLoadBalancingHttpClient.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpRequest.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpResponse.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClient.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClient.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonConfiguration.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonRequest.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonResponse.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpStatusCodeException.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/RetryableOkHttpLoadBalancingClient.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/AbstractLoadBalancingClient.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequest.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/ResettableServletInputStreamWrapper.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonCommandContext.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonRequestCustomizer.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonRetryPolicy.java delete mode 100644 spring-cloud-netflix-ribbon/src/main/resources/META-INF/additional-spring-configuration-metadata.json delete mode 100644 spring-cloud-netflix-ribbon/src/main/resources/META-INF/spring.factories delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospectorDefaultTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospectorTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/PlainRibbonClientPreprocessorIntegrationTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonApplicationContextInitializerTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfigurationIntegrationTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationIntegrationTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactoryTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorIntegrationTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorOverridesIntegrationTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorOverridesRetryTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorPropertiesOverridesIntegrationTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsEagerInitializationTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsPreprocessorIntegrationTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonDisabledTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptorTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryFactoryTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonPropertiesTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonUtilsTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringClientFactoryTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringRetryDisabledTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringRetryEnabledTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/ZonePreferenceServerListFilterTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpRequestTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpResponseTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClientTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClientTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonRequestTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonResponseTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryDisableOkHttpClientTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryEnabledOkHttpClientTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequestTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/support/RibbonCommandContextTest.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/RibbonClientDefaultConfigurationTests.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/RibbonClientDefaultConfigurationTestsConfig.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestAutoConfiguration.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestLoadBalancer.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestServerList.java delete mode 100644 spring-cloud-netflix-ribbon/src/test/resources/META-INF/spring.factories delete mode 100644 spring-cloud-netflix-ribbon/src/test/resources/application.yml delete mode 100644 spring-cloud-netflix-sidecar/pom.xml delete mode 100755 spring-cloud-netflix-sidecar/run-server.sh delete mode 100644 spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/EnableSidecar.java delete mode 100644 spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandler.java delete mode 100644 spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthIndicator.java delete mode 100644 spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarAutoConfiguration.java delete mode 100644 spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarController.java delete mode 100644 spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarMarkerConfiguration.java delete mode 100644 spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarProperties.java delete mode 100644 spring-cloud-netflix-sidecar/src/main/resources/META-INF/spring.factories delete mode 100644 spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/AcceptAllSslCertificatesContextTests.java delete mode 100644 spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/BothPropertiesEurekaTestConfigBeanTests.java delete mode 100644 spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/EurekaTestConfigBeanTests.java delete mode 100644 spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandlerTests.java delete mode 100644 spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/ManagementContextPathStatusAndHealthCheckUrlsTests.java delete mode 100644 spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/NewPropertyEurekaTestConfigBeanTests.java delete mode 100644 spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/PreferIpAddressTests.java delete mode 100644 spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SecurePortEnableds.java delete mode 100644 spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/ServerContextPathStatusAndHealthCheckUrlsTests.java delete mode 100644 spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplication.java delete mode 100644 spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplicationTests.java delete mode 100644 spring-cloud-netflix-sidecar/src/test/resources/application.yml delete mode 100644 spring-cloud-netflix-sidecar/src/test/resources/bootstrap.yml delete mode 100644 spring-cloud-netflix-sidecar/src/test/resources/health.json delete mode 100644 spring-cloud-netflix-turbine-stream/.jdk8 delete mode 100644 spring-cloud-netflix-turbine-stream/pom.xml delete mode 100644 spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/EnableTurbineStream.java delete mode 100644 spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/HystrixStreamAggregator.java delete mode 100644 spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineApplication.java delete mode 100644 spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineController.java delete mode 100644 spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamAutoConfiguration.java delete mode 100644 spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamClient.java delete mode 100644 spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamConfiguration.java delete mode 100644 spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamProperties.java delete mode 100644 spring-cloud-netflix-turbine-stream/src/main/resources/META-INF/spring.factories delete mode 100644 spring-cloud-netflix-turbine-stream/src/main/resources/turbine.yml delete mode 100644 spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/HystrixStreamAggregatorTests.java delete mode 100644 spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamConfigurationTest.java delete mode 100644 spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamTests.java delete mode 100644 spring-cloud-netflix-turbine/pom.xml delete mode 100644 spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/ClusterInformation.java delete mode 100644 spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscovery.java delete mode 100644 spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/ConfigurationBasedTurbineClustersProvider.java delete mode 100644 spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EnableTurbine.java delete mode 100644 spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaBasedTurbineClustersProvider.java delete mode 100644 spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java delete mode 100644 spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringAggregatorFactory.java delete mode 100644 spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringClusterMonitor.java delete mode 100644 spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineAggregatorProperties.java delete mode 100644 spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineClustersProvider.java delete mode 100644 spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineController.java delete mode 100644 spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineHttpConfiguration.java delete mode 100644 spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineInformationService.java delete mode 100644 spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineLifecycle.java delete mode 100644 spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineProperties.java delete mode 100644 spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/AdhocTurbineTestSuite.java delete mode 100644 spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscoveryTests.java delete mode 100644 spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/ConfigurationBasedTurbineClustersProviderTest.java delete mode 100644 spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaBasedTurbineClustersProviderTest.java delete mode 100644 spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTests.java delete mode 100644 spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/TurbineAggregatorPropertiesTest.java delete mode 100644 spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/TurbineHttpTests.java delete mode 100644 spring-cloud-netflix-zuul/pom.xml delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulProxy.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulServer.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/FiltersEndpoint.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RibbonCommandFactoryConfiguration.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RoutesEndpoint.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RoutesRefreshedEvent.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializer.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfiguration.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyMarkerConfiguration.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulRouteApplicationContextInitializer.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServerAutoConfiguration.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServerMarkerConfiguration.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServletFilter.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/CompositeRouteLocator.java delete mode 100755 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/RefreshableRouteLocator.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/Route.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/RouteLocator.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocator.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/TraceProxyRequestHelper.java delete mode 100755 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/DiscoveryClientRouteLocator.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapper.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/ServiceRouteMapper.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/SimpleServiceRouteMapper.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilter.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilter.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/DebugFilter.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java delete mode 100755 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30RequestWrapper.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30WrapperFilter.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/ServletDetectionFilter.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/FallbackProvider.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommand.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommandFactory.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommand.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommandFactory.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SendForwardFilter.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommand.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactory.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommand.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactory.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommand.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommandFactory.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/support/FilterConstants.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/DefaultCounterFactory.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/EmptyCounterFactory.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/EmptyTracerFactory.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractor.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestUtils.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/ZuulRuntimeException.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/web/ZuulController.java delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/web/ZuulHandlerMapping.java delete mode 100644 spring-cloud-netflix-zuul/src/main/resources/META-INF/additional-spring-configuration-metadata.json delete mode 100644 spring-cloud-netflix-zuul/src/main/resources/META-INF/spring.factories delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ContextPathZuulProxyApplicationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FiltersEndpointTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulProxyApplicationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulServletProxyApplicationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointDetailsTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointIntegrationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ServletPathZuulProxyApplicationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulProxyApplicationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulServerApplicationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializerTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyApplicationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfigurationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfigurationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulServerAutoConfigurationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CompositeRouteLocatorTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CustomHostRoutingFilterTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelperTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocatorTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/ZuulPropertiesTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/DiscoveryClientRouteLocatorTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapperIntegrationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapperTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilterIntegrationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilterTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterIntegrationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilterTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilterTests.java delete mode 100755 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/EagerLoadOfZuulConfigurationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/LazyLoadOfZuulConfigurationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommandTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilterLoadBalancerKeyIntegrationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilterTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SendForwardFilterTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterIntegrationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactoryTest.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFallbackTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandIntegrationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonRetryIntegrationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactoryTest.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFallbackTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonRetryIntegrationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandFallbackTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandIntegrationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/NoEncodingFormHttpMessageConverter.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandCauseFallbackPropagationTest.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandFallbackTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandHystrixThreadPoolKeyTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonRetryIntegrationTestBase.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/DefaultCounterFactoryTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/ZuulEmptyMetricsApplicationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/ZuulMetricsApplicationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/AdhocTestSuite.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/AdhocZuulTestSuite.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/NoSecurityConfiguration.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/TestAutoConfiguration.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/ZuulApacheHttpClientConfigurationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/ZuulOkHttpClientConfigurationTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractorTest.java delete mode 100644 spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/web/ZuulHandlerMappingTests.java delete mode 100644 spring-cloud-netflix-zuul/src/test/resources/META-INF/spring.factories delete mode 100644 spring-cloud-netflix-zuul/src/test/resources/application.yml rename {spring-cloud-starter-netflix/spring-cloud-starter-netflix-eureka-client => spring-cloud-starter-netflix-eureka-client}/pom.xml (69%) rename {spring-cloud-starter-netflix/spring-cloud-starter-netflix-eureka-server => spring-cloud-starter-netflix-eureka-server}/pom.xml (71%) delete mode 100644 spring-cloud-starter-netflix/pom.xml delete mode 100644 spring-cloud-starter-netflix/spring-cloud-starter-netflix-archaius/pom.xml delete mode 100644 spring-cloud-starter-netflix/spring-cloud-starter-netflix-hystrix-dashboard/pom.xml delete mode 100644 spring-cloud-starter-netflix/spring-cloud-starter-netflix-hystrix/pom.xml delete mode 100644 spring-cloud-starter-netflix/spring-cloud-starter-netflix-ribbon/pom.xml delete mode 100644 spring-cloud-starter-netflix/spring-cloud-starter-netflix-turbine-stream/pom.xml delete mode 100644 spring-cloud-starter-netflix/spring-cloud-starter-netflix-turbine/pom.xml delete mode 100644 spring-cloud-starter-netflix/spring-cloud-starter-netflix-zuul/pom.xml diff --git a/docs/pom.xml b/docs/pom.xml index 8ff32cb88..1ea475814 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT + 3.0.0.BUILD-SNAPSHOT spring-cloud-netflix-docs pom @@ -15,14 +15,10 @@ spring-cloud-netflix 1.2.x,1.3.x,1.4.x - .*.eureka.*|.*.hystrix.*|.*.ribbon.*|.*.sidecar.*|.*.turbine.*|.*.zuul.*|.*.archaius.* + .*.eureka.* - - ${project.groupId} - spring-cloud-starter-netflix-archaius - ${project.groupId} spring-cloud-starter-netflix-eureka-client @@ -31,30 +27,6 @@ ${project.groupId} spring-cloud-starter-netflix-eureka-server - - ${project.groupId} - spring-cloud-starter-netflix-hystrix - - - ${project.groupId} - spring-cloud-starter-netflix-hystrix-dashboard - - - ${project.groupId} - spring-cloud-starter-netflix-ribbon - - - ${project.groupId} - spring-cloud-starter-netflix-turbine - - - ${project.groupId} - spring-cloud-starter-netflix-turbine-stream - - - ${project.groupId} - spring-cloud-starter-netflix-zuul - diff --git a/pom.xml b/pom.xml index ab7bfefb1..fe4cff6ee 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT + 3.0.0.BUILD-SNAPSHOT pom Spring Cloud Netflix Spring Cloud Netflix @@ -79,12 +79,6 @@ - - org.springframework.cloud - spring-cloud-netflix-hystrix-contract - ${project.version} - test - org.springframework.cloud spring-cloud-netflix-dependencies @@ -131,19 +125,6 @@ javax.inject 1 - - - commons-configuration - commons-configuration - 1.8 - - - commons-logging - commons-logging - - - - com.sun.jersey @@ -188,22 +169,11 @@ spring-cloud-netflix-dependencies - spring-cloud-netflix-archaius - - - spring-cloud-netflix-core spring-cloud-netflix-concurrency-limits - spring-cloud-netflix-hystrix-dashboard - spring-cloud-netflix-hystrix-stream spring-cloud-netflix-eureka-client spring-cloud-netflix-eureka-server - spring-cloud-netflix-turbine - spring-cloud-netflix-turbine-stream - spring-cloud-netflix-sidecar - spring-cloud-netflix-zuul - spring-cloud-netflix-ribbon - spring-cloud-starter-netflix - spring-cloud-netflix-hystrix + spring-cloud-starter-netflix-eureka-client + spring-cloud-starter-netflix-eureka-server docs diff --git a/spring-cloud-netflix-archaius/pom.xml b/spring-cloud-netflix-archaius/pom.xml deleted file mode 100644 index 09cf9f680..000000000 --- a/spring-cloud-netflix-archaius/pom.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - 4.0.0 - - spring-cloud-netflix - org.springframework.cloud - 2.2.2.BUILD-SNAPSHOT - .. - - - - spring-cloud-netflix-archaius - jar - Spring Cloud Netflix Archaius - Spring Cloud Netflix Archaius - - - - org.springframework.boot - spring-boot-starter-actuator - true - - - org.springframework.cloud - spring-cloud-context - true - - - com.netflix.archaius - archaius-core - true - - - commons-configuration - commons-configuration - true - - - - org.springframework.boot - spring-boot-starter-test - test - - - - diff --git a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java b/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java deleted file mode 100644 index dbabdee59..000000000 --- a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.archaius; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; - -import javax.annotation.PreDestroy; - -import com.netflix.config.AggregatedConfiguration; -import com.netflix.config.ConcurrentCompositeConfiguration; -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DeploymentContext; -import com.netflix.config.DynamicProperty; -import com.netflix.config.DynamicPropertyFactory; -import com.netflix.config.DynamicURLConfiguration; -import org.apache.commons.configuration.AbstractConfiguration; -import org.apache.commons.configuration.ConfigurationBuilder; -import org.apache.commons.configuration.EnvironmentConfiguration; -import org.apache.commons.configuration.SystemConfiguration; -import org.apache.commons.configuration.event.ConfigurationEvent; -import org.apache.commons.configuration.event.ConfigurationListener; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.autoconfigure.AutoConfigureOrder; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; -import org.springframework.core.Ordered; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.util.ReflectionUtils; - -import static com.netflix.config.ConfigurationManager.APPLICATION_PROPERTIES; -import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_ENV_CONFIG; -import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_SYS_CONFIG; -import static com.netflix.config.ConfigurationManager.ENV_CONFIG_NAME; -import static com.netflix.config.ConfigurationManager.SYS_CONFIG_NAME; -import static com.netflix.config.ConfigurationManager.URL_CONFIG_NAME; - -/** - * @author Spencer Gibb - * @author Liang Yong - */ -@Lazy(false) -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ ConcurrentCompositeConfiguration.class, - ConfigurationBuilder.class }) -@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) -public class ArchaiusAutoConfiguration { - - private static final Log log = LogFactory.getLog(ArchaiusAutoConfiguration.class); - - private static final AtomicBoolean initialized = new AtomicBoolean(false); - - @Autowired - private ConfigurableEnvironment env; - - @Autowired(required = false) - private List externalConfigurations = new ArrayList<>(); - - private static DynamicURLConfiguration defaultURLConfig; - - @PreDestroy - public void close() { - if (defaultURLConfig != null) { - defaultURLConfig.stopLoading(); - } - setStatic(ConfigurationManager.class, "instance", null); - setStatic(ConfigurationManager.class, "customConfigurationInstalled", false); - setStatic(DynamicPropertyFactory.class, "config", null); - setStatic(DynamicPropertyFactory.class, "initializedWithDefaultConfig", false); - setStatic(DynamicProperty.class, "dynamicPropertySupportImpl", null); - initialized.compareAndSet(true, false); - } - - @Bean - public static ConfigurableEnvironmentConfiguration configurableEnvironmentConfiguration( - ConfigurableEnvironment env, ApplicationContext context) { - Map abstractConfigurationMap = context - .getBeansOfType(AbstractConfiguration.class); - List externalConfigurations = new ArrayList<>( - abstractConfigurationMap.values()); - ConfigurableEnvironmentConfiguration envConfig = new ConfigurableEnvironmentConfiguration( - env); - configureArchaius(envConfig, env, externalConfigurations); - return envConfig; - } - - protected static void configureArchaius( - ConfigurableEnvironmentConfiguration envConfig, ConfigurableEnvironment env, - List externalConfigurations) { - if (initialized.compareAndSet(false, true)) { - String appName = env.getProperty("spring.application.name"); - if (appName == null) { - appName = "application"; - log.warn("No spring.application.name found, defaulting to 'application'"); - } - System.setProperty(DeploymentContext.ContextKey.appId.getKey(), appName); - - ConcurrentCompositeConfiguration config = new ConcurrentCompositeConfiguration(); - - // support to add other Configurations (Jdbc, DynamoDb, Zookeeper, jclouds, - // etc...) - if (externalConfigurations != null) { - for (AbstractConfiguration externalConfig : externalConfigurations) { - config.addConfiguration(externalConfig); - } - } - config.addConfiguration(envConfig, - ConfigurableEnvironmentConfiguration.class.getSimpleName()); - - defaultURLConfig = new DynamicURLConfiguration(); - try { - config.addConfiguration(defaultURLConfig, URL_CONFIG_NAME); - } - catch (Throwable ex) { - log.error("Cannot create config from " + defaultURLConfig, ex); - } - - // TODO: sys/env above urls? - if (!Boolean.getBoolean(DISABLE_DEFAULT_SYS_CONFIG)) { - SystemConfiguration sysConfig = new SystemConfiguration(); - config.addConfiguration(sysConfig, SYS_CONFIG_NAME); - } - if (!Boolean.getBoolean(DISABLE_DEFAULT_ENV_CONFIG)) { - EnvironmentConfiguration environmentConfiguration = new EnvironmentConfiguration(); - config.addConfiguration(environmentConfiguration, ENV_CONFIG_NAME); - } - - ConcurrentCompositeConfiguration appOverrideConfig = new ConcurrentCompositeConfiguration(); - config.addConfiguration(appOverrideConfig, APPLICATION_PROPERTIES); - config.setContainerConfigurationIndex( - config.getIndexOfConfiguration(appOverrideConfig)); - - addArchaiusConfiguration(config); - } - else { - // TODO: reinstall ConfigurationManager - log.warn( - "Netflix ConfigurationManager has already been installed, unable to re-install"); - } - } - - private static void addArchaiusConfiguration( - ConcurrentCompositeConfiguration config) { - if (ConfigurationManager.isConfigurationInstalled()) { - AbstractConfiguration installedConfiguration = ConfigurationManager - .getConfigInstance(); - if (installedConfiguration instanceof ConcurrentCompositeConfiguration) { - ConcurrentCompositeConfiguration configInstance = (ConcurrentCompositeConfiguration) installedConfiguration; - configInstance.addConfiguration(config); - } - else { - installedConfiguration.append(config); - if (!(installedConfiguration instanceof AggregatedConfiguration)) { - log.warn( - "Appending a configuration to an existing non-aggregated installed configuration will have no effect"); - } - } - } - else { - ConfigurationManager.install(config); - } - } - - private static void setStatic(Class type, String name, Object value) { - // Hack a private static field - Field field = ReflectionUtils.findField(type, name); - ReflectionUtils.makeAccessible(field); - ReflectionUtils.setField(field, null, value); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(Health.class) - protected static class ArchaiusEndpointConfiguration { - - @Bean - @ConditionalOnAvailableEndpoint - protected ArchaiusEndpoint archaiusEndpoint() { - return new ArchaiusEndpoint(); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnProperty(value = "archaius.propagate.environmentChangedEvent", - matchIfMissing = true) - @ConditionalOnClass(EnvironmentChangeEvent.class) - protected static class PropagateEventsConfiguration - implements ApplicationListener { - - @Autowired - private Environment env; - - @Override - public void onApplicationEvent(EnvironmentChangeEvent event) { - AbstractConfiguration manager = ConfigurationManager.getConfigInstance(); - for (String key : event.getKeys()) { - for (ConfigurationListener listener : manager - .getConfigurationListeners()) { - Object source = event.getSource(); - // TODO: Handle add vs set vs delete? - int type = AbstractConfiguration.EVENT_SET_PROPERTY; - String value = this.env.getProperty(key); - boolean beforeUpdate = false; - listener.configurationChanged(new ConfigurationEvent(source, type, - key, value, beforeUpdate)); - } - } - } - - } - -} diff --git a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusDelegatingProxyUtils.java b/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusDelegatingProxyUtils.java deleted file mode 100644 index 2d95ab4c5..000000000 --- a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusDelegatingProxyUtils.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.archaius; - -import com.netflix.config.ConfigurationManager; -import org.apache.commons.configuration.AbstractConfiguration; - -import org.springframework.context.ApplicationContext; -import org.springframework.context.ConfigurableApplicationContext; - -/** - * @author Dave Syer - */ -public final class ArchaiusDelegatingProxyUtils { - - private ArchaiusDelegatingProxyUtils() { - } - - /** - * {@code ApplicationContext} class name. - */ - public static String APPLICATION_CONTEXT = ApplicationContext.class.getName(); - - public static T getNamedInstance(Class type, String name) { - ApplicationContext context = (ApplicationContext) ConfigurationManager - .getConfigInstance().getProperty(APPLICATION_CONTEXT); - return context != null && context.containsBean(name) ? context.getBean(name, type) - : null; - } - - public static T getInstanceWithPrefix(Class type, String prefix) { - String name = prefix + type.getSimpleName(); - return getNamedInstance(type, name); - } - - public static void addApplicationContext(ConfigurableApplicationContext context) { - AbstractConfiguration config = ConfigurationManager.getConfigInstance(); - config.clearProperty(APPLICATION_CONTEXT); - config.setProperty(APPLICATION_CONTEXT, context); - } - -} diff --git a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpoint.java b/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpoint.java deleted file mode 100644 index fce93bbfb..000000000 --- a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpoint.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.archaius; - -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; - -import com.netflix.config.ConcurrentCompositeConfiguration; -import com.netflix.config.ConfigurationManager; -import org.apache.commons.configuration.AbstractConfiguration; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.EnvironmentConfiguration; -import org.apache.commons.configuration.SystemConfiguration; - -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; - -/** - * An actuator endpoint that returns Archaius configuration. - * - * @author Dave Syer - */ -@Endpoint(id = "archaius") -public class ArchaiusEndpoint { - - @ReadOperation - public Map invoke() { - Map map = new LinkedHashMap<>(); - AbstractConfiguration config = ConfigurationManager.getConfigInstance(); - if (config instanceof ConcurrentCompositeConfiguration) { - ConcurrentCompositeConfiguration composite = (ConcurrentCompositeConfiguration) config; - for (Configuration item : composite.getConfigurations()) { - append(map, item); - } - } - else { - append(map, config); - } - return map; - } - - private void append(Map map, Configuration config) { - if (config instanceof ConfigurableEnvironmentConfiguration) { - return; - } - if (config instanceof SystemConfiguration) { - return; - } - if (config instanceof EnvironmentConfiguration) { - return; - } - for (Iterator iter = config.getKeys(); iter.hasNext();) { - String key = iter.next(); - map.put(key, config.getProperty(key)); - } - } - -} diff --git a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ConfigurableEnvironmentConfiguration.java b/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ConfigurableEnvironmentConfiguration.java deleted file mode 100644 index b036a1fe4..000000000 --- a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ConfigurableEnvironmentConfiguration.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.archaius; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.configuration.AbstractConfiguration; - -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.EnumerablePropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.StandardEnvironment; - -/** - * EnvironmentConfiguration wrapper class providing further configuration possibilities. - * - * @author Spencer Gibb - */ -public class ConfigurableEnvironmentConfiguration extends AbstractConfiguration { - - private final ConfigurableEnvironment environment; - - public ConfigurableEnvironmentConfiguration(ConfigurableEnvironment environment) { - this.environment = environment; - } - - @Override - protected void addPropertyDirect(String key, Object value) { - - } - - @Override - public boolean isEmpty() { - return !getKeys().hasNext(); // TODO: find a better way to do this - } - - @Override - public boolean containsKey(String key) { - return this.environment.containsProperty(key); - } - - @Override - public Object getProperty(String key) { - return this.environment.getProperty(key); - } - - @Override - public Iterator getKeys() { - List result = new ArrayList<>(); - for (Map.Entry> entry : getPropertySources() - .entrySet()) { - PropertySource source = entry.getValue(); - if (source instanceof EnumerablePropertySource) { - EnumerablePropertySource enumerable = (EnumerablePropertySource) source; - for (String name : enumerable.getPropertyNames()) { - result.add(name); - } - } - } - return result.iterator(); - } - - private Map> getPropertySources() { - Map> map = new LinkedHashMap<>(); - MutablePropertySources sources = (this.environment != null - ? this.environment.getPropertySources() - : new StandardEnvironment().getPropertySources()); - for (PropertySource source : sources) { - extract("", map, source); - } - return map; - } - - private void extract(String root, Map> map, - PropertySource source) { - if (source instanceof CompositePropertySource) { - for (PropertySource nest : ((CompositePropertySource) source) - .getPropertySources()) { - extract(source.getName() + ":", map, nest); - } - } - else { - map.put(root + source.getName(), source); - } - } - -} diff --git a/spring-cloud-netflix-archaius/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-netflix-archaius/src/main/resources/META-INF/additional-spring-configuration-metadata.json deleted file mode 100644 index 0edf13794..000000000 --- a/spring-cloud-netflix-archaius/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "properties": [ - { - "defaultValue": "true", - "name": "archaius.propagate.environmentChangedEvent", - "description": "Propagates EnvironmentChanged events to Archaius ConfigurationManager.", - "type": "java.lang.Boolean" - } - ] -} \ No newline at end of file diff --git a/spring-cloud-netflix-archaius/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-archaius/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 834129ccb..000000000 --- a/spring-cloud-netflix-archaius/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration \ No newline at end of file diff --git a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java b/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java deleted file mode 100644 index 8bfa87e5d..000000000 --- a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.archaius; - -import java.util.Collections; - -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DynamicPropertyFactory; -import com.netflix.config.DynamicStringProperty; -import org.apache.commons.configuration.AbstractConfiguration; -import org.junit.After; -import org.junit.Test; - -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -public class ArchaiusAutoConfigurationTests { - - private AnnotationConfigApplicationContext context; - - private Object propertyValue; - - @After - public void close() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - public void configurationCreated() { - this.context = new AnnotationConfigApplicationContext( - ArchaiusAutoConfiguration.class); - AbstractConfiguration config = this.context - .getBean(ConfigurableEnvironmentConfiguration.class); - assertThat(config.getString("java.io.tmpdir")).isNotNull(); - } - - @Test - public void environmentChangeEventPropagated() { - this.context = new AnnotationConfigApplicationContext( - ArchaiusAutoConfiguration.class); - ConfigurationManager.getConfigInstance().addConfigurationListener(event -> { - if (event.getPropertyName().equals("my.prop")) { - ArchaiusAutoConfigurationTests.this.propertyValue = event - .getPropertyValue(); - } - }); - TestPropertyValues.of("my.prop=my.newval").applyTo(this.context); - this.context.publishEvent( - new EnvironmentChangeEvent(Collections.singleton("my.prop"))); - assertThat(this.propertyValue).isEqualTo("my.newval"); - } - - @Test - public void configurationWithoutExternalConfigurations() throws Exception { - this.context = new AnnotationConfigApplicationContext( - ArchaiusAutoConfiguration.class); - DynamicStringProperty dbProperty = DynamicPropertyFactory.getInstance() - .getStringProperty("db.property", null); - DynamicStringProperty staticProperty = DynamicPropertyFactory.getInstance() - .getStringProperty("archaius.file.property", null); - - assertThat(dbProperty.getValue()).isNull(); - assertThat(staticProperty.getValue()).isNotNull(); - assertThat(staticProperty.getValue()).isEqualTo("Static config file property"); - } - - @Test - public void configurationWithInjectedConfiguration() throws Exception { - this.context = new AnnotationConfigApplicationContext( - ArchaiusAutoConfiguration.class, TestArchaiusExternalConfiguration.class); - DynamicStringProperty dbProperty = DynamicPropertyFactory.getInstance() - .getStringProperty("db.property", null); - DynamicStringProperty secondDbProperty = DynamicPropertyFactory.getInstance() - .getStringProperty("db.second.property", null); - DynamicStringProperty staticProperty = DynamicPropertyFactory.getInstance() - .getStringProperty("archaius.file.property", null); - - assertThat(dbProperty.getValue()).isNotNull(); - assertThat(secondDbProperty.getValue()).isNotNull(); - assertThat(staticProperty.getValue()).isNotNull(); - assertThat(dbProperty.getValue()).isEqualTo("this is a db property"); - assertThat(secondDbProperty.getValue()).isEqualTo("this is another db property"); - assertThat(staticProperty.getValue()).isEqualTo("Static config file property"); - } - -} diff --git a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpointTests.java b/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpointTests.java deleted file mode 100644 index f0fe562e6..000000000 --- a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpointTests.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.archaius; - -import java.util.Map; - -import com.netflix.config.ConcurrentCompositeConfiguration; -import com.netflix.config.ConfigurationManager; -import org.junit.Test; - -import org.springframework.core.env.StandardEnvironment; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -public class ArchaiusEndpointTests { - - private ArchaiusEndpoint endpoint = new ArchaiusEndpoint(); - - @Test - public void detectsPropertiesWhenSet() { - ConfigurationManager.getConfigInstance().setProperty("foo", "bar"); - assertThat(this.endpoint.invoke().containsKey("foo")).isTrue(); - } - - @Test - public void doesNotIncludeSpringEnvironment() { - ConcurrentCompositeConfiguration composite = new ConcurrentCompositeConfiguration( - ConfigurationManager.getConfigInstance()); - ConfigurableEnvironmentConfiguration config = new ConfigurableEnvironmentConfiguration( - new StandardEnvironment()); - assertThat(config.containsKey("user.dir")).isTrue(); - composite.addConfiguration(config); - ConfigurationManager.getConfigInstance().setProperty("foo", "bar"); - Map map = this.endpoint.invoke(); - assertThat(map.containsKey("foo")).isTrue(); - assertThat(map.containsKey("user.dir")).isFalse(); - } - -} diff --git a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/LazyLoadConfigurationTests.java b/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/LazyLoadConfigurationTests.java deleted file mode 100644 index aa456d0f6..000000000 --- a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/LazyLoadConfigurationTests.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.archaius; - -import com.netflix.config.DynamicProperty; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Liang Yong - */ - -@SpringBootTest(classes = LazyLoadConfigurationTests.TestConfig.class, - properties = { "client.ribbon.listOfServers=foo.com,bar.com", - "spring.main.lazy-initialization=true" }) -public class LazyLoadConfigurationTests { - - @Test - public void enableLazyInitialization() { - DynamicProperty instance = DynamicProperty - .getInstance("client.ribbon.listOfServers"); - assertThat(instance.getString()).isEqualTo("foo.com,bar.com"); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - static class TestConfig { - - } - -} diff --git a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/TestArchaiusExternalConfiguration.java b/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/TestArchaiusExternalConfiguration.java deleted file mode 100644 index ff4c8d792..000000000 --- a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/TestArchaiusExternalConfiguration.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.archaius; - -import com.netflix.config.ConcurrentMapConfiguration; -import org.apache.commons.configuration.AbstractConfiguration; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Alexandru-George Burghelea - */ -@Configuration(proxyBeanMethods = false) -public class TestArchaiusExternalConfiguration { - - @Bean - @Qualifier("dynamicConfiguration") - public AbstractConfiguration createDynamicConfiguration() { - ConcurrentMapConfiguration config = new ConcurrentMapConfiguration(); - config.addProperty("db.property", "this is a db property"); - config.addProperty("db.second.property", "this is another db property"); - return config; - } - -} diff --git a/spring-cloud-netflix-archaius/src/test/resources/config.properties b/spring-cloud-netflix-archaius/src/test/resources/config.properties deleted file mode 100644 index 1e9c021f4..000000000 --- a/spring-cloud-netflix-archaius/src/test/resources/config.properties +++ /dev/null @@ -1,2 +0,0 @@ -archaius.file.property=Static config file property -db.second.property=It should be overridden diff --git a/spring-cloud-netflix-concurrency-limits/pom.xml b/spring-cloud-netflix-concurrency-limits/pom.xml index 38b91cefa..84a7a4fc0 100644 --- a/spring-cloud-netflix-concurrency-limits/pom.xml +++ b/spring-cloud-netflix-concurrency-limits/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT + 3.0.0.BUILD-SNAPSHOT .. spring-cloud-netflix-concurrency-limits diff --git a/spring-cloud-netflix-core/pom.xml b/spring-cloud-netflix-core/pom.xml deleted file mode 100644 index 310d0ddb3..000000000 --- a/spring-cloud-netflix-core/pom.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - spring-cloud-netflix-core - jar - Spring Cloud Netflix Core - Deprecated - Deprecated Spring Cloud Netflix Core - will be removed. Please use spring-cloud-netflix-hystrix instead. - - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.springframework.boot - spring-boot-autoconfigure - true - - - - - java8plus - - [1.8,2.0) - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - -parameters - - - - - - - - diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/core/CoreAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/core/CoreAutoConfiguration.java deleted file mode 100644 index 0590b20e2..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/core/CoreAutoConfiguration.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2018-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.core; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.context.annotation.Configuration; - -/** - * @author Olga Maciaszek-Sharma - * @since 2.1.0 - * @deprecated Module spring-cloud-netflix-core is deprecated as of 2.1.0, use - * spring-cloud-netflix-hystrix instead. - */ -@Configuration(proxyBeanMethods = false) -@Deprecated -public class CoreAutoConfiguration { - - private static final Log LOG = LogFactory.getLog(CoreAutoConfiguration.class); - - public CoreAutoConfiguration() { - LOG.warn( - "This module is deprecated. It will be removed in the next major release. " - + "Please use spring-cloud-netflix-hystrix instead."); - } - -} diff --git a/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 7362ab93f..000000000 --- a/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.core.CoreAutoConfiguration \ No newline at end of file diff --git a/spring-cloud-netflix-dependencies/pom.xml b/spring-cloud-netflix-dependencies/pom.xml index 442a57709..7e2cf9467 100644 --- a/spring-cloud-netflix-dependencies/pom.xml +++ b/spring-cloud-netflix-dependencies/pom.xml @@ -5,24 +5,17 @@ spring-cloud-dependencies-parent org.springframework.cloud - 2.2.1.RELEASE + 2.2.2.BUILD-SNAPSHOT spring-cloud-netflix-dependencies - 2.2.2.BUILD-SNAPSHOT + 3.0.0.BUILD-SNAPSHOT pom spring-cloud-netflix-dependencies Spring Cloud Netflix Dependencies - 0.7.6 0.1.12 1.9.13 - 0.3.0 - 1.5.18 - 2.3.0 - 0.12.21 - 1.3.1 - 1.0.0 @@ -31,16 +24,6 @@ spring-cloud-netflix-eureka-client ${project.version} - - org.springframework.cloud - spring-cloud-netflix-archaius - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - ${project.version} - org.springframework.cloud spring-cloud-starter-netflix-eureka-client @@ -51,111 +34,16 @@ spring-cloud-starter-netflix-eureka-server ${project.version} - - org.springframework.cloud - spring-cloud-starter-netflix-hystrix - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-hystrix-contract - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-netflix-hystrix-dashboard - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-netflix-turbine - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-netflix-turbine-stream - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-netflix-zuul - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-core - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-hystrix - ${project.version} - org.springframework.cloud spring-cloud-netflix-eureka-server ${project.version} - - org.springframework.cloud - spring-cloud-netflix-hystrix-dashboard - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-hystrix-stream - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-sidecar - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-turbine - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-turbine-stream - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-zuul - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-ribbon - ${project.version} - - + com.netflix.concurrency-limits concurrency-limits-core @@ -166,17 +54,6 @@ concurrency-limits-servlet ${concurrency-limits.version} - - com.netflix.servo - servo-core - ${servo.version} - - - com.google.code.findbugs - annotations - - - com.netflix.eureka eureka-client @@ -243,137 +120,6 @@ - - com.netflix.hystrix - hystrix-core - ${hystrix.version} - - - com.google.code.findbugs - annotations - - - - - com.netflix.hystrix - hystrix-serialization - ${hystrix.version} - - - com.google.code.findbugs - annotations - - - - - com.netflix.hystrix - hystrix-metrics-event-stream - ${hystrix.version} - - - javax.servlet - servlet-api - - - - - com.netflix.hystrix - hystrix-javanica - ${hystrix.version} - - - com.google.code.findbugs - jsr305 - - - com.google.code.findbugs - annotations - - - org.aspectj - aspectjrt - - - - - com.netflix.ribbon - ribbon - ${ribbon.version} - - - commons-logging - commons-logging - - - - - com.netflix.ribbon - ribbon-core - ${ribbon.version} - - - com.google.code.findbugs - annotations - - - - - com.netflix.ribbon - ribbon-httpclient - ${ribbon.version} - - - com.google.code.findbugs - annotations - - - - - com.netflix.ribbon - ribbon-eureka - ${ribbon.version} - - - com.google.code.findbugs - annotations - - - javax.servlet - servlet-api - - - - - com.netflix.ribbon - ribbon-loadbalancer - ${ribbon.version} - - - com.google.code.findbugs - annotations - - - - - com.netflix.zuul - zuul-core - ${zuul.version} - - - groovy-all - org.codehaus.groovy - - - mockito-all - org.mockito - - - - - com.netflix.netflix-commons - netflix-eventbus - ${eventbus.version} - diff --git a/spring-cloud-netflix-eureka-client/pom.xml b/spring-cloud-netflix-eureka-client/pom.xml index c93ad9874..ab30b7881 100644 --- a/spring-cloud-netflix-eureka-client/pom.xml +++ b/spring-cloud-netflix-eureka-client/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT + 3.0.0.BUILD-SNAPSHOT .. spring-cloud-netflix-eureka-client @@ -32,15 +32,6 @@ spring-boot-starter-webflux true - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.springframework.cloud - spring-cloud-netflix-ribbon - true - org.springframework.cloud spring-cloud-config-client @@ -82,41 +73,11 @@ jersey-apache-client4 true - - com.netflix.archaius - archaius-core - true - - - com.netflix.ribbon - ribbon - true - - + org.springframework.boot spring-boot-autoconfigure-processor diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/loadbalancer/EurekaLoadBalancerClientConfiguration.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/loadbalancer/EurekaLoadBalancerClientConfiguration.java index 36890dd65..3956baa34 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/loadbalancer/EurekaLoadBalancerClientConfiguration.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/loadbalancer/EurekaLoadBalancerClientConfiguration.java @@ -26,7 +26,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerProperties; -import org.springframework.cloud.netflix.ribbon.eureka.ZoneUtils; +import org.springframework.cloud.netflix.eureka.support.ZoneUtils; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ZoneUtils.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/support/ZoneUtils.java similarity index 95% rename from spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ZoneUtils.java rename to spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/support/ZoneUtils.java index 1f374d8c8..ecb2bf817 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ZoneUtils.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/support/ZoneUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.netflix.ribbon.eureka; +package org.springframework.cloud.netflix.eureka.support; import org.springframework.util.StringUtils; diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ConditionalOnRibbonAndEurekaEnabled.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ConditionalOnRibbonAndEurekaEnabled.java deleted file mode 100644 index cc98d0a6d..000000000 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ConditionalOnRibbonAndEurekaEnabled.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.eureka; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import com.netflix.discovery.EurekaClient; -import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList; - -import org.springframework.boot.autoconfigure.condition.AllNestedConditions; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.context.annotation.Conditional; - -/** - * Conditional that requires both Ribbon and Eureka to be enabled. - * @author Ihor Kryvenko - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - */ -@Target({ ElementType.TYPE, ElementType.METHOD }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Conditional(ConditionalOnRibbonAndEurekaEnabled.OnRibbonAndEurekaEnabledCondition.class) -public @interface ConditionalOnRibbonAndEurekaEnabled { - - class OnRibbonAndEurekaEnabledCondition extends AllNestedConditions { - - OnRibbonAndEurekaEnabledCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnClass(DiscoveryEnabledNIWSServerList.class) - @ConditionalOnBean(SpringClientFactory.class) - @ConditionalOnProperty(value = "ribbon.eureka.enabled", matchIfMissing = true) - static class Defaults { - - } - - @ConditionalOnBean(EurekaClient.class) - static class EurekaBeans { - - } - - @ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true) - @ConditionalOnDiscoveryEnabled - static class OnEurekaClientEnabled { - - } - - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java deleted file mode 100644 index ed640554f..000000000 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.eureka; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.appinfo.InstanceInfo; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.niws.loadbalancer.DiscoveryEnabledServer; - -import org.springframework.cloud.netflix.ribbon.RibbonProperties; - -/** - * @author Dave Syer - */ -public class DomainExtractingServerList implements ServerList { - - private ServerList list; - - private final RibbonProperties ribbon; - - private boolean approximateZoneFromHostname; - - public DomainExtractingServerList(ServerList list, - IClientConfig clientConfig, boolean approximateZoneFromHostname) { - this.list = list; - this.ribbon = RibbonProperties.from(clientConfig); - this.approximateZoneFromHostname = approximateZoneFromHostname; - } - - @Override - public List getInitialListOfServers() { - List servers = setZones( - this.list.getInitialListOfServers()); - return servers; - } - - @Override - public List getUpdatedListOfServers() { - List servers = setZones( - this.list.getUpdatedListOfServers()); - return servers; - } - - private List setZones(List servers) { - List result = new ArrayList<>(); - boolean isSecure = this.ribbon.isSecure(true); - boolean shouldUseIpAddr = this.ribbon.isUseIPAddrForServer(); - for (DiscoveryEnabledServer server : servers) { - result.add(new DomainExtractingServer(server, isSecure, shouldUseIpAddr, - this.approximateZoneFromHostname)); - } - return result; - } - -} - -class DomainExtractingServer extends DiscoveryEnabledServer { - - private String id; - - @Override - public String getId() { - return id; - } - - @Override - public void setId(String id) { - this.id = id; - } - - DomainExtractingServer(DiscoveryEnabledServer server, boolean useSecurePort, - boolean useIpAddr, boolean approximateZoneFromHostname) { - // host and port are set in super() - super(server.getInstanceInfo(), useSecurePort, useIpAddr); - if (server.getInstanceInfo().getMetadata().containsKey("zone")) { - setZone(server.getInstanceInfo().getMetadata().get("zone")); - } - else if (approximateZoneFromHostname) { - setZone(ZoneUtils.extractApproximateZone(server.getHost())); - } - else { - setZone(server.getZone()); - } - setId(extractId(server)); - setAlive(server.isAlive()); - setReadyToServe(server.isReadyToServe()); - } - - private String extractId(Server server) { - if (server instanceof DiscoveryEnabledServer) { - DiscoveryEnabledServer enabled = (DiscoveryEnabledServer) server; - InstanceInfo instance = enabled.getInstanceInfo(); - if (instance.getMetadata().containsKey("instanceId")) { - return instance.getHostName() + ":" - + instance.getMetadata().get("instanceId"); - } - } - return super.getId(); - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfiguration.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfiguration.java deleted file mode 100644 index 2dbb747fb..000000000 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfiguration.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.eureka; - -import javax.annotation.PostConstruct; -import javax.inject.Provider; - -import com.netflix.appinfo.EurekaInstanceConfig; -import com.netflix.client.config.IClientConfig; -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DeploymentContext.ContextKey; -import com.netflix.discovery.EurekaClient; -import com.netflix.discovery.EurekaClientConfig; -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.ServerList; -import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList; -import com.netflix.niws.loadbalancer.NIWSDiscoveryPing; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.cloud.netflix.ribbon.PropertiesFactory; -import org.springframework.cloud.netflix.ribbon.RibbonClientName; -import org.springframework.cloud.netflix.ribbon.RibbonUtils; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.StringUtils; - -/** - * Preprocessor that configures defaults for eureka-discovered ribbon clients. Such as: - * @zone, NIWSServerListClassName, DeploymentContextBasedVipAddresses, - * NFLoadBalancerRuleClassName, NIWSServerListFilterClassName and more - * - * @author Spencer Gibb - * @author Dave Syer - * @author Ryan Baxter - */ -@Configuration(proxyBeanMethods = false) -public class EurekaRibbonClientConfiguration { - - private static final Log log = LogFactory - .getLog(EurekaRibbonClientConfiguration.class); - - @Value("${ribbon.eureka.approximateZoneFromHostname:false}") - private boolean approximateZoneFromHostname = false; - - @RibbonClientName - private String serviceId = "client"; - - @Autowired(required = false) - private EurekaClientConfig clientConfig; - - @Autowired(required = false) - private EurekaInstanceConfig eurekaConfig; - - @Autowired - private PropertiesFactory propertiesFactory; - - public EurekaRibbonClientConfiguration() { - } - - public EurekaRibbonClientConfiguration(EurekaClientConfig clientConfig, - String serviceId, EurekaInstanceConfig eurekaConfig, - boolean approximateZoneFromHostname) { - this.clientConfig = clientConfig; - this.serviceId = serviceId; - this.eurekaConfig = eurekaConfig; - this.approximateZoneFromHostname = approximateZoneFromHostname; - } - - @Bean - @ConditionalOnMissingBean - public IPing ribbonPing(IClientConfig config) { - if (this.propertiesFactory.isSet(IPing.class, serviceId)) { - return this.propertiesFactory.get(IPing.class, config, serviceId); - } - NIWSDiscoveryPing ping = new NIWSDiscoveryPing(); - ping.initWithNiwsConfig(config); - return ping; - } - - @Bean - @ConditionalOnMissingBean - public ServerList ribbonServerList(IClientConfig config, - Provider eurekaClientProvider) { - if (this.propertiesFactory.isSet(ServerList.class, serviceId)) { - return this.propertiesFactory.get(ServerList.class, config, serviceId); - } - DiscoveryEnabledNIWSServerList discoveryServerList = new DiscoveryEnabledNIWSServerList( - config, eurekaClientProvider); - DomainExtractingServerList serverList = new DomainExtractingServerList( - discoveryServerList, config, this.approximateZoneFromHostname); - return serverList; - } - - @Bean - public ServerIntrospector serverIntrospector() { - return new EurekaServerIntrospector(); - } - - @PostConstruct - public void preprocess() { - String zone = ConfigurationManager.getDeploymentContext() - .getValue(ContextKey.zone); - if (this.clientConfig != null && StringUtils.isEmpty(zone)) { - if (this.approximateZoneFromHostname && this.eurekaConfig != null) { - String approxZone = ZoneUtils - .extractApproximateZone(this.eurekaConfig.getHostName(false)); - log.debug("Setting Zone To " + approxZone); - ConfigurationManager.getDeploymentContext().setValue(ContextKey.zone, - approxZone); - } - else { - String availabilityZone = this.eurekaConfig == null ? null - : this.eurekaConfig.getMetadataMap().get("zone"); - if (availabilityZone == null) { - String[] zones = this.clientConfig - .getAvailabilityZones(this.clientConfig.getRegion()); - // Pick the first one from the regions we want to connect to - availabilityZone = zones != null && zones.length > 0 ? zones[0] - : null; - } - if (availabilityZone != null) { - // You can set this with archaius.deployment.* (maybe requires - // custom deployment context)? - ConfigurationManager.getDeploymentContext().setValue(ContextKey.zone, - availabilityZone); - } - } - } - RibbonUtils.initializeRibbonDefaults(serviceId); - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaServerIntrospector.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaServerIntrospector.java deleted file mode 100644 index fe833f328..000000000 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaServerIntrospector.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.eureka; - -import java.util.Map; - -import com.netflix.appinfo.InstanceInfo; -import com.netflix.loadbalancer.Server; -import com.netflix.niws.loadbalancer.DiscoveryEnabledServer; - -import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; - -/** - * @author Spencer Gibb - */ -public class EurekaServerIntrospector extends DefaultServerIntrospector { - - @Override - public boolean isSecure(Server server) { - if (server instanceof DiscoveryEnabledServer) { - DiscoveryEnabledServer discoveryServer = (DiscoveryEnabledServer) server; - return discoveryServer.getInstanceInfo() - .isPortEnabled(InstanceInfo.PortType.SECURE); - } - return super.isSecure(server); - } - - @Override - public Map getMetadata(Server server) { - if (server instanceof DiscoveryEnabledServer) { - DiscoveryEnabledServer discoveryServer = (DiscoveryEnabledServer) server; - return discoveryServer.getInstanceInfo().getMetadata(); - } - return super.getMetadata(server); - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfiguration.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfiguration.java deleted file mode 100644 index 1c6b0fc71..000000000 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfiguration.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.eureka; - -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.context.annotation.Configuration; - -/** - * Spring configuration for configuring Ribbon defaults to be Eureka based if Eureka - * client is enabled. - * - * @author Dave Syer - * @author Biju Kunjummen - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties -@ConditionalOnRibbonAndEurekaEnabled -@AutoConfigureAfter(RibbonAutoConfiguration.class) -@RibbonClients(defaultConfiguration = EurekaRibbonClientConfiguration.class) -public class RibbonEurekaAutoConfiguration { - -} diff --git a/spring-cloud-netflix-eureka-client/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-eureka-client/src/main/resources/META-INF/spring.factories index 12659725c..b212aa39b 100644 --- a/spring-cloud-netflix-eureka-client/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-netflix-eureka-client/src/main/resources/META-INF/spring.factories @@ -2,7 +2,6 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.netflix.eureka.config.EurekaClientConfigServerAutoConfiguration,\ org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceAutoConfiguration,\ org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration,\ -org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration,\ org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration,\ org.springframework.cloud.netflix.eureka.reactive.EurekaReactiveDiscoveryClientConfiguration,\ org.springframework.cloud.netflix.eureka.loadbalancer.LoadBalancerEurekaAutoConfiguration diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/ZoneUtilsTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/support/ZoneUtilsTests.java similarity index 90% rename from spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/ZoneUtilsTests.java rename to spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/support/ZoneUtilsTests.java index 45eb60137..0fdb872ee 100644 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/ZoneUtilsTests.java +++ b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/support/ZoneUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.netflix.ribbon.eureka; +package org.springframework.cloud.netflix.eureka.support; import org.junit.Test; diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerListTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerListTests.java deleted file mode 100644 index 258dd7d26..000000000 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerListTests.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.eureka; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.netflix.appinfo.InstanceInfo; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.niws.loadbalancer.DiscoveryEnabledServer; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * @author Spencer Gibb - */ -public class DomainExtractingServerListTests { - - static final String IP_ADDR = "10.0.0.2"; - - static final int PORT = 8080; - - static final String ZONE = "myzone.mydomain.com"; - - static final String HOST_NAME = "myHostName." + ZONE; - - static final String INSTANCE_ID = "myInstanceId"; - - private Map metadata = Collections - .singletonMap("instanceId", INSTANCE_ID); - - @Test - public void testDomainExtractingServer() { - DomainExtractingServerList serverList = getDomainExtractingServerList( - new DefaultClientConfigImpl(), true); - List servers = serverList.getInitialListOfServers(); - assertThat(servers).as("servers was null").isNotNull(); - assertThat(servers.size()).as("servers was not size 1").isEqualTo(1); - DomainExtractingServer des = assertDomainExtractingServer(servers, ZONE); - assertThat(des.getHostPort()).as("hostPort was wrong") - .isEqualTo(HOST_NAME + ":" + PORT); - } - - @Test - public void testZoneInMetaData() { - this.metadata = new HashMap<>(); - this.metadata.put("zone", "us-west-1"); - this.metadata.put("instanceId", INSTANCE_ID); - DomainExtractingServerList serverList = getDomainExtractingServerList( - new DefaultClientConfigImpl(), false); - List servers = serverList.getInitialListOfServers(); - assertThat(servers).as("servers was null").isNotNull(); - assertThat(servers.size()).as("servers was not size 1").isEqualTo(1); - DomainExtractingServer des = assertDomainExtractingServer(servers, "us-west-1"); - assertThat(des.getZone()).as("Zone was wrong").isEqualTo("us-west-1"); - } - - @Test - public void testDomainExtractingServerDontApproximateZone() { - DomainExtractingServerList serverList = getDomainExtractingServerList( - new DefaultClientConfigImpl(), false); - List servers = serverList.getInitialListOfServers(); - assertThat(servers).as("servers was null").isNotNull(); - assertThat(servers.size()).as("servers was not size 1").isEqualTo(1); - DomainExtractingServer des = assertDomainExtractingServer(servers, null); - assertThat(des.getHostPort()).as("hostPort was wrong") - .isEqualTo(HOST_NAME + ":" + PORT); - } - - protected DomainExtractingServer assertDomainExtractingServer( - List servers, String zone) { - Server actualServer = servers.get(0); - assertThat(actualServer instanceof DomainExtractingServer) - .as("server was not a DomainExtractingServer").isTrue(); - DomainExtractingServer des = DomainExtractingServer.class.cast(actualServer); - assertThat(des.getZone()).as("zone was wrong").isEqualTo(zone); - assertThat(des.getId()).as("instanceId was wrong") - .isEqualTo(HOST_NAME + ":" + INSTANCE_ID); - return des; - } - - @Test - public void testDomainExtractingServerUseIpAddress() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.setProperty(CommonClientConfigKey.UseIPAddrForServer, true); - DomainExtractingServerList serverList = getDomainExtractingServerList(config, - true); - List servers = serverList.getInitialListOfServers(); - assertThat(servers).as("servers was null").isNotNull(); - assertThat(servers.size()).as("servers was not size 1").isEqualTo(1); - DomainExtractingServer des = assertDomainExtractingServer(servers, ZONE); - assertThat(des.getHostPort()).as("hostPort was wrong") - .isEqualTo(IP_ADDR + ":" + PORT); - } - - protected DomainExtractingServerList getDomainExtractingServerList( - DefaultClientConfigImpl config, boolean approximateZoneFromHostname) { - DiscoveryEnabledServer server = mock(DiscoveryEnabledServer.class); - @SuppressWarnings("unchecked") - ServerList originalServerList = mock(ServerList.class); - InstanceInfo instanceInfo = mock(InstanceInfo.class); - given(server.getInstanceInfo()).willReturn(instanceInfo); - given(server.getHost()).willReturn(HOST_NAME); - given(instanceInfo.getMetadata()).willReturn(this.metadata); - given(instanceInfo.getHostName()).willReturn(HOST_NAME); - given(instanceInfo.getIPAddr()).willReturn(IP_ADDR); - given(instanceInfo.getPort()).willReturn(PORT); - given(originalServerList.getInitialListOfServers()) - .willReturn(Arrays.asList(server)); - return new DomainExtractingServerList(originalServerList, config, - approximateZoneFromHostname); - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaDisabledRibbonClientIntegrationTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaDisabledRibbonClientIntegrationTests.java deleted file mode 100644 index d54ceca7c..000000000 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaDisabledRibbonClientIntegrationTests.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.eureka; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAvoidanceRule; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import com.netflix.niws.loadbalancer.NIWSDiscoveryPing; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration; -import org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.eureka.EurekaRibbonClientPreprocessorIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Ribbon Eureka client should be disabled if Eureka client is not enabled. - * - * @author Biju Kunjummen - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TestConfiguration.class, - properties = "eureka.client.enabled=false") -@DirtiesContext -public class EurekaDisabledRibbonClientIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void serverListShouldNotBeEurekaBased() throws Exception { - assertThat(getLoadBalancer().getServerListImpl()) - .isNotInstanceOf(DomainExtractingServerList.class); - } - - @Test - public void ruleDefaultsToZoneAvoidance() throws Exception { - ZoneAvoidanceRule.class.cast(getLoadBalancer().getRule()); - } - - @Test - public void pingShouldNotBeEurekaBased() throws Exception { - assertThat(getLoadBalancer().getPing()).isNotInstanceOf(NIWSDiscoveryPing.class); - } - - @Test - public void serverIntrospectorShouldNotBeEurekaBased() throws Exception { - assertThat(this.factory.getInstance("foo", ServerIntrospector.class)) - .isNotInstanceOf(EurekaServerIntrospector.class); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer() { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer("foo"); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient("foo") - @Import({ UtilAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, - ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class, - EurekaDiscoveryClientConfiguration.class, EurekaClientAutoConfiguration.class, - RibbonEurekaAutoConfiguration.class }) - protected static class TestConfiguration { - - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfigurationTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfigurationTests.java deleted file mode 100644 index 7da3f6d80..000000000 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfigurationTests.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.eureka; - -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DeploymentContext.ContextKey; -import com.netflix.config.DynamicStringProperty; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import com.netflix.niws.loadbalancer.DiscoveryEnabledServer; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import org.springframework.cloud.commons.util.InetUtils; -import org.springframework.cloud.commons.util.InetUtilsProperties; -import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.VALUE_NOT_SET; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.getProperty; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.getRibbonKey; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.setRibbonProperty; - -/** - * @author Dave Syer - * @author Ryan Baxter - */ -public class EurekaRibbonClientConfigurationTests { - - @After - @Before - public void close() { - ConfigurationManager.getDeploymentContext().setValue(ContextKey.zone, ""); - } - - @Test - @Ignore - public void basicConfigurationCreatedForLoadBalancer() { - EurekaClientConfigBean client = new EurekaClientConfigBean(); - EurekaInstanceConfigBean configBean = getEurekaInstanceConfigBean(); - client.getAvailabilityZones().put(client.getRegion(), "foo"); - SpringClientFactory clientFactory = new SpringClientFactory(); - EurekaRibbonClientConfiguration clientPreprocessor = new EurekaRibbonClientConfiguration( - client, "service", configBean, false); - clientPreprocessor.preprocess(); - ILoadBalancer balancer = clientFactory.getLoadBalancer("service"); - assertThat(balancer).isNotNull(); - @SuppressWarnings("unchecked") - ZoneAwareLoadBalancer aware = (ZoneAwareLoadBalancer) balancer; - assertThat(aware.getServerListImpl() instanceof DomainExtractingServerList) - .isTrue(); - assertThat(ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone)) - .isEqualTo("foo"); - } - - private EurekaInstanceConfigBean getEurekaInstanceConfigBean() { - return new EurekaInstanceConfigBean(new InetUtils(new InetUtilsProperties())); - } - - @Test - public void testSetProp() { - EurekaClientConfigBean client = new EurekaClientConfigBean(); - EurekaInstanceConfigBean configBean = getEurekaInstanceConfigBean(); - EurekaRibbonClientConfiguration preprocessor = new EurekaRibbonClientConfiguration( - client, "myService", configBean, false); - String serviceId = "myService"; - String suffix = "mySuffix"; - String value = "myValue"; - DynamicStringProperty property = getProperty(getRibbonKey(serviceId, suffix)); - assertThat(property.get()).as("property doesn't have default value") - .isEqualTo(VALUE_NOT_SET); - setRibbonProperty(serviceId, suffix, value); - assertThat(property.get()).as("property has wrong value").isEqualTo(value); - setRibbonProperty(serviceId, suffix, value); - assertThat(property.get()).as("property has wrong value").isEqualTo(value); - } - - @Test - public void testExplicitZone() { - EurekaClientConfigBean client = new EurekaClientConfigBean(); - EurekaInstanceConfigBean configBean = getEurekaInstanceConfigBean(); - configBean.getMetadataMap().put("zone", "myZone"); - EurekaRibbonClientConfiguration preprocessor = new EurekaRibbonClientConfiguration( - client, "myService", configBean, false); - preprocessor.preprocess(); - assertThat(ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone)) - .isEqualTo("myZone"); - } - - @Test - public void testDefaultZone() { - EurekaClientConfigBean client = new EurekaClientConfigBean(); - EurekaInstanceConfigBean configBean = getEurekaInstanceConfigBean(); - EurekaRibbonClientConfiguration preprocessor = new EurekaRibbonClientConfiguration( - client, "myService", configBean, false); - preprocessor.preprocess(); - assertThat(ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone)) - .isEqualTo("defaultZone"); - } - - @Test - public void testApproximateZone() { - EurekaClientConfigBean client = new EurekaClientConfigBean(); - EurekaInstanceConfigBean configBean = getEurekaInstanceConfigBean(); - configBean.setHostname("this.is.a.test.com"); - EurekaRibbonClientConfiguration preprocessor = new EurekaRibbonClientConfiguration( - client, "myService", configBean, true); - preprocessor.preprocess(); - assertThat(ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone)) - .isEqualTo("is.a.test.com"); - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPreprocessorIntegrationTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPreprocessorIntegrationTests.java deleted file mode 100644 index 70b5e8811..000000000 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPreprocessorIntegrationTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.eureka; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAvoidanceRule; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import com.netflix.niws.loadbalancer.NIWSDiscoveryPing; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration; -import org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.eureka.EurekaRibbonClientPreprocessorIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TestConfiguration.class) -@DirtiesContext -public class EurekaRibbonClientPreprocessorIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void serverListDefaultsToDomainExtracting() throws Exception { - DomainExtractingServerList.class.cast(getLoadBalancer().getServerListImpl()); - } - - @Test - public void ruleDefaultsToZoneAvoidance() throws Exception { - ZoneAvoidanceRule.class.cast(getLoadBalancer().getRule()); - } - - @Test - public void pingDefaultsToDiscoveryPing() throws Exception { - NIWSDiscoveryPing.class.cast(getLoadBalancer().getPing()); - } - - @Test - public void serverIntrospectorDefaultsToEureka() throws Exception { - EurekaServerIntrospector.class - .cast(this.factory.getInstance("foo", ServerIntrospector.class)); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer() { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer("foo"); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient("foo") - @Import({ UtilAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, - ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class, - EurekaDiscoveryClientConfiguration.class, EurekaClientAutoConfiguration.class, - RibbonEurekaAutoConfiguration.class }) - protected static class TestConfiguration { - - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPropertyOverrideIntegrationTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPropertyOverrideIntegrationTests.java deleted file mode 100644 index 787c2dbba..000000000 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPropertyOverrideIntegrationTests.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.eureka; - -import com.netflix.discovery.EurekaClient; -import com.netflix.loadbalancer.ConfigurationBasedServerList; -import com.netflix.loadbalancer.DummyPing; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import com.netflix.niws.loadbalancer.NIWSDiscoveryPing; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.mockito.Mockito.mock; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest( - classes = EurekaRibbonClientPropertyOverrideIntegrationTests.TestConfiguration.class) -@DirtiesContext -public class EurekaRibbonClientPropertyOverrideIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void pingOverridesToDummy() throws Exception { - DummyPing.class.cast(getLoadBalancer("foo3").getPing()); - NIWSDiscoveryPing.class.cast(getLoadBalancer("bar").getPing()); - } - - @Test - public void serverListOverridesToTest() throws Exception { - ConfigurationBasedServerList.class - .cast(getLoadBalancer("foo3").getServerListImpl()); - DomainExtractingServerList.class.cast(getLoadBalancer("bar").getServerListImpl()); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer(String name) { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer(name); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClients - @ImportAutoConfiguration({ UtilAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - RibbonAutoConfiguration.class, RibbonEurekaAutoConfiguration.class }) - protected static class TestConfiguration { - - @Bean - public EurekaClient eurekaClient() { - return mock(EurekaClient.class); - } - - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonClientPreprocessorIntegrationTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonClientPreprocessorIntegrationTests.java deleted file mode 100644 index d556c3d30..000000000 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonClientPreprocessorIntegrationTests.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.eureka; - -import com.netflix.discovery.EurekaClient; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAvoidanceRule; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.util.InetUtils; -import org.springframework.cloud.commons.util.InetUtilsProperties; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter; -import org.springframework.cloud.netflix.ribbon.eureka.RibbonClientPreprocessorIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TestConfiguration.class) -@DirtiesContext -public class RibbonClientPreprocessorIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void serverListIsWrapped() throws Exception { - @SuppressWarnings("unchecked") - ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) this.factory - .getLoadBalancer("foo"); - DomainExtractingServerList.class.cast(loadBalancer.getServerListImpl()); - } - - @Test - public void ruleDefaultsToAvoidance() throws Exception { - @SuppressWarnings("unchecked") - ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) this.factory - .getLoadBalancer("foo"); - ZoneAvoidanceRule.class.cast(loadBalancer.getRule()); - } - - @Test - public void serverListFilterOverride() throws Exception { - @SuppressWarnings("unchecked") - ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) this.factory - .getLoadBalancer("foo"); - assertThat(ZonePreferenceServerListFilter.class.cast(loadBalancer.getFilter()) - .getZone()).isEqualTo("myTestZone"); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient("foo") - @ImportAutoConfiguration({ PropertyPlaceholderAutoConfiguration.class, - ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class }) - protected static class PlainConfiguration { - - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient(name = "foo", configuration = FooConfiguration.class) - @ImportAutoConfiguration({ PropertyPlaceholderAutoConfiguration.class, - ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class, - RibbonEurekaAutoConfiguration.class }) - protected static class TestConfiguration { - - @Bean - EurekaClient eurekaClient() { - return Mockito.mock(EurekaClient.class); - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class FooConfiguration { - - @Bean - public ZonePreferenceServerListFilter serverListFilter() { - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - filter.setZone("myTestZone"); - return filter; - } - - @Bean - public EurekaInstanceConfigBean getEurekaInstanceConfigBean() { - EurekaInstanceConfigBean bean = new EurekaInstanceConfigBean( - new InetUtils(new InetUtilsProperties())); - return bean; - } - - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfigurationTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfigurationTests.java deleted file mode 100644 index 29724e83c..000000000 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfigurationTests.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2016-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.eureka; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.context.annotation.Bean; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest( - classes = RibbonEurekaAutoConfigurationTests.EurekaClientDisabledApp.class, - properties = { "eureka.client.enabled=false", - "spring.application.name=eurekadisabledtest" }, - webEnvironment = RANDOM_PORT) -@DirtiesContext -public class RibbonEurekaAutoConfigurationTests { - - @Autowired - TestLoadbalancerClient testLoadbalancerClient; - - @Test - public void contextLoads() { - assertThat(testLoadbalancerClient.instanceFound).isFalse(); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - public static class EurekaClientDisabledApp { - - @Bean - public TestLoadbalancerClient testLoadbalanceClient( - LoadBalancerClient loadBalancerClient) { - return new TestLoadbalancerClient(loadBalancerClient); - } - - @Bean - public CommandLineRunner commandLineRunner( - final TestLoadbalancerClient testLoadbalancerClient) { - return args -> testLoadbalancerClient.doStuff(); - } - - } - - private static class TestLoadbalancerClient { - - Log log = LogFactory.getLog(this.getClass()); - - private LoadBalancerClient loadBalancerClient; - - private boolean instanceFound = false; - - TestLoadbalancerClient(LoadBalancerClient loadBalancerClient) { - this.loadBalancerClient = loadBalancerClient; - } - - public void doStuff() { - ServiceInstance serviceInstance = loadBalancerClient - .choose("https://host/doStuff"); - if (serviceInstance != null) { - log.info( - "There is a service instance, because Eureka discovery is enabled and the service is registered"); - instanceFound = true; - } - else { - log.warn( - "No instance found, because Eureka is disabled or there is no service matching."); - } - } - - } - -} diff --git a/spring-cloud-netflix-eureka-server/pom.xml b/spring-cloud-netflix-eureka-server/pom.xml index 6b3c43607..6c6e11b1e 100644 --- a/spring-cloud-netflix-eureka-server/pom.xml +++ b/spring-cloud-netflix-eureka-server/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT + 3.0.0.BUILD-SNAPSHOT .. spring-cloud-netflix-eureka-server @@ -41,10 +41,6 @@ spring-cloud-context true - - org.springframework.cloud - spring-cloud-netflix-hystrix - org.springframework.cloud spring-cloud-netflix-eureka-client @@ -75,17 +71,6 @@ - - com.netflix.archaius - archaius-core - - - - commons-configuration - commons-configuration - true - - javax.inject javax.inject diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java index 28bc67991..8bb5f8f41 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java @@ -30,7 +30,6 @@ import com.netflix.appinfo.AmazonInfo; import com.netflix.appinfo.ApplicationInfoManager; import com.netflix.appinfo.DataCenterInfo; import com.netflix.appinfo.InstanceInfo; -import com.netflix.config.ConfigurationManager; import com.netflix.discovery.shared.Application; import com.netflix.discovery.shared.Pair; import com.netflix.eureka.EurekaServerContext; @@ -118,10 +117,8 @@ public class EurekaController { private void populateHeader(Map model) { model.put("currentTime", StatusResource.getCurrentTimeAsString()); model.put("upTime", StatusInfo.getUpTime()); - model.put("environment", - ConfigurationManager.getDeploymentContext().getDeploymentEnvironment()); - model.put("datacenter", - ConfigurationManager.getDeploymentContext().getDeploymentDatacenter()); + model.put("environment", "N/A"); // FIXME: + model.put("datacenter", "N/A"); // FIXME: PeerAwareInstanceRegistry registry = getRegistry(); model.put("registry", registry); model.put("isBelowRenewThresold", registry.isBelowRenewThresold() == 1); diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerBootstrap.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerBootstrap.java index 2889f9272..329d4f89f 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerBootstrap.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerBootstrap.java @@ -21,7 +21,6 @@ import javax.servlet.ServletContext; import com.netflix.appinfo.ApplicationInfoManager; import com.netflix.appinfo.DataCenterInfo; import com.netflix.appinfo.InstanceInfo; -import com.netflix.config.ConfigurationManager; import com.netflix.discovery.EurekaClientConfig; import com.netflix.discovery.converters.JsonXStream; import com.netflix.discovery.converters.XmlXStream; @@ -44,18 +43,6 @@ public class EurekaServerBootstrap { private static final Log log = LogFactory.getLog(EurekaServerBootstrap.class); - private static final String TEST = "test"; - - private static final String ARCHAIUS_DEPLOYMENT_ENVIRONMENT = "archaius.deployment.environment"; - - private static final String EUREKA_ENVIRONMENT = "eureka.environment"; - - private static final String DEFAULT = "default"; - - private static final String ARCHAIUS_DEPLOYMENT_DATACENTER = "archaius.deployment.datacenter"; - - private static final String EUREKA_DATACENTER = "eureka.datacenter"; - protected EurekaServerConfig eurekaServerConfig; protected ApplicationInfoManager applicationInfoManager; @@ -109,30 +96,6 @@ public class EurekaServerBootstrap { protected void initEurekaEnvironment() throws Exception { log.info("Setting the eureka configuration.."); - String dataCenter = ConfigurationManager.getConfigInstance() - .getString(EUREKA_DATACENTER); - if (dataCenter == null) { - log.info( - "Eureka data center value eureka.datacenter is not set, defaulting to default"); - ConfigurationManager.getConfigInstance() - .setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, DEFAULT); - } - else { - ConfigurationManager.getConfigInstance() - .setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, dataCenter); - } - String environment = ConfigurationManager.getConfigInstance() - .getString(EUREKA_ENVIRONMENT); - if (environment == null) { - ConfigurationManager.getConfigInstance() - .setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, TEST); - log.info( - "Eureka environment value eureka.environment is not set, defaulting to test"); - } - else { - ConfigurationManager.getConfigInstance() - .setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, environment); - } } protected void initEurekaServerContext() throws Exception { diff --git a/spring-cloud-netflix-hystrix-contract/pom.xml b/spring-cloud-netflix-hystrix-contract/pom.xml deleted file mode 100644 index ffd5ca7fa..000000000 --- a/spring-cloud-netflix-hystrix-contract/pom.xml +++ /dev/null @@ -1,115 +0,0 @@ - - - 4.0.0 - - org.springframework.cloud - spring-cloud-build - 2.2.2.BUILD-SNAPSHOT - - - spring-cloud-netflix-hystrix-contract - 2.2.2.BUILD-SNAPSHOT - jar - spring-cloud-netflix-hystrix-contract - Spring Cloud Netflix Hystrix Contract - - 2.1.3.RELEASE - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.assertj - assertj-core - 3.11.0 - - - org.springframework.boot - spring-boot-starter-test - - - org.assertj - assertj-core - - - - - org.springframework.cloud - spring-cloud-contract-verifier - ${donotreplacespring-cloud-contract.version} - - - org.assertj - assertj-core - - - - - - - spring - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/libs-snapshot-local - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/libs-snapshot-local - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/libs-release-local - - false - - - - - - diff --git a/spring-cloud-netflix-hystrix-contract/src/main/java/org/springframework/cloud/netflix/hystrix/contract/HystrixContractUtils.java b/spring-cloud-netflix-hystrix-contract/src/main/java/org/springframework/cloud/netflix/hystrix/contract/HystrixContractUtils.java deleted file mode 100644 index 0fa0fb9a6..000000000 --- a/spring-cloud-netflix-hystrix-contract/src/main/java/org/springframework/cloud/netflix/hystrix/contract/HystrixContractUtils.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2016-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.contract; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Map; - -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.util.StreamUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * @author Daniel Lavoie - * - */ -public final class HystrixContractUtils { - - private HystrixContractUtils() { - throw new AssertionError("Must not instantiate utility class."); - } - - - public static String simpleBody() { - try { - return StreamUtils.copyToString(new DefaultResourceLoader() - .getResource("classpath:/stubs/simpleBody.json").getInputStream(), - StandardCharsets.UTF_8); - } - catch (IOException e) { - throw new IllegalStateException("Cannot read stub", e); - } - } - - public static void checkEvent(String event) { - assertThat(event).isNotNull(); - assertThat(event).isEqualTo("message"); - } - - public static void checkOrigin(Map origin) { - assertThat(origin.get("host")).isNotNull(); - assertThat(origin.get("port")).isNotNull(); - assertThat(origin.get("serviceId")).isEqualTo("application"); - // TODO: boot 2 changed application context id generation - assertThat(origin.get("id")).asString().startsWith("application"); - } - - public static void checkData(Map data, String group, String name) { - if (!data.get("type").equals("HystrixCommand")) { - assertThat(data.get("type")).isEqualTo("HystrixThreadPool"); - return; - } - assertThat(data.get("type")).isEqualTo("HystrixCommand"); - if (!data.get("name").equals(name)) { - return; - } - assertThat(data.get("name")).asString().isEqualTo(name); - assertThat(data.get("group")).isNotNull(); - assertThat(data.get("group")).isEqualTo(group); - assertThat(data.get("errorCount")).isEqualTo(0); - assertThat(data.get("errorPercentage")).isEqualTo(0); - assertThat(data.get("requestCount")).isInstanceOf(java.lang.Integer.class); - assertThat(data.get("currentConcurrentExecutionCount")) - .isInstanceOf(java.lang.Integer.class); - assertThat(data.get("rollingCountFailure")).isEqualTo(0); - assertThat(data.get("rollingCountSuccess")).isInstanceOf(java.lang.Integer.class); - assertThat(data.get("rollingCountShortCircuited")).isEqualTo(0); - assertThat(data.get("rollingCountFallbackSuccess")).isEqualTo(0); - assertThat(data.get("isCircuitBreakerOpen")).isEqualTo(false); - } - -} diff --git a/spring-cloud-netflix-hystrix-contract/src/main/resources/stubs/simpleBody.json b/spring-cloud-netflix-hystrix-contract/src/main/resources/stubs/simpleBody.json deleted file mode 100644 index 7e1bcfef5..000000000 --- a/spring-cloud-netflix-hystrix-contract/src/main/resources/stubs/simpleBody.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "origin":{ - "host":"192.168.1.192", - "port":0, - "serviceId":"application", - "id":"application:0" - }, - "event" : "message", - "data":{ - "type":"HystrixCommand", - "name":"application.hello", - "group":"Application", - "currentTime":1494840901153, - "isCircuitBreakerOpen":false, - "errorPercentage":0, - "errorCount":0, - "requestCount":1, - "rollingCountCollapsedRequests":0, - "rollingCountExceptionsThrown":0, - "rollingCountFailure":0, - "rollingCountFallbackFailure":0, - "rollingCountFallbackRejection":0, - "rollingCountFallbackSuccess":0, - "rollingCountResponsesFromCache":0, - "rollingCountSemaphoreRejected":0, - "rollingCountShortCircuited":0, - "rollingCountSuccess":0, - "rollingCountThreadPoolRejected":0, - "rollingCountTimeout":0, - "currentConcurrentExecutionCount":0, - "latencyExecute_mean":0, - "latencyExecute":{ - "0":0, - "25":0, - "50":0, - "75":0, - "90":0, - "95":0, - "99":0, - "99.5":0, - "100":0 - }, - "latencyTotal_mean":0, - "latencyTotal":{ - "0":0, - "25":0, - "50":0, - "75":0, - "90":0, - "95":0, - "99":0, - "99.5":0, - "100":0 - }, - "propertyValue_circuitBreakerRequestVolumeThreshold":20, - "propertyValue_circuitBreakerSleepWindowInMilliseconds":5000, - "propertyValue_circuitBreakerErrorThresholdPercentage":50, - "propertyValue_circuitBreakerForceOpen":false, - "propertyValue_circuitBreakerForceClosed":false, - "propertyValue_circuitBreakerEnabled":true, - "propertyValue_executionIsolationStrategy":"THREAD", - "propertyValue_executionIsolationThreadTimeoutInMilliseconds":1000, - "propertyValue_executionIsolationThreadInterruptOnTimeout":true, - "propertyValue_executionIsolationThreadPoolKeyOverride":null, - "propertyValue_executionIsolationSemaphoreMaxConcurrentRequests":10, - "propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests":10, - "propertyValue_metricsRollingStatisticalWindowInMilliseconds":10000, - "propertyValue_requestCacheEnabled":true, - "propertyValue_requestLogEnabled":true, - "reportingHosts":1 - } -} diff --git a/spring-cloud-netflix-hystrix-dashboard/pom.xml b/spring-cloud-netflix-hystrix-dashboard/pom.xml deleted file mode 100644 index 05bd2ba82..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/pom.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - 4.0.0 - spring-cloud-netflix-hystrix-dashboard - Spring Cloud Netflix Hystrix - https://projects.spring.io/spring-cloud/ - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-freemarker - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.apache.httpcomponents - httpclient - - - com.netflix.hystrix - hystrix-core - - - com.netflix.hystrix - hystrix-metrics-event-stream - - - org.webjars - jquery - 2.1.1 - - - org.webjars - d3js - 3.4.11 - - - org.springframework.boot - spring-boot-starter-test - test - - - diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/EnableHystrixDashboard.java b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/EnableHystrixDashboard.java deleted file mode 100644 index d5c38b61a..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/EnableHystrixDashboard.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2013-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.dashboard; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.context.annotation.Import; - -/** - * @author Spencer Gibb - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Import(HystrixDashboardConfiguration.class) -public @interface EnableHystrixDashboard { - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java deleted file mode 100644 index 6d6a78c42..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.dashboard; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.Header; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.PoolingClientConnectionManager; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpHeaders; -import org.springframework.ui.freemarker.SpringTemplateLoader; -import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; - -/** - * @author Dave Syer - * @author Roy Clarkson - * @author Fahim Farook - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties(HystrixDashboardProperties.class) -public class HystrixDashboardConfiguration { - - private static final String DEFAULT_TEMPLATE_LOADER_PATH = "classpath:/templates/"; - - private static final String DEFAULT_CHARSET = "UTF-8"; - - @Autowired - private HystrixDashboardProperties dashboardProperties; - - @Bean - public HasFeatures hystrixDashboardFeature() { - return HasFeatures.namedFeature("Hystrix Dashboard", - HystrixDashboardConfiguration.class); - } - - /** - * Overrides Spring Boot's {@link FreeMarkerAutoConfiguration} to prefer using a - * {@link SpringTemplateLoader} instead of the file system. This corrects an issue - * where Spring Boot may use an empty 'templates' file resource to resolve templates - * instead of the packaged Hystrix classpath templates. - * @return FreeMarker configuration - */ - @Bean - public FreeMarkerConfigurer freeMarkerConfigurer() { - FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); - configurer.setTemplateLoaderPaths(DEFAULT_TEMPLATE_LOADER_PATH); - configurer.setDefaultEncoding(DEFAULT_CHARSET); - configurer.setPreferFileSystemAccess(false); - return configurer; - } - - @Bean - public ServletRegistrationBean proxyStreamServlet() { - final ProxyStreamServlet proxyStreamServlet = new ProxyStreamServlet(); - proxyStreamServlet.setEnableIgnoreConnectionCloseHeader( - this.dashboardProperties.isEnableIgnoreConnectionCloseHeader()); - final ServletRegistrationBean registration = new ServletRegistrationBean( - proxyStreamServlet, "/proxy.stream"); - registration.setInitParameters(this.dashboardProperties.getInitParameters()); - return registration; - } - - @Bean - public HystrixDashboardController hsytrixDashboardController() { - return new HystrixDashboardController(); - } - - /** - * Proxy an EventStream request (data.stream via proxy.stream) since EventStream does - * not yet support CORS (https://bugs.webkit.org/show_bug.cgi?id=61862) so that a UI - * can request a stream from a different server. - */ - public static class ProxyStreamServlet extends HttpServlet { - - private static final Log log = LogFactory.getLog(ProxyStreamServlet.class); - - private static final long serialVersionUID = 1L; - - private static final String CONNECTION_CLOSE_VALUE = "close"; - - private boolean enableIgnoreConnectionCloseHeader = false; - - public void setEnableIgnoreConnectionCloseHeader( - boolean enableIgnoreConnectionCloseHeader) { - this.enableIgnoreConnectionCloseHeader = enableIgnoreConnectionCloseHeader; - } - - public ProxyStreamServlet() { - super(); - } - - /** - * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest - * request, javax.servlet.http.HttpServletResponse response) - */ - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - String origin = request.getParameter("origin"); - if (origin == null) { - response.setStatus(500); - response.getWriter().println( - "Required parameter 'origin' missing. Example: 107.20.175.135:7001"); - return; - } - origin = origin.trim(); - - HttpGet httpget = null; - InputStream is = null; - boolean hasFirstParameter = false; - StringBuilder url = new StringBuilder(); - if (!origin.startsWith("http")) { - url.append("http://"); - } - url.append(origin); - if (origin.contains("?")) { - hasFirstParameter = true; - } - Map params = request.getParameterMap(); - for (String key : params.keySet()) { - if (!key.equals("origin")) { - String[] values = params.get(key); - String value = values[0].trim(); - if (hasFirstParameter) { - url.append("&"); - } - else { - url.append("?"); - hasFirstParameter = true; - } - url.append(key).append("=").append(value); - } - } - String proxyUrl = url.toString(); - log.info("\n\nProxy opening connection to: " + proxyUrl + "\n\n"); - try { - httpget = new HttpGet(proxyUrl); - HttpClient client = ProxyConnectionManager.httpClient; - HttpResponse httpResponse = client.execute(httpget); - int statusCode = httpResponse.getStatusLine().getStatusCode(); - if (statusCode == HttpStatus.SC_OK) { - // writeTo swallows exceptions and never quits even if outputstream is - // throwing IOExceptions (such as broken pipe) ... since the - // inputstream is infinite - // httpResponse.getEntity().writeTo(new - // OutputStreamWrapper(response.getOutputStream())); - // so I copy it manually ... - is = httpResponse.getEntity().getContent(); - - // set headers - copyHeadersToServletResponse(httpResponse.getAllHeaders(), response); - - // copy data from source to response - OutputStream os = response.getOutputStream(); - int b = -1; - while ((b = is.read()) != -1) { - try { - os.write(b); - if (b == 10 /** flush buffer on line feed */ - ) { - os.flush(); - } - } - catch (Exception ex) { - if (ex.getClass().getSimpleName() - .equalsIgnoreCase("ClientAbortException")) { - // don't throw an exception as this means the user closed - // the connection - log.debug( - "Connection closed by client. Will stop proxying ..."); - // break out of the while loop - break; - } - else { - // received unknown error while writing so throw an - // exception - throw new RuntimeException(ex); - } - } - } - } - else { - log.warn("Failed opening connection to " + proxyUrl + " : " - + statusCode + " : " + httpResponse.getStatusLine()); - } - } - catch (Exception ex) { - log.error("Error proxying request: " + url, ex); - } - finally { - if (httpget != null) { - try { - httpget.abort(); - } - catch (Exception ex) { - log.error("failed aborting proxy connection.", ex); - } - } - - // httpget.abort() MUST be called first otherwise is.close() hangs - // (because data is still streaming?) - if (is != null) { - // this should already be closed by httpget.abort() above - try { - is.close(); - } - catch (Exception ex) { - // ignore errors on close - } - } - } - - } - - private void copyHeadersToServletResponse(Header[] headers, - HttpServletResponse response) { - for (Header header : headers) { - // Some versions of Cloud Foundry (HAProxy) are - // incorrectly setting a "Connection: close" header - // causing the Hystrix dashboard to close the connection - // to the stream - // https://github.com/cloudfoundry/gorouter/issues/71 - if (this.enableIgnoreConnectionCloseHeader - && HttpHeaders.CONNECTION.equalsIgnoreCase(header.getName()) - && CONNECTION_CLOSE_VALUE.equalsIgnoreCase(header.getValue())) { - log.warn("Ignoring 'Connection: close' header from stream response"); - } - else if (!HttpHeaders.TRANSFER_ENCODING - .equalsIgnoreCase(header.getName())) { - response.addHeader(header.getName(), header.getValue()); - } - } - } - - @SuppressWarnings("deprecation") - private static class ProxyConnectionManager { - - private final static PoolingClientConnectionManager threadSafeConnectionManager = new PoolingClientConnectionManager(); - - private final static HttpClient httpClient = new DefaultHttpClient( - threadSafeConnectionManager); - - static { - log.debug("Initialize ProxyConnectionManager"); - /* common settings */ - HttpParams httpParams = httpClient.getParams(); - HttpConnectionParams.setConnectionTimeout(httpParams, 5000); - HttpConnectionParams.setSoTimeout(httpParams, 10000); - - /* number of connections to allow */ - threadSafeConnectionManager.setDefaultMaxPerRoute(400); - threadSafeConnectionManager.setMaxTotal(400); - } - - } - - } - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardController.java b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardController.java deleted file mode 100644 index 3d372e9b6..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardController.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.dashboard; - -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.context.request.RequestAttributes; -import org.springframework.web.context.request.WebRequest; - -/** - * @author Dave Syer - */ -@Controller -public class HystrixDashboardController { - - @RequestMapping("/hystrix") - public String home(Model model, WebRequest request) { - model.addAttribute("basePath", extractPath(request)); - return "hystrix/index"; - } - - @RequestMapping("/hystrix/{path}") - public String monitor(@PathVariable String path, Model model, WebRequest request) { - model.addAttribute("basePath", extractPath(request)); - model.addAttribute("contextPath", request.getContextPath()); - return "hystrix/" + path; - } - - private String extractPath(WebRequest request) { - String path = request.getContextPath() + request.getAttribute( - "org.springframework." - + "web.servlet.HandlerMapping.pathWithinHandlerMapping", - RequestAttributes.SCOPE_REQUEST); - return path; - } - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardProperties.java b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardProperties.java deleted file mode 100644 index dc80f9bc1..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardProperties.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.dashboard; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Roy Clarkson - * @author Fahim Farook - */ -@ConfigurationProperties("hystrix.dashboard") -public class HystrixDashboardProperties { - - /** - * Directs the Hystrix dashboard to ignore 'Connection:close' headers if present in - * the Hystrix response stream. - */ - private boolean enableIgnoreConnectionCloseHeader = false; - - /** - * Initialization parameters for {@link ProxyStreamServlet}. ProxyStreamServlet itself - * is not dependent on any initialization parameters, but could be used for adding web - * container specific configurations. i.e. wl-dispatch-policy for WebLogic. - */ - private Map initParameters = new HashMap<>(); - - public boolean isEnableIgnoreConnectionCloseHeader() { - return enableIgnoreConnectionCloseHeader; - } - - public void setEnableIgnoreConnectionCloseHeader( - boolean enableIgnoreConnectionCloseHeader) { - this.enableIgnoreConnectionCloseHeader = enableIgnoreConnectionCloseHeader; - } - - public Map getInitParameters() { - return this.initParameters; - } - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/hystrixCommand.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/hystrixCommand.css deleted file mode 100644 index c31117435..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/hystrixCommand.css +++ /dev/null @@ -1,200 +0,0 @@ -.dependencies .spacer { - width: 100%; - margin: 0 auto; - padding-top:4px; - clear:both; -} - - -.dependencies .last { - margin-right: 0px; -} - -.dependencies span.loading { - display: block; - padding-top: 6%; - padding-bottom: 6%; - color: gray; - text-align: center; -} - -.dependencies span.loading.failed { - color: red; -} - - -.dependencies div.monitor { - float: left; - margin-right:5px; - margin-top:5px; -} - -.dependencies div.monitor p.name { - font-weight:bold; - font-size: 10pt; - text-align: right; - padding-bottom: 5px; -} - -.dependencies div.monitor_data { - margin: 0 auto; -} - -/* override the HREF when we have specified it as a tooltip to not act like a link */ -.dependencies div.monitor_data a.tooltip { - text-decoration: none; - cursor: default; -} - -.dependencies div.monitor_data div.counters { - text-align: right; - padding-bottom: 10px; - font-size: 10pt; - clear: both; - -} - -.dependencies div.monitor_data div.counters div.cell { - display: inline; - float: right; -} - -.dependencies .borderRight { - border-right: 1px solid grey; - padding-right: 6px; - padding-left: 8px; -} - -.dependencies div.cell .line { - display: block; -} - -.dependencies div.monitor_data a, -.dependencies span.rate_value { - font-weight:bold; -} - - -.dependencies span.smaller { - font-size: 8pt; - color: grey; -} - - - -.dependencies div.tableRow { - width:100%; - white-space: nowrap; - font-size: 8pt; - margin: 0 auto; - clear:both; - padding-left:26%; -} - -.dependencies div.tableRow .cell { - float:left; -} - -.dependencies div.tableRow .header { - width:18%; - text-align:right; - padding-right:2%; -} - -.dependencies div.tableRow .data { - width:17%; - font-weight: bold; - text-align:right; -} - - -.dependencies div.monitor { - width: 245px; /* we want a fixed width instead of percentage as I want the boxes to be a set size and then fill in as many as can fit in each row ... this allows 3 columns on an iPad */ - height: 155px; -} - -.dependencies .success { - color: green; -} -.dependencies .shortCircuited { - color: blue; -} -.dependencies .timeout { - color: #FF9900; /* shade of orange */ -} -.dependencies .failure { - color: red; -} - -.badRequest { - color: #00CC99; -} - -.dependencies .rejected { - color: purple; -} - -.dependencies .exceptionsThrown { - color: brown; -} - -.dependencies div.monitor_data a.rate { - color: black; - font-size: 11pt; -} - -.dependencies div.rate { - padding-top: 1px; - clear:both; - text-align:right; -} - -.dependencies .errorPercentage { - color: grey; -} - -.dependencies div.cell .errorPercentage { - padding-left:5px; - font-size: 12pt !important; -} - - -.dependencies div.monitor div.chart { -} - -.dependencies div.monitor div.chart svg { -} - -.dependencies div.monitor div.chart svg text { - fill: white; -} - - -.dependencies div.circuitStatus { - width:100%; - white-space: nowrap; - font-size: 9pt; - margin: 0 auto; - clear:both; - text-align:right; - padding-top: 4px; -} - -.dependencies #hidden { - width:1px; - height:1px; - background: lightgrey; - display: none; -} - - - -/* sparkline */ -.dependencies path { - stroke: steelblue; - stroke-width: 1; - fill: none; -} - - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/hystrixCommand.js b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/hystrixCommand.js deleted file mode 100644 index 9d5724d27..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/hystrixCommand.js +++ /dev/null @@ -1,542 +0,0 @@ - -(function(window) { - - // cache the templates we use on this page as global variables (asynchronously) - jQuery.get(getRelativePath("components/hystrixCommand/templates/hystrixCircuit.html"), function(data) { - hystrixTemplateCircuit = data; - }); - jQuery.get(getRelativePath("components/hystrixCommand/templates/hystrixCircuitContainer.html"), function(data) { - hystrixTemplateCircuitContainer = data; - }); - - function getRelativePath(path) { - var p = location.pathname.slice(0, location.pathname.lastIndexOf("/")+1); - return p + path; - } - - /** - * Object containing functions for displaying and updating the UI with streaming data. - * - * Publish this externally as "HystrixCommandMonitor" - */ - window.HystrixCommandMonitor = function(containerId, args) { - - var self = this; // keep scope under control - self.args = args; - if(self.args == undefined) { - self.args = {}; - } - - this.containerId = containerId; - - /** - * Initialization on construction - */ - // intialize various variables we use for visualization - var maxXaxisForCircle="40%"; - var maxYaxisForCircle="40%"; - var maxRadiusForCircle="125"; - - // CIRCUIT_BREAKER circle visualization settings - self.circuitCircleRadius = d3.scale.pow().exponent(0.5).domain([0, 400]).range(["5", maxRadiusForCircle]); // requests per second per host - self.circuitCircleYaxis = d3.scale.linear().domain([0, 400]).range(["30%", maxXaxisForCircle]); - self.circuitCircleXaxis = d3.scale.linear().domain([0, 400]).range(["30%", maxYaxisForCircle]); - self.circuitColorRange = d3.scale.linear().domain([10, 25, 40, 50]).range(["green", "#FFCC00", "#FF9900", "red"]); - self.circuitErrorPercentageColorRange = d3.scale.linear().domain([0, 10, 35, 50]).range(["grey", "black", "#FF9900", "red"]); - - /** - * We want to keep sorting in the background since data values are always changing, so this will re-sort every X milliseconds - * to maintain whatever sort the user (or default) has chosen. - * - * In other words, sorting only for adds/deletes is not sufficient as all but alphabetical sort are dynamically changing. - */ - setInterval(function() { - // sort since we have added a new one - self.sortSameAsLast(); - }, 10000); - - - /** - * END of Initialization on construction - */ - - /** - * Event listener to handle new messages from EventSource as streamed from the server. - */ - /* public */ self.eventSourceMessageListener = function(e) { - var data = JSON.parse(e.data); - if(data) { - // check for reportingHosts (if not there, set it to 1 for singleHost vs cluster) - if(!data.reportingHosts) { - data.reportingHosts = 1; - } - - if(data && data.type == 'HystrixCommand') { - if (data.deleteData == 'true') { - deleteCircuit(data.escapedName); - } else { - displayCircuit(data); - } - } - } - }; - - /** - * Pre process the data before displying in the UI. - * e.g Get Averages from sums, do rate calculation etc. - */ - function preProcessData(data) { - // set defaults for values that may be missing from older streams - setIfMissing(data, "rollingCountBadRequests", 0); - // assert all the values we need - validateData(data); - // escape string used in jQuery & d3 selectors - data.escapedName = data.name.replace(/([ !"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g,'\\$1'); - // do math - convertAllAvg(data); - calcRatePerSecond(data); - } - - function setIfMissing(data, key, defaultValue) { - if(data[key] == undefined) { - data[key] = defaultValue; - } - } - - /** - * Since the stream of data can be aggregated from multiple hosts in a tiered manner - * the aggregation just sums everything together and provides us the denominator (reportingHosts) - * so we must divide by it to get an average per instance value. - * - * We want to do this on any numerical values where we want per instance rather than cluster-wide sum. - */ - function convertAllAvg(data) { - convertAvg(data, "errorPercentage", true); - convertAvg(data, "latencyExecute_mean", false); - convertAvg(data, "latencyTotal_mean", false); - } - - function convertAvg(data, key, decimal) { - if (decimal) { - data[key] = getInstanceAverage(data[key], data["reportingHosts"], decimal); - } else { - data[key] = getInstanceAverage(data[key], data["reportingHosts"], decimal); - } - } - - function getInstanceAverage(value, reportingHosts, decimal) { - if (decimal) { - return roundNumber(value/reportingHosts); - } else { - return Math.floor(value/reportingHosts); - } - } - - function calcRatePerSecond(data) { - var numberSeconds = data["propertyValue_metricsRollingStatisticalWindowInMilliseconds"] / 1000; - - var totalRequests = data["requestCount"]; - if (totalRequests < 0) { - totalRequests = 0; - } - data["ratePerSecond"] = roundNumber(totalRequests / numberSeconds); - data["ratePerSecondPerHost"] = roundNumber(totalRequests / numberSeconds / data["reportingHosts"]) ; - } - - function validateData(data) { - assertNotNull(data,"reportingHosts"); - assertNotNull(data,"type"); - assertNotNull(data,"name"); - assertNotNull(data,"group"); - // assertNotNull(data,"currentTime"); - assertNotNull(data,"isCircuitBreakerOpen"); - assertNotNull(data,"errorPercentage"); - assertNotNull(data,"errorCount"); - assertNotNull(data,"requestCount"); - assertNotNull(data,"rollingCountCollapsedRequests"); - assertNotNull(data,"rollingCountExceptionsThrown"); - assertNotNull(data,"rollingCountFailure"); - assertNotNull(data,"rollingCountFallbackFailure"); - assertNotNull(data,"rollingCountFallbackRejection"); - assertNotNull(data,"rollingCountFallbackSuccess"); - assertNotNull(data,"rollingCountResponsesFromCache"); - assertNotNull(data,"rollingCountSemaphoreRejected"); - assertNotNull(data,"rollingCountShortCircuited"); - assertNotNull(data,"rollingCountSuccess"); - assertNotNull(data,"rollingCountThreadPoolRejected"); - assertNotNull(data,"rollingCountTimeout"); - assertNotNull(data,"rollingCountBadRequests"); - assertNotNull(data,"currentConcurrentExecutionCount"); - assertNotNull(data,"latencyExecute_mean"); - assertNotNull(data,"latencyExecute"); - assertNotNull(data,"latencyTotal_mean"); - assertNotNull(data,"latencyTotal"); - assertNotNull(data,"propertyValue_circuitBreakerRequestVolumeThreshold"); - assertNotNull(data,"propertyValue_circuitBreakerSleepWindowInMilliseconds"); - assertNotNull(data,"propertyValue_circuitBreakerErrorThresholdPercentage"); - assertNotNull(data,"propertyValue_circuitBreakerForceOpen"); - assertNotNull(data,"propertyValue_circuitBreakerForceClosed"); - assertNotNull(data,"propertyValue_executionIsolationStrategy"); - assertNotNull(data,"propertyValue_executionIsolationThreadTimeoutInMilliseconds"); - assertNotNull(data,"propertyValue_executionIsolationThreadInterruptOnTimeout"); - // assertNotNull(data,"propertyValue_executionIsolationThreadPoolKeyOverride"); - assertNotNull(data,"propertyValue_executionIsolationSemaphoreMaxConcurrentRequests"); - assertNotNull(data,"propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests"); - assertNotNull(data,"propertyValue_requestCacheEnabled"); - assertNotNull(data,"propertyValue_requestLogEnabled"); - assertNotNull(data,"propertyValue_metricsRollingStatisticalWindowInMilliseconds"); - } - - function assertNotNull(data, key) { - if(data[key] == undefined) { - throw new Error("Key Missing: " + key + " for " + data.name); - } - } - - /** - * Method to display the CIRCUIT data - * - * @param data - */ - /* private */ function displayCircuit(data) { - - try { - preProcessData(data); - } catch (err) { - log("Failed preProcessData: " + err.message); - return; - } - - // add the 'addCommas' function to the 'data' object so the HTML templates can use it - data.addCommas = addCommas; - // add the 'roundNumber' function to the 'data' object so the HTML templates can use it - data.roundNumber = roundNumber; - // add the 'getInstanceAverage' function to the 'data' object so the HTML templates can use it - data.getInstanceAverage = getInstanceAverage; - - var addNew = false; - // check if we need to create the container - if(!$('#CIRCUIT_' + data.escapedName).length) { - // args for display - if(self.args.includeDetailIcon != undefined && self.args.includeDetailIcon) { - data.includeDetailIcon = true; - }else { - data.includeDetailIcon = false; - } - - // it doesn't exist so add it - var html = tmpl(hystrixTemplateCircuitContainer, data); - // remove the loading thing first - $('#' + containerId + ' span.loading').remove(); - // now create the new data and add it - $('#' + containerId + '').append(html); - - // add the default sparkline graph - d3.selectAll('#graph_CIRCUIT_' + data.escapedName + ' svg').append("svg:path"); - - // remember this is new so we can trigger a sort after setting data - addNew = true; - } - - - // now update/insert the data - $('#CIRCUIT_' + data.escapedName + ' div.monitor_data').html(tmpl(hystrixTemplateCircuit, data)); - - var ratePerSecond = data.ratePerSecond; - var ratePerSecondPerHost = data.ratePerSecondPerHost; - var ratePerSecondPerHostDisplay = ratePerSecondPerHost; - var errorThenVolume = (data.errorPercentage * 100000000) + ratePerSecond; - - // set the rates on the div element so it's available for sorting - $('#CIRCUIT_' + data.escapedName).attr('rate_value', ratePerSecond); - $('#CIRCUIT_' + data.escapedName).attr('error_then_volume', errorThenVolume); - - // update errorPercentage color on page - $('#CIRCUIT_' + data.escapedName + ' a.errorPercentage').css('color', self.circuitErrorPercentageColorRange(data.errorPercentage)); - - updateCircle('circuit', '#CIRCUIT_' + data.escapedName + ' circle', ratePerSecondPerHostDisplay, data.errorPercentage); - - if(data.graphValues) { - // we have a set of values to initialize with - updateSparkline('circuit', '#CIRCUIT_' + data.escapedName + ' path', data.graphValues); - } else { - updateSparkline('circuit', '#CIRCUIT_' + data.escapedName + ' path', ratePerSecond); - } - - if(addNew) { - // sort since we added a new circuit - self.sortSameAsLast(); - } - } - - /* round a number to X digits: num => the number to round, dec => the number of decimals */ - /* private */ function roundNumber(num) { - var dec=1; - var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec); - var resultAsString = result.toString(); - if(resultAsString.indexOf('.') == -1) { - resultAsString = resultAsString + '.0'; - } - return resultAsString; - }; - - - - - /* private */ function updateCircle(variablePrefix, cssTarget, rate, errorPercentage) { - var newXaxisForCircle = self[variablePrefix + 'CircleXaxis'](rate); - if(parseInt(newXaxisForCircle) > parseInt(maxXaxisForCircle)) { - newXaxisForCircle = maxXaxisForCircle; - } - var newYaxisForCircle = self[variablePrefix + 'CircleYaxis'](rate); - if(parseInt(newYaxisForCircle) > parseInt(maxYaxisForCircle)) { - newYaxisForCircle = maxYaxisForCircle; - } - var newRadiusForCircle = self[variablePrefix + 'CircleRadius'](rate); - if(parseInt(newRadiusForCircle) > parseInt(maxRadiusForCircle)) { - newRadiusForCircle = maxRadiusForCircle; - } - - d3.selectAll(cssTarget) - .transition() - .duration(400) - .attr("cy", newYaxisForCircle) - .attr("cx", newXaxisForCircle) - .attr("r", newRadiusForCircle) - .style("fill", self[variablePrefix + 'ColorRange'](errorPercentage)); - } - - /* private */ function updateSparkline(variablePrefix, cssTarget, newDataPoint) { - var currentTimeMilliseconds = new Date().getTime(); - var data = self[variablePrefix + cssTarget + '_data']; - if(typeof data == 'undefined') { - // else it's new - if(typeof newDataPoint == 'object') { - // we received an array of values, so initialize with it - data = newDataPoint; - } else { - // v: VALUE, t: TIME_IN_MILLISECONDS - data = [{"v":parseFloat(newDataPoint),"t":currentTimeMilliseconds}]; - } - self[variablePrefix + cssTarget + '_data'] = data; - } else { - if(typeof newDataPoint == 'object') { - /* if an array is passed in we'll replace the cached one */ - data = newDataPoint; - } else { - // else we just add to the existing one - data.push({"v":parseFloat(newDataPoint),"t":currentTimeMilliseconds}); - } - } - - while(data.length > 200) { // 400 should be plenty for the 2 minutes we have the scale set to below even with a very low update latency - // remove data so we don't keep increasing forever - data.shift(); - } - - if(data.length == 1 && data[0].v == 0) { - //console.log("we have a single 0 so skipping"); - // don't show if we have a single 0 - return; - } - - if(data.length > 1 && data[0].v == 0 && data[1].v != 0) { - //console.log("we have a leading 0 so removing it"); - // get rid of a leading 0 if the following number is not a 0 - data.shift(); - } - - var xScale = d3.time.scale().domain([new Date(currentTimeMilliseconds-(60*1000*2)), new Date(currentTimeMilliseconds)]).range([0, 140]); - - var yMin = d3.min(data, function(d) { return d.v; }); - var yMax = d3.max(data, function(d) { return d.v; }); - var yScale = d3.scale.linear().domain([yMin, yMax]).nice().range([60, 0]); // y goes DOWN, so 60 is the "lowest" - - sparkline = d3.svg.line() - // assign the X function to plot our line as we wish - .x(function(d,i) { - // return the X coordinate where we want to plot this datapoint based on the time - return xScale(new Date(d.t)); - }) - .y(function(d) { - return yScale(d.v); - }) - .interpolate("basis"); - - d3.selectAll(cssTarget).attr("d", sparkline(data)); - } - - /* private */ function deleteCircuit(circuitName) { - $('#CIRCUIT_' + circuitName).remove(); - } - - }; - - // public methods for sorting - HystrixCommandMonitor.prototype.sortByVolume = function() { - var direction = "desc"; - if(this.sortedBy == 'rate_desc') { - direction = 'asc'; - } - this.sortByVolumeInDirection(direction); - }; - - HystrixCommandMonitor.prototype.sortByVolumeInDirection = function(direction) { - this.sortedBy = 'rate_' + direction; - $('#' + this.containerId + ' div.monitor').tsort({order: direction, attr: 'rate_value'}); - }; - - HystrixCommandMonitor.prototype.sortAlphabetically = function() { - var direction = "asc"; - if(this.sortedBy == 'alph_asc') { - direction = 'desc'; - } - this.sortAlphabeticalInDirection(direction); - }; - - HystrixCommandMonitor.prototype.sortAlphabeticalInDirection = function(direction) { - this.sortedBy = 'alph_' + direction; - $('#' + this.containerId + ' div.monitor').tsort("p.name", {order: direction}); - }; - - - HystrixCommandMonitor.prototype.sortByError = function() { - var direction = "desc"; - if(this.sortedBy == 'error_desc') { - direction = 'asc'; - } - this.sortByErrorInDirection(direction); - }; - - HystrixCommandMonitor.prototype.sortByErrorInDirection = function(direction) { - this.sortedBy = 'error_' + direction; - $('#' + this.containerId + ' div.monitor').tsort(".errorPercentage .value", {order: direction}); - }; - - HystrixCommandMonitor.prototype.sortByErrorThenVolume = function() { - var direction = "desc"; - if(this.sortedBy == 'error_then_volume_desc') { - direction = 'asc'; - } - this.sortByErrorThenVolumeInDirection(direction); - }; - - HystrixCommandMonitor.prototype.sortByErrorThenVolumeInDirection = function(direction) { - this.sortedBy = 'error_then_volume_' + direction; - $('#' + this.containerId + ' div.monitor').tsort({order: direction, attr: 'error_then_volume'}); - }; - - HystrixCommandMonitor.prototype.sortByLatency90 = function() { - var direction = "desc"; - if(this.sortedBy == 'lat90_desc') { - direction = 'asc'; - } - this.sortedBy = 'lat90_' + direction; - this.sortByMetricInDirection(direction, ".latency90 .value"); - }; - - HystrixCommandMonitor.prototype.sortByLatency99 = function() { - var direction = "desc"; - if(this.sortedBy == 'lat99_desc') { - direction = 'asc'; - } - this.sortedBy = 'lat99_' + direction; - this.sortByMetricInDirection(direction, ".latency99 .value"); - }; - - HystrixCommandMonitor.prototype.sortByLatency995 = function() { - var direction = "desc"; - if(this.sortedBy == 'lat995_desc') { - direction = 'asc'; - } - this.sortedBy = 'lat995_' + direction; - this.sortByMetricInDirection(direction, ".latency995 .value"); - }; - - HystrixCommandMonitor.prototype.sortByLatencyMean = function() { - var direction = "desc"; - if(this.sortedBy == 'latMean_desc') { - direction = 'asc'; - } - this.sortedBy = 'latMean_' + direction; - this.sortByMetricInDirection(direction, ".latencyMean .value"); - }; - - HystrixCommandMonitor.prototype.sortByLatencyMedian = function() { - var direction = "desc"; - if(this.sortedBy == 'latMedian_desc') { - direction = 'asc'; - } - this.sortedBy = 'latMedian_' + direction; - this.sortByMetricInDirection(direction, ".latencyMedian .value"); - }; - - HystrixCommandMonitor.prototype.sortByMetricInDirection = function(direction, metric) { - $('#' + this.containerId + ' div.monitor').tsort(metric, {order: direction}); - }; - - // this method is for when new divs are added to cause the elements to be sorted to whatever the user last chose - HystrixCommandMonitor.prototype.sortSameAsLast = function() { - if(this.sortedBy == 'alph_asc') { - this.sortAlphabeticalInDirection('asc'); - } else if(this.sortedBy == 'alph_desc') { - this.sortAlphabeticalInDirection('desc'); - } else if(this.sortedBy == 'rate_asc') { - this.sortByVolumeInDirection('asc'); - } else if(this.sortedBy == 'rate_desc') { - this.sortByVolumeInDirection('desc'); - } else if(this.sortedBy == 'error_asc') { - this.sortByErrorInDirection('asc'); - } else if(this.sortedBy == 'error_desc') { - this.sortByErrorInDirection('desc'); - } else if(this.sortedBy == 'error_then_volume_asc') { - this.sortByErrorThenVolumeInDirection('asc'); - } else if(this.sortedBy == 'error_then_volume_desc') { - this.sortByErrorThenVolumeInDirection('desc'); - } else if(this.sortedBy == 'lat90_asc') { - this.sortByMetricInDirection('asc', '.latency90 .value'); - } else if(this.sortedBy == 'lat90_desc') { - this.sortByMetricInDirection('desc', '.latency90 .value'); - } else if(this.sortedBy == 'lat99_asc') { - this.sortByMetricInDirection('asc', '.latency99 .value'); - } else if(this.sortedBy == 'lat99_desc') { - this.sortByMetricInDirection('desc', '.latency99 .value'); - } else if(this.sortedBy == 'lat995_asc') { - this.sortByMetricInDirection('asc', '.latency995 .value'); - } else if(this.sortedBy == 'lat995_desc') { - this.sortByMetricInDirection('desc', '.latency995 .value'); - } else if(this.sortedBy == 'latMean_asc') { - this.sortByMetricInDirection('asc', '.latencyMean .value'); - } else if(this.sortedBy == 'latMean_desc') { - this.sortByMetricInDirection('desc', '.latencyMean .value'); - } else if(this.sortedBy == 'latMedian_asc') { - this.sortByMetricInDirection('asc', '.latencyMedian .value'); - } else if(this.sortedBy == 'latMedian_desc') { - this.sortByMetricInDirection('desc', '.latencyMedian .value'); - } - }; - - // default sort type and direction - this.sortedBy = 'alph_asc'; - - - // a temporary home for the logger until we become more sophisticated - function log(message) { - console.log(message); - }; - - function addCommas(nStr){ - nStr += ''; - if(nStr.length <=3) { - return nStr; //shortcut if we don't need commas - } - x = nStr.split('.'); - x1 = x[0]; - x2 = x.length > 1 ? '.' + x[1] : ''; - var rgx = /(\d+)(\d{3})/; - while (rgx.test(x1)) { - x1 = x1.replace(rgx, '$1' + ',' + '$2'); - } - return x1 + x2; - } -})(window); diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/magnifying-glass-icon-20.png b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/magnifying-glass-icon-20.png deleted file mode 100644 index 4898b4854ec4c03ebb47fad35f05ac5bb0800a4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 863 zcmV-l1EBngP)L(qBkZQ5*;G-?^K2cURrirdVW2+g(`@#j-NZhp-|o zQHCpmRZl_mP*L>KLqt$SB|X)P5E0QsC|OieFGd*~6!zwrCFz!}ZMXYp_il6N?4BNS zVN}lY2j}ga58vPKcM$wTZQQV-wWGcLw9DyiEn!)kswh)$-@SV{_~_A_2$$Qq86< zuZ)Vy@id^AmZx7+jA=@=mc5)Qu_Sh`TXSV(WaMs9kY!o(nNz2pEcG;oh_!Sog^8qL zqG*K38YYrPh?HQ=qh-`^Rxzl7DF&`~ySLgM4jZ*qOlX*>`i~=JNM38Gv^TD@m9Hgv zBm0H7^?N*?PIEEP;c%=#R$kUIQFTIO{YNT!bIp?7JC@fTpp-%u<749q^1*Jm*B1pd znT(ppn3=(|EzYJyv-?B{fyHFvON_h?W2_bh!{g(Dd`hiKr_+WGNYycsbxh>JiO8)C z!K#LdJev46T$fGz!{PAjdB4pezyCsWQ`4bzCKIP(f7@tfgfl>;FVdR3r zV0R=EdAd*x000#*Q51Pek_yTG3j+W!cXf5$k4B?>Hk(~E1^{4+#bSx->grB}5Lztu pvz$)n5wF)P)z#JQT@(ZW-vNSIv=jeQf6h{CB zg(+3@&9vhyy3tpmYxF8aox~8 z^hUsMh&WB0-4QsFckalE-jNrTkTH>vRJbFrAT6cDmMQ=cYupe&_Vn|%L*O|1`abnh z5Eu7+itw;=bAAf<_PtSE+#cZzcXkt(k(Rk5?*9L@7X2qv)HX=;e`>nZKDx0Y^q+Xo zr$OG%j!wQf40g>;Mj|KY$b>av1azp%i*^Bz` zOFMY;+C$rRlJ`EO&;@+d-ur&VzjU3`BfG#M$-FqSpsuM}s`n`1%#y-Q8VNcRqFf zB0o};=@WTezsnwhFqcfjj}_v-{;C!h8s#|OwuTz(WqNyEn8YsWGC0W3llG%|b?u-_ zGfXLNwfP;s${&7fcj8F5EC}jvZtSWx?OhKrZpHvk4i}g+&5k_vmC6JEq-UXd&v)Nl zU0oG@RJ^4!!9(8nEYbgNsjh-%=PXMrS3zQOUTKIf*W#jV;SUZ0!@qb-^2CQYTfVL1 zuX@8Haa``>st_=jh!GG zPFW3$Fu$cThKpq|eldr`)7Fzo{!}IPmYRNs@8j3qmA8J<$ZZmK@bj(_<(N|QMg?YW z6Bs+0K2I)P#f`Wonpt_tOsGPuMIGJsj`id7M0Cl^=dN51toWmbGsO=Qi7!kjZo=M8-?5JUv5rF}P{f}`mEviqp_)qI z#dd1?urv|H@biTRs-q$~WsB56uY$~ATsZlY=wOPNm~M(l)r)v^HAQk|r-<5|Oa=GO zlSuCE+%a_%tOVTDPuSfYR3j=vGH3r|zcf!_MvLnhK`t@%y>8h3$vdLH{Wk>H@KIFDz>b-bXH8PrNk`r^CWB9=Ov%Qq&I&~ z3VpoxlpI$r+QvRK_!A5?_!V)l+MDS9h#$-vTcsH-;E0n6U?cO~Iu}G&tZG3YU&Q5> zpY++Y8Oyy7f8*??*e&;d??4co;fu?^3MNveFYs1OP4<}8>-xc52+=DzVZ^z?X7Hd#X~oY-Y#w1zBF_tMGc%p zsfK>R^?|;s1vgg*IsRN{2$x*CAKrq{G_*Q8@oCgojI2M3`n>sBweUy5Z0M^~RA%`b z+Y?pxvJZA2JJm=ZJk^+tacOL_ldKnWl$91h_)$eW`klroMVof9L+pPF-R=NnvBsIw z#(>O82b%l{lKU#FLf9bo%z@tI5UXHl3@Z$zlNFf`Q_qh4eZKF4hc@|Lr8qt(OQ84M z)avMcz2E4QTduk9@n>b-6-*Z~ThIKLv}J``U;Jq15@?Stvb7;QWMa0BPh@M)XHHHs z*wwCR&G2~}z8`rrc-ny|O7^}K-|!b}gbqJpav>b9ceF)jzB37&fjj?p0IRZQ^( zgr+JText?P4Gg!g%7*udvJZ5!3})z_-X)J710>5^O*fn!m+^N!&SqIwG@ow%rKZ0c zI}O5qQTrg7Hg$AS>d@le zi{#_M(v1DDvnex?ov2!RNDw{*AKK8Cz}ZbYF58{3|D-J7#CZUY#g3Hu=j0Rnr}PXT zt3Aa-f7&Ip!))gg1ExX0Tg0kCYqOu6M$gC`$i{#cn-t8x)UEE84eb5H6E^vv;5`ni z#Pqjo%B=J@+;7cxF@Z{a_Kd9>`6Nt1W|ikr)xH;X^P_HNDj`*t%xz73)zc9xX&Nst zvpQB5ar$GMWY#DwHm7|_0&2C%{30J8wXaNp%dl4+=yMUNZw;pVcbul{X^lG}0KV$8 zbDN4^<{ViW_FEH6fe)cr#VD8l4w%ryNbb52qTV_R%v2Fz zk$J`e7}j&6aVo$}g#^+LnS38yHE3+;KIw{8Ac35RqI5^I;J~ypO=cBDKca@-mW#mB z)Y0EF)`yv5@8Cj+MqIPm+M!K<9;h!W#*q!rRrYcp-o~lI`4l{81^?|X8K1W_LH$PKCS8M!Wfg$eE@ODpG{I>9W9aOb2+797AAwXH97|5(q8m`u; z*&%BH!=}^iSZ=h7AUbyd{#zmfw1qjofN-RhyMnZw`3EhJaOmoMaub7VN>i(aooUhKb>hAN6hwln z6o5h4vkJb5q`9$2NINj0(mNo87mmoD`~ZB$23^kC6^a1LI>j zW`+Ctu|dx1R9tNCM3_1REc0HdCRBvNEow|pkFCLV^fS<7i^fNX7R-BOv+a$- zed(s9v^5mnl|4O?=1Gd`?F5sYEHF+boy1To?vb5n^yj$M#m(G^N}gv#2UdwC2UR^X zKeE``BlDx%B}<2!wmFG!Ri9WtBStCVL)u8t{tRa0GBMbc?=Cg&>Zal4tCngRmge>q zYf6`R!ua0Ili&;hz0@Z-;n=e+`f zRhAOMu_6RRb)KXbs(ttuy}UJ|j45b!p`u8;smIGh-KT`cSgXkcM@HZWVf zecwY29lRH4IVHwy%&9RLNQ1?bw_2N?wsC=~_xIa~?y_oeL}7pP?wrKLTZ2#I6Pz&~ zHpurqoe!*b2`_qy9IU~souI9{jh6+)w9ri84GB6BMCa?n*F6bQqXdjL?*LiQ-`g9J z!}r;eb?14X=Fd!y-Z~zZH6dS<1|mkL*Dw0gdWE^X-jrUuSp4d4%%J5#pX>v?N)>9Fs~!$Qc7jAc!gvc6iOf?zpR^)-=(Sbn$rzFpB6$VTmT@Yuq^6zMTD3nRm=?=8A+%} zB_~w4TZN{2yUE}8uab;OQ4y{~tJYw$6M~9jTXayB zC7-Z^%Z2Kw;)PDt7e>6B)#?HQ3YYD5VU01Ri7 zOBwQA?6dD#x(=kEnTIh|do8ONmYkM3VY_l`@GB#UtPaSOM!z1y=FX{wd7ZeMOszPR z0e&*(a76r~LkKO)0&5g&I*w^PTOY3)2ZzXN(N$*oIwOt$(qQq2#3biub^kPv4#u3v z+LD5OF7S$Nw*gO>gkh-{pGlf$)Y+{U|MS|t?nxweJ3sA*5PEhaOSxX5ZF3%`QosYJ z*B3bZdBJKz&zncisHNpUYU1Lh?LO4qIO7F z*#_ot6cyNC^CqpkGOc@?JHj-E9pWlZe_s>cDEw|s&Q&bqGWfB^l`h-ICT*sgb|O=P zp?Rx}ssGuuvN@t_;dY)voTGUKt=@qv^M;L~dFom*qm#~h3u)qu zW~;AqFk71kCP_KS93VcRtI3?~ggwWaoDeMMA7+d8xF8@~QUL$gkIys4W6}f+TzGEr zei`|Gmk>)Z#PlbzOl}c=L7rBLF7a09FJ0Mv9psG*s#_y^_HTv+zUVMo1Jl{*v zQQ@nz$)89W<9=b3Y2~$QnaX##I)57PBIskXHK%URYmNR=9^rv%WX{k@%vJ{kut=uW zWdk2nbVM*Pzt_dfVKQ8NNbs3Sziz#>iH{|IB?T>&h~%r%oYY^h&D~!lNSs<=4YnF- zSwT|suBPfRQ)jFzf)reYF19g`#I|jnz1)IlKK>&}Fq`tHAv-9mLsUJRFFN{?97HtA z2Cxh%l9pFlCM~-C8|J zEBnShWhFW!G~G9Rcg(3Fj!!bZPz9?Z#qe4!P47d-_bHZjjehCoXC_G<)~HOt4$OQ8 zV&mZJ{sc=rRK5iCwHSf^$J~ss0(Y}^Qeo9!fmAaOd2i5TYt@cvqcw2cbnV@7Ijf_3 zfAk1DX!;w2kp!@Yx+ec~G*4g%HjX&;b^)X8MrJJ0sQtmVl@LEn!_@D!REg~|M%Cm~ z!wG?|HTVf!{iFBcfq7v~Cg*iW-}3VH5%R&HGOQN8i7M*l=J9NCF-a<~U40_}%y~zf zJHIXFNm0MV!1ufh)U+wZ-{5iOl^Iop@y29wb<|br3H?)Ip9v%dM7>oH6T}k9DNTvz zJLku|h(779Exci(UtiOv-v1e4gSiEv-A61=yENK7|kFbBwDLhbXB+&^3 z2liv1I$1gRgZWQEheGd38!);qoPUBMBff1IV>Vz^kd> znIFo09Mw=)h4k0$zEl^GRMQCi-f1ME&&~|ukwI^!au4CIgiZKfn1Me$s{3%+>*A=< zAN@#y#&;2!Qy@kU;^9Llsb-zj+%+nSW*H5=S-W~jjU-ay6JB}ayY!vL|K+r2 z+6X}!I(<(|MdW?Zt3-atpuEAOtbf>>4@jo#y6w5gZ5PjWJeL&a!w;;FlY4qDzdU>h z3W$wGc~DVgF9-hQZ2K{$G`eo!!Jgo}WvO;r!?x8}huBTfeP)F>cfn>NC@q$<+9@ns z!1eY`b8i+hhn`5IAKI2Rl38MVl4%-}No9Fo>zj$Rq{8_F$GE|wF2B_tPJKTsO?Ptd zkSe#^Y$H~5B)Gg>&D4mkB_+?l$R)2shDdTr`ppsLb1FTx#v3 zc$u^`qy47m)#TU!tK8`Y?b9K5n;d@*UFtfuu^N06A^Xp72p2gJ6- zw%Ae-fSW7dLlg4brgO^j3ilMw;~x=Hq$K%fp4eFJh(NWE@AxWK(gzcZ#L9C!s5+Mv z*Ki9DTp@F$8k0R2+1M&4Sd}LFzk!h zdbRRrAYdLT3G>(daOoc0+zc(CQ{$AUUS3#P|C1bWlBMO;k)jim)J-e%I!(B;t^fq; zgC-|9r%4EJOeK}rO153Rr-M>#iskaXOU<)utKBAQ$r!2AH+U_~8_#7RZ zbmCF_-tgEZobIwGvcZE9t6^X#P0h#{ys9MCKfMP=nGZ=ezWOoU>%K zjVv%`-qBo3`$<>{3XX1A2rGULDw>EyGVK^i9CJCy;bc{xo-EdT-i^qd;CGt+&nzF`4>x(o>P-X#AbBzzWXqJA^D99MM)B5yD_E!b zu}NHJj^#@v(}dn}ep2F?3EZ9~0t`mj-z9vY&C3l=)7bGJsl*6fdN zHaAK7Ri1}B<*;v~!?b!V%L_ANj+<0&K~wQ{Rl|*RdrQ}X)%u~GTMkb4zTE}S{X(1s z=VCaXv#U3%9%np72|juFOtmDf#CD(^GOgL4v+P@6gPu*i1Dh#${(FAYsmZeY@TK0L zC@q-MgGN`@oR(pfDV_`XaIvXZD^^cft#%pEJlD zk~wc?kJfq1d;X$kM%Rs2`@|wsXPx|s(@G*bUpunNeVDPNO2sR8jjovdkSFE93I=V> z8mYltns$9p>{^EU{tDo`HFpaK9k*%^{UH15Hbfa1-XQ49L_7v@as@@s)UaQ18zP zuG)-$QxvvbnJ+>x5@rBb@BaNI=l$6FXW#I1O(B_lYBG!9>5G8{mjjWN%jXOkUC-VWpU4E%%aFfJ8gy_q{H6LHNtuWU zD7N707>wQoA=pPnwY>Y0Ieq*_5=48+3AH`0jaYI>Cy=H50hx5ROLQIbEw?9%Qzj=J zw`F_z-qn1sD|okB+di(5DU%ckT6nif%QG6d`+=2yrBN~tJMi^znFS6+^WS53PB}_j z=1b%`hHz0bK&(W6)!e^TN^48JNW_+qGuVUexVvwS8RI>;c*=B zO&FVe6CeM2w)Z=aXpscEb-UvTG2DBez8OMdTFLR&n5$z(uak zvctNrF96ZRF4=&-f2(JsSQik)#^6H;K;t!|;^8SG+BU3yhndzVUyFIn+LJy9+Mh!o z-K>vB6{)p-hqQ8Un1rT9ay~P8TH`nd1mLuG!WF$aG_P+lk-niL=WXX zXukz$yl3^nmjTm4O_9b*Hck9b`f-{?O!; z1na*9@Pk^vUW0hX)fg=r@+0FOP_O_o>V$O&xBb~_>+3VE)c!G05HH`UHtisTcY=Y9tAD2tG{f8=@4vrMq{ zbkk#0^!vi5tz8U!bF*Mk* z1}&#dmRrvqAybTX>53(d`4qu-!opvWYR04xYND6^MZNz;Bo@eDvK<(&y+eZbrf(K4 z@7idi`I<_{z_&VU?UgEis_EI$Jw3~y#nz7k8N$NC4x}|$LMfok{w?SM{5V25nP;Y@1n=bSB_%I1d)T?6rh+K+W60$*FNmn7^Z1Ts>e5T*kE?cqOUr(2&8UWi>ho!vz4clw-GX?RA< zHFb!cx{tqm$m1V>MQzXIX~J($0ez=#fGIva8Utq7va5`h$tPc+{t^F;g$`PEr`tu_ zVTDea5GpDw(ltz2eU`NC8&Ht(Wr+h=ZTaNT$0I6_1{p(s;rHEHRz;}JKIc29Ar%v= zHFP$Tm=3B+0%CF?&^7wmEQC&qQYL)(%?tb10rl#YM)ljjAkFRs>z)4k-PFM|Um8;q zbI|yajX=6Rbgk~EtZr76PC`O$zpMHlSr+WKNAQ(hVwIcQV@2G>KmPb=<)AxE2R7cn zv^BeRy4Yr%s1lSvtTf+3>NvHEfgkRw*-7~jl&SYm(Dh(r|4V9^6={H47~*w|L2^%J zes^V3w~O1d3(Zz_)>?+Ss9Uhk+|$3aDdQR%HA8hR$_fkCv*GTUB@blwJsevUCcBL* z!r~L6%auj#b3nz}F)OdKGZ{d3iE|0P!-3p?s^>egzEKbUY!$Yhrf3t0)m^%}UarlK zoeqX4mcSdug;mjfB)Wp32@1fz59m)X>PFVuys~^_|j5AxV*db2Kf+&Ol2ub zFc_$0!VwBfBj9WGQS1&Y5L>=`nUu2BcyxTAV1BL+I<>ZXpXTpRNto#sO`Hp@?KZC8 z{fN{UoJGJpHxY2RXN76Sw!4kuB3a$3Te_WQ8kz@q+ZtWL2g(6EJ%$U5D=XZRI{TCq zj9*#U^!D3)TS&vj3d_NkHWyRfE_TwzX z5xnD{TSRPJlL-J1S|=_dGjE?w3)xo~b5`wtVh4SHYeZ%61o0MfAtUL$pHL838C^<0 zmy}SEV`TD4Z&W+49^d*GPS;-~%-a|>O#q3H zRIPa6@J*(})#K2Xf|%zh!Q;9(sb$)b7ve7x=8`bdHj<#)Bcp>i3d(ruTtrUA*$l_n z9I*vFj+9SN-i~r;J+tQPw}!x+GrLeg!4!y|8^wWqoz}Ci?TFaeHL~o_bDn~~A|~u> z?V|w;2z8AgLPEkCq!*EC11X;~%mTC8#Ct5A=YTx!!Fmw#ZpuZ#Vf=4O-0?X3_<$El zp=(9UwD>Cm3I+Q<(|`XqcXx}YYy0X)YKkZ;rrWeGo0izlj&ceUVkBFz=G19re_%XE z9~ez{USAm0JPMGn%tbsI!k;fy3ctG6n@4zk71NeAe%Ppg{#b=Ty&ne>^OAj1Lo^#7 zB62~JrmmzH5fKrt4)gmk7Jpcg3!gP_JJl~U{(Jkcl(F8hPrT4&&YTXA&lTQ-@HzaA z^!>G$wrf?3zAyZF8rEO;ikn|ge*Ea#rOfV&z)BK~k%(EkK~STCv)$ zAgxurzs;aessg$NIZ07Ij6ciCw_-47nKgn50ad8!ft44?Cbf?o_b)lW#0Z~oLM!CO zRErH17MvFwkJ%XgICOtYjq&jwR)au~xwTD_-X%50zc%m^nd6##*8CRmp%FS7j(nsR zGk0Ci>jz8ESr;O-kEPi2TMhqo8kg8+D3@y4-FfZmYB!VX+b5?UYz_M zh4hmWtFtUAA-AyP&>>P$nZA2mD&5O}h!avMmY+zbBXe}r`tMGS7N#C@k9ddDj#crR zNWs>rohC;_`7W(YxJI8vX37vYpR1eAdw|-1c^oL7r%49 ziz_y{z>}+o_D|+zV%)AUZUfB!w6nPMG17*gCF1hdh1yb2+W1fcD|e`AQPHG37;qc_C3v zrYW@I;Y0fzxu2FoR(Kz){P=(>3>67F%ub8{_N&04z@w)+1B8Gb!bJE+R*u>&z-P}^ znx&s`Cv%?KP?k3fVg?jN&r3Vjmh)CU!ZY$$0G6u*xyP3uRcE&EGH>X-2eYc z1a2W#AgG2@h5UZdp^Q=Nfs(H<{}pwy?HWg?wt1KFuV>ZdKK9VjI)jolB_im3U>Nah#FF){BIzD3BTjF=}Q+eh>)RgV>w3`0vo74#SL&@tG3Z5gFe3@CrevIE0cam%>U%#d? zk~m3z*~c^YiYjAAvQy4XS{VD%u%&PT{>ngjo7!K_X)9e<{t-l%aQw(DMdO28Tqyj! zR!CyC<)~dGD~3dF8F^DD#0IxACc*>dcIyCrVuw;Mejo$ia&ijwkpY$J)5=FKy#c9I zFInrpJb~FfKkoj1cCE|b9~uyy6=vX?t4PatE`K^66HDMeI2cZO5>xw2#s2t<$VW59 zZ=s#zC=>BF#&6>$(l%8ezZ0c0mz|@zpJ>;D66oVTL5~RrPCecuYx_=XL$wlPvJLl9 zV|3q|q8;o5v9Vot-JYx%l&{6IWp5&jK6+UmI47TA44w_77uwnozt9bmfmX$TL)2wL z7wTzEDs74txKOM=&w1?R_8SK0pmA4vg$MF2an4()E z?}Su!;-A>|b98z&bg;U19Y>QzCwvPF=h#nq5z=SsX|Bw`-l3p2q4vvne6ZzU-uVOT zLv{*LioQ?WHuY93U2%3TOE8re3d{_(2uCIj~LZ{(QaT_>*^!3M}*=H1hKCt@lSpMuxw9@gnfk;#g~jwc zil=j??N3+G{KuESCNQGD*NOYLwKI2_fh2jj_9t>Z;w?OGj7*ic?^pKiz+T54r-2Ox z`}FpXj;@{6RUem&lf5GLyH6i9g1VEs8NH_d zf*xqp*-xlS7OMSLp^U(u?0xYY$r7z62A4fZw4QZ2x0t-xLq@!^<{;So6eykgOF@{* zTM+%;ZN4~9Fibe#El>_L^wcur9Ha zjwQ|{Y{5rw4!!AE%oI==5dUW6^iWE7zV!_^$H#zz-zAQfA2s|zU zQ0#2AXFH&Cy4T>5UbfP7`&ZZ$f@zVA=lNO36>r+=Y?{r%n*4rq&j;bu_1sxs>Is6a z>)U;7+~JO7XHvRD2iLEGt(y%u`y(%|f=o!)XbUo-MVUfqC+?`GrY5&;NfD~Wy6NJH z?xZMA#t4uVY3I?HVqNd>sA841WeSdpR20^_0^aDqXMu_*-)tCY6Dg&9kXjFK^jg(e z1SSd_A-E}q;p3Stp=xS6oUbuirD6oA)Dze-sHOt3Z`j}9#e8|6d_s|c?S{bENf^Is zDg`EO7`QnU1**wt2#k%fr0e^#au8cO2&2eu5ZcWqN1qG$bL^!G^cB7NJ>^D!2!z7-=q!*?My7V8NUtu%~Ge-NMah$W}Lw)mV5 zlAy3Cvypu#Mn&24^QE}y+mV(Wkc;(bY^&dnFBzkluQQbSWA*drU&Op|oh0;``*))` ziTok-km`1NX%4_Kc7|^pZ?QfigeX><#@%SKj{zEh**L;G(Y&3Z@1M2zM&eFR0rlFq zu>@uCrkJkEQLX#Y#(hN=i{~JGc^b%m1APNV`V!h#cfBI$gbSgzSCM{ZAodt3goadE zto!S#)O*FWTNe2cH!zjcVIn!DM)Tx6n|Kt!+YSOSUq|RxTz2*x)z%I_xPcfg4S>0O zH~LLHW?@GVDleQdj=QSAx+6f=fCDD>_Ha}`nz!0AS9x^-P1Lv1taH0Cz{^#xI6*VT zp0PU!;LBIkTeNtWP21V=5@x+T+tC(>-m!cfGe#QuwXwc93>?sSM^7Tmam#Q0?mo&T zOG)#al)^1oBP{B6k9bgknb($C7`p=V-!YTJhH4U_PtGg+o{j|`~+rS3V{Lkj{ zQv1*WBiPPP)$$kH96Nk1to<{G_m?G%nX%JPawMd<22~x`iHkC6AYcgEaHcbJ=qmG6 z&pJF_b}ikxz~hb!jSsGY0#`v#UxC zitW5Q-w97-CQu>WMrVnb7Xz2Zb7gioBuY33M`7zbJFXze4BPg`I0+tvdW{5g`0JO^ zcYZ|}fr?HPNQuVe+kfZLnRs&ZxM1S6$38#C7PrWu9T)p;2~n9%O{Yx&D=j$2*ck5? z(2Fz{6uPSc&)WsYRfq-xYJKXovB_MPfjONO)Ps8UZO-T)gH0rlCR&BY*;j^>!sNpb}@^+TPw?9ECq{PEUcV zdeYR}dZV{vw~i3yzl-ExJ|)&0KA*TTKT9UO7|uJWy<+n2faY3nF~-9_5gO1@ zVEl^i{LkoFAmBzRBSE2@^OG3k&!e)w4M8Cx;fzwGk@i!7OIh-X9oK;~=HHAi4%FRO z!%^Lxj1=#tmrgWxI1`-dPkW;>ExfFI)DMuDK@8?A6V1s{{Q}s>m&C|ssQ#+RfUxuSCayR zP2@C|FW>3in;?d}mH9-6@V`69n$!;1!qrz{8B3;s-&n&LEl@lal~)9}nw2%gWmP53 zn%6u01v}8=5AouqU2~=~XWW7mV$5z>-%`(VF*gRb*O>~BGar zoqD8F49{zBFi|Q1ut8C^R&-3Mp=K?)S|JF(B}S`fU(NBK+fy&%Q4e7O z%%HN5Uq#1Gh<NhtNXw7KiX5#%j z{6~0?^v3P0c;Mc2cr!G?4ZBMM5aQoBetaQ%3#*&feVi&WKs}D{qR%-8v2XuzV))0z zo9rKuX$^MzWuu0?RCln-U{tU(3?6q4s!a+#09 iIT-U*snvepPjkHux6q>c2K*ZaM_c`oTD2-H^8WzH%xwt( diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuit.html b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuit.html deleted file mode 100644 index e9328ab8f..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuit.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - - -
- <% if(propertyValue_circuitBreakerForceClosed) { %> - [ Forced Closed ] - <% } %> - <% if(propertyValue_circuitBreakerForceOpen) { %> - Circuit Forced Open - <% } else { %> - <% if(isCircuitBreakerOpen == reportingHosts) { %> - Circuit Open - <% } else if(isCircuitBreakerOpen == 0) { %> - Circuit Closed - <% } else { - /* We have some circuits that are open */ - %> - Circuit <%= isCircuitBreakerOpen.toString().replace("true", "Open").replace("false", "Closed") %>) - <% } %> - <% } %> -
- -
- -
- <% if(typeof reportingHosts != 'undefined') { %> -
Hosts
-
<%= reportingHosts %>
- <% } else { %> -
Host
-
Single
- <% } %> -
90th
-
<%= getInstanceAverage(latencyExecute['90'], reportingHosts, false) %>ms
-
-
-
Median
-
<%= getInstanceAverage(latencyExecute['50'], reportingHosts, false) %>ms
-
99th
-
<%= getInstanceAverage(latencyExecute['99'], reportingHosts, false) %>ms
-
-
-
Mean
-
<%= latencyExecute_mean %>ms
-
99.5th
-
<%= getInstanceAverage(latencyExecute['99.5'], reportingHosts, false) %>ms
-
- - diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuitContainer.html b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuitContainer.html deleted file mode 100644 index 1a47ef7b7..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuitContainer.html +++ /dev/null @@ -1,40 +0,0 @@ -
- <% - var displayName = name; - var toolTip = ""; - if(displayName.length > 32) { - displayName = displayName.substring(0,4) + "..." + displayName.substring(displayName.length-20, displayName.length); - toolTip = "title=\"" + name + "\""; - } - %> - -
-
- <% if(includeDetailIcon) { %> -

style="padding-right:16px"> - <%= displayName %> - -

- <% } else { %> -

><%= displayName %>

- <% } %> -
-
-
-
-
- - -
diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuitProperties.html b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuitProperties.html deleted file mode 100644 index 5b8c0fae8..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuitProperties.html +++ /dev/null @@ -1,6 +0,0 @@ -
-
Median
-
<%= sla_medianLastMinute %>ms
-
99th
-
<%= sla_percentile99LastMinute %>ms
-
diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/hystrixThreadPool.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/hystrixThreadPool.css deleted file mode 100644 index e82ea5cc1..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/hystrixThreadPool.css +++ /dev/null @@ -1,141 +0,0 @@ -.dependencyThreadPools .spacer { - width: 100%; - margin: 0 auto; - padding-top:4px; - clear:both; -} - - -.dependencyThreadPools .last { - margin-right: 0px; -} - -.dependencyThreadPools span.loading { - display: block; - padding-top: 6%; - padding-bottom: 6%; - color: gray; - text-align: center; -} - -.dependencyThreadPools span.loading.failed { - color: red; -} - - -.dependencyThreadPools div.monitor { - float: left; - margin-right:5px; /* these are tweaked to look good on desktop and iPad portrait, and fit things densely */ - margin-top:5px; -} - -.dependencyThreadPools div.monitor p.name { - font-weight:bold; - font-size: 10pt; - text-align: right; - padding-bottom: 5px; -} - -.dependencyThreadPools div.monitor_data { - margin: 0 auto; -} - -.dependencyThreadPools span.smaller { - font-size: 8pt; - color: grey; -} - - -.dependencyThreadPools div.tableRow { - width:100%; - white-space: nowrap; - font-size: 8pt; - margin: 0 auto; - clear:both; -} - -.dependencyThreadPools div.tableRow .cell { - float:left; -} - -.dependencyThreadPools div.tableRow .header { - text-align:right; - padding-right:5px; -} - -.dependencyThreadPools div.tableRow .header.left { - width:85px; -} - -.dependencyThreadPools div.tableRow .header.right { - width:75px; -} - -.dependencyThreadPools div.tableRow .data { - font-weight: bold; - text-align:right; -} - -.dependencyThreadPools div.tableRow .data.left { - width:30px; -} - -.dependencyThreadPools div.tableRow .data.right { - width:45px; -} - -.dependencyThreadPools div.monitor { - width: 245px; /* we want a fixed width instead of percentage as I want the boxes to be a set size and then fill in as many as can fit in each row ... this allows 3 columns on an iPad */ - height: 110px; -} - - - - - -/* override the HREF when we have specified it as a tooltip to not act like a link */ -.dependencyThreadPools div.monitor_data a.tooltip { - text-decoration: none; - cursor: default; -} - -.dependencyThreadPools div.monitor_data a.rate { - font-weight:bold; - color: black; - font-size: 11pt; -} - -.dependencyThreadPools div.rate { - padding-top: 1px; - clear:both; - text-align:right; -} - -.dependencyThreadPools span.rate_value { - font-weight:bold; -} - - - - - - - -.dependencyThreadPools div.monitor div.chart { -} - -.dependencyThreadPools div.monitor div.chart svg { -} - -.dependencyThreadPools div.monitor div.chart svg text { - fill: white; -} - -.dependencyThreadPools #hidden { - width:1px; - height:1px; - background: lightgrey; - display: none; -} - - diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/hystrixThreadPool.js b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/hystrixThreadPool.js deleted file mode 100644 index 851562bf8..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/hystrixThreadPool.js +++ /dev/null @@ -1,343 +0,0 @@ - -(function(window) { - - // cache the templates we use on this page as global variables (asynchronously) - jQuery.get(getRelativePath("components/hystrixThreadPool/templates/hystrixThreadPool.html"), function(data) { - htmlTemplate = data; - }); - jQuery.get(getRelativePath("components/hystrixThreadPool/templates/hystrixThreadPoolContainer.html"), function(data) { - htmlTemplateContainer = data; - }); - - function getRelativePath(path) { - var p = location.pathname.slice(0, location.pathname.lastIndexOf("/")+1); - return p + path; - } - - /** - * Object containing functions for displaying and updating the UI with streaming data. - * - * Publish this externally as "HystrixThreadPoolMonitor" - */ - window.HystrixThreadPoolMonitor = function(containerId) { - - var self = this; // keep scope under control - - this.containerId = containerId; - - /** - * Initialization on construction - */ - // intialize various variables we use for visualization - var maxXaxisForCircle="40%"; - var maxYaxisForCircle="40%"; - var maxRadiusForCircle="125"; - var maxDomain = 2000; - - self.circleRadius = d3.scale.pow().exponent(0.5).domain([0, maxDomain]).range(["5", maxRadiusForCircle]); // requests per second per host - self.circleYaxis = d3.scale.linear().domain([0, maxDomain]).range(["30%", maxXaxisForCircle]); - self.circleXaxis = d3.scale.linear().domain([0, maxDomain]).range(["30%", maxYaxisForCircle]); - self.colorRange = d3.scale.linear().domain([10, 25, 40, 50]).range(["green", "#FFCC00", "#FF9900", "red"]); - self.errorPercentageColorRange = d3.scale.linear().domain([0, 10, 35, 50]).range(["grey", "black", "#FF9900", "red"]); - - /** - * We want to keep sorting in the background since data values are always changing, so this will re-sort every X milliseconds - * to maintain whatever sort the user (or default) has chosen. - * - * In other words, sorting only for adds/deletes is not sufficient as all but alphabetical sort are dynamically changing. - */ - setInterval(function() { - // sort since we have added a new one - self.sortSameAsLast(); - }, 1000) - - /** - * END of Initialization on construction - */ - - /** - * Event listener to handle new messages from EventSource as streamed from the server. - */ - /* public */ self.eventSourceMessageListener = function(e) { - var data = JSON.parse(e.data); - if(data) { - // check for reportingHosts (if not there, set it to 1 for singleHost vs cluster) - if(!data.reportingHosts) { - data.reportingHosts = 1; - } - - if(data && data.type == 'HystrixThreadPool') { - if (data.deleteData == 'true') { - deleteThreadPool(data.escapedName); - } else { - displayThreadPool(data); - } - } - } - } - - /** - * Pre process the data before displying in the UI. - * e.g Get Averages from sums, do rate calculation etc. - */ - function preProcessData(data) { - validateData(data); - // escape string used in jQuery & d3 selectors - data.escapedName = data.name.replace(/([ !"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g,'\\$1'); - // do math - converAllAvg(data); - calcRatePerSecond(data); - } - - function converAllAvg(data) { - convertAvg(data, "propertyValue_queueSizeRejectionThreshold", false); - } - - function convertAvg(data, key, decimal) { - if (decimal) { - data[key] = roundNumber(data[key]/data["reportingHosts"]); - } else { - data[key] = Math.floor(data[key]/data["reportingHosts"]); - } - } - - function calcRatePerSecond(data) { - var numberSeconds = data["propertyValue_metricsRollingStatisticalWindowInMilliseconds"] / 1000; - - var totalThreadsExecuted = data["rollingCountThreadsExecuted"]; - if (totalThreadsExecuted < 0) { - totalThreadsExecuted = 0; - } - data["ratePerSecond"] = roundNumber(totalThreadsExecuted / numberSeconds); - data["ratePerSecondPerHost"] = roundNumber(totalThreadsExecuted / numberSeconds / data["reportingHosts"]); - } - - function validateData(data) { - - assertNotNull(data,"type"); - assertNotNull(data,"name"); - // assertNotNull(data,"currentTime"); - assertNotNull(data,"currentActiveCount"); - assertNotNull(data,"currentCompletedTaskCount"); - assertNotNull(data,"currentCorePoolSize"); - assertNotNull(data,"currentLargestPoolSize"); - assertNotNull(data,"currentMaximumPoolSize"); - assertNotNull(data,"currentPoolSize"); - assertNotNull(data,"currentQueueSize"); - assertNotNull(data,"currentTaskCount"); - assertNotNull(data,"rollingCountThreadsExecuted"); - assertNotNull(data,"rollingMaxActiveThreads"); - assertNotNull(data,"reportingHosts"); - - assertNotNull(data,"propertyValue_queueSizeRejectionThreshold"); - assertNotNull(data,"propertyValue_metricsRollingStatisticalWindowInMilliseconds"); - } - - function assertNotNull(data, key) { - if(data[key] == undefined) { - if (key == "dependencyOwner") { - data["dependencyOwner"] = data.name; - } else { - throw new Error("Key Missing: " + key + " for " + data.name) - } - } - } - - /** - * Method to display the THREAD_POOL data - * - * @param data - */ - /* private */ function displayThreadPool(data) { - - try { - preProcessData(data); - } catch (err) { - log("Failed preProcessData: " + err.message); - return; - } - - // add the 'addCommas' function to the 'data' object so the HTML templates can use it - data.addCommas = addCommas; - // add the 'roundNumber' function to the 'data' object so the HTML templates can use it - data.roundNumber = roundNumber; - - var addNew = false; - // check if we need to create the container - if(!$('#THREAD_POOL_' + data.escapedName).length) { - // it doesn't exist so add it - var html = tmpl(htmlTemplateContainer, data); - // remove the loading thing first - $('#' + containerId + ' span.loading').remove(); - // get the current last column and remove the 'last' class from it - $('#' + containerId + ' div.last').removeClass('last'); - // now create the new data and add it - $('#' + containerId + '').append(html); - // add the 'last' class to the column we just added - $('#' + containerId + ' div.monitor').last().addClass('last'); - - // add the default sparkline graph - d3.selectAll('#graph_THREAD_POOL_' + data.escapedName + ' svg').append("svg:path"); - - // remember this is new so we can trigger a sort after setting data - addNew = true; - } - - // set the rate on the div element so it's available for sorting - $('#THREAD_POOL_' + data.escapedName).attr('rate_value', data.ratePerSecondPerHost); - - // now update/insert the data - $('#THREAD_POOL_' + data.escapedName + ' div.monitor_data').html(tmpl(htmlTemplate, data)); - - // set variables for circle visualization - var rate = data.ratePerSecondPerHost; - // we will treat each item in queue as 1% of an error visualization - // ie. 5 threads in queue per instance == 5% error percentage - var errorPercentage = data.currentQueueSize / data.reportingHosts; - - updateCircle('#THREAD_POOL_' + data.escapedName + ' circle', rate, errorPercentage); - - if(addNew) { - // sort since we added a new circuit - self.sortSameAsLast(); - } - } - - /* round a number to X digits: num => the number to round, dec => the number of decimals */ - /* private */ function roundNumber(num) { - var dec=1; // we are hardcoding to support only 1 decimal so that our padding logic at the end is simple - var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec); - var resultAsString = result.toString(); - if(resultAsString.indexOf('.') == -1) { - resultAsString = resultAsString + '.'; - for(var i=0; i parseInt(maxXaxisForCircle)) { - newXaxisForCircle = maxXaxisForCircle; - } - var newYaxisForCircle = self.circleYaxis(rate); - if(parseInt(newYaxisForCircle) > parseInt(maxYaxisForCircle)) { - newYaxisForCircle = maxYaxisForCircle; - } - var newRadiusForCircle = self.circleRadius(rate); - if(parseInt(newRadiusForCircle) > parseInt(maxRadiusForCircle)) { - newRadiusForCircle = maxRadiusForCircle; - } - - d3.selectAll(cssTarget) - .transition() - .duration(400) - .attr("cy", newYaxisForCircle) - .attr("cx", newXaxisForCircle) - .attr("r", newRadiusForCircle) - .style("fill", self.colorRange(errorPercentage)); - } - - /* private */ function deleteThreadPool(poolName) { - $('#THREAD_POOL_' + poolName).remove(); - } - - } - - // public methods for sorting - HystrixThreadPoolMonitor.prototype.sortByVolume = function() { - var direction = "desc"; - if(this.sortedBy == 'rate_desc') { - direction = 'asc'; - } - this.sortByVolumeInDirection(direction); - } - - HystrixThreadPoolMonitor.prototype.sortByVolumeInDirection = function(direction) { - this.sortedBy = 'rate_' + direction; - $('#' + this.containerId + ' div.monitor').tsort({order: direction, attr: 'rate_value'}); - } - - HystrixThreadPoolMonitor.prototype.sortAlphabetically = function() { - var direction = "asc"; - if(this.sortedBy == 'alph_asc') { - direction = 'desc'; - } - this.sortAlphabeticalInDirection(direction); - } - - HystrixThreadPoolMonitor.prototype.sortAlphabeticalInDirection = function(direction) { - this.sortedBy = 'alph_' + direction; - $('#' + this.containerId + ' div.monitor').tsort("p.name", {order: direction}); - } - - HystrixThreadPoolMonitor.prototype.sortByMetricInDirection = function(direction, metric) { - $('#' + this.containerId + ' div.monitor').tsort(metric, {order: direction}); - } - - // this method is for when new divs are added to cause the elements to be sorted to whatever the user last chose - HystrixThreadPoolMonitor.prototype.sortSameAsLast = function() { - if(this.sortedBy == 'alph_asc') { - this.sortAlphabeticalInDirection('asc'); - } else if(this.sortedBy == 'alph_desc') { - this.sortAlphabeticalInDirection('desc'); - } else if(this.sortedBy == 'rate_asc') { - this.sortByVolumeInDirection('asc'); - } else if(this.sortedBy == 'rate_desc') { - this.sortByVolumeInDirection('desc'); - } else if(this.sortedBy == 'error_asc') { - this.sortByErrorInDirection('asc'); - } else if(this.sortedBy == 'error_desc') { - this.sortByErrorInDirection('desc'); - } else if(this.sortedBy == 'lat90_asc') { - this.sortByMetricInDirection('asc', 'p90'); - } else if(this.sortedBy == 'lat90_desc') { - this.sortByMetricInDirection('desc', 'p90'); - } else if(this.sortedBy == 'lat99_asc') { - this.sortByMetricInDirection('asc', 'p99'); - } else if(this.sortedBy == 'lat99_desc') { - this.sortByMetricInDirection('desc', 'p99'); - } else if(this.sortedBy == 'lat995_asc') { - this.sortByMetricInDirection('asc', 'p995'); - } else if(this.sortedBy == 'lat995_desc') { - this.sortByMetricInDirection('desc', 'p995'); - } else if(this.sortedBy == 'latMean_asc') { - this.sortByMetricInDirection('asc', 'pMean'); - } else if(this.sortedBy == 'latMean_desc') { - this.sortByMetricInDirection('desc', 'pMean'); - } else if(this.sortedBy == 'latMedian_asc') { - this.sortByMetricInDirection('asc', 'pMedian'); - } else if(this.sortedBy == 'latMedian_desc') { - this.sortByMetricInDirection('desc', 'pMedian'); - } - } - - // default sort type and direction - this.sortedBy = 'alph_asc'; - - - // a temporary home for the logger until we become more sophisticated - function log(message) { - console.log(message); - }; - - function addCommas(nStr){ - nStr += ''; - if(nStr.length <=3) { - return nStr; //shortcut if we don't need commas - } - x = nStr.split('.'); - x1 = x[0]; - x2 = x.length > 1 ? '.' + x[1] : ''; - var rgx = /(\d+)(\d{3})/; - while (rgx.test(x1)) { - x1 = x1.replace(rgx, '$1' + ',' + '$2'); - } - return x1 + x2; - } -})(window) - - diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/templates/hystrixThreadPool.html b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/templates/hystrixThreadPool.html deleted file mode 100644 index 1e653ccbf..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/templates/hystrixThreadPool.html +++ /dev/null @@ -1,33 +0,0 @@ - -
- - - - -
- -
-
Active
-
<%= currentActiveCount%>
- -
Max Active
-
<%= addCommas(rollingMaxActiveThreads)%>
-
- -
-
Queued
-
<%= currentQueueSize %>
-
Executions
-
<%= addCommas(rollingCountThreadsExecuted)%>
-
-
-
Pool Size
-
<%= currentPoolSize %>
-
Queue Size
-
<%= propertyValue_queueSizeRejectionThreshold %>
-
- \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/templates/hystrixThreadPoolContainer.html b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/templates/hystrixThreadPoolContainer.html deleted file mode 100644 index 035ae845e..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/templates/hystrixThreadPoolContainer.html +++ /dev/null @@ -1,34 +0,0 @@ -
- - <% - var displayName = name; - var toolTip = ""; - if(displayName.length > 32) { - displayName = displayName.substring(0,4) + "..." + displayName.substring(displayName.length-20, displayName.length); - toolTip = "title=\"" + name + "\""; - } - %> - -
-

><%= displayName %>

-
-
-
- - - - -
diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/global.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/global.css deleted file mode 100644 index 74e80d171..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/global.css +++ /dev/null @@ -1,71 +0,0 @@ -@IMPORT url("resets.css"); - -body { - font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; -} - -img, object, embed { - max-width: 100%; -} - -img { - height: auto; -} - - -#header { - background: #FFFFFF url(../images/hystrix-logo-tagline-tiny.png) no-repeat scroll 99% 0%; - height: 65px; - margin-bottom: 5px; -} - -#header h2 { - float:left; - color: black; - position:relative; - padding-left: 20px; - top: 26px; - font-size: 20px; - font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; -} - -#header .header_nav { - position:absolute; - top:48px; - right:15px; -} - -#header .header_links { - float:left; - color: lightgray; - font-size: 18px; - top: 3px; - padding-left: 10px; - font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; -} - -#header .header_links a { - color: white; -} - -#header .header_clusters { - float:left; - position:relative; - padding-left: 10px; - top: -1px; - font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; -} - - -@media screen and (min-width: 1500px) { - - #header .header_nav { - top:13px; - right:130px; - } - - #header { - background: #FFFFFF url(../images/hystrix-logo-tagline-tiny.png) no-repeat scroll 99% 50%; - height: 65px; - } -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/monitor.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/monitor.css deleted file mode 100644 index 04b929c22..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/monitor.css +++ /dev/null @@ -1,105 +0,0 @@ -.container { - padding-left: 20px; - padding-right: 20px; -} - -.row { - width: 100%; - margin: 0 auto; - overflow: hidden; -} - -.spacer { - width: 100%; - margin: 0 auto; - padding-top:4px; - clear:both; -} - - -.last { - margin-right: 0px; -} - -.menubar { - overflow: hidden; - border-bottom: 1px solid black; -} - -.menubar div { - padding-bottom:5px; - - margin: 0 auto; - overflow: hidden; - - font-size: 80%; - font-family:'Bookman Old Style',Bookman,'URW Bookman L','Palatino Linotype',serif; - - float:left; -} - -.menubar .title { - float: left; - padding-right: 20px; - - font-size: 110%; - font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; - font-weight: bold; - - vertical-align: bottom; -} - -.menubar .menu_actions { - float: left; - position:relative; - top: 4px; -} - -.menubar .menu_legend { - float: right; - position:relative; - top: 4px; - -} - -h3.sectionHeader { - color: black; - font-size: 110%; - padding-top: 4px; - padding-bottom: 4px; - padding-left: 8px; - font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; - background: lightgrey; -} - -.success { - color: green; -} -.shortCircuited { - color: blue; -} -.timeout { - color: #FF9900; /* shade of orange */ -} -.failure { - color: red; -} - -.rejected { - color: purple; -} - -.exceptionsThrown { - color: brown; -} - -.badRequest { - color: #00CC99; -} - -@media screen and (max-width: 1100px) { - .container { - padding-left: 5px; - padding-right: 5px; - } -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/resets.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/resets.css deleted file mode 100644 index 4d137c7e3..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/resets.css +++ /dev/null @@ -1,102 +0,0 @@ -/* -html5doctor.com Reset Stylesheet -v1.6.1 -Last Updated: 2010-09-17 -Author: Richard Clark - http://richclarkdesign.com -Twitter: @rich_clark -*/ - -html, body, div, span, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -abbr, address, cite, code, -del, dfn, em, img, ins, kbd, q, samp, -small, strong, sub, sup, var, -b, i, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, figcaption, figure, -footer, header, hgroup, menu, nav, section, summary, -time, mark, audio, video { - margin:0; - padding:0; - border:0; - outline:0; - font-size:100%; - vertical-align:baseline; - background:transparent; -} - -body { - line-height:1; -} - -article,aside,details,figcaption,figure, -footer,header,hgroup,menu,nav,section { - display:block; -} - -nav ul { - list-style:none; -} - -blockquote, q { - quotes:none; -} - -blockquote:before, blockquote:after, -q:before, q:after { - content:''; - content:none; -} - -a { - margin:0; - padding:0; - font-size:100%; - vertical-align:baseline; - background:transparent; -} - -/* change colours to suit your needs */ -ins { - background-color:#ff9; - color:#000; - text-decoration:none; -} - -/* change colours to suit your needs */ -mark { - background-color:#ff9; - color:#000; - font-style:italic; - font-weight:bold; -} - -del { - text-decoration: line-through; -} - -abbr[title], dfn[title] { - border-bottom:1px dotted; - cursor:help; -} - -table { - border-collapse:collapse; - border-spacing:0; -} - -/* change border colour to suit your needs */ -hr { - display:block; - height:1px; - border:0; - border-top:1px solid #cccccc; - margin:1em 0; - padding:0; -} - -input, select { - vertical-align:middle; -} \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/1236_grid.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/1236_grid.css deleted file mode 100644 index ca5653416..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/1236_grid.css +++ /dev/null @@ -1,21 +0,0 @@ -/* SimpleGrid - a fork of CSSGrid by Crowd Favorite (https://github.com/crowdfavorite/css-grid) - * https://simplegrid.info - * by Conor Muirhead (http://conor.cc) of Early LLC (https://earlymade.com) - * License: https://creativecommons.org/licenses/MIT/ */ - -/* Containers */ -body { font-size: 1.125em; } -.grid{ width:1206px; } - -/* 6-Col Grid Sizes */ -.slot-0,.slot-1,.slot-2,.slot-3,.slot-4,.slot-5{ width:176px; } /* Sixths */ -.slot-0-1,.slot-1-2,.slot-2-3,.slot-3-4,.slot-4-5{ width:382px; } /* Thirds */ -.slot-0-1-2-3,.slot-1-2-3-4,.slot-2-3-4-5{ width:794px; } /* Two-Thirds */ -.slot-0-1-2-3-4,.slot-1-2-3-4-5{ width:1000px; } /* Five-Sixths */ - -/* 4-Col Grid Sizes */ -.slot-6,.slot-7,.slot-8,.slot-9{ width:279px; } /* Quarters */ -.slot-6-7-8,.slot-7-8-9{ width:897px; } /* Three-Quarters */ - -/* 6-Col/4-Col Shared Grid Sizes */ -.slot-0-1-2,.slot-1-2-3,.slot-2-3-4,.slot-3-4-5, .slot-6-7,.slot-7-8,.slot-8-9{ width:588px; } /* Halves */ \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/720_grid.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/720_grid.css deleted file mode 100644 index c694dc27d..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/720_grid.css +++ /dev/null @@ -1,33 +0,0 @@ -/* SimpleGrid - a fork of CSSGrid by Crowd Favorite (https://github.com/crowdfavorite/css-grid) - * https://simplegrid.info - * by Conor Muirhead (http://conor.cc) of Early LLC (https://earlymade.com) - * License: https://creativecommons.org/licenses/MIT/ */ - -/* Containers */ -body { font-size: 0.875em; padding: 0; } -.grid{ margin:0 auto; padding: 0 10px; width:700px; } -.row{ clear:left; } - -/* Slots Setup */ -.slot-0,.slot-1,.slot-2,.slot-3,.slot-4,.slot-5,.slot-0-1,.slot-0-1-2,.slot-0-1-2-3,.slot-0-1-2-3-4,.slot-0-1-2-3-4-5,.slot-1-2,.slot-1-2-3,.slot-1-2-3-4,.slot-1-2-3-4-5,.slot-2-3,.slot-2-3-4,.slot-2-3-4-5,.slot-3-4,.slot-3-4-5,.slot-4-5,.slot-6,.slot-7,.slot-8,.slot-9,.slot-6-7,.slot-6-7-8,.slot-6-7-8-9,.slot-7-8,.slot-7-8-9,.slot-8-9{ display:inline; float:left; margin-left:20px; } - -/* 6-Col Grid Sizes */ -.slot-0,.slot-1,.slot-2,.slot-3,.slot-4,.slot-5{ width:100px; } /* Sixths */ -.slot-0-1,.slot-1-2,.slot-2-3,.slot-3-4,.slot-4-5{ width:220px; } /* Thirds */ -.slot-0-1-2-3,.slot-1-2-3-4,.slot-2-3-4-5{ width:460px; } /* Two-Thirds */ -.slot-0-1-2-3-4,.slot-1-2-3-4-5{ width:580px; } /* Five-Sixths */ - -/* 4-Col Grid Sizes */ -.slot-6,.slot-7,.slot-8,.slot-9{ width:160px; } /* Quarters */ -.slot-6-7-8,.slot-7-8-9{ width:520px; } /* Three-Quarters */ - -/* 6-Col/4-Col Shared Grid Sizes */ -.slot-0-1-2,.slot-1-2-3,.slot-2-3-4,.slot-3-4-5, .slot-6-7,.slot-7-8,.slot-8-9{ width:340px; } /* Halves */ -.slot-0-1-2-3-4-5, .slot-6-7-8-9{ width: 100%; } /* Full-Width */ - -/* Zeroing Out Leftmost Slot Margins */ -.slot-0,.slot-0-1,.slot-0-1-2,.slot-0-1-2-3,.slot-0-1-2-3-4,.slot-0-1-2-3-4-5,.slot-6,.slot-6-7,.slot-6-7-8,.slot-6-7-8-9,.slot-1 .slot-1,.slot-1-2 .slot-1,.slot-1-2 .slot-1-2,.slot-1-2-3 .slot-1,.slot-1-2-3 .slot-1-2,.slot-1-2-3 .slot-1-2-3,.slot-1-2-3-4 .slot-1,.slot-1-2-3-4 .slot-1-2,.slot-1-2-3-4 .slot-1-2-3,.slot-1-2-3-4 .slot-1-2-3-4,.slot-1-2-3-4-5 .slot-1,.slot-1-2-3-4-5 .slot-1-2,.slot-1-2-3-4-5 .slot-1-2-3,.slot-1-2-3-4-5 .slot-1-2-3-4,.slot-1-2-3-4-5 .slot-1-2-3-4-5,.slot-2 .slot-2,.slot-2-3 .slot-2,.slot-2-3 .slot-2-3,.slot-2-3-4 .slot-2,.slot-2-3-4 .slot-2-3,.slot-2-3-4 .slot-2-3-4,.slot-2-3-4-5 .slot-2,.slot-2-3-4-5 .slot-2-3,.slot-2-3-4-5 .slot-2-3-4,.slot-2-3-4-5 .slot-2-3-4-5,.slot-3 .slot-3,.slot-3-4 .slot-3,.slot-3-4 .slot-3-4,.slot-3-4-5 .slot-3,.slot-3-4-5 .slot-3-4,.slot-3-4-5 .slot-3-4-5,.slot-4 .slot-4,.slot-4-5 .slot-4,.slot-4-5 .slot-4-5,.slot-5 .slot-5,.slot-7 .slot-7,.slot-7-8 .slot-7,.slot-7-8 .slot-7-8,.slot-7-8-9 .slot-7,.slot-7-8-9 .slot-7-8,.slot-7-8-9 .slot-7-8-9,.slot-8 .slot-8,.slot-8-9 .slot-8,.slot-8-9 .slot-8-9{ margin-left:0 !important; } /* Important is to avoid repeating this in larger screen css files */ - -/* Row Clearfix */ -.row:after{ visibility:hidden; display:block; font-size:0; content:" "; clear:both; height:0; } -.row{ zoom:1; } \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/986_grid.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/986_grid.css deleted file mode 100644 index 0496041f7..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/986_grid.css +++ /dev/null @@ -1,24 +0,0 @@ -/* SimpleGrid - a fork of CSSGrid by Crowd Favorite (https://github.com/crowdfavorite/css-grid) - * https://simplegrid.info - * by Conor Muirhead (http://conor.cc) of Early LLC (https://earlymade.com) - * License: https://creativecommons.org/licenses/MIT/ */ - -/* Containers */ -body { font-size: 100%; } -.grid{ width:966px; } - -/* Slots Setup */ -.slot-0,.slot-1,.slot-2,.slot-3,.slot-4,.slot-5,.slot-0-1,.slot-0-1-2,.slot-0-1-2-3,.slot-0-1-2-3-4,.slot-0-1-2-3-4-5,.slot-1-2,.slot-1-2-3,.slot-1-2-3-4,.slot-1-2-3-4-5,.slot-2-3,.slot-2-3-4,.slot-2-3-4-5,.slot-3-4,.slot-3-4-5,.slot-4-5,.slot-6,.slot-7,.slot-8,.slot-9,.slot-6-7,.slot-6-7-8,.slot-6-7-8-9,.slot-7-8,.slot-7-8-9,.slot-8-9{ display:inline; float:left; margin-left:30px; } - -/* 6-Col Grid Sizes */ -.slot-0,.slot-1,.slot-2,.slot-3,.slot-4,.slot-5{ width:136px; } /* Sixths */ -.slot-0-1,.slot-1-2,.slot-2-3,.slot-3-4,.slot-4-5{ width:302px; } /* Thirds */ -.slot-0-1-2-3,.slot-1-2-3-4,.slot-2-3-4-5{ width:634px; } /* Two-Thirds */ -.slot-0-1-2-3-4,.slot-1-2-3-4-5{ width:800px; } /* Five-Sixths */ - -/* 4-Col Grid Sizes */ -.slot-6,.slot-7,.slot-8,.slot-9{ width:219px; } /* Quarters */ -.slot-6-7-8,.slot-7-8-9{ width:717px; } /* Three-Quarters */ - -/* 6-Col/4-Col Shared Grid Sizes */ -.slot-0-1-2,.slot-1-2-3,.slot-2-3-4,.slot-3-4-5, .slot-6-7,.slot-7-8,.slot-8-9{ width:468px; } /* Halves */ \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/LICENSE.txt b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/LICENSE.txt deleted file mode 100644 index e942914a7..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2011 Crowd Favorite, Ltd. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/README.txt b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/README.txt deleted file mode 100644 index 772768319..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/README.txt +++ /dev/null @@ -1 +0,0 @@ -https://simplegrid.info/ \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/percentage_grid.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/percentage_grid.css deleted file mode 100644 index 1254f636d..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/percentage_grid.css +++ /dev/null @@ -1,27 +0,0 @@ -/* Extension of SimpleGrid by benjchristensen to allow percentage based sizing on very large displays - * - * SimpleGrid - a fork of CSSGrid by Crowd Favorite (https://github.com/crowdfavorite/css-grid) - * https://simplegrid.info - * by Conor Muirhead (http://conor.cc) of Early LLC (https://earlymade.com) - * License: https://creativecommons.org/licenses/MIT/ */ - -/* Containers */ -body { font-size: 1.125em; } -.grid{ width:100%; } - -/* Slots Setup */ -.slot-0,.slot-1,.slot-2,.slot-3,.slot-4,.slot-5,.slot-0-1,.slot-0-1-2,.slot-0-1-2-3,.slot-0-1-2-3-4,.slot-0-1-2-3-4-5,.slot-1-2,.slot-1-2-3,.slot-1-2-3-4,.slot-1-2-3-4-5,.slot-2-3,.slot-2-3-4,.slot-2-3-4-5,.slot-3-4,.slot-3-4-5,.slot-4-5,.slot-6,.slot-7,.slot-8,.slot-9,.slot-6-7,.slot-6-7-8,.slot-6-7-8-9,.slot-7-8,.slot-7-8-9,.slot-8-9{ display:inline; float:left; margin-left:0px; } - - -/* 6-Col Grid Sizes */ -.slot-0,.slot-1,.slot-2,.slot-3,.slot-4,.slot-5{ width:16.6%; } /* Sixths */ -.slot-0-1,.slot-1-2,.slot-2-3,.slot-3-4,.slot-4-5{ width:33.3%; } /* Thirds */ -.slot-0-1-2-3,.slot-1-2-3-4,.slot-2-3-4-5{ width:66.6%; } /* Two-Thirds */ -.slot-0-1-2-3-4,.slot-1-2-3-4-5{ width:83.3%; } /* Five-Sixths */ - -/* 4-Col Grid Sizes */ -.slot-6,.slot-7,.slot-8,.slot-9{ width:25%; } /* Quarters */ -.slot-6-7-8,.slot-7-8-9{ width:75%; } /* Three-Quarters */ - -/* 6-Col/4-Col Shared Grid Sizes */ -.slot-0-1-2,.slot-1-2-3,.slot-2-3-4,.slot-3-4-5, .slot-6-7,.slot-7-8,.slot-8-9{ width:50%; } /* Halves */ \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/images/hystrix-logo-tagline-tiny.png b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/images/hystrix-logo-tagline-tiny.png deleted file mode 100644 index 8919c2925c76589b9f8fb1a802803f9d4597f1e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13315 zcmZ|01yq|s*Di_#2p${?h2Tz*;_lMoUR(T zf!%GaZJqes1u6c6;Cn0otA=1T#<~IbhlZUOdkvp@k6XpLX z`G53Cm^qm^TG~5X+S!8t=`}L8b8!}=p!nC&|9<^XKbi$nV|ASYuuyeM1vx1|giL9-&nd6(V zv(dla39iMUP)giC^pQm+J?Xge{_kt|51hKX&7ouQIh8;lN?178tpeth73PnP`12;||&L zV97NE1YiNB{IG_J(8O8cdVv7SjTjLy=qU~;6!>-lECTH12Stjo!uiIC_<>$XBQ|tc z;iR8|0JzOkUxWZypwz}077)<4Zi4j0p9Be(Y(8<-a>9COJ} zbT~o8?be%CPYo}V$8TEAF7Y2%+FUZ0`yH?e`Q3`Mo8{sBT|snRFvtXibs-cBIR8cy zq6@yOZ*$^ZX|h>9M(*igWp7YlRw4#rcY$RV8%A#a660=?wR>Ee?;U7CLm@IvwyW>> zT$`7ITB2(t?|=iYfL8$Jn{m^zc&OlD5%(~~z=ek|ysOE~I#IogUG&sR2S)m_u%WQQ zA>U}$YaI$2>mB+L`6t)ATy(7XOR<-s?{X8z%TE5jm+)tXE8Hl+c-W%EjYg&;^fv@x zI6C6klfv~qTEGmgq{bUByPYmsj%D+^**5z;doDM5KXQ==+8EF2v6!7X9K#b?FEWC^ z4b&>b1)OxTZg$x4k$rBq%^GDErxNRzMj*)n2U0gkE_-hkKq{@J&lTT%`4>o{2CdcM zc&^qfYl7`STrR@zc_QX6CZycr)oQeA^Z;>L%!Tk|KaZ_-#V%0w!fe&(way_GH6K2BoPwAZ4gjU482^4tHugrSiXYp8c7nTaq zo5-myb|$~;d%}GK~GM&F+HMKK-MQNA{Zkfb0hOB0Wn0Kfh$(S5p3#}r+d^7 zIwj>OyXaHAqbZPPt$>|T&4t!nq*V9c zI7n0(!O+M2urCOuRb33;9ab)dW#{E?OHos1StFv%sBfh;#sQUp#TfwwH#Ro)EIMvO zE52hm)oJ9V`-0pHcYtjp~1;z6hcjvtd* zIHeG=#-84UDlL?oZJ+rY zV#=MLNsPK9@zg8MdKJ(I7-j|iKPVqrMHV2A+r!gFb*_QF0a(Krl(E!yLWn)9#-9X$ z$h-)P2s^(UxeR67>Qo&I1m(QC9)Uu|*N(oLH-TWPRV9be%7 zGRLIK=J!NMZlqxD289bXoGHeYo~39)Xxb7LQ8N5A;Mb~Bjxb-86(B~EKr8RO6V1Hm zL-Jfup{)Au{@B;YU4w6bVFC;r`_yareeH?+pILzslUo+I}l2ytD=&h!R=Pfc16<)o5HMf z*umfM>|n;I!%>29XyLrrQQI9V<8JnFA0%eAc;Jsy$BpE zjY+VS`f!eL_pCoU4b0DEW)rmg6z3<;>%%tWE!q}c6$BJKhW#Pn`%LF)+0z0{VMmw7 zvkFMJa}tB5YXZVq9VOEouLPm(YTMva@VzJy2(3cVqtOcU29Td9wKy_3E|>xVXG1Dw z^d6VHE;GdnoFC4|=MCEVT%0>Gg`69|&N~V}U)7H$aL4E!z4=Ku@ZtIs>jo_EON&X> zYef+0KI-jY;}#oNfCeHOp`ovM2*&scQuZpWa7gTMNK_z0LTCV) zh+3PP>>_%ywza5@=v5lWYwSeVPfqKF9`tutU0;`*sviGbPU;1r$l5+l3XcwJeXf1c z)U4L!y{!<6z-MGA*diMW9W~=wp%|i_151_%<{?Ou=QH@Bgvu|J%Sbl`f;A5K+_}wV z5qgw(EdNNjWgg?;_@?bEFd3{x;azIhXsmkQ^&*`{a!lCUbw5{sUC8Z1t}dG?Zf$e1 z(&>K1wxZK1Zn*A^i3Gr&#MDMOA50IvcwX(-b@vyX<`nzf*>pUfwkyXVb0JdNvq~Gj z+IdD+aD1geJEuEumU!`TwzUS-?~OS`0D5&Atq)R}BSv~cGS1r1x}2hjxgG7guam#d zb)*qjuNP6_;xlPlZ0`8Gy4&Qq>lOwiw}m8txuK&{ZIFt7Jf8AM?b>~ zC5y+P<)|9y(WAd>IyQiH7xq7p!>v0R;LAnk>$;49X!sf-L)P(hG;Q;XyM)*3vYrxZAZ^v9oUgOHciNKFJWK1>Jz9k z8?us_(j$~b+xubbb{+kF&y>lJXa`N_)8pW8d<&~9CmQnx^Jmw8P^%Slx=zb0_%hDZ z_)fUz^PYoL1i9o=nKjlcO3&`cx$30n`?=ytReGwBr~Th?+a9yS-(zL(WqVaOI$Vx( zx6kW)jd$U=yIlX)%=kPIT&>sM##qxaeKUADSwAUs)b()4$bSXJQLuk~Tz~!4^RSm6 z?EP?1f}zIl{oqVqq;9TeCcNeLCyaK6B%z?CdZ1vczNc4!aax$FSMihUd%W^W}l|tHm!l_ZfQYUEV>4NQ-uAgWPNG z{ZnT9euM@>Pv`wp9DVJ-+uiJb5So1z1Mfq`sSwfM*PI(ecs;^scdr3^oyrA2+-FKA z&lA)3uTN*@Gk6^GxsC6DXVv^?SHZrwo%1hGs2x7u5AN?FZ3|w$8(>95DaHD>+re1! zwZPleGd=fH5B+70s?Ol+L$7gS?!W0D1Qx%pJJVY$~WltA>tGMy!>WLlXM?s7xQv?WSg^S{!^KmT4YYZFk9bd)uK7<172 zJga;sZ?IZi@xDB9v&}PxW9fckpFe8VulA@fuC82(=>Gt(QKP(Cg^T+<$)T8${c@uN zKUVv;h9Q!}P6i}LE7xL|O~@Rb@He5hk(qFGQ`2}LJED>nn7E;0#rC$0`ji~Y)DbyX znX5YgRTO?%5KEpEc(k71S^By%67{ZCQTTpgHgdB+gb_cluvHcbon)WX;|lAxvuX1^ z?^%b_&b^i``R^n~bv0I1WpNUITrEiu-r+A{QRX5a?~4)I(>_$lhi&IYvlL$QUDuPP z!Q%-XmGRS#ONHf0r-z$mI~)9K#nca$@r$agp<-|U)|{(8H^$S_jby`D&r7mjg!7Jx ziwhuK^z^*3)yra=6qCflvXXq$1|C`bE*JV|^Xp0|9J@1$w^ybgSrgBnZ~Hsr3Z#gaV6Ukl+J{wIbDna_+ zTVDG!L}b8Ob^GZBpX;#&9mAZ%=JJ8v9cSNd(XHT|HR)02V*M8{JMTE)7hmA0>9Q`7mL~ z`@A|dR|%>v&J7!mS+)Y9>+OW9RYA37Z( zSmWRpqB`_#*{FYiEw$=(ph4VgnQ`bA^=gWR zD`PH9S+=6EjlYs$(b1a2yk52R?T=OUd1nVj=d)9m_Kt*By2qOnNQTr$50b-SQufIX zTD*Ads!83D^RLzfEBw#VlG}>Vqtd$Qh?R-RPT`07?iVxdT<%rpghlQN-aQiH(KeT( zUL-_7ej%SuRR!uxno*Prwy z1Iyo9IN1b2~+a}B3u;8ZFo@(zTGEPFchE+wKlJLF5@ZRUEC97o_!#0 zFYywhoD_kjO*HhEO{!4S*qEZJzrs2FlqnVfg((-ucy5+tLrRnq2j7kTa8*NitP1%- z8~KwYMJG%}L^vQFg+7A4InqdE#Dv;fNx6J@J#)+#{5ef5`w;ES76;=Y{_Ot{DmqE*-<|jyp@O*Y}cr*Ycphe}q zyi$ZIcomC`v{GuatudHOJzzK=Oz*BS?IO<{I+yZ}(`v!v_-L*wgP7ekRGgDuwfIwd zx5>`+2+%~beJ*by7%Scl`%mYF_b}aGh3DJu*T%i4KM|1h!w4miqy6j4ZFiM7g}s@0 zUENQM$B@UrMA$$y_NO1C%3}4bUAK!)yGx(c^ph>jAI`d7*8&13_>Ml^&Medgqn)QToILB*h8Lba>Lr0Jn8F(HyF$~A`EvuSqB2vK@Wl%J^Ekis ztcB-*6AfDSV%9B8IgKXg^8{1pc^|5)&{hN^$tG%?+-qaNYWfJHE0s#HG+HS}La%$v zj+HT0V#Z-gSOTtOi>z{Jqh3)s-p(aiDPaJK7?6O+Jm2fAZ8<)PP)S$2Y^YBF@g!|z zu1e=C8`3?s_a&;VVdY5D$5yN*B*$~)S(x;Vpyu>2Y$aUj#VA8%dd{Ck{@8QKO?wcf zDJ2+8_b{d!DywJ$u&3@lnp}7i!`S^mC zFX0vEj=QRQNDn!rn=e1n8eVo%3|4Ry1>*E)EN?ay3PaH%V>U4Z3lux1^q@Y|1t{TL zu>`{omCoKy+*16cH1GkJAq-bN@R)>w&Sz_aOPktl=z&z{0tFIen2Cf2fT&|gUh&%& z$7KKo-uA*y0d>{!7{W@>((ReQZ6-i5ZK#;5QHDj;D_ul>h-N}pp^;@fQ^juBzgC8$X9Ojc0wcH57BO=v!G_zZRuHyM9WL7kDPeP$SgC{WJ7e$F^G%V1I8y4`kg0e2Bw$3; zM3?FaUM|HRsufn^wyD9T_S)6Tt3h~jcKWTxMT=Ohr&ZH-W3jV(g_D_zR8(RcQ7<*^ zlOaCTRB`Lix%-0=kOMl-V!w>sw09pwp{7xXzsC&2d&uul#FRE2$0MVy&`mdmuV7Qs zARzl+X0E$5wLdYd!{;R73f~qyzIx8uoUf$T{yiKYC%r>aiMHXgT;{Z+4asQ|;fuV^ zI_Lcn!D{lS84hOb{j1?ipm8Oy-1+B{$rv4Qk2CZFTQXEZx{*9QD_=E%-#+}QNsa3r zw@(0h;EM5F^lO`1EBsl;Dhwfd;I8^6HVD>}OgXHOHib!j=@>ICY-fjvXKfam6cCQf zquu#gJC<+FzyuZ+Dh&^dpd#7{e&UtA$5JoXaKK}r(f&Ry_FE0C4U`bq2MlT|3)Afk ziBmr)R5NfZ{qjiB^(;HOJp5`~n}2;s_p?fJ6yN;VG&qyd4&E^=1&trh@;6d`25BS` z=~~YD*<(AtiA*Le9XTmQu%CrkWDKZu(-5bRjM9LK;*0|A7c%mM&KPy=AX01P#+xIru{U1 zEN~bSSBw*gB1R<&FwzC66P77TErpD44qVXwv{@Jmh;{cEsm|oaY*xi6V;g;s+DSFc z634BmFU~+B{OS3KPE+4FekFoh?%hu!L92#UGCr;_ty12xfk=P5p6%OBKadI%*y$Cn zsxA}fG-5(e`cTyqAV*>UqlD%s=6wmWI4u`wrS_^uwM4=8JId*Kw0WX?7c{aUSQH2g z^@p(5bl!Z6fJ4~R^I~Q` zVLGM?dPPrX{rHL~)SJsMMLxl(TUbiEppbDA_JK-cgNK?@eJXces4N*z^rT?H8|@q6 z2?(PLRvG=6!^fHpEAQx%Vk!pVlAwiX=1U8kocUp)*6R|xeE>=<8UO73Z$1oSiC_7H zOkA*y2<`nUzil_tai}9d)2Y<>f9LSXv*)cAJ&9!q_<~>*;*YwS5F5*odvl=0wFooj zvmGb>smD7PP3a}|WGco803}x6f+2RQXzp1UF+a<=aw-};1`RF5vT2$RR==x@-i3c$sR*zT z@yPY9Auzx;g=}RX-B=rKW8PAE_<-h*+0_D9d+|{| z>{#60_xrNjiX)+Cj@kwx1B?l;94yb%NsNfp^W&}C$#V1hdR~aNFq~fxJq_5JVQh^+ z&skY_9_e~B?yu?uvZEMbE`IYLi(YpfpaokpduEaF6bFfi0t#2wV%lMf+e zy`3A0ziw9{e2`NLWl7-PGjelvNm9;Y7{li5eB>D2S@NLp)v0X7&tLRAjG&Vf%1Jlwp}*T7jQ$>nCLTLhy7qE=aPDQWPIPAk*OjSrl_!qf1xQ#OTZs7 z;0h}mJmooktzi>9n73$p{%aM28e-+I%A#70oRg(2qiTM0?L&Mpt_TVc=MT^o#S&zT z3i!eDO97dWK<~TViXc}gZMNsMH$Cdb`(_u_2_NR2T}5sx2W>RQTLgC3O$8DfVYW7* zo!QbJD99vvFFp4?04@M{Ek>=hy?G~YG|nim2S%AxL)0V76X_01mq@+avZv|<_I3g& zdw>JXAeE@_cI%xgR%v&jtb%tC*VQVUXmXUwB7zTy7^%5|!5^N3t z-2JEwr$%e`aj(O`N=oS1I0-9^>_Ru{i}ia+LBVks2{ERNo#${SbHfSzWu0eT_e16m z)qxMaj*dfPZN>4gC%DG%YYB3tHmoY>KXM{c$6}5_c#Q_G>4wD0xKLV1m~WuN4(L8) zid5x=xBv~5Mz@`L$8=K75=lu)gJ1a-mb%2Df4v`_nx003v8qBw!E1PH!7z(5B! zxKgvmXErXotP!{R$g%3T4vC;^q}S>Fti1}Jq=Rb7Cx`VUvOMcSsmDw&mDRTDN@L38 z5!BwsDzbpbIm|MVZxkf^NY91c7E*V0d*c~3RHb70QhExfim`Crq6DxAl=f6HA}esc zvj8@9@&PEU$tTm~AZ0mA1gg}G_#;5|6V2`KL<3sl0%KJe`E6W|;x_u*RK^&y)mmE6 z3tGRCQl!)l4vyYDarOKXdQ#<|@4jP64AF9-R%SLaQo7C7Y2QD;I@B$)+mpwK2BmLQ zuw{mfCSH@%&3CyweD|O}|B|pGkz8b^WcxdxO$?|Ot)#Uvb8@-!krn=Zw`#${Txrj+SUuUc+Gh&&6dPvg@nb@S1VDcnH?1~MoOFtKU8uI* zbVS8ANW+tc%YTvYozcS4;t}t%Ia0`JI zd+eTKl`w;_vISHt@GYQWiQKkGQ>qlCRhWE99xM4TtWx&RgFV^VR-ZoUS>qKC35nPQ zeCGU`%ExLD086OYX6-P3w|{y9Iov1~yhzpFuM@0&nD#{I0)GP1J8QETo_kIWNyl=HzpK8x&nh1A=j_mww!h{9yqiLlOGIJkjatGq%}AYSJ-q zn2)}b4~rvcv>H4NU0k(D)iHwV2y+9q3P`OdPyh96L+W`kj)I&O37X=6^#%WP(STM4 zR~5QvJ@lQY2d%p7gGdEeoOUY5mw+O&1W?ebf34XC#;}}j;n+~QTt>8Hp(;lNK|E?K z34k5Pfo+Ha-^WOsN2MA|fQd?cv3Wd06|E}PbNqTjIcZ0%(KvR|Ev z@AvJBaFik;jV55|qY+vyzaQ&2iVx|rixyD106AQxB`guc`dEyrT03 zHxpQbS&*npZkuyj21|yh(81!DERSIAgAhzI@?vJYhr6

|K^q_b~H6{^lbFB~L*+qe(|#z4xfEmJB>>8&$B?fz$RTrULtaK3Jxz^1K`n%=p z5GK3hf=QbWHk2~)Uo>&Ys?evcGqM1ZPy z_d|&eudvtsqy`%sQMnvbl|0pjWSUYX*r?&$bp!#7z!SePRDYAk{giobqCDt+AR9$< zfJFW-Dpj`yVm_v0*ZG@4$Dq6ocT<9j@mV}qMV61m(t*_MuoPC7iXjx;3p8KYIehiS z5#4I8GR^$BzeZA2-H}j6rB5IC=!GYwOVvF|*3`EZ`-QV~NRpl_{7ePm(NY~YM#CIZ zFfV_`dpW^MT8WsP&3AemH~DFY-JSx1q~Yc4x#GYy-52@EAD1xrb3}izx6M5|vrZH1 zkgr@^sIUcB5Pg}A3>&UKDPjCI!C$qGrIO|#E~hAq0jAz#>; z+8V>~R)dca8_53g}*F*RO&EA9$m@E8#F(sX_)dDRG&a^40g5?pa|NL z-;@lMDqQ`JyXXfC&&15N#5M+0TiEnhC2uXWk`n0{xMHS%J1($nI{Bg=F?24QEj%b9 z^1f%!VpgUvJ_SlqIVo@%Ij8~dD8T9q+a~GOOHKP*bS`bm2XSHZ*d+`lf6W~30>dEl z1n#4zB_8yetP!Q6o~hmSaYP~qeNx72XiJ>oL!F~}Rr(nfq|B4z0R5F#Dl?I9Ko}=| zaRewr?vJodoedUjs%P8+5+U zcfS&^@i4DYq#m#4n~ea*Z9FQMZBKU9XZn~pE7Wh(EwGX?PWat#*Su?P4}D+1ery$d z>IrOW&6+7taAdkD-187a%AQLI{%MG@yzcG=WE(iIysB!&iFT^)1OzupzKKU4pD zay=hX+7r%9{k7C!iPJ@Y^?nw|LqLY{o75Gic`-mG1V@HC-67g$Y`+j4o>RM)t6H17 z!@;|zBA3-S59a~7+z>xTa%{g8a24^V!Pq=Quz;CWJPyA@x>WqdJ-9g{-2dkQw(D45 zoR!R79n!^W&Z39H0ahp~)zIHk3y`G6K0#>wQq-?(ol36fqahPTe??jCkUzZHTkO=J zDb%_KoJ{DcR5F;4i;+h;{rPG}0dI`hL{g1ke@U5s;u%-hInYa*kuR$xNC&8DJ6l-i zwb`nVzxzp+GZjuNYLcv<@+SDTtb<2V&Tq6%3yXjTYHgC&%B8^^=BXx>aLkFHF zITbN1;YTw=@D{ltGwx~L#%%xs>P^`++E|2oeXJO%4;$u02KUSLPj4)y zOLa{-O|pZ}2Szx9JO+8a00MNC#p;@_hiUJd14D6a){FScKj0M9UOXDlQ`Ba+FFYPPT?)r2XE&j09q6LI**z6IV5{T(VU4cp2!GsP6JqS6)7@%RZuF;bMNxn z*ZlW==R%J9llNmr9IIHJ5CFoMljt&ub{`4Nq9PTW9HQ}yqMl2~j>Lo3qH(haH^=w| zQPgCtaYP2aoXZ*YT!pQ7Bt&vYMrKjrZ$_Ixfzd(}+c9aaZNTr#kj;rv)(JfHZhFtb zDA|gpQ}~N>DMKO-tvqy(RrnHmA?qh3`I~XCvbn}Hf{DHWJE5G=R=G{U~svCmkEr2Q%L!= z<8_IRb+CvSh>wEGmFt5kTS^-cjUq_F+A%=+r?kSt`^ss7e~bh!#FH^`-}{OA)dAG+r+)EO`-03{sJE!&YySw6-c4fL5mC=k z#WMF)UX;QR6)6`;rS&HNloQ#mq=?K?6ueHH$*=#c^u?VnVAhW8cS08jTWxxhqR5vH zK~~G{PvP^CL}W?yj$~+(UP9z*?grZIkmTkO;bf~{gf}8g0$VbD1;JCM>U3(w_Te42 zcU>0iqK;`E6LB_XpTSz<#$t%1#Zcb)kD4{9i5BgCtK;ch%5x^+%;}EB8+RFw2(G`5 z=eq5L=S8ni?a@`jEc^?-5oBMujKgP=xSqH6l~1erPtgQPj?s$nw$9gbMax^%296Q; za=fF*v0udVDwlWCIl}~2%BHRM4*-H#sUJkMF*VHcg(wHr-uM=jZdv7YQMgvJ%8ABD z8qC+<$J9h)mx>uGHTpE7^BH#YLsHi&jk(|5U~(YRQD?d@PTkXEVR+_`X%tHPr|iBw zo?!|zkGturv$~px77fdg$4HIkwg?trP2$=iz?zj}2<%zZqe0l`d~%c`S~Q1p9^Zon zc~vAYV#dd4t$?@AlY+OYZsD8+%1$lSXKQ9s(kIB$KwM)pR|J2U8V^LE$E^G;B$xB? zmiBHD^H6N~9xuBfkN4Q5)E+paj2-A>!OC!Fe>ejIZe3wqF^a4V?JXI_g9kG__ZFa z;L#+UG5zF2wADZVA_<+b*GabpgT~8kU4*4yv&S8Sb0jHgAX0}OVo%TDsH3mKX zB>ZS_b8y$^hT8-hBYyro6$7&ml|{r2*oZ_Nr}UDf`(QNFA^ihcG~OqNbVe%Mm+Ex_ z+kXQymYP4z$cREEPn!+_@kRW>>*O;h9?9Q~BD{ozT0IND#RPlfiT+Mbn!x&}w1M~o)yMBgg%Kw+n|vnc2Op8m+Sv+I{#^}BDwUp`mV)e(Wp&NHPY zG`UEJPf65*DA}dij`3uY^-x!4(F7A{$&a*YWd=Md$wo(@pdRA z%7L!KmSVm|Dep&=S%F~^trc~yH1;#Fd^iQtO&%45`a0dm$h^A1X3|KyZn=vhD4W+w z$QqVYT6w75Y+wv0qB!&x8kz1anjxG=q9Y5UCIp2pDnk zI%ASzLv?x`z8^1COre(9y`nkN}JjPp(UC~+knY( z?eqGKr&or)wdmC17(y0W91;#37LccQz6aQ|8RZV#1soQL4_ZcN?)k>UeGt)Z}G+0foE&CB6$wAC{q+ay21uVmGcpT=^@F}JJ6hQ2*2UG~?_gEuk zwCqy-`a#KXP#UM~mmdlf_P0qC3X!lTWpP%ki>#)wJt@IFGV6$)wXtv^fDM2$_Pz8* zED+#pILx8wvgNV6g-E@ff`yqckrqSuw8il#%irZ+FCtpintN0$!fYAXuo^*I>_T{+KbOHm9)O^9WnQVeZgldWK?UnoX?pp7%I@@?R(?UeN! zi~kz{1Ppn~??w2R@UU@C;xAs#PLeGSx?=dpqknqKZU_*@?)~yFJEBDd41kFKD?z2e zAYfh|ujX6z-`1uHU zJh%V?Y)xGZ2|R3V?3}qgc!~ZcmkaRx&&Tvc1pjK{V$DnR?@4LMDi8?UJDC!&(lO8) zGq5oburbmxGPAI=v(peTF)%XFGceIJGSM=!b1^eXf zaIv(vBlt(6p^?3-3oj91rvF}ot%I!We+#yA{x3xVR7US%=s?d%$3Smu`_H=m)!Nxb z$@G6u<9}@Jtm5flO0Q(7d;{S98=Wv8%1A zor|OhFA?BBbS9Q2Tw?6(VvLOJEDY>S3~U^Xj6!0J%wmE7ehN^)BlWX2^jak`ZE7t z`*I08nHsv-JE_>)+x*7@6fEpr?42#_9SDS#SqWqfjVK zds~8k>6gp$e;8j(=>N6ufA=-{|IryeU^4Xo7{~u%EdTikV1fTU{&Miby6RI!~h3R?;`6Ei?Bg=;)Fwi32o|1 zvaOr2lZZ$LSv%kx8*Farc8+R&*I!@NRbJOwL1k~HZ{>Tfcgd)_uJiu&J<0K=D^{zP zwX^9RU0Egn)!fX;&W^#evH0iW@{pvVw|sS7)4@N!vGKk+KfboLes+BRZbaaNF8eH2 z{x-X1W`^#UuvK$aZ?FF4>26=a?pI(Sa9}cIIM~(l?py+raG6>pUXla}`^a^e(FYED zsupP-W`d03{3V7G(67(WV9=oSAh$@$FcBiwBIdaY9AkH3#ybDx$)gcdiAtr&ix@4s zJDn4Znb4yE4;2T_C--R!6b{xXav0zX$zP#QEfHGlm0p%?xU zNys9|hA=v}yi6RiGGrms+oVrB;12--sY+%1OMH3xu*bguFujj>do?vRCChJDe`ITG zYvRK4v=uf*@e))w5n&-1&^vr=^tGLZ1uLQ=Ob0ci0scAu0w$Q!x3{+#+^egrX2eLr z9fg?h-07()8HMAv>CL64&dyP&!L%squ#5+sUlX;qS7F>Z+1X&Cnw3f}E^aW<^&&)N z%(}c=bLNWbY#bKG*2agy67P^UHa2z?BmSRd3KTIo5&@LN;#ZfKv1HUsxkNVo9At`A zs6-s*0&~VtJs=m7A_SWH_Vt((*mz0nQPOVq`uH)Si3mg}2+g|0ww;BT{t?rgn?43} znDPy+tv8p*Xudc&7uR}<@rLHs%q$e=4qC&7D!RVi5or@(<8=f(Xn*8U7YZ~fVxan-LPdjKgSNCGYw#Lx`*@5pUNdJGmjD(_PGFZs35t=ar6ni|C5l5MIE~7L z*4EZ&Cpf}>RVYh>wkQJKv$Jz_V&t~wic!o{3{Yv^t*yAHA7U~Ybz_)hlei0 zj9&uTcONWkhYdCwg@~k~KipbeA7hQgw>EV9GaN;+Yx>SFukwr z)Y7Bff?pNYjmgOdBq?@vb#}G3MSQ>lWxsxD=J@|vVP}ELwrv-hvKgGk^oq&K(xQ-& zkLO#xIX}0vu|raW3k`T!U0UAb!pqAOs*r&}Imd3|_)ypsJ(A&&*b#=v5z~f*lMP}N1y35CB zh_bUh5g;R42Sz=;dg)W@=|d-i2>;K)55YE0$W> zJh-^C!!&JNUS0iT%wCPZTCT6pSc^DYT2}hzin0!liOgPTX=#A!-$jlY1n8}-FNR8b zwMiy{?9PLqbx+O8+uQ zDe>=<*hY-Evb1y!HvYi30UY|=+*~m^2Y2Uc407a|xVYx#fp&0rclI%BVc*~}->VcN zEIaTE46q-r?(PTVTe(|8AhZHmsh4ECSmzfP;IRBu)YXSX9+e$c*sI7qV4VTNKYk1( ze*xX^st@>FD^EAw5ZjXAOf_GGrZ72 zfNV>II^4fq`1`jOoD}p5LD0lOf}s}}6(LHNIPfR(0}zL13AQ>ZIwcvWpy5AC1^q-c zMoLv(*2^n;DDLQ3ksVsjXgE^!je$1iDdgkf@c~@D&c+$lGQ7d^K)$HlR)&VxM|*n2 zAl^P*-3GhWRn}nfAh_(UO%Z`89|{dDpbI+Whvo!tPVEBPh0rJ{y0doW#Y+8S{6KkI9hZ&l8@ceSNw_B|M9TDp`;#YU?T=pP!k_(3sZoyVm>g zwHRq=XbAkpVDb%;ft=T~loO}_{ON2fQMs(Z$O(g*2Fj|cszO(U8!Io8lpxfkASIcj z0?C9khkbmO2Imx0R7^CmMUzW|NpupR2}Ml7#>E}Fk9Z9!D--**0xv2$Y(NH7Js>VE zHS97Hawt|%zOpg`1)&p#v?n|mCMNl+bhxB`8^ z%qmq&L4cBqnvQCvH%`Y;qhC)v3C$=^q!5un8uSx12u5;Klo@9a4F>n|=_v^H_3ahL zuc_-p2*=u*(P(Rao-*+Xhmc(1k}q;-<_U0ROlGI2n>TW35P6JOH#NyzR`mAL&n+b& zj{mrQhJ3H7t!3pgF*X&wRVprcgPZnHKAy?gl49owtipSeJ-BgLxf+4^-VpTHik_(F^(Oqq9*$lL9nuY7*nMyjWnJp)O|91g^w@Hm85H|(YvI8lPMt<85_4jl0I_OnEe zU8s0?WM|20QA3GDL<60j-shnpxq-mI4V6LsE>12(8rXkP0I89LxvFb(L9=p$C$uj@ zAK5O!B7_2rQ(uz3ZaiV?6UwjxlvR46tA({S$^*li)~;kokzNBhvLrr1MZhTr`W||a z8osfLuJTV@WSW=6Y;7%ru91-#be!Ui4KH_f^@IKjfQNxBepLVVrwps4G&VN2<#{_i zxu8C~LZQBEXlej5=}5|@_F$o5!4%5O&!-1!5(D2;P*Y1oWPJuUp`t|VGw9<-6d8nZ z24A|D!rlUL5ewb)2xEXVJK7xw z3l|p*^w+m>TQt9#%Ea<=b7lK76w>qkBd|8wpme}j0a1fhkhpk!oFauPCue)m8yQsQ zz`(%zl1FUcm5y!>;ZbcZZ4jQY5d(NsDe~Z8m~)ZRg&(uo~G5QxFEQ zYyTi76~rBh0({^^bXAoVE|Umrd%LHD-L_EE`$X!cUnL8XOom&zsmaF123R}{GLM#; z9&o4eknZmCIS#gOSGS!=DOh9(Ae5)sk!fvP`vo34%u6KNyjNJr%e!@Uh7}f0L`<}s zNT(;m%!7)H3+Fk*His3%l6_!p#~30rXV|V}h$&)*6((bb$)Q9=u*eh&oS)WTG#M5h z74;ASiP|@3+)x>{XDFV8%aBXpOaYMsILht@y-5wv!{B%eNst8K9 zsr5vktgiOTafU1s96TyoI<^PQzk7ubODdoeVT<7p3OQL+BXbFPCxv$9eF2p7pJB-` z*;yLH4vZ9!)pd0v2LiJ2glcLlrd^sDfkpu+>8Yw5oLtaqK{@>XNSKmv;<{}ac4k&o z$1)Khtsvr_`qR1*vauif3UIenzuE;q7!;L_o#S6bqBAli29+E zeR~ZzG%(;ZY~ZeJZqm@Okg)d(Omzo*^e^f5BoS*c^4aNtB*=(~l@ZRyVf}=kpBNu! zK3w11+j~hhv;iChcrN2H8J^88f(X%2a1cCUHXEqS6sppgtuXk(W~$)rEK$+WjZ81D zcUTx0g0C>&iiJg`y|_aNEp>hUcx`NSjN{|OT}Dulhx3G9+0!BiZLC53Bvd5ew>t#ec>nA`-rRo9VBW3t<+uTAt%P<1$Xmy zNtv298(bMIgxn>3!D7&1bHzd*pahONju9;3Kwm8X`J-N&-4aYX_;p=(4YQSjwg=a+ zB}__6>V*i)q;9X^GaN)zXk%9#CVPfQRGS6n+-n4FXd$hllETM$dJ0r`&k|9Gj)5+i zI1+w`!_udSF{9u2jLYp-v*#O+$6cpFMJ|_P;89Uq%gag&pCeMkR8>~? zBZr&MEe44Z6BpOY&Jryq>C;}Uw2PPb&&Hov8KIz^A#!RODocBeyaIMVA0n}f(|MGz zG-MV!3I;?Ih!O?<3N#EziMf@HDsgf#aBxb=q5Gk6<&V!_#-qq>{5n zi_&Y2#~-cBuTbX!w)B`P{P zHWb$d_E1Or8CrF9^EYM%EOApjk_&cF)i7Ux*7TFgTrKB=93ucr_TmJI$l(gzHt6_gJn6%5CD1AxU`r29y)=yiK z08K45bWGG+f3(3*cgnCkzXP(8(QrUiX{wrwNEgLf6!E zeu6R*k8^Um3)Sbg5fDB!IxJMM$jtQc8>QITXqOQv_60n27q6j?;72Gp7tHR(iTG8k zo``Dgr@N$LA_0umk}BM^T(IA4OhU^8vL^c`{i#?KJYIlZC^$INQ>+Oek2D;N^lV6VCX-_kQtjCI zw7a{rvx@@*ov2h=d*yd0s<7{JO=xF!b$70>o?g#dCc_~kqhhSAta?ZUhX~<}hl?#6W_!?3gs-pf>r2$M^p8og zvzbY0Y3YlzE7dX617wuP>rVF@KA)iy=mWU)nYDIndH-G(w<(K$$-QCH(id_%x0pmc zqR>!LwY0Pzbx=j8P!Nlt*XNY|uTIp#%}qEvpHr*qQwT^%#xk>AOG?F?{GvD1D*wKpt1o@z8<&stR z++t-ixkeX7^6>EJ-Sf?MGY&cc&G6bEBKi8dKcP?fK|GP!Xm;NHLqpKd4;bz>25S*c zA6@Tls{Ou&ZRH>YC?o9Z5G?>-Ok5m09k*f#sIzFg*Lwe@H_=$&j8IX1`ZV?@%HsTd zuHjRj5&4HrP$7n2;jib9MLv=NZiA8wr@ACI* z*MOgagJNYt{z7}IpVaE&e8>!YkLX~O^v92fn?L>v0hU9f+?-qo(pPJDjoXFmjpjxP zB;DNx2_K&Txg?INuZe@bf1kr4!W*y{GcR9$8E?vYi$jV9n~0fg?d<5+q7QKoRWQeB zsl$Sm<}*J{H4mGxYL!Ie?y6!E-kN13@2MdD8InYKB&P zft!oG%)#x3S?}xXi@0S7RdU_!6a0!wA|xcVv$MN3E0@b1!i?V}WehB!)P$f1<#1de zsRH&Y^&``=sXk!=E0%d^U5yA`Cfb#*C1vn2n!cwR$P1Ze45&Xvd-=7s#qF+$j)R2P zUw%LypAXjYyQN8HW!lRBdoaF%(yoqfvFt41AKdoy9f1P1>hRD+ct0^YJ3Tkq+TNbu z^f$u^1OzB00s{Oan*EfqkXrcp`8kWxZXv ziWC~6RkPrm%|OVV-X(2{zWuit0;^#H>SfNtw(mQ_?X!Fyiy|2g2>e#BJ^u|CibXnk z&uBq~uG2k;q&4W3Q3z_}e3WsWv4u@OJ7gOYkm|Pym{Q5F9Go$9}6F#>aAi#yzN=Yihk9kW3SA;P)CvV{H z7M`A_4M+Hn(x=t(NH&mEH8)rHGDEkqFcQi^BDA!>v9Pp+hk<$988?1;e+`O&m4iI$ z1aFJG$4~;t7z2gQ<1$T>s@%LgkPpl8JBm7jDeY=*R*hGh&0x%>MN+5eC)V~<+le2Io&Kg5BHmD+WP^oz>2pzmOnh_)_(GtQFwynScTr0s! zF?D#@BUTP%)rxSPj&@+&?K3MVp3OM=zU{HYicXp^^w`v?Qv9!nDBzj2Z7yfXKhyqR z%m)n+Y1E0rVw|=|_xBg-`>lh=^AcL>Bq)F)F-(0z{>aMCoX*HI65#=&5a2H&BK~4t z4(Saxs;Hw)!o^0WNtBwDaE9qep`oQUlacPX#^><(Gua}Arsbv5PA_GXybb2NhcT)kE>+_>zoz6JYBD}XZ zHzLGZ2Cw%s&eKv~i_bc;$Kl_<6UL(t&KT0@^kz7i)TsHsZ|+}ToQ>wcLf4&M13@8Q zVvIH(EScQYf_zqI^gUvXh!PE0`NuBmmx2AvS(;lug!8=-(I}9{>mwsM^sS(k-ryyv z2OVf#Qmcsa4I27E|Bfkka7dw`pImMBTv4RJtM-brPu6Z5i82By@ z4tTAPUAn&ah{Yc&+*DLde0*@j$m!{CmMRljoPJ z9J>M`$)UOo1*|xChuV>J9am8;PLUA$dBQYeQHZg9jYNu-jMidKS}N<>DtNHQC6RLbrKjxN zj4<8`U}o7B=kit9#mLK~NW25$yXZ49Kt9l49JHbJ=XMY7#CAHD8xl^wQt9*a-v2aJ zYs>ZIXUX30{b>5Hegxs^Z1#BBh4I5q_v`(IDMa_E#ERHM)L>X&r^9|h99|oOY`jql zIw}?wAYqEqo~%WN&DngY(08Sw38-DViEgZJ0S02^z9XaNC0&LNFwotoXyVyi_V~`- z7W!V2UpB8n;IJ?0z9(1i7StEn_IkrR{0t00@(c7=kOCdP)3#wZ9uF^(Wyfaj?5(dn zj|cW`Ta}9^T3Ua~<+4n80;G#og$J3+t8<_Hg?nsmYHDk0v$C}ho!S+jjrc4Vz#>Jw zE{7-?MYH(r<2tjcaZkU3!{Oq$-7aVa#FZ)!?eqPrP_UnFB_uN;%I5$4d4HZ215!0I zGIDT8h;dYpAf3mXM0Knyx>JaUSf;Q#!IVAIJS3bHc6;MM6pyG^ZL2V_yB z^GimCIxe4Mi~KB`k#^mK2!TseTN^U?V*kUt4*#87ywt|lMn_lI>H_-(;*W!~n@dg_ zkEeyh?aR2bu8_4epzKN8X4z93$|>gZyzT2HF4$x~WdN+IsCakX?d|Gv+@f7mvnIzA z{^RG&k*da4iy8bCW8?ivK4*2W(IXWdP=|CiPIAOmNnd2%naE-AULh*4J%PrrQPpUN zUs~PFSagI$AQgU~vjkksPTXOIV^JvX6NY1~%Q?L0n@bPRv;67_L79K-dvm`z%x7|Vo!?@FDkGw!W8+uj`|$W3nW!&*OI3E5K1%g_ zQCSQZ4)(UVHpxrpo!h8v0%K88Q5E*d#q~O)e>@|s3YC3+`T+2(>}>6rv#`ednoMRD zs>eP3cq}?rk+#5-9L~o6a(Z)JPLJD$?fKzobgoVgVRpCA-xtXC*sbN|Ckv(0W1BGR z()7JN0~BgC4Z&MPjS~D{x5PhW9r0b_SNIbgdb0Anf)V!42iw8Gdyj+kmrBsZxU+Jt zbdBxXltGO}Kzw5y3M6fb_HjR&s#{}9u9mYhmgF zZ;tF9E*od(=dLz68(+7CtE#K{zg~t&FnuIEyBc93M@cM1)S;;rpz_Z`6dyA)GsQ$C(BR;9PjIC>tZl(S;6YYR<^LoRLjW=jAR2QrQJZsKX4ltg}h#n?kb81bg^^z13J}7=yL|h+=$& zB!*SoKr|P6ErOBTXXodm;A$h=oG5Qr2K(y}5|GjYG@Tgh7Ibk%cfp(fc37R;<#fFw ztzQm%Ao%%-Z@2C{p5?z1Wn;xfMQOE~6xbzHzZYkF`_w%=y>{Ftr$O)vYHdg5dw~pQ zvp9ba7?ZrEWaUMcOGU)LKhp}_XQK(58WkbxpK8go8~g?AE}ibo$S5*5EfWzgzEG*k zm)C=bpkU!1wEx@UPXHGFvht_Zzj`&p^YL6&z>WiK_2IeKf99(9u|->OXx+-U-RC|m zRtFcFZB}H}vd@^qGMev&MYy(kl*I)_*i3@CLsS{po~;fvCc?kKl7lx|E=86=bPRpO z3Yq*|hBjvsu?p43#^TWFkVQw@e#pWIB8!(~Z<=U?gtmXJ?hy_*uIM_54^A$6C5%+h z`xOmchcdNcMc!^>YU?dM-;dAv7)~a&xq12R@!~~ZRbBmgMf*mgM2T8Dn%k~-Iw5ZG zWAF(c?gudOkcfDsBy7U)x-$l$Uu5K+I{a={0<`ns;NU7_=J*4bpMjm3*tNUt1+193 zs8?J2(cuvWDmoUY`Sm6zRq1|TAu*??CqzG8b~wJDM5)oLwa>+s`%CRB0FPOz_0Hfe zQ22OQls}oxUj@_niF@7o?bl&|Q4*f)G0?(lH0q3fk16{@TezRxV!@||mrrgE72}uc zMasGr2OU1EqgyVlK&9v$3P0X3HJT#qf}R6fs}4$q zY1=97%-(UJ!yN@*r$)OMT6ye?l*@^(`*-9!Q)y}GP4_z5bQY_R*W3>O?L>9G zFf{|N`{$Y5peuD_qjS%jm-lzyZbn80WwK~zR7y%}KBxQk;v%u@;)ENXIB%=qV7}T%y^SoJT6At#1n3+V>AaJpB1w7DAvE z#zag-owWCJ0c)0l!Fq#X&Yhc=#4mP#qM^oF{@Gzq&JfU|@4-0y%4@E_11YmS-#L5Z zZ9mO#+I8@{D10F#7`lJ5WZo01!~vkitn~hZUzV)&c*E_myyl&r2gyt6TpXNR#ikf@ z`Qoef;Zg!%C@3guwOZqgQC}E(K3L=eX2-MH*@*b{><{Vm`s>Z!^l@Y{k@Ld(9~`Py zVrBriUPB||PDr>z5Wl0-TPG(M%o@F(a^|^SCNp&B^z3RF{1#08YFkfNJ3BGa)XeOk zv{oHs&ocHM0kV`ouwSiSuhjivlD?PA`H3b6bmS})Bky3swa?J5{WUG`+D>3w zk&ux8yC^dQ*wH^KrYH+>v~}Az{CWwFmRh)ahlG1{cw`PaAH|E_w{&o}_fx*p0WnaP4Nf z$N5n_-RCvq7lf~w$9Ue3yvw1dIZ%WgZr_oq1!Oh*@4{f*ivTsAY&X4hkMbO6fA z^Ss&Uh2VCkv;qjg!Ors-3I9$y<}RxPJexD=8sa{LTEqO+c_amPl-XT1!jY-OWo`!Ui0M?~o&Axl2kg zm*8<3LRd0Pw$`2`qE$szE!C7RUZT%mKASI>Y*O|MmYs(U z4^JP6KIl308x9^G95XCwv(xPgVaMNp?~?QF4d5@kK4-WMQ1SFz_1Ji1WCzXleSjBX z6Q1ULpP4rpe!4A0`#0PES=F~wM#}L04n~;DVO;<5J-&ju}aWn}rCKWGjrQJ~}1XrSjKB6#H|CIYjSVHEl9 z--+AS)S^kLii*B^-*nIZ%z}tWOA;D5|4sjWCvPVN-j}3>v#^Id%=^4O$!OW({3B9U zadmxhRa#`vc^BVe*uU7njq5Ht5*TIx7LQ;?VS_xd#lm6f!!t$i8QBe3pkLJTuC}fI zVazz*i4ZJjs>8IDiG}B~KOArW`tQhvJszh|2%^AInQZn8czX?(Z};cWcrvC1)E(&a zr|K=Id_J%H<%?vhRT&CRYbr3<5@)`JJ}_k(*18S47Jxh`)B(|OD% zmE|moi6bK;XwqqJ?yi-RbzVDr!b=@Hj(==*FwKA7eKq(nCn<9r0?8nhd;xZHI+NZ0 zNBxies@)+GW^c=q31VgLO09UT>Q^N7=B#Kh%l}kP*aB!JmBWWM}>xDUdoe%`UJvtzcv-&hzouvXx7Ap|e10wbBm;LDa-nWfS zkhKY;d*$ronPtj|x0CcgO3I4{MB=g7k1xg-@WCp=!h_yV*VZ;xBXc`lUZHDM{w|=o z6tvY1jg66UaZKO2X4VY7_S$(*Pft-3R^Hy7rxg;!j-VWOx!zArElqnl*~hc7PzcO1 zs{T!n2LM9YSZ{v*&9SWfU)O`qo1S;G_f{t*mL8|as!@FZocptSuFWj1sHo_b zs#M+QKpB~i2grcpV@IbTSBKMYXTu+yKTvRRwDt66=wM3{PIShf?w;aEaDk$nmZ%~1RaH^% zJ#A#KoP*!Vo#1sVGG8jz%QmkQsh)>cTrVs0ioq&a5Z{5LBZK(-ejlSZ{%Zhig@J-o zJNo>T;1Exce`V7#JT;Zo&-GgvL8vg#|9JiK(x&dm^Z0Z&>yptQ^%%D7ulZ4YXU?MX ze6OhM_?QTv*VJ@QE8tp>uU8Bwr+XQ!k(uqU%4vD*6)9aA*+0Jy%=_r+?d$&u$0U$c zl$D*$R*tr}d!P@HeSPbilgU*Ns-^B(9pTVAe>d-A`$l(n`x+VH`rwm%eS|LgB_2-` zI8Ub2;W2ZGl`7@(IlKK)*T0ZG3Gm*!9Xe>ZrV2%Nx*ve0|I1BhztJ_mIH)VA=Ck?R zlUW`5eZ~96$pMR4d>jHcqFEIEj07%z9vm|ulo?DeA*{aDHaHmz1E)2U16^&gNk6G2 zdH<4qI)a&uxD<<_>BmM4A^DpETHQT72J=ym83}#<@acx{N}!C)etI}ZLaTCoNw+M? z##j5tUM8z|3t!RV49E>>#o2f)j^Jb(4FD2iy<7~Q1wn8)9`Hnrk@-8!!K*L72EIvl zk|TNg%E@weU1c+IIu@h2;Bfd+zoT zrb=NUAvv!8Y}Jki(>7&VZ-=e4$(Ogj&}1&dI@>BMM{YoJL7ur0?wOX61<;61m|l11 z=9()Yfs`)S<{cf4J3GAN@Obrzdf@JgL}8Og;z2vBDk|P?i{-OiRw+Pyv|6tX*;;Fr zQ~^oh`d^mTFj&549Qz(iYh&4CeF`@F%`sK0n#I3D6BvO3mY90l5UptgK*Fg3m7r`H zc{zX2C+lw)7P3MJ8sH7!$m3MFii?V6J(#K@^F+n(v^FZRV_2Sn@rh^v)p&YDkUx0xc8yN^z2nEITm-VIZ z3p=`ZxnFfJUF=)AZ?=TBAg5BI;`==iuHGn6rP^(_0sG-OS(@5@e%#NVJ+fF>SbV%B z%LgJGQXCu{tZcePuN7f6yFPY4T>_}!@sV*-l6giZ;LKlSS2yVrCAYe(Nmw87ij*;x zsi~!*?V|4T^eW$4e#n@+{Jf@Bv9(vFHPqs9KQXjXjK4nGsnh5bt5N`D(VMP!K`}A1 zZwj7S=UHBB*>gStXLdWE-$g>qj`T!KMuQ`?UB8U zc&{t&z^%l};e)iMt3gbfaDy4uuu6qTm%D1ZT0%i4h1(vX+d6jdBqhlpq{g-=h^pzsgZ#Qa{zeO^z2J89c3-U4(y!KOcG(R7<-Y03Mpa~B zP;s|{42#1@Lpk4M?8x`M3)Lf5&-q|fjEv|1Xvhmw!~6kKX{pc9+-7O+y_$yVJUDv> zSJO<#sxJPU)De!|T(wli@DU9ecz;qZJ~g?cW?}>NP?_OjSI*_ z$+jnH-l=e81cKMy@Fl4G67n^{NP^erXq1eOFZ>3)hKLsR6qgnvAA2XQ9u2Ni;2?rS z<)PmH3lOI84y()a+-XQiFnmt{T=o0mL2sZR5JsOOjdq8Kf<&Fki9iTdRaIAamz`eo z!05%fbk{&oda63mnTMz6*9z*(;~^vNPh1D`N)atJH9yrG;1M1G=Vaw5Guzz6%=a5m zQi(3eN@&SM;C1M2PHomI?Qz)Kzo+k6>$iSF!o~e~yQl|l++Tcpc-Z`9HtlzHS!$l= z&6YKlUT`4g8Vs%y&nE?r1+mBlPRdppQKmz%Q;*&81fb-c^% z8?(EcfOILW#sgs6?%!ZxV#C0~;t&$ziWlYx5*<|=nYgg<-wvO*tV~uwmrRi_o5Iar z%|#Z#$%o&qr8oVe@uFS{x8M$_aFs861V&ZDmXjNLE@?}d=Q6KCBi&G+d-L>=85~Z1eB9|Itm>?s9Q;_31b&UoMyb6Bjpw z!EQ5Y7`Cp14G6EYq^7IAbeX?zXKU+tfi);yy(t)j(|eY z?l4Kru9nue{~(<<-{2*F!p>{>$VlXs7pHQe74@qQQS zqrnK!&RB;e%|~-27C!`=my{dRbaZw=!K?7xPc44D?yIUUMH<=1J|y#?M03Y z9R;7AW$J%8Ys<>kmWF~8q^(J@bb*a2$m#h3V6qTe9-5(*H?B^;Z|O|?E`Jx5kl0vP zKR-h^ySzI(LWRv#>NL?|kxJDn=aX6c&qI4w2zXAzGkxzzG>dkr(ljZO+1}d)K$YE5 zJUKbJ)n;9Ym+5Q0$q;7*>5L zOpZwom!r{Z6q*;q`1ZD-{Bg-AsNPa7ikB>NhE8TjmP<7P4Bjv#KVF`mliRd}Rr@lG z(%`Ia0XS0cB+-|`^dbthbRVD2Z-+#^NbZl3ufg!!Bg@@5*a_ax59gF4WAbJN4+FTB zN&4<4k8vn5F1O2<4%Z7ny&D+Sb`5IzSRgp{B`YhN|Lf2`JpO}=g8>l{(PPKgAHb(( zCNcoPjGnKdC-h~Snp$zvG38$7qU^J4` zr=<~cMw=yH{%J9|<~j8WBz_ChrXq<7@xUw#j9$4kC2;JpeQ{}LXQw1jSt9~Z(O2-q zdBz;lk?%U4nV@5*ChRPl)E~EjFq%9fm5<0V!O6_}=z((WlvszYpFR|(H-}UHc=Y)A zD|kpWql(`PNyx0D1~M{bB;@6#Ww8YmD6F39kbe1iLhIxXuF1rQc^^UW>|0*h1izW) zscN$bsI@{SQ|%Xu-M4(77tn~ogY0|mjsci{ElHyn2qQ#)=DAR(-bi<@zTz8guN{BGBxG!nl;M&1Vyp|!NM;_>)1le6hj z>`{@q-KKKgH?PmmpjREg23`^PUMh-;l;qjBJwBJu7L_!Ni_32M)v$*n`TsTlaC>&S?@#)P^RoKFRD{XZdv$fD zdf%7V94qT+h*ZlspYjYIYqj^7I`~ydNvTe!uNMD;bsX1u{Q>ZRR(PETD7Pr&`&SQ( zuR7V_Ve4`W++Ml(Ksgk}KG zq`g>G9^v8byIxlkiNzUS03fdQ>NaiL5=8pk*!1L%_pX7Zrl*L=X-(#8)?%C7aKSGm zPUv`@cQz^tMET>Zqsa12_g#WK4F^g)l!ar@D_(cfq0vAqcNaIC&zEHTo=>^iWuA{) zVVhPk(hFQE=?Of))4gCwme@=HDBkRLr6tGL#)Jnqb)xU{OE2B(hKw(lUpLOkjt*Y@ zI}t=z@~w@shGoF{Z78yoTK(@&X+b?bl?RI+rTz#n>!L?1I>lkS%0f{LL_2faJIrFj zT&1q%u_fiC!eX~oegcP#=XoHZhqu~?bGmR#LrX!|m_;`PdU~$(XuX~3EnN_<`cf3F z2_#)5ovBP9l%yg{JBy{s@c!4+-!!hm!k{k3oh`#Z$lvTyRs>&1luK3;^a87&*a;`U zx4N8E9UYPGo+mh+&3a#taeQhqF)`O#?fHQ~^6>E)NJuc(2uV0JWVV0P>A#+(Z#4|i z$Pj0Vdz^kmZl($_kYRxz=j<4(euJ>0=!t&zf<(=h!-_*A68aG^5 ztyXhf0NV1%9WpV$aJvZ_urb3D#b5P|EJ{h*N4|yZP63ZO9lTgM1E0~>*5=*aY+C2~ z=xnG+;0N#OC>mIq$(!ADoXTM3rl-%34o_TW$qZlN{cS#rw^hU4 zXmbP;ITIzD#qJd{agcK)dlMHuv>|0f>a`T2F))3g3TH$YqHbQu^J+~@`SN-Jnx!3M>kC=31H zh2i*M+(V;48DF=>wKu)r!2U>ON7U*z8%>FiT{JstyPfo!Z3@XX9yeR68($EZsc0Q2 z*$zK!{?G;5)Iqo!jJ3l7iL)3AA&-#$)wa*!_cj~l5Q7)V<^EDjy`*nd z9<6lL8KbpYfnYS1S~@8RvgYR2sPNql8PD>(!|_|ZAEoQ}+zv$7($*rnXiSmg`P+I$fG`F<0(&Fwi7Q=?UR7OvOvTqE4yY~;SV#PTDmGhJDkE8?W58A%jn>+DU082@7 zIt#|s?6?#X&nu$W=@3x7-}bqH$I-?~tD{UM6&(hkX%-1!Izby%H|`%}^w_1%(4r=s zP$+n6$KkBV<1%93I0!K<*jw?xxtq&&qvalgocJSXA5BsR1=d05Iz_>>bh6Q z$92bxXQM0^f2$0>a#1j+CAlSeGf?-v5+YQ6~tn*T1_lb zhCky2Bo$n`&Cck?#mU`4Lpz^L7du}(GzF2_wFg{Yayr-0&~m$|LnS;sZT&uOiQYid zjHFGMla#ZwwLH5#of}FybOL0?a6rvNO&0Wan;{)p=Z3a9OCvMrL~BAY-4amC3;pYr zfUvS!-P!fo!rl`2VBzEJIPQN@bPisX_gxgvO>Szc$((Fklbc+VHSy*q+t!n9+jdQ^ zn{C_n`+NU_*1D^Ezvt}z+51#aGsOz`0r@}c^E0gx+j%Q%KiChe>4iv08qKZRRjuU! zS7Hpid~1Vq#(7rXJvkpud^hSYi>Zb>&b z`o;H8sDhrFx^{X$_GI)@wECv!ZY9@7j?=%DHi;&!4S;K$y$X86R@|BL3up+`?6(_M z9r9SH3TpIk_x4!M#-4aV1fmZ_Z3N@Z15rKP3)9MI6vz=m7pWgWH2*_c>~-Bcg+ z*rP2Hu)4x`C8+aUuoN7FMa+dQRZ-enSYCd6vws#|hDdBn48N|H5#SF6q^JPMmyeHc z8z1;%sKkO+hNhfpzwClyrR1eYy5dl_i<}?dmh0utC=T3+I^4a=uo|#1k~Mlh%V_Cr zTfO9@r4ewg zvbD4#2C4nLeJ_OA5UQ6Few*A z2;uzUv(v0qWM*Swx-b@8DJ6_xmY(WliG${s3H8fnkv=q^lZ)-~?!L0RG8P48`Vbi< z=IG+YH?5SzX3gSY%}o;Z41Ym}pMU$@W%Iqic@q@{*-p>ozOvc>p`cKY9as7X>lG;` zr9A)Nr?~}H+xJ9K1m;0+u2UEtSiBJC|P6$XPzHS?eh(K}^f6J?{KiwHn)i41t{11LC z9p{s|Qe9nLEUbN!wSaeM97dgvgj60I9Wny;uBV+sS#YMnVlD%1D|ECs4*160|G0V2B!J!qH{YL`HUY!s5k{Y>}R> zQl#-9Ru^P3>n~;&cF|gL3%EoFijYR5$XCNej5F0?hpY=t&c7EH?3lg{izrA01@+eV zhJ(s%j3jnnU|U<)CaI{3?;M?UTOGr0E3>k)TsFKOEt!Dl3gZm@bcoC5>8kVbdoHKu ze;@tur~ppCo@tiL%exYD`@(Ir`r*{jw7HELBlz%amQAyVxS*7h_Je}b^KKd*5|Y=% z3cd2u=jj@-7(&{6@>|>5);rwyJ6atoqD<=`Zy-|v`PlFVB6VkH(A~pLPhWobC7pE3 zyQR4~hD)NVuB@#iPnj&y_vkdJ(8&@plS&~ACR9sF2{KzzUEODAPnvmgIP{Brsqarp zxwOFT*1!9s!k-ZBuKK#?Rl0oFg$A|;;n+-?aq*e6b5jrpo$}hHgCOy0PVs?sq_QF- zYxy}F)+BSco0E#e|O3rGeEci++hA_bX#8CaO zQFl~+z;0ygE$aC?+rM=8`>nQns^||b*)7~+=*jN89e@vgk;n`h-_R*Tk7{ z9E?16*{B^{TwGG6_&!U=;|2oZ*0g$ebxH3I`TcmO19kb7%6^eW8=vUp7l3+uH?ZGE z+3KLBrMnj1djA8aqo8nod$Ny;LV23n((dsEU~D1+B1A;wor9yG;9&U_=3Ek?81WNC z*vLQb7PRz=e?Q*|KyulEk*$Td%bgXigf-vm%7O)J%2UvsFb>AqkzZR{+UmuN3gDe+Zln`h`o>=kQxDsiN%G-{J3Zc6SU?_mK@t! z3iuyh-Cv^;VFgyt&dn(UKU|86Fv^f|3{q2m?QwCGEp2T{2}#JcUx&8+{rmEVqWu`` z$LL#HTfwP(#hv;2H6+=;H5{9oKcC*w?ji!5Z^`Q|FT0ABTv8>>b?v02Jaq`{VadOex)7kWa`;1YkT3?WLTs287<<-|fC426_G`FQrJT)pc-#&Plw>0%V&4k@@oE(*mM4ndxpq3GrIReW{PP*D?~Qoy<1(6%?_39- zgO>*q2W08F6#E<6+gdq6d{OXlG5((F>c17m3GuUiXYo#HFjQiq6jW&vQ0|>7<{xh! zu5T@EEbz!^5BE{Hwqk~I@V;YUquwehX~|@>0X9u;Z|>j=Z_?)KvdHEY1YyA}-yAD5 z_xG$2K~k8piGIw*gm}di8eExDRZ+{Y-{UqF%M$i$@K(h3?sy!u(zO3Fn%O@LtWUge z1LpK$6c=2hMs(MDI2K)5S$VzG`xkWvg-_zhxo03O2dVj;9vR(dAOql5UKZLf?M9(> zR~kUGVVG3#aB#R7*)nMA4St}d=M?H?Bd*}dh!Vi_RRas!N)o9?#^W|LWkhZP!)adIk= zL~@w0r^FtSn_XMGXhOV$+DWTo#f8YX=ZpHgbPn-n<`7*qIV4AY?S(VbPG})KgA4p>kc7WXqD@UE!nL`%wzRY=Nx}6a3)qwU#2t%00Buf=B};#- zsHo1S#Tw2;STfEV5Co?nGC(3z%$7}+)>p-;tvmv_-F>z^(oPNz#X^DTP!&7B7?pOn zj}a=wa3Dy7NH<*hd1T8&@%Xq?G&L00jifTvCsKY-}l zK2CMLEAn&L4iuTtCH1>y@!IRy8A8vjR{f_>Ctma@p336)M^OK z!SUg9-`w3>Y&SaoZ>I7G@&*{|c0q}(Jj_32WDqpUAkcZTLEMF#c&{KdEY|g+yEwTl zaFpd~sb@UTG|+ zdz?(+cUv5F^_75tAB_P4=!(lzB-ZCu|BZM;Llb6XfEvE(aj;SjZfy89ZZcO95#@`D z_5`dV2#4cho?cvREGaVm7zqa=RXuupI<4b~%^_x1o&=5+6$L2+LirNCt^r~k@oqkT zB7VKOhIU_t#khGXIl=w?w|`CHuzE{piy)no;)$dE)lrZ_<~X_PI~}f=uLRT*vA&T3 zfy@{eh;I}G>-@gHNqW|eWWEG~e{n?ID`?oc;E4mWdL|qmd>-DOYl=e9&bYSs0}j?5 zRd!nJeO{09WAEV`qTJ(El*^>6F+F)BInKSLY~k0^Q?npZAd!kSa#~8h*zCJ$qa$V`Nh@S8^o7a_$?JtQPCtu&5R8G{S_Q#e^sF7 zii4dKl6qx%MHKq{%*u~b+(=ekS|=rKWwl>wS)_}Pmk)1g4^_M2Z2JPt3DQfQ!66Z{D0}OBjJuRxJbaB1nf| zx$i%@XbF&KF&oB5o|B{GSIt=?|t2?{y-yea7FZR;x z-rP<;A5HHu204^_h84uUyd#R*C=gtF3RU4_I+H_2|)+qL@i5lQ}V)w}PTr8(Q=k;#z%<+E6Z1 z$nG}ig=6K2OF#2#hDOwF`ZJ(i-3>bm9q8%X-UF4QmZQ=_@T%#E zu3;+hel|uK9vW#Nh(AdV9sYH?*_+V%k|*Nf^Gpdwza+ zy1QlY>5-HPt@rx+9ED4GetJ4PJBw88%)(LGQc!WJW$Mkx!=T?}+>aRpABCt~u3?*< zp8mRQmTkN7HaBfF1n>Ip1k_AzcwA-zIM=`eIH{6*s8q(pU2A0~D8d|xSrE$ufP-4w zEoB&9D5k;z1XUpI7d&C9DG&&A|9tNje43JK#>b3*Xj-^K!WmRZvof-j^%3M|htZ4Z z{nMbv{aw zQz0p3=#uywOd5RSW}_#AO8(EB9CA8;2*Tvv5!9#hk?*g&zHV4h^6%%0Z%Y~7=<*a> zE5z&qe6%~bChR3Y`p=;$VHEdL5v=(?4F?#Y(4H1boH8*BhZyyO* zN`4!0DMw3~Rl#cQ3it?*K?BEZW?3sYOv$1w}nQLqpK<{{B~j zZ^oW9>;zt0UERM`e-rV%S=vh@=rvV#z5~17=W}s3K+xKBxiuCSn~Db|fMy>qRv(v( zv%T&oeP*ar5stk_E>R!uo2(s|;TvttAR>p@w6iu|niV$O&z)?#P?0TkttU3t+b`N4 zC-pyfZ#n&)?Wl#Q@c&}t5(a$c95;ay34`1W)Am)w1&ox-uAZPSQ2AcXlP5Br?ayY0Q7KiaP;SG zBLxP*#Nc9DcNm^^pRgd~az6D(f@rRcW3YMqjLTatZ8W5RDC^^^5*otn_%Q zm0au>t#QCsl>v3%&6UpjJdb(Vk>D^{9QZ?1S*>({Cc8Qb4!u>hd#v)TUHi?=Hm<2I z6xTIAr}|^~AC3slZ^GHF&yZ$xb?%+EODT}h&)J*Q9H7#UcR3E|C#e53i*OzOc0|^c+pujPcjN4_y z6)3ut~_e!Uk zkBHJ&Z=_nCE@LH8&$W9{(1;TgL4P3=6!hCQ+7~$`dytx(oVN(Tlv;fs*isU)bNfSB z1~gh-HvyF#d@dJYBM}~LC`eDIW96ju^0CoGIvgfVrdc?!R&OBx&uuZsh*naO3udC~|Fn!|XLGgDIw zvar1G4CMAgN>Lg7IvI$Vh?-C=UTV>hDF0pqrP?*|C4qH5IN*#U&EV&c!K^3_o@EVf zQ2k#pIyxIhJ(Q7QzBY_Z>}&=pq^s4+BT9Fk$UN``0Y}RZJU{OpRlT%YxrnRz(b_msthlz=W`xSWJOm3KL4=B5bf<@9;-FBYr z5#~7>d0O2j7_20<-a=AaL9XT+uCC?{Q)d8uS7Mg!)mBq;^-AorXL?v7neV}?Lfb^iu6L&J3e>u+-h;ihP&Anpb*ZAQQb{RYTtE|_ zD5C~0l+8fZ(9(WJjafBCr4(9J9;}t)PvzA&Q*p&UpXeb;(+t5%+ zPR<&nnW~ED<@=S>#mR|KNRX70_N6Ss1`>+j|bMB9se3!a>w%d6|A!te^5bkNI z?q8W#hJDXDy(pK&Z66fECBAVcXgtvt}tWWt;nYzWLxYdgW8j00833NuJO zPF0LxVc-6M0K=uee#1*rXOdF`%d3;;Wgc#8TJ4H$g#Fy>Dtl>6UETE?2L}*BSZ3!> zDKUyQBXy5Q5haYvk}uFTln1->6N-Gui*-w`s8Yj=kX+lj(Zr6kRxT= zj35H=NdRoS$F)T4c4ICEdvlO72 zESONj`xLGi5etIdVEosF+=RrpfO5;e?c8lcshIGyhT6KeXc>Amw8!*=iA)wREf7dk z%U$B9SAWkIgn_b!MOskMehLeVproz%sc^D=VzZJYBH=B;ka=(K zl1l>@nS5-GUOG<>M|k-7o9^#XE<#URN3rA$@N_7}5Nw{e`^gdN6*?_e1K0iVCNT6g zSm8H$WZLlXoX9c zZFdhn&8{?U<<#kn9y#F%T!FL!bqgmqx94EF^ecXVwwqT|yFHjR`x&~v&aQ*HNXLKTaJ$$cT%hUvwgV>HcYfvlA2)jNyMdn%N(NiF4OX zcKDm~&FwoMr=DzI6Bv9!GZGI>h?M}7osf}PkK)OUOlJi$1jK-H7aEoR7EI3{SJ|0S zQCg)?)MXWA!30w_TP4I5`^|IRs z7>quQeKaB_KR%XmKHr9(5OzzCD6ao(vrkUki>RDp`$AN1d>#tH!@vrB>`~%Jjn?V| zAs$DAM{sYipM5;#^c8CA2|GpNUGIzgi+Nnpx^8B`yE3tU_a10=dFK|4Dvas^{2$qx zmE(i6`65UW5D-#%Je)l|v;k2X`C$f&u0R>&ph9l-w&r%bjDf(qAdMN{k~OMS5YIDF zbnCH#*HlzE3%A@AECw&O*q$>{Fal}-c&vMn(3u<8L`d9}%r?MU_=nI_OFB=UUVS+%<$MpWH9drO=IAgEiMF0@M2F9lSudQXuv={Aw1jLNu{x3k;Km< z>iO_;xjZgzco$a`-0dG`oBfiA^RqaQ{OZA~q3x!-YK}{tuj}$Q;j$s<{F0FMyP&Yp zcD?QX!egQ9apTo&GW(MFyTR$zd>K$XMC`fMHIdHwE0uM>*#b64UE9M$%}LJC&|c1( zFp|TrqBtakO?%qRt&*VM-%8PDMXt5I9lr;axgQM1cAj1yIbL~9=pkC`aG&21M*_Bg z0C8JdS&=!QC}Grn@j2^+H&9i35#&Gae3ZWIgp#J7!AL7n#Y!YAIi(G4qow|%i65>} zLQA`j1q&smBr3{8np^moHD2)Rq@ejZ%R&C&FWV0on8o+cF6cmG*8QYr{z;FGzvnai zbXW5IA!tC^;J?zk|HeYUk~?2)pjeHfJ+QbaF{0V~ZbORHIy2!l!$=stV6(}i~2EQ?2Ud3m~&j@vonb?2^;QKs%XE#0U?opg-c zQgly^-LQd*5wvuAahr{S@!r{mlAac##(-079xM^015tXj?d2p_mHwjQcLH(DuLgY& zXKSTr>~`AQ&&i!PHw1c;{H3by7iY_|$-@Tw;3~$pTuJQz%hK}+BenSwF`TNiL?Y{D zxzhNGPX`Cs1nHTXl|iko@%dLxVQS4G(pRKc;HT5=ZF!OsF*0nm{R1qZ?iu$xu9miz zrk19!4j%rxDLKIb53L2v2b8{Ui{18JYW*Ax`XCDNUtnsj0$0UOPv;YV7clID@daIl zXFs4GEw^~BIv*7I{jqPQ`ZwtPc8u3F$zWSQD5`*ihlfY(WASnPFR%gsoeSB3X7@l2 z9bsuq&n?_o*SZoIU7&( z%=Uq+_Qm(KnC{y|CDIc2_%V?pKo|3n>j(2IGODs5oCWAaUbEezcj7b^_1C2^bfi47as{5F+U5mJL7hi@#Y!U*ubGQ~HK#N$I1 zgZ-AlCVbbtNAdRle#oRHMNP~Y-4Tsp8m)pX`CP;5=Q+B(JZlEd>=uSrdE(B&*Ttww z95G-Y0(7rGOEshxP&RojWo<=8*zAo}T_UpDW5Ye@I5Z?ZlX1Qqxi|jp1RQY0%0L_F zDpP4WmBWFDlmk4Uwxv0`9mCb5^(N%__cr^zW^(kR3!9nkkc2X)rd>LEcMUPu@dD{J z4KeJGr~31_%B@iTKH8{0OtJJ7zPL4-FfL@;RJHY{@<4vbA?|niv_;`sj<$x83-LiH`)q z#zSd3RHfV1Kzf$XX7*tpezrp>=!%{UYl;!<`8;ESgv~(VwN^!;pBQ0P-@rq~Hxw3L z7uf_EA|r`GLJ=>c{kPP=*7Ut56P+f5@SAV|WeF5b?KQ;2ojTAv^Vjb0H#Jo#j!KPt z>CTsHtzM5dYz_|Q)2np90r|c2ZRHew zwMG9?kJpC?@oKnY87^2t6ZhDT^2S(<4@IuB=!N%p0d2g(UMP`(mj33|zgqH!H_INl z#rWGpZ4IqD5>ow54s#byd9EBZ1H7R{C?|K)H(nh z8KWIFtRC1Ydx%Eu6K!Y&ln`Cr%*+ge%PRH5?95(xDm6VlnzAyW661nYMMXLppTXK1 zXp*4Hof;U>Gz?C;kx@_>D&+CLFp48!=E6Q5|^GtRu?gy7aT( zUGQqcuJ9$M^?Q%N6DVq~W;%aq#O6i+6>xFS+uEYFyfpV)T|FVGCk0YQ;9<}6>7Rec z+U5?bZ%F6sb_f^@=9pLe)avpCmVwWYBXaI=0CoKKr_=h8u>+y=bSANUIQsI0Yx7Un zj;g4?D3wsqa(suahWtz=P2!1OUZg@o${WKZlr=69*2v0@CKf$s;^Nv7s+5<^=&V*LnVkUzO}zUz zCMXs-pU*R6aKUhZ2>$YZ6ziLlqadVjW^Qixa94`9`N>7kXdJ;4f+nQfKmNG`iv+;C z_p7}DVF(Cs*W#mPbSj_uqId%kUWZZP@hBAyzg@Y4HqED&P1sB)f**a8dwO?qy03NM z*M?VZyBdM^jgEKEAB}PQOkLEarK#Pn(uz{%UYUERlZ(#Iju4Y#(F7n18%UUek}qS= z0o654ji+bkRGi`;_N;Y3ZCNZY@)s5sv^gt=*452pCWx6m9{OMz)A~5fG5-VSRmBLt z904y}pvB)|NS2$M8(KQRyD?}VSXpVKFfY#!V3HV=xUjJi6x;yf&n~?1yIpi}K8eZd zdk2snhf)+yVqE5@-Z?+s;Mp(tkHZ{%*_6I>4(uNdoeR}mF6wu$w{iU5_-!}TWKHaK zMJoKo6*k*p%yq{1ev6!q-^(lJA0hR@iq~wlsp)~Rg)ia+`*@!y(ykE|4>ylmQj#9G z3w9nvPTf!UZ~wM^-!hywHTWy=L}C>JP!&wvKCgU=EJdR88L^ zti(K-SgDW;-MbL0MyCpE`hWm`pcV1m)9a!Y*|Nqp<3RWP2!(W{mW7Ru@5jD{rX~-x zma4+AOQ*m(iH5hgAR}Xyak{AiqWf)+m{yf6Px?RDcBt24jAm}0c3(Etgk&oHuBDBI z!FNQ#mELKDE99c+M3I2a3C}ZobuQ)mrrp;{*PFLuoXIq{q2Xckesz5!A$LchYQQ*D ztln{?FDNID?MMnjN<-FxEj_h>{$lh)BnLyR^a`t)U1#w0CEwT`{tgB&Pr5(xpSX6n z8z!{hPPojI0A!}a)y<5FZTBOQFSYrL`sso$w}-^h-rbW55{XygzySQ?JK}*PMhQV6 zFxkmPMdj7ad@LY-gV)m142lW$w}cfhEw7BFA*A@};^BNTn$$cBdn80|yEl-hCJ#NN z)61~dVb4a+Ru2%2RaK~>GsGDui}2RmAyYL||7~scu9C0apC}X;FKaa%s8Qyld>a{L zLlp^N_i8o62hLrbgFwezHf!Uf;NU6DiI&DKSz)?1fBzgJ(v6J`iubT$tVBn>PN-4u z?Lw2REWLJ@Ghj6NxuID7`3NDOyZtp-LgJZcxuP(xW1?Kd&K1VhP#gp@b;mpHt$k`e z6zJ?sJHdCpT>7o0eDfhmESJTK+jhONTHb5*mi&t$rMuK$5sK3scsCc}v6{^wZuRpVO9wg~P8;AuP;K$n7Z>x6-<@C2k5= zovT@WQ)8L#lwo*mv+17Cztr(wLM(=zg$*l0tW`5rCx%Ckfg!iPKD}KsQ!Gw_d~5B3 z;&n}0r5NnyctI=~Q_Ifz(M!PN9l3e;~zIORJ& zWF}gnAn3~J{N=u4{0wM|h?Np+gkmm7N(y7OeQ7Q~E$;MaeVff(ZSsMD8)$nJYmgU>-K;c`Tz0(ZSu9NP6r5Kv2Wm|qSVuD}1 z)JJ%YPo#N1MOva!(z$j!dSVF(35D{i$glTC)RQ{dO;#GjWwZPe1D!r^W;v|S&zqbd zREmUP!m2B%`8-a(sgt241dZ8PS!k)NkSF5wIuL*3u$b$h%9fFDbKILU48nz5+tRUl zV@YrO$B#@ACtl>ZA8u%4!)ZDW4J;&3&`=>8O`5s{Siie#OA(+pMet@oJ+M6=ee2tq z_l{0jTFV>3Mq8Z_0^4TkM;5l1XBX!S^TABhkh{|}b9J?~{xX~EivBx0J7dZ5j2Yd& zeADyG)9cIg)8gNtxwhQ3Xb;(mDA{mXVc#IN`IWBjZ_@>hBr*#GulImSjP=98z@nj{ z!S3_!9;Hk?v6J2CTe88;T}UsV{n8LB@#rsE4rbQ3r`g6{(%vVCsou4-v-c2G5yz{& zA4u5#OB588e;K~cA+#Zm=j)}Jl&vJuv=IhNBm|R;C3Ft?9wkLih9wGB`HTgjz8h%8 z#%I>MZuh06q%?1O;LOBlB{f;>k3K9c)M8RbXR}MwCT>Vc^JLn^by9g&bWYV)RyLM) zWx@2CKug5E!otb{OLfx)uo0BuFQGU=tPzG5wJd!DaSGpw3XyO#v$9&OG?Z4LKFB8* zRG|(j>Z(9@Fk0J?_JS|u39X-q8St+#WRX^8m+kD*yv_FT%YN%`0<68x=9Gq-uDE}F zXXhN@J>K`8Cp-;Jt)5enl&ezU{KQXB?WJSO#i~qsek`9In781V7_<(CLo;$wQ7IOe z!qA~stN|8oc4VUNiU#(3t#Gj{xS_5zEsYj8*S?Vx?&`M6$1A!c z8xd}vPvZQ2ue>lyZf;oV06Xb$GK2Q;enxHTFw7XI1USO?d=_-8V|5bb!#~+37=y=w z0YOj6`I~$10Pc@H7EBRVbZFE;cp}j^~IxWt6C> zc{L8jskD`qlM_77fd5cpDALCS1Zp6iojFa5_Rvb=y1Ke9&rfPFb`|_D>{t+W>Tt4N z;m5}NO@i#8>;G1=VmUKF`TJX+oo{mq6Rc`$x9F#)rG}soo0=U$^f+IyEw7~Eu~L#z zI$zgMrloveR8{x60`mbZ$#qy5{XCR8zB4-$UwV-OU9Q`Y7g;Srb=49~xkM6~-la|6 z*bhn7(7HB~#G9eiDPCp4-9s*`gN=-dfc+iBai=eY1i}pvNoD0_E^kjpGldbZP4y9D zCAGUE;`V7=)w(A8QBZF9q&O}vz)2L~N=`JvtUR;Tkn9qH*ObTf6WtfVqa-?OR5 zTavf6zB@G$GGc_Co}7A=P;K`$j@NGaED=dc<|h8o1gdo*+z?4=K3ZQ`tdkFdV&!e0i9VMgi;U{|MC#5=5U0I2~ zS$O^$m#yxAiULf3?e_)kJelbS-S!-O^w?H5GmDa#syfBVogcEMlbQXRf=5@;)~lMm zm2K?kD2=N)WrRrjhA`0NA){}`&vez}+k|McoV(GIg=E|AHk+Lh&Tmv&kj@`FGliAb z)-3_m4ElONOQ(s+`xbc&cWVnL2Unp^mnX+D>!YCi3!M9l`ygczx|g&ZNBPe8lFz!M z*nFzN!7Xf`dJvls5ZSufV{n9uA5Bb7hJVURNrfq?$;BZ7 zQ@s=O^9u_Hww*D(!s>wOU1cjG0>tQf=F;mvz1IzRNCKTzZcy}ci_3Q}4orU}DMhHh zOp&t{39u7#l@v6v+gxtc)qS9bnkFS}?YB5^{P}u1TLpnM!9Y)zFBwh1K}$t>3TVr= z_&XvJZ+3bzJPHjBjkLlf3Es^5EOGgHjMUea_4Vc4;%Xm;d&);qTP~MWizMl`7`YVo zk(EJCE-L(w%!a6)LqR~L*VgoSdC^GG-pZV{(Wx#bXQHQPNM`imVW$3)m0M6_Fd<3Y zPt&hdW8Bpbk5=V<%aEFeVr4@p;62VHY(4)2K20rHlfwq(jVQ2u&Hs{>Fzf7Ukn``o&JDx z!mF#JtCNxW2^IDp@$IK!VnTwcaRJV^Z~KRb`+IxJ14jn6E1{vG0z#i5(9m>x9=c*m zrBI58V!!njCWW~FEze^O7LhPD$Br)?VGZ}TW%-Fnxdv8e3!VMZlxFz?H=FIIAb9^4 z!Q>mWE#a$lw$XaJ%VBA^m`txTEb%hxD&r~}SMr|4=fc>{7Jw*4v+4S^WUU*Y-AybC zv2+8Bk4SF_iA;c&oLEp3H9Q`b-Tm35+m1@eA6kCB!&(P|&WE*nn{RU}mX9k6Akx#z zAB^N^Zm_bkXtO`JkT-=}{c1LplV1)^ymN63YoPK2+sv%MWz^%KEHH@qA=|4qTE#Ra z4#q;JVZ@xzi%>vUo$GOUczZ*zOHWTRET>yftTFZbS5kvS64umsMwV9&UPvPa|yZ$o;mm41+mDyR9<$V6LmYEa8s2f4HZr9tI12>-Z$TjcH`0sWws?2(u87@{UNt%tJ%N z%8Qr9?{3Wgme{A5``T#^uN~(pCrNX~4|fU@H>wV#Yo0Z2uBg(jz4 z22xb5fRy7h_Q+vW^vmrkSCW80N~n7bhso;o!=p68c(^WQJPsB~B`zL*$8|n^Ibau? z5ouV6WQ(aK|39ju^xd8cL@f22@@lTQuCy{;OtXn?>fcpb13Q1UIjso3Vl_T3n+fm> z;Nz!0-!yBhi;v=@1N&At0JD5nH#hJojWRtod%A16=Ps3 zP*K!SUB!!C&RbB*$^@5yEJTIV@X|@ZS`Dz&sopCx=~U(xJ9M%)%z+6FQwnBzsV zaSBJnw3VdRSCBe8>%G}I$T^6LF(+wSqiF6=5$|hbtQH)rEhmK2`GwzZk9koTWR;K&O|`uaYhe0e!FlQ1(}(}gv) zG$^RJIYwZve+pubj7=cFD2@GhpPc(atIv2A-w<$z0TE52)?}Ab-^VAVR)Eiic1_6y zqsM!V4QAk}y)sI_T7U9aq-aIzBRO9$mwKhlFDV0)H9Hckr^{yTrZ?v!MLxN7Cwr&+ zo9jkQ#B@A-Sy>rc8CgwP9auit(_MV@BjRsB@Cwd}H$H_r@zK#pAwS4msGM)>bg|m9 z&W%3}&)V9$&}1LooYzu9mLB6LTBDRJwrB-V3Y)u5T>YaXBXXN^B$$`}Yi6TdO;cSU zoQ8&mZ)Zwc%GLrtEF6c>#3C1P`5#m@GyZf)0RC-^D7Xn$(AP6j`%aGT#_tFz? zrtK0K&t*%-U@fnI)g{VdPPR@}0^Szt+__TLt z@cHoLruFohpW+9?2q@A5#V~!xK*zTGd0~Ffm}H4&wn!od4`p$BYRPr?V~_LDH)Y!oyHRn&mMxIi1g1LI!?pR->}&qq0QR=U-A8 zyg6{{0bfJ#34d;0i5f<#z8gnw;e$`9w2jw}6Twqf&WXcUQ$$1r==!p;LA@r(wE8+Y zt{%Cl|E`XTtzZFb!8v9(a)*MFYn-(3o5WwSZ2=pERqZ`IG-Zmy-a&yteJCUPCg}Q>C zZ-!&1&%nLZ@>$>W2^NVdX2agYvx#50^eeubPxVoz{-uCc9z$GS=5^ibIfzPMnleM8 zqvLWx!{Oqx)Ydkjm9_@@BS^jH-7LpMuTeCk3IN0q8B;h~b>-KeNKH*iZz1q{u|4M4L`-MqB-E~=3t5Ir^C5W-c}0f4E8fq{pOsvVaeudAaMP`$v-l^ zF-51HVLxG4&+YR(2^Z3fwO77%Mq1cZZ2+5QO`H!p8OvHqB92n9s;Kz?T}oJ3c*z(% z6H^<_O$e#^l+4sv=UWLA&D4&?z#R-;-v37yJlvjNU(|mm;Orf4zckP6cr5?7>+xBP z^^-ohCEVD{3nH3;%G6p!6`P^O!?mrgJ-s)~5`=?;wXmSdH8sS^?LOlF%AD%`k&cGYjy4+)Qkgn@}~bh!oL)T2NA zIDmvBPer){4=V#FYGq(-ECYAM&BN1v_wX?HTWuRo?QwD#>kFJI{4G{MDenk31)pH_ zr))UTN4T;sNBL~8?Pn!Y@rv}hB-D0toVUG_MTAj*j;3m2Vv0F9;p*Z8sZUkeNAgSp z;46GCmj`5b3SbXW(z22oWMmYPr-lZ{9)&h(qpxgJO*X9DEl~qzt*h8Fa{;}~kHiz*8K*&h*zu7R%L~ABJ05h_gzGTU$5xGNX7D~G%P9iS5RA)t}CmwXN`tN8GPvI|;wyp$N58J*u) zg@gf)A62v>$mf<;HE}XAaghoNZtsmm>H7%8`%}9V^LzP1@n z{0gkQ&Q`17G;g7sEytEIW0@ERHM5#_aErCD9x(C4<=N_u)~Og5AgNFMX|{)*9;G)jaQ z_Q4n5hi8q8+JS4VlGWjyaNB>aMu^1qymL95%|U5zE>^_(pQU0^IYy3V`9gfja6OT^ z+QGrDDHpL*LdNil5mqpW>{xtDX{n{)$Pi;LE?JXz1{hF-UmI$e7?ks>K0l+rwRL4r zQRm;7Y1vM=F5t`)Cx=r##23|69tRY6Tz1!Fq>lutns_5r227xE5)><=hW%J$dv)N{ z$g$-g94x_jQAL!s@wH!41Kr=yPIe}mlNJ6TnLSLN`>Fw#n}JB4ww$*97|%yxo@SN2a0FicxDHBEl}&|Q~V-GIJO6>^3ma>zq! z#u9cWF~*x>m%9Cpg6vl8E9^sdyu$l8CU+v(LsL^5#SzC?1-&5J{R^3L+Fuuu{mrc| z;nLSO0LihDN6j{}Qyg8~+#FhjPnidUQ3WA7Na)z|TT4sJWag$fmS@%|w)Wp>*6?fY z|Erk_W2yc4=z5bj$@Z!;JKigH5fJ(3{cwtNAmF<&wg++c*uGghT*o>~UxH!jW){i*Qu*^htOEqOf z-qP~C8jvz4VIKbX4`}HtC@DdQ;1goP(F?VU%=U@K##x?w1=i)P%(P zc`6DDDyn`zWa^B$S+-{1p9_Pxezo@RfcOTS*T_XMmTLHB&{Qi=_CJo!@uAYL zjpDh-p~67^yPHU-q&8&TEC?yrEN>GeDk@8 z;eTeZcL?d9Pg>}cMw`DL{G7(?Cs4Yoo2bU#H8V0Y+z$<+qbncsAe9`2VI-4^L!3A{ zr=t1Ujc%2jgBJUS)-xI4Dzd zTB@R<(t5`HpZxQEKjho<8X`mlph|QTT6i7dsfgL(@imJ2sGqd7w6_V4C)m~>8)_Sg zaW_9}xi*0yBanI8DWTS)(&B~FW}tZ2E4%m^E5M%ZR~eR%S|gYrenxvyzSpeqzW++y zx`?RI?Z0}ob8xY{ix2d+e#d0}QPL^-ktm(kvD_qHP-3o>6Mt9;df1=(_v#_0~D!RnOPkhpz8c_rc>RW?j>8@!OF0t$&Fj^e5{HZK_ZMMc;?LxG76ef|GU2ygM2ghq1FX6V0btsQ*%p{aD5sc1&gv0{ZVhuvt zcYvnyJ?yd@tRxH`-l<6%u_h`fx7?E^L@w=}WF<$^puS~|fwy68O$*qC0LB0@=kh6V zSiU;~8J7a=I)Yrt!Z80pZJQtGYi{P|WXut5SPLDMjg?^y9ER{<0Ypq-v~+u@D?096 zn&}ds;L#zw40t}m19Pj`?3Pa!@sS=F_TgGg0X4JW3TUH4|z=CQ0S$GF&la0{5P zAlcN_7(xX^fEf2z05fSGS~_Tpj=9(;-268Ifqtj3lc*ifyyND6QFb6pX-eS}?9-;v zx_$FH<>RMMn<+~n;v2%w=_TJU)&Y6m9GFH7JUG?H+*(Nm(Bcp!%Y zbK~DIaKqVn_fBZZ?yS^_oz@77rNbpTaSGx?^<`~swYmQNM$3-a9E+ID90$+siLJTUxBS}-u}rAOl3xmSVC3V*0LF9^(N7(R=2sU^cjh0xGmpIxNM zZC!n-f`oCqX}7^)*m`er=)%Bty>{>BPtT36D$Xr6;rE|+en7@Nz`WSVEEpi4CK28F zr>3dijp9I`#rUhB(~gfmONrR{pB$YnXmJ8SxW}>LjMuz&)xv__te0zi%^KFCy5ubr z!Di#EYf802Ix3l|sVlSz#zux+e-?xL%dO}X%n(LLaE`oSZ3TTxL^2+oLw@U954NVA zwXxLFAs(7tBPjPi8 z(%1Fg_T!mc6sP`Wn!>tLWKUdzj5vFq05@oS#@J5SNZ5$%r%k|G8D%tcN@zI`INt)r z?z!LXBn0NyL$O$N(a1X#L~Pc*Zhh(`eJsa8;(M09X2_?l^lapkG|o?Gpmx42x#I2Z z?R3#*s!IvBbQb{uVYS+VBB+Nj^C8sWai06w5`yWZ6=qK@HgXrwIe7H=X-Lw6UbC$y~?)%W`# z?ZoZ4m`vUwY1AU~nO<+rj|+m{u{ra{*$ba8eh}a0)Rdg8EQ*WE1KU;S zG6%<05Wv&f_z1LE*P3LxY0T9Ifj$*(FfIZ>p4ZU$tt;yb3-Apjj*dUvH^;}fxa)4( zL(mgg=2B8MS5}tQ)fFT402BQ*VLn;fcNNShc-Z0fEL{*^!Y_%71Ms!1W*2sNJgfsb zXVuo@vwHX-EEZec#Vjqrlz|^w$hbzaB|vo{fUP744|fC&w*moFu}*3F5MHAsmsIC$ zgkNzxFfln$CRB%1!|Ap+u$l&=vj58=#-Yz4c713*eDch9nC<|UY6rkk)rkS!46*VXOC z#UX-mE?z(U`FZKp$h}ElG6PMQkN5+=s@p5X_SmKi=+I!hx~c{~tPuY!!a2Pkf)(~a z0Tb#QKO!!bg;^!VR0T>g8X6nBHR|KM@6sArlS?uyDhdK$8WIy%PRy-NDv4L5$6d=Z zTMs5=WIo-_Spa6!=<@P1i!#wF3mI8HL-hCeyjH$NxQDvzs;#?YCL$Pea${>C&$yvO zphFOejO@aB{@R(1O~k`8<&&ymr<|ZhdZ1sIeTi=Na7)a`$H(Kzqw8rgrEg)uEJWq*1gui+1Z=45%IUWSih;Y zGY&Q@+fdu#+w65Z-Cy~l6`Bg*S@ z<-XJ+{C>xxf&oM8@>F!F{jH$7D7U$>(A^@|eaXT31qlh9XgC-V?Drv8NcS#}9`Qsb zj|(+%j*PE+FBZ1O`r4p(TZhN!O9Q!7JtH#%D^rydb;owr3?i81tZea=khZf zY|OM}4T)0-aAX)@Vt_gK`OhCPc@|}5z$wJ2P8cizvZ2Sx8nw{qUnK01*QHwqCjhEW zzT;r9c)ht!p(O;J2$_ieMYjB{qM@;{JWm!Qc4Q4R<>;U&z;uPZ{ydAyx#Vvz2xi-_ zTYQQ0d_h9O$)%BJSf;@Ayy91g8?8f?w~r!*;gM24t{t1Rva$m79gZf^XYqOaCfwMC z5GPfV+Ntl*fZW^L+N4Bf3DdFV7Gx-)o>^Ic8MR6PRkZhLGhh?(H9YpJbxwCkFRJ2p zs20L~ZuE?0+)Iu>TAqsGA4#eEWh3>UY=dLS_WMe}lu^t1n#DK=zQT-&%=AU`rV@QI zx3sVkJ?UEk8pb$nAG_d(rpgCk=%l4_-C?_Mu_=UvNHo;VATD56lCshe{sf@ob9kk{ zIwq3!o3cen9`E`Oa5EU+9m)G&ej?ZO&Clyn)Yr#ubnq5QV$pq{U!3(1?}|vChBMG` zS+R|XKX#gqWYsp5Ogj(XlD0c2c>Hl#-PX1P)I9;*RN&57Ci2P5{D4cK)ek$py$`&n z<%6a9=nFaLvo;`sy25L+ui|k!W*bS)yhZbYB0}l#`T!OOFAn*xJm$cmW`p5h9(R4c ztiH^=x9?gQLU2|Ou>$t!MH*roajrC>|FJjAf^6s`;%x1Vd}^HMWgo1sg6mFb8eCtF zbc`T8z+^h_$Hr@>aJb*`$SJqz7l9=x|*BSQy`Evp| zwYmiawzsz*AlXdSTGII6Dd`fvg{P-$Ypt!fd3yN!`v)QsB72WO7aT!7v0;2ixg8|Q zcrJZt`y>yW*F=~@_rBzE4ECkOjD@i0bU3gy77-Ef;tf|SZ@UxDE^$@f$D`V>&`L;1 zP}QSExKW&)kr*9$eJ!hwr=0PTLm{wVx(W`iV#ucQcW(h7U*Ql!zV=OZTbZ)6X| zOu#L7XX{C}kBv-UYa1&Y^LrCKqOq7SF3wqo)txPbQ`$N^+dDkOMMq~A(;bOnMLZM? zh0qbE`9$3!`^LlsNY31Z%>I@}YU;mIV}KoPaY|AW(A!$6Bc3>u*XtWDH=vyUDNQ}} zaq><(|NeDoU;TBM!Z2!b6Xj}taB;9}ijs(-Yhi(BM*&k3Te5%h_epOLnh7??(e#>OTlLau6SnApSsTc?z2k*EU*c`;-Y5H$5a>KY=Z zEtjADx)|jZaj0eP%x0kD(I!Q6$jB7mwGbi!YS>|6-EHXUL7@5Gr!D0uypQuPUq~92 zir}2`1*pH)6VFfnv;pVlU24&ubXNG;Wd$M%K*ZPz(j}b6{dPr}zviKVRab|hPm{|f zGV+_g0r-qg#OHRy9`n>7HVQhQK;=pk#0; zttSkkermKODg?0&sEo%$N7d3bODVZoosUv`Zwm$KI8VMS*JCh6_XcU1Det`O5o zvFTC=n3=;QC34Vo``hbQza)lKqlQC8#{%DCeYDXor{kIY&8Sa1>R&PQbP@P$*1L)0 z>1)6L{)I5&;N;L;UfG)Ih4gdYwP8wlcjmN~#orIc<6xxbG=C97vD?tSPqV@2bd_6o z7WnYo!ai954%`1kHc8$fX{W$D?smg#PysQbMDbWJsM&npPZ(j@Ul;3eGE-7YY)DL2 z6{n5}|Ka$eJ|H0>qCO%bBO|vqF0+F7d|p8aMsuU7J8MzmX5;bFgw8=E@;i&cLHO}( zA&PyvtsKya-cLq04@7e7>q!wZ9L1&@>gw*U9~^;TpRLPlE2W5wi;Hx5UfaKab#-m! z+~)Tu5KlW3jdSQRsp6k<8Hn_RDVrZ*!2 zyNQab^5V2_{|PwQ^T1MH-|8fw<=BobRcoy^w3JW>F$|sc&V9fs8FvmFLg$lt`?4b! z4azAPi%qg=cD`D0?%m`nz$Ujf~P%YD+iUookqh%S+ZO zIderHob80Z9uZ=LedoFFHe0LwAt;!dPnVa(LALhfp9Zy_%wn-%bxP?ovn`cPn2>Nq zrc8UdHZ?Rg9Ao*w!PRO`?3_j^X=L zwuwxxqzl~~_DXK9DJ3b(vBIn}vluMpQ5X@WiL0`e_gVOW2a`8c_jkqQ`KYe8 z#xUpagkmvN**CY3L9I)*4yvpXzn`C;!Qpx@du?#BaU@SjrI8}Y`h|(cV@pmn4Y21L zBR3eU`k=A44c~@=#w$!r47-+Y>ieGFUUHdqcCWW4;!Hu|{4Wxc3KHgIo;AErs1_D9 zE-tFX_{5Hz7`f%;?THr`VCTnE9o7RPB8e)%3&>c=`&)X~{;2pNy%y0n6(fDF_g^5% zVrWSEcVTo?Qd=noS{8j|(DD9$oABx0HgC0<F=(wG4gOiLN1Plff4f~lev`@4Q)+Lkm}~t(%kaAk+HtMjg5(gft53b0w-yI zc5zwWY-yP+j19CA(KP6ti=ZeyB_Sc*LQKJ z8scKF;HKKTA)OaMA}p`0q-tt7IXlIpC(S8^aILIf50th2oyCKM^altVKpA`_!7Es) z8bmO#xbCx>7@ts47qjh@4A^-%2R#qq!jn`d45n5KwdC@qyHq1z@Ldg@R+gR}fkUx4 zJd}m}GKA5Wb&1NWxahm=%;L6#P}*K_G#d#!%GR^;gcJg_6jc`&qA&bEyDSzc6X?7; zG1f+!-eGNZWFUDQfCexHg&Ba=3O1q6L9^NgK==tc%ng+x*c>;9$mGq#})CID(zW^ex>Apt!pA+buJ zY-D~FSg8T3_FojjZAx??=f=#!T9Cg1q_;imLv#y&VyDIuMSSvJJiDM)7^@NRH~_C8QkITP*(6YN5pp zX{M6s8kUdg6^$bBT=dl_u7j4s-U(u3X7CZiHM6il691*f<4jLw6kE-j?S1eM3mvl{ z-vn?(-i>grtt_n|BA_6^!`IZ+DS7cS>}0OD0tdtbpK)<%ZDFm$>V>wveIa<#``Hdz z05r61(uh>GH;hk1WOG7(rMHiNZf-z;QCMAbSsp0`Q*PwMGfbq$%M2r{1PvKS%0UG6 z&!X}By1CbgV`y`?F-op#zgHYGT)qQe_!ST7oG2pPP5AUG_r-~IB_1e8FhV@P#>&o$ z3Tq)DAv1A10T~%jAy1G^Why6cN(LOdYJU%v2Qc0oh z1#Z(-2`_WnjYHa_29;Pt$}2y_8f5gXQ>wDqp69CX7HYE{{Sceau@N|)k=`|$&S z0o;_-E#v6#&jkn6@L{=xiHg^f& zbQy_>i%UyOnrvZ#oD2$t5&av4(jN5eZ9*u-f17QO03RAAk?e2l@?HZ1O_&s8& zrDY(B@bRh_#of)#Ru+(<)YASb1uHr2jhnI z*?V5+rBd1K62z4cB+qjTfU9w5hnbBH2PX{?m)CMHxf%!;^2@1KlKSe(F>?_mLW|Nl z+TWlcLJ&+&j!#UCncG+>5?R`Gd<>K|J3P7lzzo|(?jy_OTwex|-Rpe5_C0-YwI<_u zZJ`*GLC*2EweZtV zpFhz8@Q931XV?3jEwC<>Rj5&m(((fcD8lTIBX2&UBW zt&xQ2i;5`SlYPTO$1w#TdjT=5{3{CnTD!$! zVno{2JHlupfRhEkW8>@GY8_8QK)6|U3fx+O3$P`LcGtHyWb9H+D6TKv{BwA0l6Zx$ z^hX#P*V<6es@-vUh9c8LVY{dXa0LhRrDUcSkX_QVyUi69D^j3T<5en<0(W9Xg4o^t zeMSbJ8Kmrcr{J&bbRl5M}~ z)q20y?2s2kL8W;Dqyyg%Z$Fb+Od|c(rGujmH(^xS*fe1k29)Gg;7=enyu*UjG-Z>S zIoL^+Kp^^k;638ax3MyVhJypQ)b;S1NU!b8Nh}~B^0>xkTlw>E_SPfBky^p49hl?W z5O=`81uT%p!;f>;EFcK-Qr>7^Q?rHVuk2^d}B}bjA zVv2`>&q4b`(5QI3vh#w=@yHgK0Fh*!c24Nr+@`1N2KdrCF zQkdeK!HHbl+(ZO>ij9lo?>6QZQrPW0lnnRqt$qsSYielff$SLMP%?5bzOU>2BFbcV z$R1!%W`Q18Eo1?!VRsT;eYaua_Ncb~o{D>1&c$6Z0ynG(dD9CW&qpwbvlYHkJyN8#ZK=@J&@@)XH+;&{+ykBrVns1fVSa*5U9JGzx z1_0fL9m_5Eyk^3Hot_2;dDlR_&K5lkix#Z@^>7A@FzxZTkkD>%U!Rp`Cy75Y3v;-% zl*c?5H&f}1LncNAVNNmr)6*MLD?`rf&rP#x?~qJV1jD-GmE)p zs8Lo(hR)gXc5~CkKTmuEw0@=)AIqUp=2XYX8}41{p>Dgmxg@%S{|fXoGdC9ux6wRj zPS&3qsBeb|{c@@QNJ_$VYOLYruF2)NzCMnm)1x(RWo==>XTLWD^twhrW}aj+nM?p5 z-&o4mwUWt2FXVEtCXJ^%eJ`T>yW&}Tdd)ztLNHsT@NmbYCpm5H_JV;xoo8gFrK)Yk z0_ob?#>wHKr^yTLDzaYD@TDfBu#jT7UKCo{zj4@1ii$oduStqu9PMmB!HYzhGRPr? zaPjfmO^0`0lga{6zVjV`n|%WGIB%98jP|`i&8P9s$VifoR%%+DfrZKA8DD0jlWh^2 z>U*7mJI65RY1W*%wb8sU!p7p_^hN~(5lm=A>%%e@NGgLh!95(8jOEWr{3I`E^jrd5 zX|TT^pTiz8SuluIH7qjJ?c@0naeirYV4xuUE*wY_`t5xGj)M$Lu0TaW>+MX7wT1{1 z<*#7#^;aZb4|5r79Tn%FZGU|`I{jdU?lQPsB+U+R`dkbh@6tJHpY$vl zI#KwZh-gUS9QV#o{Avh+$ReKtfwK!=<*$^OnCil;%D_NlGd*IZf3jYFa+jziqR+6f z7DG^Q6kf0dU#Fy2T|VD!92{y5L?b<3hAAQ=Wma9zU(R-;PzX8uQhHxu?>=e5_Vw*Y zK6@lbF=@5xfXv#+h(yzPuwE}U4fW^yhWl_5eO$7doZMNw**QMGYTVDwHs^#^aw3d_ zM3tWx7gjR|JAQ(!=?dAQ8Vo#!fBLE(tuHQcS*?IGdcSsoL^P6s{i|r}n?*`$>Ub&# z2`j5{wBpd%h>WD9jj5&IF$xkKGUC-@dtpN1quQ@*G(bUV{sZk3i2UH((Xrw0A^>Z! z{5skJ?5h|2DcISMt_KN}zi1B*X00{Z85np9sj7;)sJfV{Er}9(pRrd}Vxm+c{1b^l z<7_p|&&N18yyp7vZ4Vm|kdl(39QON|&8DiA%X@nEil7O1({j!B;Y=N@a37#ea85B4TtIXk7=e)SL=gxQQYsitd*cF$KzNZ=jOru zS}b^)5gL0&rY$n|yb{=6ENm!`1m|5&FKBfDVy3j5=(2B7NkK|}GQENjeF2a{->(M= z5BUlKPr}7k4iIEi`w-In+z(hJJYyF5}uguQQ%R@X7ILLf*J6&rPfqsaH&VafBCS2-xWj1Fph!79af zK{lPm<;6h1$8v)O*3uWNgsX)xdb(b1_4fnKbR%ehKkYp<0BS(K*!%=~wr!W?u229^ znxAd2xF8!N6JwTo-IuF@`T6^1tR!=DGZ44S!;?)=3MzQFt)p|djYVmnc6^DQ;};ti z<26?bibKi63CrgTP2RJ;&4RyiaF^}3GNL9FWNU7_6ycz1{ebG~7(s@UMbKlRQC?g} z=E}-9^6)fnD(5R#3rR@}c{_0dJ=A0Bo%8+U?TTCn6!?bv4e!r)zGqCpiF1sz4D^(3 zY-Dx|_zJ?lc83)L(zEmVGZhyNtR;l3*GVx2us!+r^?{CxO1t&p7O<{YYtI8oY9~+` zE{8qoU=PUkfa9rd2VSJ9$K>>MthF-?L2KY0y+JN+kLUApX;)XaZ%5n5*Gs!m zNq_(!`g>)CQ{QerUlPmTU+4)Jok5301o83y+R79v$F!sj-N?{TO(Qn(&&dRWIiO^p zULGR67Z;Zg(^Gc&7m!P=hki=*7ggE}jneyg^j-_7+c9q~`wv=uLzCIIad!`DPC2eC zjx(7^*E1__vUB+8>6gZ3Q(j!y0%)@3TFpBEAa+|{k?(x@w)^#Rw*pYh;az#o5fKq> z)1vS>MrvTH+dSWWz_*Zw@DqZtkPst&{QGx*j|lJtJ#VSO$B`ptMnUfQ)OFjV^pEH3 zr@N=E7p3$$X0}+JgnS)(qnH-BX>)T*ZQR5kd!I$tSG{tQAPpGf`+F=9SWMvG0BQFt zf%JRA&QEJ&>+SvX^X+3#7BUmeaz8w8gU2e$>q`*H<| z5~cY^kGFs$Awuvkp80Q%gvHUM@I;^sNdc08aHjr zyM77w^ajYtsN>*FK`o)n|49i+!GY4Cwz@byHIS~vJvr6Ln*p$bt4nH&O3K}km-5uz z{Y*B%j!KheI-AFYc<0-`mFhYE8So*@%&uxigTNXxVq(;F*DJ4x!?+XBJ{~Ujef|Hg^z=N);DQrHz@p`n| zl}!{pgq7uaaC+GI$q*tY<|OH!`@`&}Y`hHb-x$$YPf4d$C|l<=unpXt357LP8RB3-nOoTlVPc3;shsKMF;7JzuzFpQO*`dFpt6(5$g2 z6WW@R98D~ad#$?*2ZptWyNBh~)d*a!0eMQi9gHFiQ&TH5CT7z2{>!96A`G;1d|g)K zxxa|l%Ee|lA%zoNBgll9yhaLTX=$Y+JB9HUi-4M`sHzGpjL*UN0;=rTIXD@i*s1Jz z(U5>Y=cYMLd+hs`RsJ514>`9L16$auYWoPY3Ayrqll2J(W*hP02?+rNp3O^3x4UpG zm>HN6aan;?3ElSNZp8h4v=5HM0feVEr?>U!K!odX;VJK+rf0SDIpLtU_kR5%06G^8 z=O5n|QLx!qdpU0;$TWPns)y)%Towkp%#VHxi(q15@x4YJuJLg9B_woStRskSUtZc= zZrO4YZ|?*keE9mxR9KIXOJf)rvCPls_Y3pOZDG&vP_v5Gg)thdqM(o%7{u04W##Bv z8Uh_%vmWKTjgVgKL_}b0M?e=KD-+XTjOnSV5KM(mJLb1Roa(5bF|l!n^g{>II%<=oQBMl(}FEX>z81&7Kop`q^X;U39T z)VhekpI-_og3DgK9!-2E0bL83O*LsMny8~#ZYhe}?aWnTM41SWNwJn9%XLkYiu?ZI z#0CCK%JIVD;_D$_Ru*e{C$yxD^TXR8S)Y8k_}KI0YN_C;!SfV$qwj5>^LeA|?^6DG z-N0_`6!$xNtnM$pJptmJUy22oSO=e&E?`MU3v11{SU)9N9ItO>`2w)}vm{8t$5WW} z5CE`8@TF)ZHn*d>eDwc|hlI4?|r-w&dO2{zb-cVX$Utf*&$CKAhAGX%t zdXT3TFo0ioZgx7~Q|Fm{#F`*Qgd?B7=I1qu31#aU>cg{i36ngt*rWQY{EZ4eJ3eW# zzlOlAtToDBH7u81ikJQv1N5)Tj{2K%P~JWk2rR9*&JP)Cm4y9l*R*T9PT zThp)1OoEdK5Ezg5Mk@*o@w2Y3s{ZY=O$q+fh!|U#Q{Kn#HF%%NKZ>^ zHJqL`^!N=Tw4S`BZ|ge59n;#zrSJ6l*W(AEaTuQwWf*=48N?k7z-;a6q?($VTr$uy zmJqQW?p<~Y(RK;(b4y4{uzEa0N3Y`AwD0en)Bqg@l2||6ZeA?BK0f%oK6w~ke0zgF z-Y?u&#art}d_HAh1u&?q9af#yptfF*QFxQn)5ox#O;jm7GO9!D&qkjr{tC71y=vK#2#of;*1jzDPl64vI->>^^DItob_ST z%c2B#K-l_(MXq}L^pA8m1DDCMl6$Q+Z{mshO5jz-MNP*gw2hnQ?h@6WaDBNJ1h+ zPaoCotL-L2UZx>wkrq-tJeGpuPB~6QOGERSj6M<_S=9TZ2jpgklSB$giHCg8N}d^c zt*wLnAn!$4_hg~Uq9Qp{?wHv0n@N)_tHi>1e|guJr{IxMGM0H-!Acw5uh`#Vgpx&a zdpX_Q5E8i|dmn&GI52%c75#jTlMRKxQEjj8(K)jHK`gIDmdWLSIXZ=WbG^^t0z_K? zA+dQgw|k!MYe?Ty9PCjQpELKW^QGILV@AajX24@q*e}D#`fIsq9~bWmx3UAG+2!#j z{qv5ALtVY|qYf8E5H?U$xYxH(yLE)qqZdzsN^@Sqg_iRA6bk`?5UQHs zwF^>q%w36N^t}MO>-B8tThqB|Ekj2Lt38 z8;Fy*+ZG?Nuv8TQgaU&BY096pMQHbrO3<9ljdi3kPjB3qPH=E2L6FY?1dMv7M7c`$ z8jT@#aQJz^r@?Y%ta*B;rw0i6_vm6_V2V?Lw{P-7 znLs^t0IT~=QfW41LnOR>Hegc+p!3<0fOVXW4Wa8gfMi))O9#kl8Y>z&#l=X5C59wK zikg}h8NX*1S2f8>`h*weX3Ptdv_(vs)PaIEsDNNylb6G?dNJb#NBqDs(ao%tg}WZrmLHCa&p_XMd+bu)%S{~_sRO3 z%lhr*u1FjX(xs)EJhmZ*UJgN(uyUTqS(CddugC;{yQH%-pp=+BOACA=6PIAX!sTUN6(mG;tqx@5 zlLb&Kd(15@A#Q0a%jz1cpi;5(pwj7%TmhVROpb4BP|!p4^~}36BCt?QwX!xYX;Ut2 zySYL5sUzWckIzcWts(tc#<#QU&F2N7v8`(ZTQa_h9;8y{=I-RB<0b3TSekYU)O!ru zy#(B1k!rVz8Aqn1UdYcbqmeuJ0}opaLBL+$?pgD%O=}@nT2gU#eGoRVHrSqkp?^7Q z(!$D$!o6>LNXx^~>(l^kwI}On~VPyvlRQzo{MmbGmI+ zUlcq>`Yq2;UES)Yp066Q44)sb+o-*m6YhAb?kl}0vcVa3f8H1Kg@xT-UT!geLL>$A zd4)&FUR~eXm|4-$QJ-D%<(2O4pKdP6O(wG;6H#;iw{UfSypzL0J+Oy*p3TftI7XQ4 zlvB`v*n({GMft+t5`jwPjmk*Vbp5?ADs5rdHWT ziz~{@%VWAYOD!kv76qvIy~VZh^F}r%E*ggA0m8O;9TIV!_dxIL_77!Vz?9T`UjI=a#`#~4O zk-d@<=}%!jd3j~!gr<^}$w}1|A%BygKqxjANdZw{qS8vwfH9c_JRo31=jZr<`5Ol2 zMZ>$tX{}wqZdS_!a9MxV=iIWcf}V8!=n)S2jfP6V>ZVjTLhCry;rY6wFgt^E=X5xh z$>S9IBMf@KDa9>L$|ovRqumXo5aVzn7Yt8~9zh3CH6fdsN&(E&czqCJsG_T#T z#~pWCgH=Hq9iFQX@p&|}gkIQKiDYuDg@?8LD(zd0np1}4=qpFLOb2qm4)pih*nGFIO*t6yNa;*u=QG~}%abf(Q zs@B$5gWH4S<73D&AzEFcQ3=VFeS)sOxx9Q~4H}#Fll@b`Gn14i9UK&v*4kRQcpP^P zhC4E(lc0@t710`qcBinj4@+ zxcXYiPQ?-Xtqz(KdCH!YmNE0_Sb7qZczV)s8=DPdTnKq;wnzlLUrm_b*(&>ZJg@VdxEym)@wYVu(;u{0zG< zLSUB3$*IOh#=d$$QS?_#f=G%rAUb7bbxu+BZ9!h!~`PDI!HVSLUH$rW9Q^l zD8Pb)f~XF20DbbCnQ^@3ahwKrNwk|zBWNMRCSG19g?;e&g1;H_cJrzgm6TYdX=<#m z_ho-O{)clF-zn1pb_d)r#+w`Kd!DCR@29tIZCqC^deATZlPEh>gTso2Ev?Fti$LI! z$NjO$zvD5IkS7#=HprVd!q`PeN+u9tJEQq3xO)nM`0D1GiiWNjwkM+O6gY-Ga;iX9 zigXZ6^0JlSeF!ncF}(^^BB2+ktsIPY|D+U%zT>B)r2df6IAd95+ckypFR&yQLc+lF zm0z~>E)3WlNGIEBD#)e*0(Fhl|%I zfhiaSsqQnFJ6s*?%Tx!q1LjZI1@x0}eIg^Tva<49dwXzPK*q*pwd~SiGqo&;lmYnC zQsh9b`QloCQCP zQh3u*QwQ=b^p*WNuLl)pfRl8xyV{z%V)t=UQNgWOM`);k(%=8p=6>6t*)CsQSt$c` z5*%#H_r#iA9{r7X5oPmcyn}`SgOi}(Kcg)xCuC*~FABqAv{Qbqck#*6n;%g>=*rug z{Y|v3jO0HMBdpg;>@)-pHai>T2yzt=PVaib$Bi4MaKs*?>eKP-9WX8sAupKe=m3lo zxfGFvZ_ffiby-cK>+L;=kk5^li^k&Hj6U9+Klmot2UbOFS^^S0&O3axB|g52u<$bp zS#DkvJ1;K*mp`Cfgrtb8t3z{pA8!#6`Rda9Iztf4JFSsu-^GDL_5nE*93pEQ`kB};e1OkK?J)y`Jj zA5)Es6`&SZxIJ=a(x>u9FQ!q1&+AFryfq^3)2PqGN~X8HI9XstEFZHXTD$orUffU# zy$z6GO?*VZ)jTGQ?xrNCsOd@|cxnH$aUuWfT7k>&V#99E*FbODeVUW|Wwl3)p;t^7xkeah*-+qj!shSi;}Sl=4PMu6FlCvI$hL;p3wz z2UaCuXam4DW@c8vB#jFXH9cKQ#TAT&m6ZNTjYFxllb8g-;@Jv__JGuvn(Ad}VDLr`3X~~UWV9A2sVldzDJa~<*mnZi(^LK3DHZ}6jC=ALi^F-6pn5}2a2Fd(OKLj0 zR!=4jPbm>{aw79@V!3vHYH{)ciw|(02^`vuh!U&fwSS5IS5iuUjx?E~((dKfpx%X5 zTP!XwuL30k&}J{BSCB(OfE?4_>N35)`ULALtbOr4{;C3>OR0Dl??JRs7P7Ld7>gOxzvyH1#xSNr@cM<8`b#lH&c%*A~rU{J8@fGFtSHVD!NwNZL}`S+kyxn4*n#h zJKy&3g4^3GJxMi?2%rdU-c5Zpz|~!jzV+A0%DMzE^WVN{JW{) z5SlYpRnGp|MRbX^QA$apit*!*-t^KFwoq*gxl@L52}63r2X-C5g8tvMoqAM%0;UM< zH-A4ZE$sjZ0Xf?#?$(|cH@6&RNib~RAx?Y1j{EtxEoz(A-A!yVSC4FNVUBXPNuQPc z6&s#jyW{UOobsP6(WpijM<3z4)o+7Vb|Eu}hTh#E-e*vNU^UA%nKuYDLKvNv1X5St zr^c+*s+M|{h1QF9bkfvNo7%_!xa-1>8Ai7c;3t~uh(Zw&(32NZjH_%+TIx@^fpoe@ z0;);Ix9wTWG-)tfzeZ-dy{;!F8vjgsd?=1{4RAjgTlV&Rpr2xBbva*2szY%{D%C-R z^zl^~kxK&eU;O{|)NiAp%HcDQ`kV0V@1KGZzqPsfc`J7_1fy1l7GCkEdHgXq0EKdX z#a}wXP^XWGb*A_ZJ4-q!gC|PW&24k2U|-YW3!a)2&Py0*jPa$8=eyQ!n8P8&{B%yK zYDLHEMJpbw`)Pw!W!nwo2K`N|Vj<@$S5k6X=k0^IAh*Pin74DAENXI!Z>%Hlj*f?Dh+K-Gv<4;n^} z+;FF-qs!>k@BA!$ydDEzxB-2fI0a}Sm%JtX!Usy zfzxuKB4c&9h>}tXsVdp~{l$Vc_1T2b`wb2|)r0rbg+g{mO~TH61j)6ado)q6sLAKa zYMKStAf0J{Fosn94yCGogX5kxS$6YYp24^+zjjG($53UwFy)pzP2oIQp~MJOtiFZV ziWf&sE5@-^u(iMsncW_*rPZ&ZvH->>_vHxjD5X8yKIT+MY4Hpqne2QM1*JK!iFEhD z>dZ0-8QXcMq;JtCjbEMhM1Uh^ApE7<&WW%T(K#Xy+-uc-+=d;*YrIqx3t??G<| zjFLh1R;QB2d4|73@=j0YPp|YJ&NhUXAmO-iX*F2WJkOTox%Z#Wva+fNsA3h(4k*!KMl0%t7`n&C z$_1f3&|y~+@EV#L_U+sAK5YqED%3xJL@erw`z<~Kv-B>#m4U(gKqV+hH8Iug+m?W{ z(D_PzuSbab$oL%)pd6t9Thze({-dUTczB#pu7og<51j1CovhL0ax3u`2>98;fobHmqliHJ~$EJI{_@i_s9w}i(sH{Fn zjQ8WxXHb7Jy#dd+SJ_F~6v9H)Ets1lmZEM&&hB8c!<~XD(;-_9@^{lo8JtpN<&xIWu#(%#P{xu04rnrwygp~!G%j#;GA^#?qF}{?d4HkUMWLTcz%TOV*q1p ze7vo_-Nng~Y#Lz$B>r|r77+K1>(^1XRQvM0DhL=5;1}TUM>zD4e|{#H%iZ1G6B0D~ z1f2Ww9GlH?7CZ0XzaN_fvdC3c5oRAcas=m=O+#b1SWa%O`t4#{J4S|wnTXdMpSR1L zS+a?0Q!S}XCQ(b^(>;{m2@Fb-9Yqe4t6@qcj_{jR?Yh+)Hoz!CwZUDren4Y5$QqG` zsl>fWNq_{nFRWlGjPUUAz~DewZqA%Nix<;~h=|n@5wJY{?f?F+kz1+CZ42D7eH*;u z&(C~`_UXe99*?(W^F}bOuUx&>kL0@3m{o?sK>+<*d4x5rsW!b%9C@TD2DQ>Y(*rT}avNSg#o+iCr+LcSA6@K@QhXScnB!=O}}mVS$HBLM;aD^@P=>FG&HNhRMVU?Xu$g1v+NwUktuY*dSx z1TKhyL^6%Q&*^%Qx0|Nu8 zscCE$`<0jfgWwQMzHkwqV{~*B-cOPWsNiyqjEvrR^G$3rJuM9_8HOnbY!A>zTyryZ zGn62*;3_eFp`7*4DoL@n@5aeA`M1Uy5DY3Q;DIOK8dq>eb~rL{6k=6WBy+}^s>YyV zZDpmhrc!TWU);Md$;M8^=5o)UKZoN6OZM*D3y=5PZ?6&9_Q9VW0JeSo`i%|^gA?)g z#>M*k`GQ4VP;j5}PQz9%w-<@BvU3#*Z9IFagFRD++4}=y;|BzW%7F_~IM zW~g={suNXaFRdD?G(P0>n0^3j3WXNFu@kxwz)FFAOy5BNm6u zxqRXpj%lE5d)u}|c%Em^QgmtCuwk8>Se%}b(bGdswU;joF)|WnWMymjL4i=|>n-j@ zO6EO%z|hszowGehc}10>fbZ|;LwQs#SKPXt3Ct|0y}wmWMqKV3oGJ2oE=qwxM;1AfzH7ChYFkv zsooyW8>`_|#mlTlxLR#WnO1>c1EWAC7;h+F3OUsm8>F6Zoz3XC}&XVo=zIxHQ^+(C5Y-@PXr zl|@CaA}3LTG^eKA1i9b4XE)(c`mNh=)ZN`}<;oTK`D@p%!Q0)Ouo++BDmNz=G?j;k zhl^N@bMxQD2Q(N+qj**CMjTY|q?T+iF>&?`lb`^Ysx%GP`Jn<^=_!I6ni_);LASKD zB*eUfkzikE`>cf%7#u{<7;twnv2mauva+)A-`#)U08HMxoq?Zpb90MWwMwo~T>j=V z;b(8&w9&@e_SUToAaz86=JB>|eMuk?T)cFJ?ylWjT^t=8@(T**kX>Xv#a=1O(a_Ln zps(ldDyI8DRdr2kTRZRy%1YN)u3S}2PVL&cgODLJK0cnAnFW|UaA3d2*{Z7B+S@@^ zHg4R2pRcH>fLFd__pVv5@$g7jcQ>rKn4=aku2fDcv6%R4!S+xq0S&uflYuCe1k)ec zMLnOVvot>Qo{!O%|HgAHJA}==&Z#b=46Aeh~@9(>H z>o)$JyLat`N1C61x4&P*;s;A1F>wnlTNf`~rli{I;^Sb+%e!-z?#8XHEgkIas;g^% zD*60rfYH|04r_)LeHpoj4||G=OM#A4R;H?NXl!U|4i8^xXD1>Y%FN1EC=~10ttEUh zCntx^=4{-k(E+iksj0tzz|c?_78Zt078Vw85rR(WzoC*XQinJ+AgHoolnjEemWf$S zN^;0U!vm&epyyZD3SltRaYMp|$UC3N=Lh`&!~-j_gX#wtH#Z#?tG;$t{=y?7Y;0|L zTrNB@{MUEw+6fOZOSK1sfoI!0c5KsOv#wpcLAV?+khN>$fJ@xHS3tfm0|Why8`d>8 zJ!oibqPurX3v;2+u&%!TSpmj?R0`5bmu-*wsdDr3mxqQ>#y!9`O-Z>ava=0aNi5eT zl}gjnZkd{z#;Lalprfy^FYivi0pB1tHcrFnN>68VIAP&oc;l+Hvxpwwhn6BAox#BZp_$3!<0K&Yph; zEpWvK^%YU5>`h7{pI;SzVKN9|`!#FUz|9twl;9_~Z{H52>u$cra=vO+goTAgU427q zYb$uql@qC9#tEuF<;C1_ei7`p%?YRC3O!aSe?=Hp^x38hR5 z3yV}S4b9j{MOitQ%Zt$5n#^LenL0X@botPcBb(8%F)pgcBztLnY;IBOoO0|X>8+CPeFJxd$O{xm0 zX>UbdR$d`AG!%(!DUWtYBrUD&>(|AT>GR`ZFdb29}JwnhBIIzPNIUxj8Tj zLSP%@J1!=srLFbBgJzQNh!-Ch)7L*xTvA5)lN{{rygc0R7nNwaeK6R-@Fs`M7Y;Dk z9JcmNx{|JL9UYdBH?^M%$U|0Ej>?@!MNU$0rt9hH$H&JK=E265%O|5EBMA|}>}+5i ztaX|}!}9WSE{F4CM1&r$qOfdql*8k=yL)Jt-J`!ffrTcpcmfk=6uoug`1kIrp*sJG zl-w=M=)r}Qca}+ngn$0{h}hm88&U)0P_U* z6pW~-NHC3Vq@<89YHDf{5w^0hsAz;H1yCfi0VvkhH)^^47j$)Xb#)gkFtiVuY_z|x z-@~2Ok6BV$&KK~>xl#;OU%z&saj`McHSzyOVW#LCJlHix@H zbJti?V-tvunBIYg**qD!IcO#opU+pSdqAR+nwguk@89cfi9bKW$Pv8pXU-3Y=Cshj zisNv3y}dmIJphIi+P4iG9`5eumKG(&#D#p>vQSeqv%*3ON9s!nn}KSVmX(taxw?v% zI@o7ux_~t==L*!ZhbF=H8S+X|SXtB4?H!$Bv9lIGRdY*g6iL3(k*~@bvGpQ_L?jXk zd@&+Cj1X#UYil1Ilm-O_5Licbbq&yQFE1}m?%odzt)IXDe7G_yrbXptK#}2};_@;~ zl>hywgq^>5_Wb4ZKfklHGl$3R?d{W)^<`kF;JsDoSQ{4yj{+^if*2^G27Y9F=_vq)MAGHx=s*_}1afw-uqZri1!dYu zM@J`ckNCJ)@}WC-?&|9;CPexW`|2K>&54R4I{Q01JDnVt66#X-_4mO-OK4~FG!A`z zeOnvb*48${ypNAhfByi1YJ(<$*HKzVJcnIW##3| zS1c!Irc_o|ip63Z8*2@FthG%cmy><6Fz@H*%UBS@#nnZQcIn1*kB|_c+Jt=+K*?TQ zxuT+?f(ii9EiG;2sJ5ypYvk&T>>SE;524V|$J6T`eLNd*XlG~F*Wdpf7^*QnJq;W{ zOI8&uX0j2P8;yxySKk19owCCSyo1Gy7cUD9AH;0!-adciY{e6v%jq<4?ckXVk=H^Q%nFd3(pGm~i z9N5Q8VVF7=st_UV6j-*9S%(o9s~x^+V>?TWvf?(Q68$Std5CULq2(7QIVdW zeh>*u^$iV6%*X0{3H-92M7BOT(-!JZR6x< zY+_PHWf~=H-dIsyNl6K!RFVnCC%L@F$H%#Bjt6eX>{C75-Q7WB zw6zgw1~3Y8=o-fAh;Yh;C6P#E=U`WOzlg#^ps(-k z1EGd}PX!P=Qr{3Pw*C!htb#tSjCBUS?oFGTv8=9K*^$o}l zU#WD!o~Fmm(+Ug+`vEC2dCAz=*v!ndp^2z8fcpgo`qz=@2MlW)YePd}6%964E)T7! zs-pW1mgeT8qhn|z>F2=sZewIb1~iWDsH*$P$cP`cM1rGrDRV(~%(2HcKB(n+58@%Da*G*loAUtgbknz~P+AwhLCMiIbFhp98FnLL6Y zu;h)=AAJrC+5r}nmYw2tjg4L&)Hxaoh2r7EUT3O0Jwrpoqa!jes;yBiEv=qZC+zC# zB2;#J+6UYYrQ65T)3c?eg*Sx%P)BnI-@_W z@S;k@nwXgA>FIHEbEQ&EQ%+8f3kew3)>dpb zmt6c0Oe~Oca&&^B%C`?}q6u0938|{0=GnmVEiEj5oN71EfuS1R-4B;ibr3~IUthn| zQtEc-wRLrVz7+e*TYz{_HMwePdSGg5I_J*yr*4SF&Xk^34|fl8TwJA0Jls1aU6iM? zFkdn~{fI8|U~O%wWxK_5U_8ztm&=9piR)kyIXKwSkd~1}ixyF;Z%`MmRCU+KL1TYJmU)UJ{?rr#sp| zAf;pEpcY(79R<+Q*(ssqBt6{^E$Q82Pw%j_vK$_wsK6@{*|v9dQhvq9$E%AbVhucd zXo$9+FX&-If#5kXe#$XCJZwrIaAvmG%O*}T9MYhVQg&l92g6K z=;`Tkxzr5-wM0u6#xUR;Xo1Z$E*Q@`Fih$B`g~e5Kh=Z9r1iOJDJ%SpjQ0){p[s].s.push({s:u,e:b(this),n:t})}else{p[s].n.push({e:b(this),n:t})}});for(var g in p){var d=p[g];d.s.sort(function k(t,s){var i=t.s.toLowerCase?t.s.toLowerCase():t.s;var u=s.s.toLowerCase?s.s.toLowerCase():s.s;if(c(t.s)&&c(s.s)){i=parseFloat(t.s);u=parseFloat(s.s)}return(e.order=="asc"?1:-1)*(iu?1:0))})}var m=[];for(var g in p){var d=p[g];var n=[];var f=b(this).length;switch(e.place){case"first":b.each(d.s,function(s,t){f=Math.min(f,t.n)});break;case"org":b.each(d.s,function(s,t){n.push(t.n)});break;case"end":f=d.n.length;break;default:f=0}var q=[0,0];for(var l=0;l=f&&l0?d[1]:false}function a(e,f){var d=false;b.each(e,function(h,g){if(!d){d=g==f}});return d}b.fn.TinySort=b.fn.Tinysort=b.fn.tsort=b.fn.tinysort})(jQuery); \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/js/tmpl.js b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/js/tmpl.js deleted file mode 100644 index 251b3681b..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/js/tmpl.js +++ /dev/null @@ -1,43 +0,0 @@ - -//Simple JavaScript Templating -//John Resig - https://johnresig.com/ - MIT Licensed -// https://johnresig.com/blog/javascript-micro-templating/ -(function(window, undefined) { - var cache = {}; - - window.tmpl = function tmpl(str, data) { - try { - // Figure out if we're getting a template, or if we need to - // load the template - and be sure to cache the result. - var fn = !/\W/.test(str) ? - cache[str] = cache[str] || - tmpl(document.getElementById(str).innerHTML) : - - // Generate a reusable function that will serve as a template - // generator (and which will be cached). - new Function("obj", - "var p=[],print=function(){p.push.apply(p,arguments);};" + - - // Introduce the data as local variables using with(){} - "with(obj){p.push('" + - - // Convert the template into pure JavaScript - str - .replace(/[\r\t\n]/g, " ") - .split("<%").join("\t") - .replace(/((^|%>)[^\t]*)'/g, "$1\r") - .replace(/\t=(.*?)%>/g, "',$1,'") - .split("\t").join("');") - .split("%>").join("p.push('") - .split("\r").join("\\'") - + "');}return p.join('');"); - - //console.log(fn); - - // Provide some basic currying to the user - return data ? fn(data) : fn; - }catch(e) { - console.log(e); - } - }; -})(window); diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/templates/hystrix/index.ftlh b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/templates/hystrix/index.ftlh deleted file mode 100644 index d9d62a692..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/templates/hystrix/index.ftlh +++ /dev/null @@ -1,58 +0,0 @@ -<#import "/spring.ftl" as spring /> - - - - - -Hystrix Dashboard - - - - - - - -

- -
- -
-
- -

Hystrix Dashboard

- -

- Cluster via Turbine (default cluster): https://turbine-hostname:port/turbine.stream -
- Cluster via Turbine (custom cluster): https://turbine-hostname:port/turbine.stream?cluster=[clusterName] -
- Single Hystrix App: https://hystrix-app:port/actuator/hystrix.stream -

- Delay: ms -      - Title:
-
- -

-
- -
-
- - diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/templates/hystrix/monitor.ftlh b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/templates/hystrix/monitor.ftlh deleted file mode 100644 index 373a2f2ee..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/templates/hystrix/monitor.ftlh +++ /dev/null @@ -1,202 +0,0 @@ -<#import "/spring.ftl" as spring /> - - - - - - Hystrix Monitor - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
Loading ...
- -
- -
- -
-
Loading ...
-
- - - - - - - - diff --git a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfigurationTests.java b/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfigurationTests.java deleted file mode 100644 index d3261c8b6..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfigurationTests.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.dashboard; - -import java.util.Map; - -import org.apache.http.Header; -import org.apache.http.message.BasicHeader; -import org.junit.Test; - -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Roy Clarkson - * @author Fahim Farook - * @author Biju Kunjummen - */ -public class HystrixDashboardConfigurationTests { - - @Test - public void normal() { - MockHttpServletResponse response = new MockHttpServletResponse(); - Header[] headers = new Header[1]; - headers[0] = new BasicHeader("Content-Type", "text/proxy.stream"); - HystrixDashboardConfiguration.ProxyStreamServlet proxyStreamServlet = new HystrixDashboardConfiguration.ProxyStreamServlet(); - ReflectionTestUtils.invokeMethod(proxyStreamServlet, - "copyHeadersToServletResponse", headers, response); - assertThat(response.getHeaderNames().size()).isEqualTo(1); - assertThat(response.getHeader("Content-Type")).isEqualTo("text/proxy.stream"); - } - - @Test - public void connectionClose() { - MockHttpServletResponse response = new MockHttpServletResponse(); - Header[] headers = new Header[2]; - headers[0] = new BasicHeader("Content-Type", "text/proxy.stream"); - headers[1] = new BasicHeader("Connection", "close"); - HystrixDashboardConfiguration.ProxyStreamServlet proxyStreamServlet = new HystrixDashboardConfiguration.ProxyStreamServlet(); - ReflectionTestUtils.invokeMethod(proxyStreamServlet, - "copyHeadersToServletResponse", headers, response); - assertThat(response.getHeaderNames().size()).isEqualTo(2); - assertThat(response.getHeader("Content-Type")).isEqualTo("text/proxy.stream"); - assertThat(response.getHeader("Connection")).isEqualTo("close"); - } - - @Test - public void ignoreConnectionClose() { - MockHttpServletResponse response = new MockHttpServletResponse(); - Header[] headers = new Header[2]; - headers[0] = new BasicHeader("Content-Type", "text/proxy.stream"); - headers[1] = new BasicHeader("Connection", "close"); - HystrixDashboardConfiguration.ProxyStreamServlet proxyStreamServlet = new HystrixDashboardConfiguration.ProxyStreamServlet(); - proxyStreamServlet.setEnableIgnoreConnectionCloseHeader(true); - ReflectionTestUtils.invokeMethod(proxyStreamServlet, - "copyHeadersToServletResponse", headers, response); - assertThat(response.getHeaderNames().size()).isEqualTo(1); - assertThat(response.getHeader("Content-Type")).isEqualTo("text/proxy.stream"); - assertThat(response.getHeader("Connection")).isNull(); - } - - @Test - public void doNotIgnoreConnectionClose() { - MockHttpServletResponse response = new MockHttpServletResponse(); - Header[] headers = new Header[2]; - headers[0] = new BasicHeader("Content-Type", "text/proxy.stream"); - headers[1] = new BasicHeader("Connection", "close"); - HystrixDashboardConfiguration.ProxyStreamServlet proxyStreamServlet = new HystrixDashboardConfiguration.ProxyStreamServlet(); - proxyStreamServlet.setEnableIgnoreConnectionCloseHeader(false); - ReflectionTestUtils.invokeMethod(proxyStreamServlet, - "copyHeadersToServletResponse", headers, response); - assertThat(response.getHeaderNames().size()).isEqualTo(2); - assertThat(response.getHeader("Content-Type")).isEqualTo("text/proxy.stream"); - assertThat(response.getHeader("Connection")).isEqualTo("close"); - } - - @Test - public void initParameters() { - new ApplicationContextRunner() - .withUserConfiguration(HystrixDashboardConfiguration.class) - .withPropertyValues( - "hystrix.dashboard.init-parameters.wl-dispatch-polixy=work-manager-hystrix") - .run(context -> { - final ServletRegistrationBean registration = context - .getBean(ServletRegistrationBean.class); - assertThat(registration).isNotNull(); - - final Map initParameters = registration - .getInitParameters(); - assertThat(initParameters).isNotNull(); - assertThat(initParameters.get("wl-dispatch-polixy")) - .isEqualTo("work-manager-hystrix"); - }); - } - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardContextTests.java b/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardContextTests.java deleted file mode 100644 index 19aeebaa5..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardContextTests.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.dashboard; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.hystrix.dashboard.HystrixDashboardContextTests.Application; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, - properties = { "spring.application.name=hystrix-dashboard", - "server.servlet.context-path=/context" }) -public class HystrixDashboardContextTests { - - public static final String JQUERY_PATH = "/context/webjars/jquery/2.1.1/jquery.min.js"; - - @LocalServerPort - private int port = 0; - - @Test - public void homePage() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/context/hystrix", String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - String body = entity.getBody(); - assertThat(body.contains("base href=\"/context/hystrix\"")) - .as("wrong base path rendered in template").isTrue(); - } - - @Test - public void correctJavascriptLink() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/context/hystrix", String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - String body = entity.getBody(); - assertThat(body.contains("src=\"" + JQUERY_PATH + "\"")) - .as("wrong jquery path rendered in template").isTrue(); - } - - @Test - public void cssAvailable() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/context/hystrix/css/global.css", - String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void webjarsAvailable() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + JQUERY_PATH, String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void monitorPage() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/context/hystrix/monitor", - String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - String body = entity.getBody(); - assertThat(body.contains("base href=\"/context/hystrix/monitor\"")) - .as("wrong base path rendered in template").isTrue(); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @EnableHystrixDashboard - protected static class Application { - - } - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardHomePageTests.java b/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardHomePageTests.java deleted file mode 100644 index 9c3b36683..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardHomePageTests.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.dashboard; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.cloud.netflix.hystrix.dashboard.HystrixDashboardHomePageTests.Application; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "server.port=0", "spring.application.name=hystrix-dashboard" }) -public class HystrixDashboardHomePageTests { - - @Value("${local.server.port}") - private int port = 0; - - @Test - public void homePage() { - ResponseEntity entity = new TestRestTemplate() - .getForEntity("http://localhost:" + this.port, String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - entity.getBody().contains(""); - } - - @Test - public void cssAvailable() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/hystrix/css/global.css", - String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void monitorPage() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/hystrix/monitor", String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @EnableHystrixDashboard - @Controller - protected static class Application { - - @RequestMapping("/") - public String home() { - return "forward:/hystrix"; - } - - } - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardTests.java b/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardTests.java deleted file mode 100644 index 907063f2a..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardTests.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.dashboard; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.cloud.netflix.hystrix.dashboard.HystrixDashboardTests.Application; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "spring.application.name=hystrix-dashboard" }) -public class HystrixDashboardTests { - - @Value("${local.server.port}") - private int port = 0; - - @Test - public void homePage() { - ResponseEntity entity = new TestRestTemplate() - .getForEntity("http://localhost:" + this.port + "/hystrix", String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - String body = entity.getBody(); - assertThat(body.contains("")).isTrue(); - assertThat(body.contains("\"/webjars")).isTrue(); - assertThat(body.contains("= \"/hystrix/monitor")).isTrue(); - } - - @Test - public void cssAvailable() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/hystrix/css/global.css", - String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void monitorPage() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/hystrix/monitor", String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - String body = entity.getBody(); - assertThat(body.contains("")).isTrue(); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @EnableHystrixDashboard - protected static class Application { - - } - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/test/resources/templates/test.txt b/spring-cloud-netflix-hystrix-dashboard/src/test/resources/templates/test.txt deleted file mode 100644 index 69d32d57c..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/test/resources/templates/test.txt +++ /dev/null @@ -1 +0,0 @@ -The presence of this templates directory tests the Spring Boot FreeMarker configuration \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-stream/pom.xml b/spring-cloud-netflix-hystrix-stream/pom.xml deleted file mode 100644 index 0a988a863..000000000 --- a/spring-cloud-netflix-hystrix-stream/pom.xml +++ /dev/null @@ -1,171 +0,0 @@ - - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - spring-cloud-netflix-hystrix-stream - jar - Spring Cloud Netflix Hystrix Stream - Spring Cloud Netflix Hystrix Stream - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-logging - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.springframework.cloud - spring-cloud-stream - - - com.fasterxml.jackson.core - jackson-databind - - - com.netflix.hystrix - hystrix-core - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - com.netflix.hystrix - hystrix-metrics-event-stream - test - - - com.netflix.hystrix - hystrix-javanica - test - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.boot - spring-boot-starter-web - test - - - org.springframework.boot - spring-boot-starter-actuator - test - - - org.springframework.cloud - spring-cloud-stream-test-support - test - - - org.springframework.cloud - spring-cloud-netflix-hystrix-contract - test - - - org.springframework.cloud - spring-cloud-contract-verifier - test - - - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client - test - - - - - - org.springframework.cloud - spring-cloud-contract-maven-plugin - ${donotreplacespring-cloud-contract.version} - true - - - - .* - org.springframework.cloud.netflix.hystrix.stream.StreamSourceTestBase - - - - - - org.springframework.cloud - spring-cloud-netflix-hystrix-contract - ${project.version} - - - - - org.codehaus.mojo - build-helper-maven-plugin - - - add-source - generate-test-sources - - add-test-source - - - - ${project.build.directory}/generated-test-sources/contracts/ - - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.springframework.cloud - spring-cloud-contract-maven-plugin - [1.0.0.RELEASE,) - - convert - generateTests - - - - - - - - - - - - - - diff --git a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfiguration.java b/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfiguration.java deleted file mode 100644 index 0b0e6f522..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfiguration.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.stream; - -import javax.annotation.PostConstruct; - -import com.netflix.hystrix.HystrixCircuitBreaker; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.stream.annotation.EnableBinding; -import org.springframework.cloud.stream.annotation.Output; -import org.springframework.cloud.stream.config.BindingProperties; -import org.springframework.cloud.stream.config.BindingServiceConfiguration; -import org.springframework.cloud.stream.config.BindingServiceProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.messaging.MessageChannel; -import org.springframework.scheduling.annotation.EnableScheduling; - -/** - * Autoconfiguration for a Spring Cloud Hystrix on Spring Cloud Stream. Enabled by default - * if spring-cloud-stream is on the classpath, and can be switched off with - * hystrix.stream.queue.enabled. There are some high level configuration - * options in {@link HystrixStreamProperties}. The binding name for Spring Cloud Stream is - * {@link HystrixStreamClient#OUTPUT} so you can configure stream other properties through - * that. - * - * @author Spencer Gibb - * @author Dave Syer - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ HystrixCircuitBreaker.class, EnableBinding.class }) -@ConditionalOnProperty(value = "hystrix.stream.queue.enabled", matchIfMissing = true) -@EnableConfigurationProperties -@EnableScheduling -@EnableBinding(HystrixStreamClient.class) -@AutoConfigureBefore(BindingServiceConfiguration.class) // Needed for bindings done in -// auto config -public class HystrixStreamAutoConfiguration { - - @Autowired - private BindingServiceProperties bindings; - - @Autowired - private HystrixStreamProperties properties; - - @Autowired - @Output(HystrixStreamClient.OUTPUT) - private MessageChannel outboundChannel; - - @Autowired(required = false) - private Registration registration; - - @Bean - public HasFeatures hystrixStreamQueueFeature() { - return HasFeatures.namedFeature("Hystrix Stream (Queue)", - HystrixStreamAutoConfiguration.class); - } - - @PostConstruct - public void init() { - BindingProperties outputBinding = this.bindings.getBindings() - .get(HystrixStreamClient.OUTPUT); - if (outputBinding == null) { - this.bindings.getBindings().put(HystrixStreamClient.OUTPUT, - new BindingProperties()); - } - BindingProperties output = this.bindings.getBindings() - .get(HystrixStreamClient.OUTPUT); - if (output.getDestination() == null) { - output.setDestination(this.properties.getDestination()); - } - if (output.getContentType() == null) { - output.setContentType(this.properties.getContentType()); - } - } - - @Bean - public HystrixStreamProperties hystrixStreamProperties() { - return new HystrixStreamProperties(); - } - - @Bean - public HystrixStreamTask hystrixStreamTask( - SimpleDiscoveryProperties simpleDiscoveryProperties) { - ServiceInstance serviceInstance = this.registration; - if (serviceInstance == null) { - serviceInstance = simpleDiscoveryProperties.getLocal(); - } - return new HystrixStreamTask(this.outboundChannel, serviceInstance, - this.properties); - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamClient.java b/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamClient.java deleted file mode 100644 index add5d36e6..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamClient.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.stream; - -import org.springframework.cloud.stream.annotation.Output; -import org.springframework.messaging.MessageChannel; - -/** - * Store Hystrix Stream Client output information. - * - * @author Dave Syer - */ -public interface HystrixStreamClient { - - /** - * Hystrix Stream Output channel name. - */ - String OUTPUT = "hystrixStreamOutput"; - - /** - * Provides Hystrix Stream Output setup. - * @return corresponding {@link MessageChannel} instance - */ - @Output(OUTPUT) - MessageChannel hystrixStreamOutput(); - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamProperties.java b/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamProperties.java deleted file mode 100644 index c42ce15fe..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamProperties.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.stream; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.netflix.hystrix.HystrixConstants; - -/** - * @author Spencer Gibb - */ -@ConfigurationProperties("hystrix.stream.queue") -public class HystrixStreamProperties { - - /** Flag to indicate that Hystrix Stream is enabled. Default is true. */ - private boolean enabled = true; - - /** Flag to indicate to prefix metric names with serviceId. Default is true. */ - private boolean prefixMetricName = true; - - /** Flag to indicate to send the id field in the metrics. Default is true */ - private boolean sendId = true; - - /** - * The destination of the stream. Destination as defined by Spring Cloud Stream. - * Defaults to springCloudHystrixStream - */ - private String destination = HystrixConstants.HYSTRIX_STREAM_DESTINATION; - - /** The content type of the messages. Defaults to application/json */ - private String contentType = "application/json"; - - /** How often (in ms) to send messages to the stream. Defaults to 500. */ - private long sendRate = 500; - - /** - * How often to put messages in the queue. This queue drains to the stream. Defaults - * to 500. - */ - private long gatherRate = 500; - - /** - * The size of the metrics queue. This queue drains to the stream. Defaults to 1000. - */ - private int size = 1000; - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public boolean isPrefixMetricName() { - return prefixMetricName; - } - - public void setPrefixMetricName(boolean prefixMetricName) { - this.prefixMetricName = prefixMetricName; - } - - public boolean isSendId() { - return sendId; - } - - public void setSendId(boolean sendId) { - this.sendId = sendId; - } - - public String getDestination() { - return destination; - } - - public void setDestination(String destination) { - this.destination = destination; - } - - public String getContentType() { - return contentType; - } - - public void setContentType(String contentType) { - this.contentType = contentType; - } - - public long getSendRate() { - return sendRate; - } - - public void setSendRate(long sendRate) { - this.sendRate = sendRate; - } - - public long getGatherRate() { - return gatherRate; - } - - public void setGatherRate(long gatherRate) { - this.gatherRate = gatherRate; - } - - public int getSize() { - return size; - } - - public void setSize(int size) { - this.size = size; - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTask.java b/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTask.java deleted file mode 100644 index d94cabd3b..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTask.java +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.stream; - -import java.io.IOException; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Collection; -import java.util.concurrent.LinkedBlockingQueue; - -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.netflix.hystrix.HystrixCircuitBreaker; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixCommandMetrics; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.HystrixThreadPoolKey; -import com.netflix.hystrix.HystrixThreadPoolMetrics; -import com.netflix.hystrix.util.HystrixRollingNumberEvent; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.BeansException; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.messaging.MessageChannel; -import org.springframework.messaging.MessageHeaders; -import org.springframework.messaging.support.MessageBuilder; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.util.Assert; - -/** - * @author Spencer Gibb - * @see com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller (nested - * private class MetricsPoller) - */ -public class HystrixStreamTask implements ApplicationContextAware { - - private static Log log = LogFactory.getLog(HystrixStreamTask.class); - - private MessageChannel outboundChannel; - - private ServiceInstance registration; - - private HystrixStreamProperties properties; - - private ApplicationContext context; - - // Visible for testing - final LinkedBlockingQueue jsonMetrics; - - private final JsonFactory jsonFactory = new JsonFactory(); - - public HystrixStreamTask(MessageChannel outboundChannel, ServiceInstance registration, - HystrixStreamProperties properties) { - Assert.notNull(outboundChannel, "outboundChannel may not be null"); - Assert.notNull(registration, "registration may not be null"); - Assert.notNull(properties, "properties may not be null"); - this.outboundChannel = outboundChannel; - this.registration = registration; - this.properties = properties; - this.jsonMetrics = new LinkedBlockingQueue<>(properties.getSize()); - } - - /* for testing */ ServiceInstance getRegistration() { - return registration; - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException { - this.context = applicationContext; - } - - // TODO: use integration to split this up? - @Scheduled( - fixedRateString = "${hystrix.stream.queue.sendRate:${hystrix.stream.queue.send-rate:500}}") - public void sendMetrics() { - ArrayList metrics = new ArrayList<>(); - this.jsonMetrics.drainTo(metrics); - - if (!metrics.isEmpty()) { - if (log.isTraceEnabled()) { - log.trace("sending stream metrics size: " + metrics.size()); - } - for (String json : metrics) { - // TODO: batch all metrics to one message - try { - // TODO: remove the explicit content type when s-c-stream can handle - // that for us - this.outboundChannel.send(MessageBuilder.withPayload(json) - .setHeader(MessageHeaders.CONTENT_TYPE, - this.properties.getContentType()) - .build()); - } - catch (Exception ex) { - if (log.isTraceEnabled()) { - log.trace("failed sending stream metrics: " + ex.getMessage()); - } - } - } - } - } - - @Scheduled( - fixedRateString = "${hystrix.stream.queue.gatherRate:${hystrix.stream.queue.gather-rate:500}}") - public void gatherMetrics() { - try { - // command metrics - Collection instances = HystrixCommandMetrics - .getInstances(); - if (!instances.isEmpty()) { - log.trace("gathering metrics size: " + instances.size()); - } - - for (HystrixCommandMetrics commandMetrics : instances) { - HystrixCommandKey key = commandMetrics.getCommandKey(); - HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory - .getInstance(key); - - StringWriter jsonString = new StringWriter(); - JsonGenerator json = this.jsonFactory.createGenerator(jsonString); - - json.writeStartObject(); - - addServiceData(json, registration); - json.writeStringField("event", "message"); - json.writeObjectFieldStart("data"); - json.writeStringField("type", "HystrixCommand"); - String name = key.name(); - - if (this.properties.isPrefixMetricName() && registration != null) { - name = registration.getServiceId() + "." + name; - } - - json.writeStringField("name", name); - json.writeStringField("group", commandMetrics.getCommandGroup().name()); - json.writeNumberField("currentTime", System.currentTimeMillis()); - - // circuit breaker - if (circuitBreaker == null) { - // circuit breaker is disabled and thus never open - json.writeBooleanField("isCircuitBreakerOpen", false); - } - else { - json.writeBooleanField("isCircuitBreakerOpen", - circuitBreaker.isOpen()); - } - HystrixCommandMetrics.HealthCounts healthCounts = commandMetrics - .getHealthCounts(); - json.writeNumberField("errorPercentage", - healthCounts.getErrorPercentage()); - json.writeNumberField("errorCount", healthCounts.getErrorCount()); - json.writeNumberField("requestCount", healthCounts.getTotalRequests()); - - // rolling counters - json.writeNumberField("rollingCountCollapsedRequests", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.COLLAPSED)); - json.writeNumberField("rollingCountExceptionsThrown", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.EXCEPTION_THROWN)); - json.writeNumberField("rollingCountFailure", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.FAILURE)); - json.writeNumberField("rollingCountFallbackFailure", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.FALLBACK_FAILURE)); - json.writeNumberField("rollingCountFallbackRejection", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.FALLBACK_REJECTION)); - json.writeNumberField("rollingCountFallbackSuccess", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.FALLBACK_SUCCESS)); - json.writeNumberField("rollingCountResponsesFromCache", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.RESPONSE_FROM_CACHE)); - json.writeNumberField("rollingCountSemaphoreRejected", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.SEMAPHORE_REJECTED)); - json.writeNumberField("rollingCountShortCircuited", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.SHORT_CIRCUITED)); - json.writeNumberField("rollingCountSuccess", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.SUCCESS)); - json.writeNumberField("rollingCountThreadPoolRejected", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.THREAD_POOL_REJECTED)); - json.writeNumberField("rollingCountTimeout", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.TIMEOUT)); - - json.writeNumberField("currentConcurrentExecutionCount", - commandMetrics.getCurrentConcurrentExecutionCount()); - - // latency percentiles - json.writeNumberField("latencyExecute_mean", - commandMetrics.getExecutionTimeMean()); - json.writeObjectFieldStart("latencyExecute"); - json.writeNumberField("0", commandMetrics.getExecutionTimePercentile(0)); - json.writeNumberField("25", - commandMetrics.getExecutionTimePercentile(25)); - json.writeNumberField("50", - commandMetrics.getExecutionTimePercentile(50)); - json.writeNumberField("75", - commandMetrics.getExecutionTimePercentile(75)); - json.writeNumberField("90", - commandMetrics.getExecutionTimePercentile(90)); - json.writeNumberField("95", - commandMetrics.getExecutionTimePercentile(95)); - json.writeNumberField("99", - commandMetrics.getExecutionTimePercentile(99)); - json.writeNumberField("99.5", - commandMetrics.getExecutionTimePercentile(99.5)); - json.writeNumberField("100", - commandMetrics.getExecutionTimePercentile(100)); - json.writeEndObject(); - // - json.writeNumberField("latencyTotal_mean", - commandMetrics.getTotalTimeMean()); - json.writeObjectFieldStart("latencyTotal"); - json.writeNumberField("0", commandMetrics.getTotalTimePercentile(0)); - json.writeNumberField("25", commandMetrics.getTotalTimePercentile(25)); - json.writeNumberField("50", commandMetrics.getTotalTimePercentile(50)); - json.writeNumberField("75", commandMetrics.getTotalTimePercentile(75)); - json.writeNumberField("90", commandMetrics.getTotalTimePercentile(90)); - json.writeNumberField("95", commandMetrics.getTotalTimePercentile(95)); - json.writeNumberField("99", commandMetrics.getTotalTimePercentile(99)); - json.writeNumberField("99.5", - commandMetrics.getTotalTimePercentile(99.5)); - json.writeNumberField("100", commandMetrics.getTotalTimePercentile(100)); - json.writeEndObject(); - - // property values for reporting what is actually seen by the command - // rather than what was set somewhere - HystrixCommandProperties commandProperties = commandMetrics - .getProperties(); - - json.writeNumberField( - "propertyValue_circuitBreakerRequestVolumeThreshold", - commandProperties.circuitBreakerRequestVolumeThreshold().get()); - json.writeNumberField( - "propertyValue_circuitBreakerSleepWindowInMilliseconds", - commandProperties.circuitBreakerSleepWindowInMilliseconds() - .get()); - json.writeNumberField( - "propertyValue_circuitBreakerErrorThresholdPercentage", - commandProperties.circuitBreakerErrorThresholdPercentage().get()); - json.writeBooleanField("propertyValue_circuitBreakerForceOpen", - commandProperties.circuitBreakerForceOpen().get()); - json.writeBooleanField("propertyValue_circuitBreakerForceClosed", - commandProperties.circuitBreakerForceClosed().get()); - json.writeBooleanField("propertyValue_circuitBreakerEnabled", - commandProperties.circuitBreakerEnabled().get()); - - json.writeStringField("propertyValue_executionIsolationStrategy", - commandProperties.executionIsolationStrategy().get().name()); - json.writeNumberField( - "propertyValue_executionIsolationThreadTimeoutInMilliseconds", - commandProperties.executionIsolationThreadTimeoutInMilliseconds() - .get()); - json.writeBooleanField( - "propertyValue_executionIsolationThreadInterruptOnTimeout", - commandProperties.executionIsolationThreadInterruptOnTimeout() - .get()); - json.writeStringField( - "propertyValue_executionIsolationThreadPoolKeyOverride", - commandProperties.executionIsolationThreadPoolKeyOverride() - .get()); - json.writeNumberField( - "propertyValue_executionIsolationSemaphoreMaxConcurrentRequests", - commandProperties - .executionIsolationSemaphoreMaxConcurrentRequests() - .get()); - json.writeNumberField( - "propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests", - commandProperties - .fallbackIsolationSemaphoreMaxConcurrentRequests().get()); - - // TODO - /* - * The following are commented out as these rarely change and are verbose - * for streaming for something people don't change. We could perhaps allow - * a property or request argument to include these. - */ - - // json.put("propertyValue_metricsRollingPercentileEnabled", - // commandProperties.metricsRollingPercentileEnabled().get()); - // json.put("propertyValue_metricsRollingPercentileBucketSize", - // commandProperties.metricsRollingPercentileBucketSize().get()); - // json.put("propertyValue_metricsRollingPercentileWindow", - // commandProperties.metricsRollingPercentileWindowInMilliseconds().get()); - // json.put("propertyValue_metricsRollingPercentileWindowBuckets", - // commandProperties.metricsRollingPercentileWindowBuckets().get()); - // json.put("propertyValue_metricsRollingStatisticalWindowBuckets", - // commandProperties.metricsRollingStatisticalWindowBuckets().get()); - json.writeNumberField( - "propertyValue_metricsRollingStatisticalWindowInMilliseconds", - commandProperties.metricsRollingStatisticalWindowInMilliseconds() - .get()); - - json.writeBooleanField("propertyValue_requestCacheEnabled", - commandProperties.requestCacheEnabled().get()); - json.writeBooleanField("propertyValue_requestLogEnabled", - commandProperties.requestLogEnabled().get()); - - json.writeNumberField("reportingHosts", 1); // this will get summed across - // all instances in a cluster - - json.writeEndObject(); // end data attribute - json.writeEndObject(); - json.close(); - - // output - this.jsonMetrics.add(jsonString.getBuffer().toString()); - } - - // thread pool metrics - for (HystrixThreadPoolMetrics threadPoolMetrics : HystrixThreadPoolMetrics - .getInstances()) { - HystrixThreadPoolKey key = threadPoolMetrics.getThreadPoolKey(); - - StringWriter jsonString = new StringWriter(); - JsonGenerator json = this.jsonFactory.createGenerator(jsonString); - json.writeStartObject(); - - addServiceData(json, this.registration); - json.writeObjectFieldStart("data"); - - json.writeStringField("type", "HystrixThreadPool"); - json.writeStringField("name", key.name()); - json.writeNumberField("currentTime", System.currentTimeMillis()); - - json.writeNumberField("currentActiveCount", - threadPoolMetrics.getCurrentActiveCount().intValue()); - json.writeNumberField("currentCompletedTaskCount", - threadPoolMetrics.getCurrentCompletedTaskCount().longValue()); - json.writeNumberField("currentCorePoolSize", - threadPoolMetrics.getCurrentCorePoolSize().intValue()); - json.writeNumberField("currentLargestPoolSize", - threadPoolMetrics.getCurrentLargestPoolSize().intValue()); - json.writeNumberField("currentMaximumPoolSize", - threadPoolMetrics.getCurrentMaximumPoolSize().intValue()); - json.writeNumberField("currentPoolSize", - threadPoolMetrics.getCurrentPoolSize().intValue()); - json.writeNumberField("currentQueueSize", - threadPoolMetrics.getCurrentQueueSize().intValue()); - json.writeNumberField("currentTaskCount", - threadPoolMetrics.getCurrentTaskCount().longValue()); - json.writeNumberField("rollingCountThreadsExecuted", - threadPoolMetrics.getRollingCountThreadsExecuted()); - json.writeNumberField("rollingMaxActiveThreads", - threadPoolMetrics.getRollingMaxActiveThreads()); - - json.writeNumberField("propertyValue_queueSizeRejectionThreshold", - threadPoolMetrics.getProperties().queueSizeRejectionThreshold() - .get()); - json.writeNumberField( - "propertyValue_metricsRollingStatisticalWindowInMilliseconds", - threadPoolMetrics.getProperties() - .metricsRollingStatisticalWindowInMilliseconds().get()); - - json.writeNumberField("reportingHosts", 1); // this will get summed across - // all instances in a cluster - - json.writeEndObject(); // end of data object - json.writeEndObject(); - json.close(); - // output to stream - this.jsonMetrics.add(jsonString.getBuffer().toString()); - } - } - catch (Exception ex) { - log.error("Error adding metrics to queue", ex); - } - } - - private void addServiceData(JsonGenerator json, ServiceInstance localService) - throws IOException { - json.writeObjectFieldStart("origin"); - json.writeStringField("host", localService.getHost()); - json.writeNumberField("port", localService.getPort()); - json.writeStringField("serviceId", localService.getServiceId()); - if (this.properties.isSendId()) { - json.writeStringField("id", this.context.getId()); - } - json.writeEndObject(); - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-hystrix-stream/src/main/resources/META-INF/spring.factories deleted file mode 100644 index ca7c0a243..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.hystrix.stream.HystrixStreamAutoConfiguration diff --git a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfigurationNoRegistrationTests.java b/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfigurationNoRegistrationTests.java deleted file mode 100644 index 40d66d3ac..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfigurationNoRegistrationTests.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.stream; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest({ "eureka.client.enabled=false" }) -@DirtiesContext -public class HystrixStreamAutoConfigurationNoRegistrationTests { - - @Autowired - HystrixStreamTask task; - - @Autowired(required = false) - Registration registration; - - @Autowired - SimpleDiscoveryProperties simpleDiscoveryProperties; - - @Test - public void withoutRegistrationWorks() throws Exception { - assertThat(this.registration).isNull(); - assertThat(this.simpleDiscoveryProperties).isNotNull(); - assertThat(task.getRegistration()) - .isEqualTo(this.simpleDiscoveryProperties.getLocal()); - } - - @EnableAutoConfiguration - @SpringBootConfiguration - protected static class Config { - - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfigurationTests.java b/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfigurationTests.java deleted file mode 100644 index 1ea188c14..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfigurationTests.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.stream; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@DirtiesContext -public class HystrixStreamAutoConfigurationTests { - - @Autowired - HystrixStreamTask task; - - @Autowired - Registration registration; - - @Test - public void withRegistrationWorks() throws Exception { - assertThat(task.getRegistration()).isEqualTo(this.registration); - } - - @EnableAutoConfiguration - @SpringBootConfiguration - protected static class Config { - - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTaskTests.java b/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTaskTests.java deleted file mode 100644 index 42f968451..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTaskTests.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2016-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.stream; - -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixCommandMetrics; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.strategy.properties.HystrixPropertiesCommandDefault; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.junit.MockitoJUnitRunner; - -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.context.ApplicationContext; -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageChannel; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.verifyNoInteractions; - -/** - * @author Marcin Grzejszczak - */ -@RunWith(MockitoJUnitRunner.class) -public class HystrixStreamTaskTests { - - @Mock - MessageChannel outboundChannel; - - @Mock - DiscoveryClient discoveryClient; - - @Mock - ApplicationContext context; - - @Spy - HystrixStreamProperties properties; - - @Mock - Registration registration; - - @InjectMocks - HystrixStreamTask hystrixStreamTask; - - @Test - public void should_not_send_metrics_when_they_are_empty() throws Exception { - this.hystrixStreamTask.sendMetrics(); - - verifyNoInteractions(this.outboundChannel); - } - - @Test - public void should_send_metrics_when_they_are_not_empty() throws Exception { - this.hystrixStreamTask.jsonMetrics.put("someJson"); - - this.hystrixStreamTask.sendMetrics(); - - then(this.outboundChannel).should().send(any(Message.class)); - } - - @Test - public void should_gather_json_metrics() throws Exception { - HystrixCommandKey hystrixCommandKey = HystrixCommandKey.Factory - .asKey("commandKey"); - HystrixCommandMetrics.getInstance(hystrixCommandKey, - HystrixCommandGroupKey.Factory.asKey("commandGroupKey"), - new HystrixPropertiesCommandDefault(hystrixCommandKey, - HystrixCommandProperties.defaultSetter())); - - this.hystrixStreamTask.setApplicationContext(this.context); - this.hystrixStreamTask.gatherMetrics(); - - assertThat(this.hystrixStreamTask.jsonMetrics.isEmpty()).isFalse(); - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTests.java b/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTests.java deleted file mode 100644 index 835271704..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.stream; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.stream.test.binder.MessageCollector; -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageChannel; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - * @author Daniel Lavoie - */ -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = { "debug=true", - "spring.jmx.enabled=true", "spring.application.name=mytestapp" }) -@DirtiesContext -public class HystrixStreamTests { - - @Autowired - private HystrixStreamTask task; - - @Autowired - private Application application; - - @Autowired(required = false) - private Registration registration; - - @Autowired - private ObjectMapper mapper; - - @Autowired - private MessageCollector collector; - - @Autowired - @Qualifier(HystrixStreamClient.OUTPUT) - private MessageChannel output; - - @Test - public void contextLoads() throws Exception { - this.application.hello(); - // It is important that local service instance resolves for metrics - // origin details to be populated - assertThat(this.registration).isNotNull(); - assertThat(this.registration.getServiceId()).isEqualTo("mytestapp"); - this.task.gatherMetrics(); - Message message = this.collector.forChannel(output).take(); - JsonNode tree = mapper.readTree((String) message.getPayload()); - assertThat(tree.hasNonNull("origin")).isTrue(); - assertThat(tree.hasNonNull("data")).isTrue(); - assertThat(tree.hasNonNull("event")).isTrue(); - assertThat(tree.findValue("event").asText()).isEqualTo("message"); - } - - @EnableAutoConfiguration - @EnableCircuitBreaker - @RestController - @SpringBootConfiguration - public static class Application { - - @HystrixCommand - @RequestMapping("/") - public String hello() { - return "Hello World"; - } - - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/StreamSourceTestBase.java b/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/StreamSourceTestBase.java deleted file mode 100644 index 36e39faa0..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/StreamSourceTestBase.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.stream; - -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; -import org.junit.runner.RunWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.cloud.contract.verifier.messaging.MessageVerifier; -import org.springframework.cloud.contract.verifier.messaging.boot.AutoConfigureMessageVerifier; -import org.springframework.cloud.contract.verifier.messaging.stream.StreamStubMessages; -import org.springframework.cloud.netflix.hystrix.contract.HystrixContractUtils; -import org.springframework.cloud.netflix.hystrix.stream.StreamSourceTestBase.TestApplication; -import org.springframework.cloud.stream.config.BindingProperties; -import org.springframework.cloud.stream.config.BindingServiceProperties; -import org.springframework.cloud.stream.test.binder.MessageCollector; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageChannel; -import org.springframework.messaging.MessageHeaders; -import org.springframework.messaging.converter.DefaultContentTypeResolver; -import org.springframework.messaging.converter.MappingJackson2MessageConverter; -import org.springframework.messaging.support.MessageBuilder; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.MimeTypeUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * Base class for sensor autogenerated tests (used by Spring Cloud Contract). - * - * This bootstraps the Spring Boot application code. - * - * @author Marius Bogoevici - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = TestApplication.class, - properties = { "spring.application.name=application" }) -@AutoConfigureMessageVerifier -public abstract class StreamSourceTestBase { - - @Autowired - TestApplication application; - - public void createMetricsData() throws Exception { - application.hello(); - } - - public void assertOrigin(Object input) { - System.err.println(input); - @SuppressWarnings("unchecked") - Map origin = (Map) input; - HystrixContractUtils.checkOrigin(origin); - } - - public void assertData(Object input) { - // System.err.println(input); - @SuppressWarnings("unchecked") - Map data = (Map) input; - HystrixContractUtils.checkData(data, TestApplication.class.getSimpleName(), - "application.hello"); - } - - public void assertEvent(Object input) { - HystrixContractUtils.checkEvent((String) input); - } - - @EnableAutoConfiguration - @EnableCircuitBreaker - @RestController - public static class TestApplication { - - @HystrixCommand - @RequestMapping("/") - public String hello() { - return "Hello World"; - } - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - // TODO: remove this as soon as contract 2.0.0 is available - @Bean - MessageVerifier> contractVerifierMessageExchange( - ApplicationContext applicationContext) { - return new PatchedStubMessages(applicationContext); - } - - } - - static class PatchedStubMessages implements MessageVerifier> { - - private static final Logger log = LoggerFactory - .getLogger(StreamStubMessages.class); - - private final ApplicationContext context; - - private final MessageCollector messageCollector; - - private final ContractVerifierStreamMessageBuilder builder = new ContractVerifierStreamMessageBuilder(); - - PatchedStubMessages(ApplicationContext context) { - this.context = context; - this.messageCollector = context.getBean(MessageCollector.class); - } - - @Override - public void send(T payload, Map headers, String destination) { - send(this.builder.create(payload, headers), destination); - } - - @Override - public void send(Message message, String destination) { - try { - MessageChannel messageChannel = this.context - .getBean(resolvedDestination(destination), MessageChannel.class); - messageChannel.send(message); - } - catch (Exception e) { - log.error( - "Exception occurred while trying to send a message [" + message - + "] " + "to a channel with name [" + destination + "]", - e); - throw e; - } - } - - @Override - public Message receive(String destination, long timeout, TimeUnit timeUnit) { - try { - MessageChannel messageChannel = this.context - .getBean(resolvedDestination(destination), MessageChannel.class); - Message message = this.messageCollector.forChannel(messageChannel) - .poll(timeout, timeUnit); - if (message == null) { - return message; - } - return MessageBuilder.createMessage(message.getPayload(), - message.getHeaders()); - } - catch (Exception e) { - log.error("Exception occurred while trying to read a message from " - + " a channel with name [" + destination + "]", e); - throw new IllegalStateException(e); - } - } - - private String resolvedDestination(String destination) { - try { - BindingServiceProperties channelBindingServiceProperties = this.context - .getBean(BindingServiceProperties.class); - for (Map.Entry entry : channelBindingServiceProperties - .getBindings().entrySet()) { - if (destination.equals(entry.getValue().getDestination())) { - if (log.isDebugEnabled()) { - log.debug("Found a channel named [{}] with destination [{}]", - entry.getKey(), destination); - } - return entry.getKey(); - } - } - } - catch (Exception e) { - log.error( - "Exception took place while trying to resolve the destination. Will assume the name [" - + destination + "]", - e); - } - if (log.isDebugEnabled()) { - log.debug("No destination named [" + destination - + "] was found. Assuming that the destination equals the channel name", - destination); - } - return destination; - } - - @Override - public Message receive(String destination) { - return receive(destination, 5, TimeUnit.SECONDS); - } - - private MappingJackson2MessageConverter converter() { - ObjectMapper mapper = null; - try { - mapper = this.context.getBean(ObjectMapper.class); - } - catch (NoSuchBeanDefinitionException e) { - - } - MappingJackson2MessageConverter converter = createJacksonConverter(); - if (mapper != null) { - converter.setObjectMapper(mapper); - } - return converter; - } - - protected MappingJackson2MessageConverter createJacksonConverter() { - DefaultContentTypeResolver resolver = new DefaultContentTypeResolver(); - resolver.setDefaultMimeType(MimeTypeUtils.APPLICATION_JSON); - MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); - converter.setContentTypeResolver(resolver); - return converter; - } - - } - - static class ContractVerifierStreamMessageBuilder { - - public Message create(T payload, Map headers) { - return MessageBuilder.createMessage(payload, new MessageHeaders(headers)); - } - - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/test/resources/application.yml b/spring-cloud-netflix-hystrix-stream/src/test/resources/application.yml deleted file mode 100644 index dc48699c9..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/test/resources/application.yml +++ /dev/null @@ -1,6 +0,0 @@ -server: - port: 17642 - -logging: - level: - org.springframework.netflix.hystrix.stream: TRACE \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-stream/src/test/resources/contracts/shouldProduceValidMetricsData.groovy b/spring-cloud-netflix-hystrix-stream/src/test/resources/contracts/shouldProduceValidMetricsData.groovy deleted file mode 100644 index 452bbd44b..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/test/resources/contracts/shouldProduceValidMetricsData.groovy +++ /dev/null @@ -1,29 +0,0 @@ -package contracts - -import org.springframework.cloud.netflix.hystrix.contract.HystrixContractUtils - -org.springframework.cloud.contract.spec.Contract.make { - // Human readable description - description 'Should produce valid metrics data' - // Label by means of which the output message can be triggered - label 'metrics' - // input to the contract - input { - // the contract will be triggered by a method - triggeredBy('createMetricsData()') - } - // output message of the contract - outputMessage { - // destination to which the output message will be sent - sentTo 'hystrixStreamOutput' - headers { - header('contentType': 'application/json') - } - body(HystrixContractUtils.simpleBody()) - testMatchers { - jsonPath('$.origin', byCommand('assertOrigin($it)')) - jsonPath('$.event', byCommand('assertEvent($it)')) - jsonPath('$.data', byCommand('assertData($it)')) - } - } -} diff --git a/spring-cloud-netflix-hystrix/pom.xml b/spring-cloud-netflix-hystrix/pom.xml deleted file mode 100644 index 7d4800ff8..000000000 --- a/spring-cloud-netflix-hystrix/pom.xml +++ /dev/null @@ -1,186 +0,0 @@ - - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - spring-cloud-netflix-hystrix - jar - Spring Cloud Netflix Hystrix - Spring Cloud Netflix Hystrix - - - org.springframework.boot - spring-boot-autoconfigure - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-actuator - true - - - org.springframework.boot - spring-boot-starter-security - true - - - org.springframework.boot - spring-boot-starter-web - true - - - org.springframework.boot - spring-boot-starter-webflux - true - - - org.springframework.boot - spring-boot-starter-reactor-netty - true - - - io.netty - netty-codec-http - true - - - io.projectreactor - reactor-core - true - - - io.reactivex - rxjava-reactive-streams - true - - - org.springframework.retry - spring-retry - true - - - org.springframework.boot - spring-boot-starter-aop - - - org.springframework.cloud - spring-cloud-commons - true - - - org.springframework.cloud - spring-cloud-context - true - - - com.netflix.ribbon - ribbon-loadbalancer - true - - - com.netflix.hystrix - hystrix-core - true - - - com.netflix.hystrix - hystrix-serialization - true - - - com.netflix.hystrix - hystrix-metrics-event-stream - true - - - com.netflix.hystrix - hystrix-javanica - true - - - com.netflix.ribbon - ribbon-core - true - - - com.netflix.ribbon - ribbon-httpclient - true - - - io.reactivex - rxjava - true - - - com.sun.jersey.contribs - jersey-apache-client4 - true - - - com.squareup.okhttp3 - okhttp - true - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.cloud - spring-cloud-netflix-ribbon - test - - - org.springframework.cloud - spring-cloud-test-support - test - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - io.projectreactor - reactor-test - test - - - com.netflix.ribbon - ribbon - test - - - - - java8plus - - [1.8,2.0) - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - -parameters - - - - - - - - diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/AbstractHystrixConfigBuilder.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/AbstractHystrixConfigBuilder.java deleted file mode 100644 index 0fd465b7a..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/AbstractHystrixConfigBuilder.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2013-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixCommandProperties; - -import org.springframework.cloud.client.circuitbreaker.ConfigBuilder; -import org.springframework.util.StringUtils; - -/** - * @author Ryan Baxter - */ -public abstract class AbstractHystrixConfigBuilder - implements ConfigBuilder { - - private final String commandName; - - protected String groupName; - - protected HystrixCommandProperties.Setter commandProperties; - - public AbstractHystrixConfigBuilder(String id) { - this.commandName = id; - } - - public AbstractHystrixConfigBuilder groupName(String groupName) { - this.groupName = groupName; - return this; - } - - public AbstractHystrixConfigBuilder commandProperties( - HystrixCommandProperties.Setter commandProperties) { - this.commandProperties = commandProperties; - return this; - } - - protected HystrixCommandGroupKey getGroupKey() { - String groupNameToUse; - if (StringUtils.hasText(this.groupName)) { - groupNameToUse = this.groupName; - } - else { - groupNameToUse = commandName + "group"; - } - return HystrixCommandGroupKey.Factory.asKey(groupNameToUse); - } - - protected HystrixCommandKey getCommandKey() { - return HystrixCommandKey.Factory.asKey(this.commandName); - } - - protected HystrixCommandProperties.Setter getCommandPropertiesSetter() { - return this.commandProperties != null ? this.commandProperties - : HystrixCommandProperties.Setter(); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/EnableHystrix.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/EnableHystrix.java deleted file mode 100644 index 58ea88894..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/EnableHystrix.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2013-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; - -/** - * Convenience annotation for clients to enable Hystrix circuit breakers (specifically). - * Use this (optionally) in case you want discovery and know for sure that it is Hystrix - * you want. All it does is turn on circuit breakers and let the autoconfiguration find - * the Hystrix classes if they are available (i.e. you need Hystrix on the classpath as - * well). - * - * @author Dave Syer - * @author Spencer Gibb - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@EnableCircuitBreaker -public @interface EnableHystrix { - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfiguration.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfiguration.java deleted file mode 100644 index 311bd4ae0..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfiguration.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import com.netflix.hystrix.Hystrix; -import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect; -import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet; -import com.netflix.hystrix.metric.consumer.HystrixDashboardStream; -import com.netflix.hystrix.serial.SerialHystrixDashboardData; -import io.micrometer.core.instrument.binder.hystrix.HystrixMetricsBinder; -import org.reactivestreams.Publisher; -import rx.Observable; -import rx.RxReactiveStreams; - -import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.reactive.DispatcherHandler; - -import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.REACTIVE; -import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.SERVLET; - -/** - * Auto configuration for Hystrix. - * - * @author Christian Dupuis - * @author Dave Syer - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ Hystrix.class, HealthIndicator.class, - HealthContributorAutoConfiguration.class }) -@AutoConfigureAfter({ HealthContributorAutoConfiguration.class }) -public class HystrixAutoConfiguration { - - @Bean - @ConditionalOnEnabledHealthIndicator("hystrix") - public HystrixHealthIndicator hystrixHealthIndicator() { - return new HystrixHealthIndicator(); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnProperty(value = "management.metrics.binders.hystrix.enabled", - matchIfMissing = true) - @ConditionalOnClass({ HystrixMetricsBinder.class }) - protected static class HystrixMetricsConfiguration { - - @Bean - public HystrixMetricsBinder hystrixMetricsBinder() { - return new HystrixMetricsBinder(); - } - - } - - /** - * See original - * {@link org.springframework.boot.actuate.autoconfigure.jolokia.JolokiaEndpointAutoConfiguration}. - */ - @Configuration(proxyBeanMethods = false) - @ConditionalOnWebApplication(type = SERVLET) - @ConditionalOnBean(HystrixCommandAspect.class) // only install the stream if enabled - @ConditionalOnClass({ HystrixMetricsStreamServlet.class }) - @EnableConfigurationProperties(HystrixProperties.class) - protected static class HystrixServletAutoConfiguration { - - @Bean - @ConditionalOnAvailableEndpoint - public HystrixStreamEndpoint hystrixStreamEndpoint(HystrixProperties properties) { - return new HystrixStreamEndpoint(properties.getConfig()); - } - - @Bean - public HasFeatures hystrixStreamFeature() { - return HasFeatures.namedFeature("Hystrix Stream Servlet", - HystrixMetricsStreamServlet.class); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnWebApplication(type = REACTIVE) - @ConditionalOnBean(HystrixCommandAspect.class) // only install the stream if enabled - @ConditionalOnClass({ DispatcherHandler.class }) - @EnableConfigurationProperties(HystrixProperties.class) - protected static class HystrixWebfluxManagementContextConfiguration { - - @Bean - @ConditionalOnAvailableEndpoint - public HystrixWebfluxEndpoint hystrixWebfluxController() { - Observable serializedDashboardData = HystrixDashboardStream - .getInstance().observe() - .concatMap(dashboardData -> Observable.from(SerialHystrixDashboardData - .toMultipleJsonStrings(dashboardData))); - Publisher publisher = RxReactiveStreams - .toPublisher(serializedDashboardData); - return new HystrixWebfluxEndpoint(publisher); - } - - @Bean - public HasFeatures hystrixStreamFeature() { - return HasFeatures.namedFeature("Hystrix Stream Webflux", - HystrixWebfluxEndpoint.class); - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreaker.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreaker.java deleted file mode 100644 index 645704fa9..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreaker.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2013-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.util.function.Function; -import java.util.function.Supplier; - -import com.netflix.hystrix.HystrixCommand; - -import org.springframework.cloud.client.circuitbreaker.CircuitBreaker; - -/** - * Hystrix implementation of {@link CircuitBreaker}. - * - * @author Ryan Baxter - */ -public class HystrixCircuitBreaker implements CircuitBreaker { - - private HystrixCommand.Setter setter; - - public HystrixCircuitBreaker(HystrixCommand.Setter setter) { - this.setter = setter; - } - - @Override - public T run(Supplier toRun, Function fallback) { - - HystrixCommand command = new HystrixCommand(setter) { - @Override - protected T run() throws Exception { - return toRun.get(); - } - - @Override - protected T getFallback() { - return fallback.apply(getExecutionException()); - } - }; - return command.execute(); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerAutoConfiguration.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerAutoConfiguration.java deleted file mode 100644 index 5cb1a8c18..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerAutoConfiguration.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.hystrix.Hystrix; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; -import org.springframework.cloud.client.circuitbreaker.Customizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Ryan Baxter - * @author Eric Bussieres - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ Hystrix.class }) -@ConditionalOnProperty(name = "spring.cloud.circuitbreaker.hystrix.enabled", - matchIfMissing = true) -public class HystrixCircuitBreakerAutoConfiguration { - - @Autowired(required = false) - private List> customizers = new ArrayList<>(); - - @Bean - @ConditionalOnMissingBean(CircuitBreakerFactory.class) - public CircuitBreakerFactory hystrixCircuitBreakerFactory() { - HystrixCircuitBreakerFactory factory = new HystrixCircuitBreakerFactory(); - customizers.forEach(customizer -> customizer.customize(factory)); - return factory; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerConfiguration.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerConfiguration.java deleted file mode 100644 index 11dbc9f2a..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerConfiguration.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import com.netflix.hystrix.Hystrix; -import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect; -import org.apache.catalina.core.ApplicationContext; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.actuator.NamedFeature; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - * @author Christian Dupuis - * @author Venil Noronha - */ -@Configuration(proxyBeanMethods = false) -public class HystrixCircuitBreakerConfiguration { - - @Bean - public HystrixCommandAspect hystrixCommandAspect() { - return new HystrixCommandAspect(); - } - - @Bean - public HystrixShutdownHook hystrixShutdownHook() { - return new HystrixShutdownHook(); - } - - @Bean - public HasFeatures hystrixFeature() { - return HasFeatures - .namedFeatures(new NamedFeature("Hystrix", HystrixCommandAspect.class)); - } - - /** - * {@link DisposableBean} that makes sure that Hystrix internal state is cleared when - * {@link ApplicationContext} shuts down. - */ - private class HystrixShutdownHook implements DisposableBean { - - @Override - public void destroy() throws Exception { - // Just call Hystrix to reset thread pool etc. - Hystrix.reset(); - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerFactory.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerFactory.java deleted file mode 100644 index 4b0b91e8c..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerFactory.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2013-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.util.function.Function; - -import com.netflix.hystrix.HystrixCommand; -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; - -import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; -import org.springframework.util.Assert; - -/** - * Builds Hystrix circuit breakers. - * - * @author Ryan Baxter - */ -public class HystrixCircuitBreakerFactory extends - CircuitBreakerFactory { - - private Function defaultConfiguration = id -> HystrixCommand.Setter - .withGroupKey( - HystrixCommandGroupKey.Factory.asKey(getClass().getSimpleName())) - .andCommandKey(HystrixCommandKey.Factory.asKey(id)); - - public void configureDefault( - Function defaultConfiguration) { - this.defaultConfiguration = defaultConfiguration; - } - - public HystrixConfigBuilder configBuilder(String id) { - return new HystrixConfigBuilder(id); - } - - public HystrixCircuitBreaker create(String id) { - Assert.hasText(id, "A CircuitBreaker must have an id."); - HystrixCommand.Setter setter = getConfigurations().computeIfAbsent(id, - defaultConfiguration); - return new HystrixCircuitBreaker(setter); - } - - public static class HystrixConfigBuilder - extends AbstractHystrixConfigBuilder { - - public HystrixConfigBuilder(String id) { - super(id); - } - - @Override - public HystrixCommand.Setter build() { - return HystrixCommand.Setter.withGroupKey(getGroupKey()) - .andCommandKey(getCommandKey()) - .andCommandPropertiesDefaults(getCommandPropertiesSetter()); - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCommands.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCommands.java deleted file mode 100644 index 1eca90075..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCommands.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.util.function.Function; - -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.HystrixObservableCommand; -import com.netflix.hystrix.HystrixObservableCommand.Setter; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import rx.Observable; -import rx.RxReactiveStreams; - -import org.springframework.util.StringUtils; - -/** - * Utility class to wrap a {@see Publisher} in a {@see HystrixObservableCommand}. Good for - * use in a Spring WebFlux application. Allows more flexibility than the @HystrixCommand - * annotation. - * - * @author Spencer Gibb - */ -public final class HystrixCommands { - - private HystrixCommands() { - throw new AssertionError("Must not instantiate utility class."); - } - - /** - * @param publisher A {@link Publisher} to pass to the new - * {@link PublisherHystrixCommand} - * @param type of the {@link Publisher}s to be built by the returned builder - * @return a builder for Hystrix-command-specific {@link Publisher}s - */ - public static PublisherBuilder from(Publisher publisher) { - return new PublisherBuilder<>(publisher); - } - - /** - * A builder class for building Hystrix-command-specific {@link Publisher}s. - * - * @param type of the {@link Publisher}s to be built - */ - public static class PublisherBuilder { - - private final Publisher publisher; - - private String commandName; - - private String groupName; - - private Function> fallback; - - private Setter setter; - - private HystrixCommandProperties.Setter commandProperties; - - private boolean eager = false; - - private Function, Observable> toObservable; - - public PublisherBuilder(Publisher publisher) { - this.publisher = publisher; - } - - public PublisherBuilder commandName(String commandName) { - this.commandName = commandName; - return this; - } - - public PublisherBuilder groupName(String groupName) { - this.groupName = groupName; - return this; - } - - public PublisherBuilder fallback(Publisher fallback) { - this.fallback = throwable -> fallback; - return this; - } - - public PublisherBuilder fallback(Function> fallback) { - this.fallback = fallback; - return this; - } - - public PublisherBuilder setter(Setter setter) { - this.setter = setter; - return this; - } - - public PublisherBuilder commandProperties( - HystrixCommandProperties.Setter commandProperties) { - this.commandProperties = commandProperties; - return this; - } - - public PublisherBuilder commandProperties( - Function commandProperties) { - if (commandProperties == null) { - throw new IllegalArgumentException( - "commandProperties must not both be null"); - } - return this.commandProperties( - commandProperties.apply(HystrixCommandProperties.Setter())); - } - - public PublisherBuilder eager() { - this.eager = true; - return this; - } - - public PublisherBuilder toObservable( - Function, Observable> toObservable) { - this.toObservable = toObservable; - return this; - } - - public Publisher build() { - if (!StringUtils.hasText(commandName) && setter == null) { - throw new IllegalStateException( - "commandName and setter can not both be empty"); - } - Setter setterToUse = getSetter(); - - PublisherHystrixCommand command = new PublisherHystrixCommand<>( - setterToUse, this.publisher, this.fallback); - - Observable observable = getObservableFunction().apply(command); - - return RxReactiveStreams.toPublisher(observable); - } - - public Function, Observable> getObservableFunction() { - Function, Observable> observableFunc; - - if (this.toObservable != null) { - observableFunc = this.toObservable; - } - else if (this.eager) { - observableFunc = cmd -> cmd.observe(); - } - else { // apply a default onBackpressureBuffer if not eager - observableFunc = cmd -> cmd.toObservable().onBackpressureBuffer(); - } - return observableFunc; - } - - public Setter getSetter() { - Setter setterToUse; - if (this.setter != null) { - setterToUse = this.setter; - } - else { - String groupNameToUse; - if (StringUtils.hasText(this.groupName)) { - groupNameToUse = this.groupName; - } - else { - groupNameToUse = commandName + "group"; - } - - HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory - .asKey(groupNameToUse); - HystrixCommandKey commandKey = HystrixCommandKey.Factory - .asKey(this.commandName); - HystrixCommandProperties.Setter commandProperties = this.commandProperties != null - ? this.commandProperties : HystrixCommandProperties.Setter(); - setterToUse = Setter.withGroupKey(groupKey).andCommandKey(commandKey) - .andCommandPropertiesDefaults(commandProperties); - } - return setterToUse; - } - - public Flux toFlux() { - return Flux.from(build()); - } - - public Mono toMono() { - return Mono.from(build()); - } - - } - - private static class PublisherHystrixCommand extends HystrixObservableCommand { - - private Publisher publisher; - - private Function> fallback; - - protected PublisherHystrixCommand(Setter setter, Publisher publisher, - Function> fallback) { - super(setter); - this.publisher = publisher; - this.fallback = fallback; - } - - @Override - protected Observable construct() { - return RxReactiveStreams.toObservable(publisher); - } - - @Override - protected Observable resumeWithFallback() { - if (this.fallback != null) { - Publisher fallbackPublisher = fallback.apply(getExecutionException()); - return RxReactiveStreams.toObservable(fallbackPublisher); - } - return super.resumeWithFallback(); - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixConstants.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixConstants.java deleted file mode 100644 index f4a035b55..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixConstants.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -/** - * @author Spencer Gibb - */ -public final class HystrixConstants { - - /** - * Hystrix stream destination name. - */ - public static final String HYSTRIX_STREAM_DESTINATION = "springCloudHystrixStream"; - - private HystrixConstants() { - throw new AssertionError("Must not instantiate constant utility class"); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixHealthIndicator.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixHealthIndicator.java deleted file mode 100644 index 838ce1dbe..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixHealthIndicator.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.hystrix.HystrixCircuitBreaker; -import com.netflix.hystrix.HystrixCommandMetrics; - -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health.Builder; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; - -/** - * A {@link HealthIndicator} implementation for Hystrix circuit breakers. - *

- * This default implementation will not change the system state (e.g. OK) but - * includes all open circuits by name. - * - * @author Christian Dupuis - */ -public class HystrixHealthIndicator extends AbstractHealthIndicator { - - private static final Status CIRCUIT_OPEN = new Status("CIRCUIT_OPEN"); - - @Override - protected void doHealthCheck(Builder builder) throws Exception { - List openCircuitBreakers = new ArrayList<>(); - - // Collect all open circuit breakers from Hystrix - for (HystrixCommandMetrics metrics : HystrixCommandMetrics.getInstances()) { - HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory - .getInstance(metrics.getCommandKey()); - if (circuitBreaker != null && circuitBreaker.isOpen()) { - openCircuitBreakers.add(metrics.getCommandGroup().name() + "::" - + metrics.getCommandKey().name()); - } - } - - // If there is at least one open circuit report OUT_OF_SERVICE adding the command - // group - // and key name - if (!openCircuitBreakers.isEmpty()) { - builder.status(CIRCUIT_OPEN).withDetail("openCircuitBreakers", - openCircuitBreakers); - } - else { - builder.up(); - } - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixMetricsProperties.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixMetricsProperties.java deleted file mode 100644 index dc45c3ead..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixMetricsProperties.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.util.Objects; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Venil Noronha - * @author Gregor Zurowski - */ -@ConfigurationProperties("hystrix.metrics") -public class HystrixMetricsProperties { - - /** Enable Hystrix metrics polling. Defaults to true. */ - private boolean enabled = true; - - /** Interval between subsequent polling of metrics. Defaults to 2000 ms. */ - private Integer pollingIntervalMs = 2000; - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public Integer getPollingIntervalMs() { - return pollingIntervalMs; - } - - public void setPollingIntervalMs(Integer pollingIntervalMs) { - this.pollingIntervalMs = pollingIntervalMs; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - HystrixMetricsProperties that = (HystrixMetricsProperties) o; - return enabled == that.enabled - && Objects.equals(pollingIntervalMs, that.pollingIntervalMs); - } - - @Override - public int hashCode() { - return Objects.hash(enabled, pollingIntervalMs); - } - - @Override - public String toString() { - return new StringBuilder("HystrixMetricsProperties{").append("enabled=") - .append(enabled).append(", ").append("pollingIntervalMs=") - .append(pollingIntervalMs).append("}").toString(); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixProperties.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixProperties.java deleted file mode 100644 index a08fb0ce0..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixProperties.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Configuration properties for Hystrix Servlet. - * - * @author Spencer Gibb - * @since 2.0.0 - */ -@ConfigurationProperties(prefix = "management.endpoint.hystrix") -public class HystrixProperties { - - /** - * Hystrix settings. These are traditionally set using servlet parameters. Refer to - * the documentation of Hystrix for more details. - */ - private final Map config = new HashMap<>(); - - public Map getConfig() { - return this.config; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpoint.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpoint.java deleted file mode 100644 index f4982aaee..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpoint.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.util.Map; -import java.util.function.Supplier; - -import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet; - -import org.springframework.boot.actuate.endpoint.web.EndpointServlet; -import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint; - -/** - * {@link org.springframework.boot.actuate.endpoint.annotation.Endpoint} to expose a - * Jolokia {@link HystrixMetricsStreamServlet}. - * - * @author Phillip Webb - * @since 2.0.0 - */ -@ServletEndpoint(id = "hystrix.stream") -public class HystrixStreamEndpoint implements Supplier { - - private final Map initParameters; - - public HystrixStreamEndpoint(Map initParameters) { - this.initParameters = initParameters; - } - - @Override - public EndpointServlet get() { - return new EndpointServlet(HystrixMetricsStreamServlet.class) - .withInitParameters(this.initParameters); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixWebfluxEndpoint.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixWebfluxEndpoint.java deleted file mode 100644 index 80fda4ca0..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixWebfluxEndpoint.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.time.Duration; - -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; - -import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; - -/** - * @author Spencer Gibb - */ -@RestControllerEndpoint(id = "hystrix.stream") -public class HystrixWebfluxEndpoint { - - private final Flux stream; - - public HystrixWebfluxEndpoint(Publisher dashboardData) { - stream = Flux.interval(Duration.ofMillis(500)).map(aLong -> "{\"type\":\"ping\"}") - .mergeWith(dashboardData).share(); - } - - // path needs to be empty, so it registers correct as /actuator/hystrix.stream - @GetMapping(path = "", produces = MediaType.TEXT_EVENT_STREAM_VALUE) - public Flux hystrixStream() { - return stream; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreaker.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreaker.java deleted file mode 100644 index 699a0481f..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreaker.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2013-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.util.function.Function; - -import com.netflix.hystrix.HystrixObservableCommand; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import rx.Observable; -import rx.RxReactiveStreams; -import rx.Subscription; - -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker; - -/** - * @author Ryan Baxter - */ -public class ReactiveHystrixCircuitBreaker implements ReactiveCircuitBreaker { - - private HystrixObservableCommand.Setter setter; - - public ReactiveHystrixCircuitBreaker(HystrixObservableCommand.Setter setter) { - this.setter = setter; - } - - @Override - public Mono run(Mono toRun, Function> fallback) { - HystrixObservableCommand command = createCommand(toRun, fallback); - - return Mono.create(s -> { - Subscription sub = command.toObservable().subscribe(s::success, s::error, - s::success); - s.onCancel(sub::unsubscribe); - }); - } - - @Override - public Flux run(Flux toRun, Function> fallback) { - HystrixObservableCommand command = createCommand(toRun, fallback); - - return Flux.create(s -> { - Subscription sub = command.toObservable().subscribe(s::next, s::error, - s::complete); - s.onCancel(sub::unsubscribe); - }); - } - - private HystrixObservableCommand createCommand(Publisher toRun, - Function fallback) { - HystrixObservableCommand command = new HystrixObservableCommand(setter) { - @Override - protected Observable construct() { - return RxReactiveStreams.toObservable(toRun); - } - - @Override - protected Observable resumeWithFallback() { - if (fallback == null) { - super.resumeWithFallback(); - } - return RxReactiveStreams.toObservable( - (Publisher) fallback.apply(this.getExecutionException())); - } - }; - return command; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerAutoConfiguration.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerAutoConfiguration.java deleted file mode 100644 index ff9459a25..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerAutoConfiguration.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.client.circuitbreaker.Customizer; -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Eric Bussieres - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(name = { "reactor.core.publisher.Mono", "reactor.core.publisher.Flux", - "com.netflix.hystrix.Hystrix" }) -@ConditionalOnProperty(name = "spring.cloud.circuitbreaker.hystrix.enabled", - matchIfMissing = true) -public class ReactiveHystrixCircuitBreakerAutoConfiguration { - - @Autowired(required = false) - private List> customizers = new ArrayList<>(); - - @Bean - @ConditionalOnMissingBean(ReactiveCircuitBreakerFactory.class) - public ReactiveHystrixCircuitBreakerFactory reactiveHystrixCircuitBreakerFactory() { - ReactiveHystrixCircuitBreakerFactory factory = new ReactiveHystrixCircuitBreakerFactory(); - customizers.forEach(customizer -> customizer.customize(factory)); - return factory; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerFactory.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerFactory.java deleted file mode 100644 index db8a70eb7..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerFactory.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2013-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.util.function.Function; - -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixObservableCommand; - -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker; -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory; -import org.springframework.util.Assert; - -/** - * @author Ryan Baxter - */ -public class ReactiveHystrixCircuitBreakerFactory extends - ReactiveCircuitBreakerFactory { - - private Function defaultConfiguration = id -> HystrixObservableCommand.Setter - .withGroupKey( - HystrixCommandGroupKey.Factory.asKey(getClass().getSimpleName())) - .andCommandKey(HystrixCommandKey.Factory.asKey(id)); - - @Override - protected ReactiveHystrixConfigBuilder configBuilder(String id) { - return new ReactiveHystrixConfigBuilder(id); - } - - @Override - public void configureDefault( - Function defaultConfiguration) { - this.defaultConfiguration = defaultConfiguration; - } - - @Override - public ReactiveCircuitBreaker create(String id) { - Assert.hasText(id, "A CircuitBreaker must have an id."); - HystrixObservableCommand.Setter setter = getConfigurations().computeIfAbsent(id, - defaultConfiguration); - return new ReactiveHystrixCircuitBreaker(setter); - } - - public static class ReactiveHystrixConfigBuilder - extends AbstractHystrixConfigBuilder { - - public ReactiveHystrixConfigBuilder(String id) { - super(id); - } - - @Override - public HystrixObservableCommand.Setter build() { - return HystrixObservableCommand.Setter.withGroupKey(getGroupKey()) - .andCommandKey(getCommandKey()) - .andCommandPropertiesDefaults(getCommandPropertiesSetter()); - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityAutoConfiguration.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityAutoConfiguration.java deleted file mode 100644 index 8d4bb55ba..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityAutoConfiguration.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.security; - -import javax.annotation.PostConstruct; - -import com.netflix.hystrix.Hystrix; -import com.netflix.hystrix.strategy.HystrixPlugins; -import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; -import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategyDefault; -import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; -import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook; -import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher; -import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.AllNestedConditions; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration.HystrixSecurityCondition; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.core.context.SecurityContext; - -/** - * @author Daniel Lavoie - */ -@Configuration(proxyBeanMethods = false) -@Conditional(HystrixSecurityCondition.class) -@ConditionalOnClass({ Hystrix.class, SecurityContext.class }) -public class HystrixSecurityAutoConfiguration { - - private static final Log LOGGER = LogFactory - .getLog(HystrixSecurityAutoConfiguration.class); - - @Autowired(required = false) - private HystrixConcurrencyStrategy existingConcurrencyStrategy; - - @PostConstruct - public void init() { - // Keeps references of existing Hystrix plugins. - HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance() - .getEventNotifier(); - HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance() - .getMetricsPublisher(); - HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance() - .getPropertiesStrategy(); - HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance() - .getCommandExecutionHook(); - HystrixConcurrencyStrategy concurrencyStrategy = detectRegisteredConcurrencyStrategy(); - - HystrixPlugins.reset(); - - // Registers existing plugins excepts the Concurrent Strategy plugin. - HystrixPlugins.getInstance().registerConcurrencyStrategy( - new SecurityContextConcurrencyStrategy(concurrencyStrategy)); - HystrixPlugins.getInstance().registerEventNotifier(eventNotifier); - HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher); - HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy); - HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook); - } - - private HystrixConcurrencyStrategy detectRegisteredConcurrencyStrategy() { - HystrixConcurrencyStrategy registeredStrategy = HystrixPlugins.getInstance() - .getConcurrencyStrategy(); - if (existingConcurrencyStrategy == null) { - return registeredStrategy; - } - // Hystrix registered a default Strategy. - if (registeredStrategy instanceof HystrixConcurrencyStrategyDefault) { - return existingConcurrencyStrategy; - } - // If registeredStrategy not the default and not some use bean of - // existingConcurrencyStrategy. - if (!existingConcurrencyStrategy.equals(registeredStrategy)) { - LOGGER.warn( - "Multiple HystrixConcurrencyStrategy detected. Bean of HystrixConcurrencyStrategy was used."); - } - return existingConcurrencyStrategy; - } - - static class HystrixSecurityCondition extends AllNestedConditions { - - HystrixSecurityCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnProperty(name = "hystrix.shareSecurityContext") - static class ShareSecurityContext { - - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/security/SecurityContextConcurrencyStrategy.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/security/SecurityContextConcurrencyStrategy.java deleted file mode 100644 index 56235f0b5..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/security/SecurityContextConcurrencyStrategy.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.security; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.Callable; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import com.netflix.hystrix.HystrixThreadPoolKey; -import com.netflix.hystrix.HystrixThreadPoolProperties; -import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; -import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable; -import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle; -import com.netflix.hystrix.strategy.properties.HystrixProperty; - -import org.springframework.security.concurrent.DelegatingSecurityContextCallable; - -/** - * @author Daniel Lavoie - */ -public class SecurityContextConcurrencyStrategy extends HystrixConcurrencyStrategy { - - private HystrixConcurrencyStrategy existingConcurrencyStrategy; - - public SecurityContextConcurrencyStrategy( - HystrixConcurrencyStrategy existingConcurrencyStrategy) { - this.existingConcurrencyStrategy = existingConcurrencyStrategy; - } - - @Override - public BlockingQueue getBlockingQueue(int maxQueueSize) { - return existingConcurrencyStrategy != null - ? existingConcurrencyStrategy.getBlockingQueue(maxQueueSize) - : super.getBlockingQueue(maxQueueSize); - } - - @Override - public HystrixRequestVariable getRequestVariable( - HystrixRequestVariableLifecycle rv) { - return existingConcurrencyStrategy != null - ? existingConcurrencyStrategy.getRequestVariable(rv) - : super.getRequestVariable(rv); - } - - @Override - public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, - HystrixProperty corePoolSize, - HystrixProperty maximumPoolSize, - HystrixProperty keepAliveTime, TimeUnit unit, - BlockingQueue workQueue) { - return existingConcurrencyStrategy != null - ? existingConcurrencyStrategy.getThreadPool(threadPoolKey, corePoolSize, - maximumPoolSize, keepAliveTime, unit, workQueue) - : super.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, - keepAliveTime, unit, workQueue); - } - - @Override - public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, - HystrixThreadPoolProperties threadPoolProperties) { - return existingConcurrencyStrategy != null - ? existingConcurrencyStrategy.getThreadPool(threadPoolKey, - threadPoolProperties) - : super.getThreadPool(threadPoolKey, threadPoolProperties); - } - - @Override - public Callable wrapCallable(Callable callable) { - return existingConcurrencyStrategy != null - ? existingConcurrencyStrategy - .wrapCallable(new DelegatingSecurityContextCallable(callable)) - : super.wrapCallable(new DelegatingSecurityContextCallable(callable)); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-netflix-hystrix/src/main/resources/META-INF/additional-spring-configuration-metadata.json deleted file mode 100644 index 216f5dfd8..000000000 --- a/spring-cloud-netflix-hystrix/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "properties": [ - { - "defaultValue": "true", - "name": "management.metrics.binders.hystrix.enabled", - "description": "Enables creation of OK Http Client factory beans.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": false, - "name": "hystrix.shareSecurityContext", - "description": "Enables auto-configuration of the Hystrix concurrency strategy plugin hook who will transfer the `SecurityContext` from your main thread to the one used by the Hystrix command.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": true, - "name": "spring.cloud.circuitbreaker.hystrix.enabled", - "description": "Enables auto-configuration of the Hystrix Spring Cloud CircuitBreaker API implementation.", - "type": "java.lang.Boolean" - } - ] -} \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-hystrix/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 929e0a746..000000000 --- a/spring-cloud-netflix-hystrix/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,8 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.hystrix.HystrixAutoConfiguration,\ -org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerAutoConfiguration,\ -org.springframework.cloud.netflix.hystrix.ReactiveHystrixCircuitBreakerAutoConfiguration,\ -org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration - -org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker=\ -org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/AdhocTestSuite.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/AdhocTestSuite.java deleted file mode 100644 index 172b59509..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/AdhocTestSuite.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2012-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix; - -import org.junit.Ignore; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -/** - * A test suite for probing weird ordering problems in the tests. - * - * @author Dave Syer - */ -@RunWith(Suite.class) -@SuiteClasses({ - // org.springframework.cloud.netflix.test.OkHttpClientConfigurationTests.class, - // org.springframework.cloud.netflix.test.ApacheHttpClientConfigurationTests.class, - // org.springframework.cloud.netflix.hystrix.HystrixCommandsTests.class, - // org.springframework.cloud.netflix.hystrix.HystrixOnlyTests.class, - // org.springframework.cloud.netflix.hystrix.security.HystrixSecurityTests.class, - // org.springframework.cloud.netflix.hystrix.security.HystrixSecurityNoFeignTests.class, - // org.springframework.cloud.netflix.hystrix.HystrixStreamEndpointTests.class, - // org.springframework.cloud.netflix.hystrix.HystrixConfigurationTests.class, - // org.springframework.cloud.netflix.resttemplate.RestTemplateRetryTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorOverridesRetryTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonUtilsTests.class, - // org.springframework.cloud.netflix.ribbon.test.RibbonClientDefaultConfigurationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientConfigurationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientHttpRequestFactoryTests.class, - // org.springframework.cloud.netflix.ribbon.SpringRetryEnabledTests.class, - // org.springframework.cloud.netflix.ribbon.PlainRibbonClientPreprocessorIntegrationTests.class, - // org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClientTests.class, - // org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpRequestTests.class, - // org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpResponseTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorIntegrationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientsPreprocessorIntegrationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientsEagerInitializationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonInterceptorTests.class, - // org.springframework.cloud.netflix.ribbon.support.ContextAwareRequestTests.class, - // org.springframework.cloud.netflix.ribbon.support.RibbonCommandContextTest.class, - // org.springframework.cloud.netflix.ribbon.support.RetryableStatusCodeExceptionTests.class, - // org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilterTests.class, - // org.springframework.cloud.netflix.ribbon.DefaultServerIntrospectorDefaultTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorPropertiesOverridesIntegrationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactoryTests.class, - // org.springframework.cloud.netflix.ribbon.SpringClientFactoryTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonAutoConfigurationIntegrationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClientTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorOverridesIntegrationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonApplicationContextInitializerTests.class, - // org.springframework.cloud.netflix.ribbon.okhttp.SpringRetryDisableOkHttpClientTests.class, - // org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonResponseTests.class, - // org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClientTests.class, - // org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonRequestTests.class, - // org.springframework.cloud.netflix.ribbon.okhttp.SpringRetryEnabledOkHttpClientTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientConfigurationIntegrationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonDisabledTests.class, - // org.springframework.cloud.netflix.ribbon.DefaultServerIntrospectorTests.class, - // org.springframework.cloud.netflix.ribbon.SpringRetryDisabledTests.class, - // org.springframework.cloud.netflix.feign.beans.FeignClientTests.class, - // org.springframework.cloud.netflix.feign.FeignClientsRegistrarTests.class, - // org.springframework.cloud.netflix.feign.encoding.FeignAcceptEncodingTests.class, - // org.springframework.cloud.netflix.feign.encoding.FeignContentEncodingTests.class, - // org.springframework.cloud.netflix.feign.FeignLoggerFactoryTests.class, - // org.springframework.cloud.netflix.feign.FeignCompressionTests.class, - // org.springframework.cloud.netflix.feign.EnableFeignClientsTests.class, - // org.springframework.cloud.netflix.feign.SpringDecoderTests.class, - // org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests.class, - // org.springframework.cloud.netflix.feign.FeignHttpClientUrlTests.class, - // org.springframework.cloud.netflix.feign.invalid.FeignClientValidationTests.class, - // org.springframework.cloud.netflix.feign.support.FeignHttpClientPropertiesTests.class, - // org.springframework.cloud.netflix.feign.support.SpringMvcContractTests.class, - // org.springframework.cloud.netflix.feign.support.SpringEncoderTests.class, - // org.springframework.cloud.netflix.feign.FeignClientOverrideDefaultsTests.class, - // org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClientOverrideTests.class, - // org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientPathTests.class, - // org.springframework.cloud.netflix.feign.ribbon.RetryableFeignLoadBalancerTests.class, - // org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientRetryTests.class, - // org.springframework.cloud.netflix.feign.ribbon.FeignLoadBalancerTests.class, - // org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientTests.class, - // org.springframework.cloud.netflix.feign.ribbon.CachingSpringLoadBalancerFactoryTests.class, - // org.springframework.cloud.netflix.feign.valid.scanning.FeignClientEnvVarTests.class, - // org.springframework.cloud.netflix.feign.valid.scanning.FeignClientScanningTests.class, - // org.springframework.cloud.netflix.feign.valid.FeignOkHttpTests.class, - // org.springframework.cloud.netflix.feign.valid.FeignClientValidationTests.class, - // org.springframework.cloud.netflix.feign.valid.FeignClientTests.class, - // org.springframework.cloud.netflix.feign.valid.FeignHttpClientTests.class, - // org.springframework.cloud.netflix.feign.valid.FeignClientNotPrimaryTests.class, - // org.springframework.cloud.netflix.feign.FeignClientFactoryTests.class, - -}) -@Ignore -public class AdhocTestSuite { - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfigurationTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfigurationTests.java deleted file mode 100644 index c16111be4..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfigurationTests.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; -import org.springframework.context.ConfigurableApplicationContext; - -import static org.assertj.core.api.Assertions.fail; - -@RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({ "micrometer-core-*" }) -public class HystrixAutoConfigurationTests { - - @Test - @Ignore // TODO: why does this test fail in maven, but not in IDE? - public void contextStarts() { - try (ConfigurableApplicationContext context = new SpringApplicationBuilder() - .web(WebApplicationType.NONE).sources(TestApp.class).run()) { - try { - context.getBean("hystrixMetricsBinder"); - fail("HystrixMetricsBinder class should not be found"); - } - catch (NoSuchBeanDefinitionException e) { - // this is the correct case - } - } - } - - @EnableCircuitBreaker - @SpringBootConfiguration - @EnableAutoConfiguration - protected static class TestApp { - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerIntegrationTest.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerIntegrationTest.java deleted file mode 100644 index ddd432793..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerIntegrationTest.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2013-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import com.netflix.hystrix.HystrixCommand; -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandProperties; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.cloud.client.circuitbreaker.CircuitBreaker; -import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; -import org.springframework.cloud.client.circuitbreaker.Customizer; -import org.springframework.cloud.netflix.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.stereotype.Service; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - classes = HystrixCircuitBreakerIntegrationTest.Application.class) -@DirtiesContext -@Import(NoSecurityConfiguration.class) -public class HystrixCircuitBreakerIntegrationTest { - - @Autowired - Application.DemoControllerService service; - - @Test - public void testSlow() { - assertThat(service.slow()).isEqualTo("fallback"); - } - - @Test - public void testNormal() { - assertThat(service.normal()).isEqualTo("normal"); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - protected static class Application { - - @RequestMapping("/slow") - public String slow() throws InterruptedException { - Thread.sleep(3000); - return "slow"; - } - - @GetMapping("/normal") - public String normal() { - return "normal"; - } - - @Bean - public Customizer customizer() { - return factory -> factory - .configure( - builder -> builder.commandProperties(HystrixCommandProperties - .Setter().withExecutionTimeoutInMilliseconds(2000)), - "slow"); - } - - @Bean - public Customizer defaultConfig() { - return factory -> factory.configureDefault(id -> HystrixCommand.Setter - .withGroupKey(HystrixCommandGroupKey.Factory.asKey(id)) - .andCommandPropertiesDefaults(HystrixCommandProperties.Setter() - .withExecutionTimeoutInMilliseconds(4000))); - } - - @Service - public static class DemoControllerService { - - private TestRestTemplate rest; - - private final CircuitBreakerFactory cbFactory; - - private final CircuitBreaker circuitBreakerSlow; - - DemoControllerService(TestRestTemplate rest, - CircuitBreakerFactory cbBuilder) { - this.rest = rest; - this.cbFactory = cbBuilder; - this.circuitBreakerSlow = cbBuilder.create("slow"); - } - - public String slow() { - return circuitBreakerSlow.run( - () -> rest.getForObject("/slow", String.class), t -> "fallback"); - } - - public String normal() { - return cbFactory.create("normal").run( - () -> rest.getForObject("/normal", String.class), - t -> "fallback"); - } - - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerTest.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerTest.java deleted file mode 100644 index 1a974c249..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2013-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import org.junit.Test; - -import org.springframework.cloud.client.circuitbreaker.CircuitBreaker; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - */ -public class HystrixCircuitBreakerTest { - - @Test - public void run() { - CircuitBreaker cb = new HystrixCircuitBreakerFactory().create("foo"); - String s = cb.run(() -> "foobar", t -> "fallback"); - assertThat(cb.run(() -> "foobar", t -> "fallback")).isEqualTo("foobar"); - } - - @Test - public void fallback() { - CircuitBreaker cb = new HystrixCircuitBreakerFactory().create("foo"); - assertThat((String) cb.run(() -> { - throw new RuntimeException("Boom"); - }, t -> "fallback")).isEqualTo("fallback"); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCommandsTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCommandsTests.java deleted file mode 100644 index e92691093..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCommandsTests.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.time.Duration; - -import com.netflix.hystrix.exception.HystrixRuntimeException; -import org.junit.Test; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -public class HystrixCommandsTests { - - @Test - public void monoWorks() { - StepVerifier.create(HystrixCommands.from(Flux.just("works")) - .commandName("testworks").toMono()).expectNext("works").verifyComplete(); - } - - @Test - public void eagerMonoWorks() { - StepVerifier - .create(HystrixCommands.from(Mono.just("works")).eager() - .commandName("testworks").toMono()) - .expectNext("works").verifyComplete(); - } - - @Test - public void monoTimesOut() { - StepVerifier.create(HystrixCommands.from(Mono.fromCallable(() -> { - Thread.sleep(1500); - return "timeout"; - })).commandName("failcmd").toMono()).verifyError(HystrixRuntimeException.class); - } - - @Test - public void monoFallbackWorks() { - StepVerifier - .create(HystrixCommands.from(Mono.error(new Exception())) - .commandName("failcmd").fallback(Mono.just("fallback")).toMono()) - .expectNext("fallback").verifyComplete(); - } - - @Test - public void monoFallbackWithExceptionWorks() { - StepVerifier.create( - HystrixCommands.from(Mono.error(new IllegalStateException())) - .commandName("failcmd").fallback(throwable -> { - if (throwable instanceof IllegalStateException) { - return Mono.just("specificfallback"); - } - return Mono.just("genericfallback"); - }).toMono()) - .expectNext("specificfallback").verifyComplete(); - } - - @Test - public void fluxWorks() { - StepVerifier.create(HystrixCommands.from(Flux.just("1", "2")) - .commandName("multiflux").toFlux()).expectNext("1").expectNext("2") - .verifyComplete(); - } - - @Test - public void fluxWorksDeferredRequest() { - StepVerifier - .create(HystrixCommands.from(Flux.just("1", "2")).commandName("multiflux") - .build(), 1) - .expectNext("1").thenAwait(Duration.ofSeconds(1)).thenRequest(1) - .expectNext("2").verifyComplete(); - } - - @Test - public void toObservableFunctionWorks() { - StepVerifier - .create(HystrixCommands.from(Flux.just("1", "2")).commandName("multiflux") - .toObservable(cmd -> cmd.toObservable()).build(), 1) - .expectNext("1").thenAwait(Duration.ofSeconds(1)).thenRequest(1) - .verifyError(); - } - - @Test - public void eagerFluxWorks() { - StepVerifier - .create(HystrixCommands.from(Flux.just("1", "2")).commandName("multiflux") - .eager().toFlux()) - .expectNext("1").expectNext("2").verifyComplete(); - } - - @Test - public void fluxTimesOut() { - StepVerifier.create(HystrixCommands.from(Flux.from(s -> { - try { - Thread.sleep(1500); - } - catch (InterruptedException e) { - throw new RuntimeException(e); - } - })).commandName("failcmd").toFlux()).verifyError(HystrixRuntimeException.class); - } - - @Test - public void fluxFallbackWorks() { - StepVerifier - .create(HystrixCommands.from(Flux.error(new Exception())) - .commandName("multiflux").fallback(Flux.just("a", "b")).toFlux()) - .expectNext("a").expectNext("b").verifyComplete(); - } - - @Test - public void extendTimeout() { - StepVerifier.create(HystrixCommands.from(Mono.fromCallable(() -> { - Thread.sleep(1500); - return "works"; - })).commandName("extendTimeout") - .commandProperties( - setter -> setter.withExecutionTimeoutInMilliseconds(2000)) - .toMono()).expectNext("works").verifyComplete(); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixConfigurationTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixConfigurationTests.java deleted file mode 100644 index ccfa7be77..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixConfigurationTests.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect; -import io.micrometer.core.instrument.binder.MeterBinder; -import io.micrometer.core.instrument.binder.hystrix.HystrixMetricsBinder; -import org.junit.Test; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * @author Biju Kunjummen - */ -public class HystrixConfigurationTests { - - @Test - public void nonWebAppStartsUp() { - new ApplicationContextRunner() - .withUserConfiguration(HystrixCircuitBreakerConfiguration.class) - .run(c -> { - assertThat(c).hasSingleBean(HystrixCommandAspect.class); - }); - } - - @Test - public void hystrixMetricsConfigured() { - new WebApplicationContextRunner().withUserConfiguration(TestApp.class).run(c -> { - assertThat(c.getBeansOfType(MeterBinder.class).values()) - .hasAtLeastOneElementOfType(HystrixMetricsBinder.class); - }); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - protected static class TestApp { - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixOnlyTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixOnlyTests.java deleted file mode 100644 index 7a1ad2732..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixOnlyTests.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.util.Base64; -import java.util.List; -import java.util.Map; - -import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.cloud.netflix.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; -import static org.springframework.cloud.netflix.test.TestAutoConfiguration.PASSWORD; -import static org.springframework.cloud.netflix.test.TestAutoConfiguration.USER; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = HystrixOnlyApplication.class, webEnvironment = RANDOM_PORT, - properties = { "management.endpoint.health.show-details=ALWAYS" }) -@DirtiesContext -@ActiveProfiles("proxysecurity") -public class HystrixOnlyTests { - - private static final String BASE_PATH = new WebEndpointProperties().getBasePath(); - - @LocalServerPort - private int port; - - @Test - public void testNormalExecution() { - ResponseEntity res = new TestRestTemplate() - .getForEntity("http://localhost:" + this.port + "/", String.class); - assertThat(res.getBody()).as("incorrect response").isEqualTo("Hello world"); - } - - @Test - public void testFailureFallback() { - ResponseEntity res = new TestRestTemplate() - .getForEntity("http://localhost:" + this.port + "/fail", String.class); - assertThat(res.getBody()).as("incorrect fallback") - .isEqualTo("Fallback Hello world"); - } - - @Test - @SuppressWarnings("unchecked") - public void testHystrixHealth() { - Map map = getHealth(); - // https://github.com/spring-projects/spring-boot/issues/17929 - // if the default changes back, this will need to be reverted. - assertThat(map).containsKeys("components"); - Map details = (Map) map.get("components"); - assertThat(details).containsKeys("hystrix"); - Map hystrix = (Map) details.get("hystrix"); - assertThat(hystrix).containsEntry("status", "UP"); - } - - @Test - public void testNoDiscoveryHealth() { - Map map = getHealth(); - // There is explicitly no discovery, so there should be no discovery health key - assertThat(map.containsKey("discovery")) - .as("Incorrect existing discovery health key").isFalse(); - } - - @Test - public void testHystrixInnerMapMetrics() { - // We have to hit any Hystrix command before Hystrix metrics to be populated - String url = "http://localhost:" + this.port; - ResponseEntity response = new TestRestTemplate().getForEntity(url, - String.class); - assertThat(response.getStatusCode()).as("bad response code") - .isEqualTo(HttpStatus.OK); - - // Poller takes some time to realize for new metrics - try { - Thread.sleep(2000); - } - catch (InterruptedException e) { - } - - Map> map = (Map>) getMetrics(); - - assertThat(map.get("names").contains("hystrix.latency.total")) - .as("There is no latencyTotal group key specified").isTrue(); - assertThat(map.get("names").contains("hystrix.latency.execution")) - .as("There is no latencyExecute group key specified").isTrue(); - } - - private Map getMetrics() { - return getAuthenticatedEndpoint("/metrics"); - } - - private Map getHealth() { - return getAuthenticatedEndpoint("/health"); - } - - private Map getAuthenticatedEndpoint(String endpoint) { - return new TestRestTemplate().exchange( - "http://localhost:" + this.port + BASE_PATH + endpoint, HttpMethod.GET, - new HttpEntity(createBasicAuthHeader(USER, PASSWORD)), Map.class) - .getBody(); - } - - public static HttpHeaders createBasicAuthHeader(final String username, - final String password) { - return new HttpHeaders() { - private static final long serialVersionUID = 1766341693637204893L; - - { - String auth = username + ":" + password; - byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes()); - String authHeader = "Basic " + new String(encodedAuth); - this.set("Authorization", authHeader); - } - }; - } - -} - -class Service { - - @HystrixCommand - public String hello() { - return "Hello world"; - } - - @HystrixCommand(fallbackMethod = "fallback") - public String fail() { - throw new RuntimeException("Always fail"); - } - - public String fallback() { - return "Fallback Hello world"; - } - -} - -// Don't use @SpringBootApplication because we don't want to component scan -@Configuration(proxyBeanMethods = false) -@EnableAutoConfiguration -@EnableCircuitBreaker -@RestController -@Import(NoSecurityConfiguration.class) -class HystrixOnlyApplication { - - @Bean - public Service service() { - return new Service(); - } - - @Autowired - private Service service; - - @RequestMapping("/") - public String home() { - return this.service.hello(); - } - - @RequestMapping("/fail") - public String fail() { - return this.service.fail(); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpointTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpointTests.java deleted file mode 100644 index bc0edf471..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpointTests.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - -import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.cloud.netflix.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; - -/** - * @author Dave Syer - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = HystrixStreamEndpointTests.Application.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "spring.application.name=hystrixstreamtest" }) -@DirtiesContext -public class HystrixStreamEndpointTests { - - private static final String BASE_PATH = new WebEndpointProperties().getBasePath(); - - private static final Log log = LogFactory.getLog(HystrixStreamEndpointTests.class); - - @LocalServerPort - private int port = 0; - - @Test - public void hystrixStreamWorks() throws Exception { - String url = "http://localhost:" + port; - // you have to hit a Hystrix circuit breaker before the stream sends anything - ResponseEntity response = new TestRestTemplate().getForEntity(url, - String.class); - assertThat(response.getStatusCode()).as("bad response code") - .isEqualTo(HttpStatus.OK); - - URL hystrixUrl = new URL(url + BASE_PATH + "/hystrix.stream"); - - List data = new ArrayList<>(); - for (int i = 0; i < 5; i++) { - try (InputStream in = hystrixUrl.openStream()) { - byte[] buffer = new byte[1024]; - in.read(buffer); - data.add(new String(buffer)); - } - catch (Exception e) { - log.error("Error getting hystrix stream, try " + i, e); - } - } - - for (String item : data) { - if (item.contains("data:")) { - return; // test passed - } - } - fail("/hystrix.stream didn't contain 'data:' was " + data); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableCircuitBreaker - @Import(NoSecurityConfiguration.class) - protected static class Application { - - @Autowired - Service service; - - @Bean - Service service() { - return new Service(); - } - - @RequestMapping("/") - public String hello() { - return service.hello(); - } - - } - - protected static class Service { - - @HystrixCommand - public String hello() { - return "Hello World"; - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixWebfluxEndpointTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixWebfluxEndpointTests.java deleted file mode 100644 index 82f68fcd3..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixWebfluxEndpointTests.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.util.Map; - -import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Test; -import org.junit.runner.RunWith; -import reactor.core.publisher.Flux; -import reactor.test.StepVerifier; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.cloud.netflix.test.TestAutoConfiguration; -import org.springframework.http.MediaType; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Dave Syer - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - properties = { "spring.main.web-application-type=reactive", - "spring.application.name=hystrixstreamwebfluxtest" /* "debug=true" */ }) -@DirtiesContext -public class HystrixWebfluxEndpointTests { - - private static final String BASE_PATH = new WebEndpointProperties().getBasePath(); - - private static final Log log = LogFactory.getLog(HystrixWebfluxEndpointTests.class); - - @LocalServerPort - private int port; - - @Test - public void hystrixStreamWorks() { - String url = "http://localhost:" + port; - // you have to hit a Hystrix circuit breaker before the stream sends anything - WebTestClient testClient = WebTestClient.bindToServer().baseUrl(url).build(); - testClient.get().uri("/").exchange().expectStatus().isOk(); - - WebClient client = WebClient.create(url); - - Flux result = client.get().uri(BASE_PATH + "/hystrix.stream") - .accept(MediaType.TEXT_EVENT_STREAM).exchange() - .flatMapMany(res -> res.bodyToFlux(Map.class)).take(5) - .filter(map -> "HystrixCommand".equals(map.get("type"))) - .map(map -> (String) map.get("type")); - - StepVerifier.create(result).expectNext("HystrixCommand").thenCancel().verify(); - } - - @RestController - @EnableCircuitBreaker - @EnableAutoConfiguration(exclude = TestAutoConfiguration.class, excludeName = { - "org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration", - "org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration", - "org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration" }) - @SpringBootConfiguration - protected static class Config { - - @HystrixCommand - @RequestMapping("/") - public String hi() { - return "hi"; - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerIntegrationTest.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerIntegrationTest.java deleted file mode 100644 index 4cd3ebeb4..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerIntegrationTest.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2013-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import java.time.Duration; - -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.HystrixObservableCommand; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.client.circuitbreaker.Customizer; -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker; -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory; -import org.springframework.cloud.netflix.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.stereotype.Service; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - classes = ReactiveHystrixCircuitBreakerIntegrationTest.Application.class) -@DirtiesContext -@Import(NoSecurityConfiguration.class) -public class ReactiveHystrixCircuitBreakerIntegrationTest { - - @LocalServerPort - int port = 0; - - @Autowired - ReactiveHystrixCircuitBreakerIntegrationTest.Application.DemoControllerService service; - - @Before - public void setup() { - service.setPort(port); - } - - @Test - public void testSlow() { - assertThat(service.slow().block()).isEqualTo("fallback"); - } - - @Test - public void testNormal() { - assertThat(service.normal().block()).isEqualTo("normal"); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - protected static class Application { - - @RequestMapping("/slow") - public Mono slow() { - return Mono.just("slow").delayElement(Duration.ofSeconds(3)); - } - - @GetMapping("/normal") - public Mono normal() { - return Mono.just("normal"); - } - - @Bean - public Customizer customizer() { - return factory -> factory - .configure( - builder -> builder.commandProperties(HystrixCommandProperties - .Setter().withExecutionTimeoutInMilliseconds(2000)), - "slow"); - } - - @Bean - public Customizer defaultConfig() { - return factory -> factory - .configureDefault(id -> HystrixObservableCommand.Setter - .withGroupKey(HystrixCommandGroupKey.Factory.asKey(id)) - .andCommandPropertiesDefaults(HystrixCommandProperties - .Setter().withExecutionTimeoutInMilliseconds(4000))); - } - - @Service - public static class DemoControllerService { - - private int port = 0; - - private final ReactiveCircuitBreakerFactory cbFactory; - - private final ReactiveCircuitBreaker circuitBreakerSlow; - - DemoControllerService(ReactiveCircuitBreakerFactory cbBuilder) { - this.cbFactory = cbBuilder; - this.circuitBreakerSlow = cbBuilder.create("slow"); - } - - public Mono slow() { - return WebClient.builder().baseUrl("http://localhost:" + port).build() - .get().uri("/slow").retrieve().bodyToMono(String.class) - .transform(it -> circuitBreakerSlow.run(it, t -> { - t.printStackTrace(); - return Mono.just("fallback"); - })); - } - - public Mono normal() { - return WebClient.builder().baseUrl("http://localhost:" + port).build() - .get().uri("/normal").retrieve().bodyToMono(String.class) - .transform(it -> cbFactory.create("normal").run(it, t -> { - t.printStackTrace(); - return Mono.just("fallback"); - })); - } - - public void setPort(int port) { - this.port = port; - } - - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerTest.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerTest.java deleted file mode 100644 index f14c47131..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2013-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix; - -import org.assertj.core.util.Arrays; -import org.junit.Test; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - */ -public class ReactiveHystrixCircuitBreakerTest { - - @Test - public void monoRun() { - ReactiveCircuitBreaker cb = new ReactiveHystrixCircuitBreakerFactory() - .create("foo"); - Mono s = Mono.just("foobar") - .transform(it -> cb.run(it, t -> Mono.just("fallback"))); - assertThat(s.block()).isEqualTo("foobar"); - } - - @Test - public void monoFallback() { - ReactiveCircuitBreaker cb = new ReactiveHystrixCircuitBreakerFactory() - .create("foo"); - assertThat(Mono.error(new RuntimeException("boom")) - .transform(it -> cb.run(it, t -> Mono.just("fallback"))).block()) - .isEqualTo("fallback"); - } - - @Test - public void fluxRun() { - ReactiveCircuitBreaker cb = new ReactiveHystrixCircuitBreakerFactory() - .create("foo"); - Flux s = Flux.just("foobar", "hello world") - .transform(it -> cb.run(it, t -> Flux.just("fallback"))); - assertThat(s.collectList().block()) - .isEqualTo(Arrays.asList(new String[] { "foobar", "hello world" })); - } - - @Test - public void fluxFallback() { - ReactiveCircuitBreaker cb = new ReactiveHystrixCircuitBreakerFactory() - .create("foo"); - assertThat(Flux.error(new RuntimeException("boom")) - .transform(it -> cb.run(it, t -> Flux.just("fallback"))).collectList() - .block()).isEqualTo(Arrays.asList(new String[] { "fallback" })); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityApplication.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityApplication.java deleted file mode 100644 index ff2904ca6..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityApplication.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2013-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.security; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Configuration; - -/** - * @author Daniel Lavoie - */ -@Configuration(proxyBeanMethods = false) -@SpringBootApplication -public class HystrixSecurityApplication { - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityAutoConfigurationTest.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityAutoConfigurationTest.java deleted file mode 100644 index b1d0cf982..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityAutoConfigurationTest.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.security; - -import java.lang.reflect.Field; - -import com.netflix.hystrix.strategy.HystrixPlugins; -import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; -import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategyDefault; -import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; -import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook; -import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher; -import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy; -import org.junit.Test; -import org.mockito.internal.util.reflection.FieldSetter; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author : ailin.zhou - */ -public class HystrixSecurityAutoConfigurationTest { - - @Test - public void testInit() throws NoSuchFieldException, IllegalAccessException { - - // save test context - HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance() - .getEventNotifier(); - HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance() - .getMetricsPublisher(); - HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance() - .getPropertiesStrategy(); - HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance() - .getCommandExecutionHook(); - HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance() - .getConcurrencyStrategy(); - - // test - testForMultiConcurrentStrategy(); - - // recover test context - HystrixPlugins.reset(); - HystrixPlugins.getInstance().registerConcurrencyStrategy(concurrencyStrategy); - HystrixPlugins.getInstance().registerEventNotifier(eventNotifier); - HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher); - HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy); - HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook); - - } - - private void testForMultiConcurrentStrategy() - throws IllegalAccessException, NoSuchFieldException { - HystrixSecurityAutoConfiguration securityStrategy = new HystrixSecurityAutoConfiguration(); - - // 1.existingConcurrencyStrategy is null, registeredStrategy is default - HystrixPlugins.reset(); - securityStrategy.init(); - // result is default - assertThat(getOriginalInSecurityConcurrencyStrategy()) - .isEqualTo(HystrixConcurrencyStrategyDefault.getInstance()); - - // 2.existingConcurrencyStrategy is null, registered strategy is customized - HystrixPlugins.reset(); - HystrixConcurrencyStrategy customized = new HystrixConcurrencyStrategy() { - }; - HystrixPlugins.getInstance().registerConcurrencyStrategy(customized); - securityStrategy.init(); - // result is customized - assertThat(getOriginalInSecurityConcurrencyStrategy()).isEqualTo(customized); - - // 3.existingConcurrencyStrategy is not null, registeredStrategy is default. - HystrixPlugins.reset(); - HystrixConcurrencyStrategy existingConcurrencyStrategy = new HystrixConcurrencyStrategy() { - }; - FieldSetter - .setField(securityStrategy, - securityStrategy.getClass() - .getDeclaredField("existingConcurrencyStrategy"), - existingConcurrencyStrategy); - securityStrategy.init(); - // result is existingConcurrencyStrategy - assertThat(getOriginalInSecurityConcurrencyStrategy()) - .isEqualTo(existingConcurrencyStrategy); - - // 4.existingConcurrencyStrategy is not null, registeredStrategy is customized. - HystrixPlugins.reset(); - HystrixPlugins.getInstance().registerConcurrencyStrategy(customized); - FieldSetter - .setField(securityStrategy, - securityStrategy.getClass() - .getDeclaredField("existingConcurrencyStrategy"), - existingConcurrencyStrategy); - securityStrategy.init(); - assertThat(getOriginalInSecurityConcurrencyStrategy()) - .isEqualTo(existingConcurrencyStrategy); - } - - private HystrixConcurrencyStrategy getOriginalInSecurityConcurrencyStrategy() - throws IllegalAccessException, NoSuchFieldException { - HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance() - .getConcurrencyStrategy(); - Field existingConcurrencyStrategy = concurrencyStrategy.getClass() - .getDeclaredField("existingConcurrencyStrategy"); - existingConcurrencyStrategy.setAccessible(true); - HystrixConcurrencyStrategy strategyInSecurityStrategy = (HystrixConcurrencyStrategy) existingConcurrencyStrategy - .get(concurrencyStrategy); - return strategyInSecurityStrategy; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityNoFeignTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityNoFeignTests.java deleted file mode 100644 index e79b80333..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityNoFeignTests.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.security; - -import com.netflix.hystrix.strategy.HystrixPlugins; -import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringRunner.class) -@DirtiesContext -@SpringBootTest(classes = HystrixSecurityApplication.class) -public class HystrixSecurityNoFeignTests { - - @Test - public void testSecurityConcurrencyStrategyInstalled() { - HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance() - .getConcurrencyStrategy(); - assertThat(concurrencyStrategy) - .isInstanceOf(SecurityContextConcurrencyStrategy.class); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/CustomConcurrenyStrategy.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/CustomConcurrenyStrategy.java deleted file mode 100644 index 5884ffcb5..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/CustomConcurrenyStrategy.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2016-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.security.app; - -import java.util.concurrent.Callable; - -import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; - -import org.springframework.stereotype.Component; - -@Component -public class CustomConcurrenyStrategy extends HystrixConcurrencyStrategy { - - private boolean hookCalled; - - @Override - public Callable wrapCallable(Callable callable) { - this.hookCalled = true; - - return super.wrapCallable(callable); - } - - public boolean isHookCalled() { - return hookCalled; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/UsernameController.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/UsernameController.java deleted file mode 100644 index 91806236f..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/UsernameController.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.hystrix.security.app; - -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * @author Daniel Lavoie - */ -@RestController -@RequestMapping("/username") -public class UsernameController { - - @RequestMapping - public String getUsername(@RequestHeader String username) { - return username; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/resttemplate/RestTemplateRetryTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/resttemplate/RestTemplateRetryTests.java deleted file mode 100644 index 9b990457f..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/resttemplate/RestTemplateRetryTests.java +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.resttemplate; - -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.concurrent.atomic.AtomicInteger; - -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.AvailabilityFilteringRule; -import com.netflix.loadbalancer.BaseLoadBalancer; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.IRule; -import com.netflix.loadbalancer.LoadBalancerBuilder; -import com.netflix.loadbalancer.LoadBalancerStats; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.loadbalancer.ServerStats; -import com.netflix.niws.client.http.HttpClientLoadBalancerErrorHandler; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.loadbalancer.LoadBalanced; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.SocketUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = RestTemplateRetryTests.Application.class, - webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=resttemplatetest", - "logging.level.com.netflix=DEBUG", - "logging.level.org.springframework.cloud.netflix.resttemplate=DEBUG", - "logging.level.com.netflix=DEBUG", "badClients.ribbon.MaxAutoRetries=25", - "badClients.ribbon.OkToRetryOnAllOperations=true", - "ribbon.http.client.enabled" }) -@DirtiesContext -public class RestTemplateRetryTests { - - private static final Log logger = LogFactory.getLog(RestTemplateRetryTests.class); - - @Autowired - private RestTemplate testClient; - - @Before - public void setup() throws Exception { - // Force Ribbon configuration by making one call. - this.testClient.getForObject("http://badClients/ping", Integer.class); - } - - @Test - public void testNullPointer() throws Exception { - - LoadBalancerStats stats = LocalBadClientConfiguration.balancer - .getLoadBalancerStats(); - ServerStats badServer1Stats = stats - .getSingleServerStat(LocalBadClientConfiguration.badServer); - ServerStats badServer2Stats = stats - .getSingleServerStat(LocalBadClientConfiguration.badServer2); - ServerStats goodServerStats = stats - .getSingleServerStat(LocalBadClientConfiguration.goodServer); - - badServer1Stats.clearSuccessiveConnectionFailureCount(); - badServer2Stats.clearSuccessiveConnectionFailureCount(); - int numCalls = 10; - long targetConnectionCount = goodServerStats.getTotalRequestsCount() + numCalls; - - // A null pointer should NOT trigger a circuit breaker. - for (int index = 0; index < numCalls; index++) { - try { - this.testClient.getForObject("http://badClients/null", Integer.class); - } - catch (Exception exception) { - } - } - logServerStats(LocalBadClientConfiguration.badServer); - logServerStats(LocalBadClientConfiguration.badServer2); - logServerStats(LocalBadClientConfiguration.goodServer); - - assertThat(badServer1Stats.isCircuitBreakerTripped()).isTrue(); - assertThat(badServer2Stats.isCircuitBreakerTripped()).isTrue(); - assertThat(targetConnectionCount) - .isLessThanOrEqualTo(goodServerStats.getTotalRequestsCount()); - - // Wait for any timeout thread to finish. - - } - - private void logServerStats(Server server) { - LoadBalancerStats stats = LocalBadClientConfiguration.balancer - .getLoadBalancerStats(); - ServerStats serverStats = stats.getSingleServerStat(server); - logger.debug("Server : " + server.toString() + " : Total Count == " - + serverStats.getTotalRequestsCount() + ", Failure Count == " - + serverStats.getFailureCount() + ", Successive Connection Failure == " - + serverStats.getSuccessiveConnectionFailureCount() - + ", Circuit Breaker ? == " + serverStats.isCircuitBreakerTripped()); - } - - @Test - public void testRestRetries() { - - LoadBalancerStats stats = LocalBadClientConfiguration.balancer - .getLoadBalancerStats(); - ServerStats badServer1Stats = stats - .getSingleServerStat(LocalBadClientConfiguration.badServer); - ServerStats badServer2Stats = stats - .getSingleServerStat(LocalBadClientConfiguration.badServer2); - ServerStats goodServerStats = stats - .getSingleServerStat(LocalBadClientConfiguration.goodServer); - - badServer1Stats.clearSuccessiveConnectionFailureCount(); - badServer2Stats.clearSuccessiveConnectionFailureCount(); - int numCalls = 20; - long targetConnectionCount = goodServerStats.getTotalRequestsCount() + numCalls; - - int hits = 0; - - for (int index = 0; index < numCalls; index++) { - hits = this.testClient.getForObject("http://badClients/good", Integer.class); - } - - logServerStats(LocalBadClientConfiguration.badServer); - logServerStats(LocalBadClientConfiguration.badServer2); - logServerStats(LocalBadClientConfiguration.goodServer); - - assertThat(badServer1Stats.isCircuitBreakerTripped()).isTrue(); - assertThat(badServer2Stats.isCircuitBreakerTripped()).isTrue(); - assertThat(targetConnectionCount) - .isLessThanOrEqualTo(goodServerStats.getTotalRequestsCount()); - assertThat(hits).isGreaterThanOrEqualTo(numCalls); - logger.debug("Retry Hits: " + hits); - } - - @Test - public void testRestRetriesWithReadTimeout() throws Exception { - - LoadBalancerStats stats = LocalBadClientConfiguration.balancer - .getLoadBalancerStats(); - ServerStats badServer1Stats = stats - .getSingleServerStat(LocalBadClientConfiguration.badServer); - ServerStats badServer2Stats = stats - .getSingleServerStat(LocalBadClientConfiguration.badServer2); - ServerStats goodServerStats = stats - .getSingleServerStat(LocalBadClientConfiguration.goodServer); - - badServer1Stats.clearSuccessiveConnectionFailureCount(); - badServer2Stats.clearSuccessiveConnectionFailureCount(); - assertThat(!badServer1Stats.isCircuitBreakerTripped()).isTrue(); - assertThat(!badServer2Stats.isCircuitBreakerTripped()).isTrue(); - - int hits = 0; - - int numCalls = 15; - for (int index = 0; index < numCalls; index++) { - hits = this.testClient.getForObject("http://badClients/timeout", - Integer.class); - } - logServerStats(LocalBadClientConfiguration.badServer); - logServerStats(LocalBadClientConfiguration.badServer2); - logServerStats(LocalBadClientConfiguration.goodServer); - - assertThat(badServer1Stats.isCircuitBreakerTripped()).isTrue(); - assertThat(badServer2Stats.isCircuitBreakerTripped()).isTrue(); - assertThat(!goodServerStats.isCircuitBreakerTripped()).isTrue(); - - // 15 + 4 timeouts. See the endpoint for timeout conditions. - assertThat(hits).isGreaterThanOrEqualTo(numCalls + 4); - - // Wait for any timeout thread to finish. - Thread.sleep(600); - - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @RibbonClient(name = "badClients", configuration = LocalBadClientConfiguration.class) - @Import(NoSecurityConfiguration.class) - public static class Application { - - private AtomicInteger hits = new AtomicInteger(1); - - private AtomicInteger retryHits = new AtomicInteger(1); - - @RequestMapping(method = RequestMethod.GET, value = "/ping") - public int ping() { - return 0; - } - - @RequestMapping(method = RequestMethod.GET, value = "/good") - public int good() { - int lValue = this.hits.getAndIncrement(); - return lValue; - } - - @RequestMapping(method = RequestMethod.GET, value = "/timeout") - public int timeout() throws Exception { - int lValue = this.retryHits.getAndIncrement(); - - // Force the good server to have 2 consecutive errors a couple of times. - if (lValue == 2 || lValue == 3 || lValue == 5 || lValue == 6) { - Thread.sleep(500); - } - return lValue; - } - - @RequestMapping(method = RequestMethod.GET, value = "/null") - public int isNull() throws Exception { - throw new NullPointerException("Null"); - } - - @LoadBalanced - @Bean - RestTemplate restTemplate() { - return new RestTemplate(); - } - - } - - // Load balancer with fixed server list for "local" pointing to localhost - // and some bogus servers are thrown in to test retry - @Configuration(proxyBeanMethods = false) - static class LocalBadClientConfiguration { - - static BaseLoadBalancer balancer; - static Server goodServer; - static Server badServer; - static Server badServer2; - - LocalBadClientConfiguration() { - } - - @Value("${local.server.port}") - private int port = 0; - - @Bean - public IRule loadBalancerRule() { - // This is a good place to try different load balancing rules and how those - // rules - // behave in failure states: BestAvailableRule, WeightedResponseTimeRule, etc - - // This rule just uses a round robin and will skip servers that are in circuit - // breaker state. - return new AvailabilityFilteringRule(); - - } - - @Bean - public ILoadBalancer ribbonLoadBalancer(IClientConfig config, - ServerList serverList, IRule rule, IPing ping) { - - goodServer = new Server("localhost", this.port); - badServer = new Server("mybadhost", 10001); - badServer2 = new Server("localhost", SocketUtils.findAvailableTcpPort()); - - balancer = LoadBalancerBuilder.newBuilder().withClientConfig(config) - .withRule(rule).withPing(ping).buildFixedServerListLoadBalancer( - Arrays.asList(badServer, badServer2, goodServer)); - return balancer; - } - - @Bean - public RetryHandler retryHandler() { - return new OverrideRetryHandler(); - } - - static class OverrideRetryHandler extends HttpClientLoadBalancerErrorHandler { - - OverrideRetryHandler() { - this.circuitRelated.add(UnknownHostException.class); - this.retriable.add(UnknownHostException.class); - } - - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientStatusCodeExceptionTest.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientStatusCodeExceptionTest.java deleted file mode 100644 index 8a5778754..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientStatusCodeExceptionTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.apache; - -import java.io.ByteArrayInputStream; -import java.net.URI; -import java.util.Locale; - -import org.apache.http.Header; -import org.apache.http.HttpEntity; -import org.apache.http.ProtocolVersion; -import org.apache.http.StatusLine; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.entity.BasicHttpEntity; -import org.apache.http.message.BasicHeader; -import org.apache.http.message.BasicStatusLine; -import org.apache.http.util.EntityUtils; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -/** - * @author Ryan Baxter - */ -@RunWith(MockitoJUnitRunner.class) -public class HttpClientStatusCodeExceptionTest { - - @Test - public void getResponse() throws Exception { - CloseableHttpResponse response = mock(CloseableHttpResponse.class); - doReturn(new Locale("en")).when(response).getLocale(); - Header foo = new BasicHeader("foo", "bar"); - Header[] headers = new Header[] { foo }; - doReturn(headers).when(response).getAllHeaders(); - StatusLine statusLine = new BasicStatusLine(new ProtocolVersion("http", 1, 1), - 200, "Success"); - doReturn(statusLine).when(response).getStatusLine(); - BasicHttpEntity entity = new BasicHttpEntity(); - entity.setContent(new ByteArrayInputStream("foo".getBytes())); - entity.setContentLength(3); - doReturn(entity).when(response).getEntity(); - HttpEntity copiedEntity = HttpClientUtils.createEntity(response); - HttpClientStatusCodeException ex = new HttpClientStatusCodeException("service", - response, copiedEntity, new URI("https://service.com")); - assertThat(ex.getResponse().getLocale().toString()).isEqualTo("en"); - assertThat(ex.getResponse().getAllHeaders()).isEqualTo(headers); - assertThat(ex.getResponse().getStatusLine().getReasonPhrase()) - .isEqualTo("Success"); - assertThat(ex.getResponse().getStatusLine().getStatusCode()).isEqualTo(200); - assertThat(ex.getResponse().getStatusLine().getProtocolVersion().getProtocol()) - .isEqualTo("http"); - assertThat(ex.getResponse().getStatusLine().getProtocolVersion().getMajor()) - .isEqualTo(1); - assertThat(ex.getResponse().getStatusLine().getProtocolVersion().getMinor()) - .isEqualTo(1); - assertThat(EntityUtils.toString(ex.getResponse().getEntity())).isEqualTo("foo"); - verify(response, times(1)).close(); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpStatusCodeExceptionTest.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpStatusCodeExceptionTest.java deleted file mode 100644 index 31a231462..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpStatusCodeExceptionTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.okhttp; - -import java.net.URI; - -import okhttp3.Headers; -import okhttp3.MediaType; -import okhttp3.Protocol; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.ResponseBody; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - */ -@RunWith(MockitoJUnitRunner.class) -public class OkHttpStatusCodeExceptionTest { - - @Test - public void getResponse() throws Exception { - Headers headers = new Headers.Builder().add("foo", "bar").build(); - Response response = new Response.Builder().code(200).headers(headers).code(200) - .message("Success") - .body(ResponseBody.create(MediaType.parse("text/plain"), "foo")) - .protocol(Protocol.HTTP_1_1) - .request(new Request.Builder().url("https://service.com").build()) - .build(); - ResponseBody body = response.peekBody(Integer.MAX_VALUE); - OkHttpStatusCodeException ex = new OkHttpStatusCodeException("service", response, - body, new URI("https://service.com")); - assertThat(ex.getResponse().headers()).isEqualTo(headers); - assertThat(ex.getResponse().code()).isEqualTo(200); - assertThat(ex.getResponse().message()).isEqualTo("Success"); - assertThat(ex.getResponse().body().string()).isEqualTo("foo"); - assertThat(ex.getResponse().protocol()).isEqualTo(Protocol.HTTP_1_1); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/test/NoSecurityConfiguration.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/test/NoSecurityConfiguration.java deleted file mode 100644 index 889476863..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/test/NoSecurityConfiguration.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.test; - -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration(proxyBeanMethods = false) -public class NoSecurityConfiguration extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.authorizeRequests().anyRequest().permitAll().and().csrf().disable(); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/test/TestAutoConfiguration.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/test/TestAutoConfiguration.java deleted file mode 100644 index 3b56a87b9..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/test/TestAutoConfiguration.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.test; - -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@Import({ NoopDiscoveryClientAutoConfiguration.class }) -@AutoConfigureBefore(SecurityAutoConfiguration.class) -public class TestAutoConfiguration { - - public static final String USER = "user"; - - public static final String PASSWORD = "{noop}password"; - - @Configuration(proxyBeanMethods = false) - @Order(Ordered.HIGHEST_PRECEDENCE) - protected static class TestSecurityConfiguration - extends WebSecurityConfigurerAdapter { - - TestSecurityConfiguration() { - super(true); - } - - @Bean - public UserDetailsService userDetailsService() { - InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); - manager.createUser( - User.withUsername(USER).password(PASSWORD).roles("USER").build()); - return manager; - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - // super.configure(http); - http.antMatcher("/proxy-username").httpBasic().and().authorizeRequests() - .antMatchers("/**").permitAll(); - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/resources/META-INF/spring.factories b/spring-cloud-netflix-hystrix/src/test/resources/META-INF/spring.factories deleted file mode 100644 index 60ea354e8..000000000 --- a/spring-cloud-netflix-hystrix/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.test.TestAutoConfiguration diff --git a/spring-cloud-netflix-hystrix/src/test/resources/application.yml b/spring-cloud-netflix-hystrix/src/test/resources/application.yml deleted file mode 100644 index 82d37798a..000000000 --- a/spring-cloud-netflix-hystrix/src/test/resources/application.yml +++ /dev/null @@ -1,35 +0,0 @@ -server: - port: 9999 - compression: - enabled: true - min-response-size: 1024 - mime-types: application/xml,application/json -spring: - application: - name: testclient -eureka: - server: - enabled: false - client: - registerWithEureka: false - fetchRegistry: false -#error: -# path: /myerror -hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000 -ribbon: - ConnectTimeout: 3001 - ReadTimeout: 60001 -foo: - ribbon: - ConnectTimeout: 7 - ReadTimeout: 17 -badClients: - ribbon: - MaxAutoRetriesNextServer: 10 - ReadTimeout: 200 -endpoints: - health: - sensitive: false -hystrix: - shareSecurityContext: true -management.endpoints.web.exposure.include: '*' diff --git a/spring-cloud-netflix-hystrix/src/test/resources/archaius_db_store.sql b/spring-cloud-netflix-hystrix/src/test/resources/archaius_db_store.sql deleted file mode 100644 index 6b914cb50..000000000 --- a/spring-cloud-netflix-hystrix/src/test/resources/archaius_db_store.sql +++ /dev/null @@ -1,8 +0,0 @@ -create table if not exists properties ( - property_key VARCHAR(40) NOT NULL PRIMARY KEY, - property_value VARCHAR(255) NOT NULL, -); - -insert into properties(property_key, property_value) values ('db.property','this is a db property'); -insert into properties(property_key, property_value) values ('db.second.property','this is another db property'); - diff --git a/spring-cloud-netflix-hystrix/src/test/resources/config.properties.bak b/spring-cloud-netflix-hystrix/src/test/resources/config.properties.bak deleted file mode 100644 index 1e9c021f4..000000000 --- a/spring-cloud-netflix-hystrix/src/test/resources/config.properties.bak +++ /dev/null @@ -1,2 +0,0 @@ -archaius.file.property=Static config file property -db.second.property=It should be overridden diff --git a/spring-cloud-netflix-hystrix/src/test/resources/static/index.html b/spring-cloud-netflix-hystrix/src/test/resources/static/index.html deleted file mode 100644 index 27f581907..000000000 --- a/spring-cloud-netflix-hystrix/src/test/resources/static/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - -

- File to upload:
Name:

Press here to upload the file via ribbon proxy! -
-
- File to upload:
Name:

Press here to upload the file via direct proxy! -
-
- File to upload:
Name:

Press here to upload the file via proxy servlet! -
-
- File to upload:
Name:

Press here to upload the file directly! -
- - \ No newline at end of file diff --git a/spring-cloud-netflix-ribbon/pom.xml b/spring-cloud-netflix-ribbon/pom.xml deleted file mode 100644 index fa9d6440c..000000000 --- a/spring-cloud-netflix-ribbon/pom.xml +++ /dev/null @@ -1,128 +0,0 @@ - - - - spring-cloud-netflix - org.springframework.cloud - 2.2.2.BUILD-SNAPSHOT - .. - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix-ribbon - - - - org.springframework.boot - spring-boot-starter-web - true - - - org.springframework.boot - spring-boot - true - - - org.springframework.boot - spring-boot-autoconfigure - true - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.cloud - spring-cloud-commons - true - - - org.springframework.cloud - spring-cloud-context - true - - - org.springframework.cloud - spring-cloud-netflix-archaius - - - com.netflix.ribbon - ribbon - true - - - com.netflix.ribbon - ribbon-core - true - - - com.netflix.ribbon - ribbon-httpclient - true - - - com.netflix.ribbon - ribbon-loadbalancer - true - - - - com.sun.jersey.contribs - jersey-apache-client4 - true - - - com.squareup.okhttp3 - okhttp - true - - - org.springframework.retry - spring-retry - true - - - commons-configuration - commons-configuration - true - - - com.netflix.servo - servo-core - true - - - com.netflix.netflix-commons - netflix-commons-util - true - - - com.netflix.hystrix - hystrix-javanica - true - - - org.springframework.cloud - spring-cloud-test-support - test - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.boot - spring-boot-starter-security - test - - - org.springframework.boot - spring-boot-starter-actuator - test - - - \ No newline at end of file diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospector.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospector.java deleted file mode 100644 index 222a832a2..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospector.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.Collections; -import java.util.Map; - -import com.netflix.loadbalancer.Server; - -import org.springframework.beans.factory.annotation.Autowired; - -/** - * @author Spencer Gibb - */ -public class DefaultServerIntrospector implements ServerIntrospector { - - private ServerIntrospectorProperties serverIntrospectorProperties = new ServerIntrospectorProperties(); - - @Autowired(required = false) - public void setServerIntrospectorProperties( - ServerIntrospectorProperties serverIntrospectorProperties) { - this.serverIntrospectorProperties = serverIntrospectorProperties; - } - - @Override - public boolean isSecure(Server server) { - return serverIntrospectorProperties.getSecurePorts().contains(server.getPort()); - } - - @Override - public Map getMetadata(Server server) { - return Collections.emptyMap(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/PropertiesFactory.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/PropertiesFactory.java deleted file mode 100644 index 9786a4e55..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/PropertiesFactory.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2016-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.HashMap; -import java.util.Map; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.IRule; -import com.netflix.loadbalancer.ServerList; -import com.netflix.loadbalancer.ServerListFilter; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.env.Environment; -import org.springframework.util.StringUtils; - -import static org.springframework.cloud.netflix.ribbon.SpringClientFactory.NAMESPACE; - -/** - * @author Spencer Gibb - */ -public class PropertiesFactory { - - @Autowired - private Environment environment; - - private Map classToProperty = new HashMap<>(); - - public PropertiesFactory() { - classToProperty.put(ILoadBalancer.class, "NFLoadBalancerClassName"); - classToProperty.put(IPing.class, "NFLoadBalancerPingClassName"); - classToProperty.put(IRule.class, "NFLoadBalancerRuleClassName"); - classToProperty.put(ServerList.class, "NIWSServerListClassName"); - classToProperty.put(ServerListFilter.class, "NIWSServerListFilterClassName"); - } - - public boolean isSet(Class clazz, String name) { - return StringUtils.hasText(getClassName(clazz, name)); - } - - public String getClassName(Class clazz, String name) { - if (this.classToProperty.containsKey(clazz)) { - String classNameProperty = this.classToProperty.get(clazz); - String className = environment - .getProperty(name + "." + NAMESPACE + "." + classNameProperty); - return className; - } - return null; - } - - @SuppressWarnings("unchecked") - public C get(Class clazz, IClientConfig config, String name) { - String className = getClassName(clazz, name); - if (StringUtils.hasText(className)) { - try { - Class toInstantiate = Class.forName(className); - return (C) SpringClientFactory.instantiateWithConfig(toInstantiate, - config); - } - catch (ClassNotFoundException e) { - throw new IllegalArgumentException("Unknown class to load " + className - + " for class " + clazz + " named " + name); - } - } - return null; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RestClientRibbonConfiguration.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RestClientRibbonConfiguration.java deleted file mode 100644 index 4260027e6..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RestClientRibbonConfiguration.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.niws.client.http.RestClient; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; - -/** - * @author Spencer Gibb - */ -@SuppressWarnings("deprecation") -@Configuration(proxyBeanMethods = false) -@RibbonAutoConfiguration.ConditionalOnRibbonRestClient -class RestClientRibbonConfiguration { - - @RibbonClientName - private String name = "client"; - - /** - * Create a Netflix {@link RestClient} integrated with Ribbon if none already exists - * in the application context. It is not required for Ribbon to work properly and is - * therefore created lazily if ever another component requires it. - * @param config the configuration to use by the underlying Ribbon instance - * @param loadBalancer the load balancer to use by the underlying Ribbon instance - * @param serverIntrospector server introspector to use by the underlying Ribbon - * instance - * @param retryHandler retry handler to use by the underlying Ribbon instance - * @return a {@link RestClient} instances backed by Ribbon - */ - @Bean - @Lazy - @ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class) - public RestClient ribbonRestClient(IClientConfig config, ILoadBalancer loadBalancer, - ServerIntrospector serverIntrospector, RetryHandler retryHandler) { - RestClient client = new RibbonClientConfiguration.OverrideRestClient(config, - serverIntrospector); - client.setLoadBalancer(loadBalancer); - client.setRetryHandler(retryHandler); - return client; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonApplicationContextInitializer.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonApplicationContextInitializer.java deleted file mode 100644 index 1a54530a4..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonApplicationContextInitializer.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.List; - -import org.springframework.boot.context.event.ApplicationReadyEvent; -import org.springframework.context.ApplicationListener; - -/** - * Responsible for eagerly creating the child application context holding the Ribbon - * related configuration. - * - * @author Biju Kunjummen - */ -public class RibbonApplicationContextInitializer - implements ApplicationListener { - - private final SpringClientFactory springClientFactory; - - // List of Ribbon client names - private final List clientNames; - - public RibbonApplicationContextInitializer(SpringClientFactory springClientFactory, - List clientNames) { - this.springClientFactory = springClientFactory; - this.clientNames = clientNames; - } - - protected void initialize() { - if (clientNames != null) { - for (String clientName : clientNames) { - this.springClientFactory.getContext(clientName); - } - } - } - - @Override - public void onApplicationEvent(ApplicationReadyEvent event) { - initialize(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java deleted file mode 100644 index 3755b8750..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.ArrayList; -import java.util.List; - -import com.netflix.client.IClient; -import com.netflix.client.http.HttpRequest; -import com.netflix.ribbon.Ribbon; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.AllNestedConditions; -import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.loadbalancer.AsyncLoadBalancerAutoConfiguration; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.cloud.client.loadbalancer.RestTemplateCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.client.AsyncRestTemplate; -import org.springframework.web.client.RestTemplate; - -/** - * Auto configuration for Ribbon (client side load balancing). - * - * @author Spencer Gibb - * @author Dave Syer - * @author Biju Kunjummen - */ -@Configuration -@Conditional(RibbonAutoConfiguration.RibbonClassesConditions.class) -@RibbonClients -@AutoConfigureAfter( - name = "org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration") -@AutoConfigureBefore({ LoadBalancerAutoConfiguration.class, - AsyncLoadBalancerAutoConfiguration.class }) -@EnableConfigurationProperties({ RibbonEagerLoadProperties.class, - ServerIntrospectorProperties.class }) -public class RibbonAutoConfiguration { - - @Autowired(required = false) - private List configurations = new ArrayList<>(); - - @Autowired - private RibbonEagerLoadProperties ribbonEagerLoadProperties; - - @Bean - public HasFeatures ribbonFeature() { - return HasFeatures.namedFeature("Ribbon", Ribbon.class); - } - - @Bean - public SpringClientFactory springClientFactory() { - SpringClientFactory factory = new SpringClientFactory(); - factory.setConfigurations(this.configurations); - return factory; - } - - @Bean - @ConditionalOnMissingBean(LoadBalancerClient.class) - public LoadBalancerClient loadBalancerClient() { - return new RibbonLoadBalancerClient(springClientFactory()); - } - - @Bean - @ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate") - @ConditionalOnMissingBean - public LoadBalancedRetryFactory loadBalancedRetryPolicyFactory( - final SpringClientFactory clientFactory) { - return new RibbonLoadBalancedRetryFactory(clientFactory); - } - - @Bean - @ConditionalOnMissingBean - public PropertiesFactory propertiesFactory() { - return new PropertiesFactory(); - } - - @Bean - @ConditionalOnProperty("ribbon.eager-load.enabled") - public RibbonApplicationContextInitializer ribbonApplicationContextInitializer() { - return new RibbonApplicationContextInitializer(springClientFactory(), - ribbonEagerLoadProperties.getClients()); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(HttpRequest.class) - @ConditionalOnRibbonRestClient - protected static class RibbonClientHttpRequestFactoryConfiguration { - - @Autowired - private SpringClientFactory springClientFactory; - - @Bean - public RestTemplateCustomizer restTemplateCustomizer( - final RibbonClientHttpRequestFactory ribbonClientHttpRequestFactory) { - return restTemplate -> restTemplate - .setRequestFactory(ribbonClientHttpRequestFactory); - } - - @Bean - public RibbonClientHttpRequestFactory ribbonClientHttpRequestFactory() { - return new RibbonClientHttpRequestFactory(this.springClientFactory); - } - - } - - // TODO: support for autoconfiguring restemplate to use apache http client or okhttp - - @Target({ ElementType.TYPE, ElementType.METHOD }) - @Retention(RetentionPolicy.RUNTIME) - @Documented - @Conditional(OnRibbonRestClientCondition.class) - @interface ConditionalOnRibbonRestClient { - - } - - private static class OnRibbonRestClientCondition extends AnyNestedCondition { - - OnRibbonRestClientCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @Deprecated // remove in Edgware" - @ConditionalOnProperty("ribbon.http.client.enabled") - static class ZuulProperty { - - } - - @ConditionalOnProperty("ribbon.restclient.enabled") - static class RibbonProperty { - - } - - } - - /** - * {@link AllNestedConditions} that checks that either multiple classes are present. - */ - static class RibbonClassesConditions extends AllNestedConditions { - - RibbonClassesConditions() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnClass(IClient.class) - static class IClientPresent { - - } - - @ConditionalOnClass(RestTemplate.class) - static class RestTemplatePresent { - - } - - @SuppressWarnings("deprecation") - @ConditionalOnClass(AsyncRestTemplate.class) - static class AsyncRestTemplatePresent { - - } - - @ConditionalOnClass(Ribbon.class) - static class RibbonPresent { - - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClient.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClient.java deleted file mode 100644 index d2da7ae58..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClient.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.IRule; -import com.netflix.loadbalancer.ServerListFilter; - -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * Declarative configuration for a ribbon client. Add this annotation to any - * @Configuration and then inject a {@link SpringClientFactory} to access the - * client that is created. - * - * @author Dave Syer - */ -@Configuration(proxyBeanMethods = false) -@Import(RibbonClientConfigurationRegistrar.class) -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface RibbonClient { - - /** - * Synonym for name (the name of the client). - * - * @see #name() - * @return name of the Ribbon client - */ - String value() default ""; - - /** - * The name of the ribbon client, uniquely identifying a set of client resources, - * including a load balancer. - * @return name of the Ribbon client - */ - String name() default ""; - - /** - * A custom @Configuration for the ribbon client. Can contain override - * @Bean definition for the pieces that make up the client, for instance - * {@link ILoadBalancer}, {@link ServerListFilter}, {@link IRule}. - * - * @see RibbonClientConfiguration for the defaults - * @return the custom Ribbon client configuration - */ - Class[] configuration() default {}; - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java deleted file mode 100644 index 91198a8f4..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.net.URI; - -import javax.annotation.PostConstruct; - -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ConfigurationBasedServerList; -import com.netflix.loadbalancer.DummyPing; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.IRule; -import com.netflix.loadbalancer.PollingServerListUpdater; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.loadbalancer.ServerListFilter; -import com.netflix.loadbalancer.ServerListUpdater; -import com.netflix.loadbalancer.ZoneAvoidanceRule; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import com.netflix.niws.client.http.RestClient; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.client.apache4.ApacheHttpClient4; -import org.apache.http.client.params.ClientPNames; -import org.apache.http.client.params.CookiePolicy; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.ribbon.apache.HttpClientRibbonConfiguration; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -import static com.netflix.client.config.CommonClientConfigKey.DeploymentContextBasedVipAddresses; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.setRibbonProperty; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToSecureConnectionIfNeeded; - -/** - * @author Dave Syer - * @author Tim Ysewyn - */ -@SuppressWarnings("deprecation") -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties -// Order is important here, last should be the default, first should be optional -// see -// https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653 -@Import({ HttpClientConfiguration.class, OkHttpRibbonConfiguration.class, - RestClientRibbonConfiguration.class, HttpClientRibbonConfiguration.class }) -public class RibbonClientConfiguration { - - /** - * Ribbon client default connect timeout. - */ - public static final int DEFAULT_CONNECT_TIMEOUT = 1000; - - /** - * Ribbon client default read timeout. - */ - public static final int DEFAULT_READ_TIMEOUT = 1000; - - /** - * Ribbon client default Gzip Payload flag. - */ - public static final boolean DEFAULT_GZIP_PAYLOAD = true; - - @RibbonClientName - private String name = "client"; - - // TODO: maybe re-instate autowired load balancers: identified by name they could be - // associated with ribbon clients - - @Autowired - private PropertiesFactory propertiesFactory; - - @Bean - @ConditionalOnMissingBean - public IClientConfig ribbonClientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.loadProperties(this.name); - config.set(CommonClientConfigKey.ConnectTimeout, DEFAULT_CONNECT_TIMEOUT); - config.set(CommonClientConfigKey.ReadTimeout, DEFAULT_READ_TIMEOUT); - config.set(CommonClientConfigKey.GZipPayload, DEFAULT_GZIP_PAYLOAD); - return config; - } - - @Bean - @ConditionalOnMissingBean - public IRule ribbonRule(IClientConfig config) { - if (this.propertiesFactory.isSet(IRule.class, name)) { - return this.propertiesFactory.get(IRule.class, config, name); - } - ZoneAvoidanceRule rule = new ZoneAvoidanceRule(); - rule.initWithNiwsConfig(config); - return rule; - } - - @Bean - @ConditionalOnMissingBean - public IPing ribbonPing(IClientConfig config) { - if (this.propertiesFactory.isSet(IPing.class, name)) { - return this.propertiesFactory.get(IPing.class, config, name); - } - return new DummyPing(); - } - - @Bean - @ConditionalOnMissingBean - @SuppressWarnings("unchecked") - public ServerList ribbonServerList(IClientConfig config) { - if (this.propertiesFactory.isSet(ServerList.class, name)) { - return this.propertiesFactory.get(ServerList.class, config, name); - } - ConfigurationBasedServerList serverList = new ConfigurationBasedServerList(); - serverList.initWithNiwsConfig(config); - return serverList; - } - - @Bean - @ConditionalOnMissingBean - public ServerListUpdater ribbonServerListUpdater(IClientConfig config) { - return new PollingServerListUpdater(config); - } - - @Bean - @ConditionalOnMissingBean - public ILoadBalancer ribbonLoadBalancer(IClientConfig config, - ServerList serverList, ServerListFilter serverListFilter, - IRule rule, IPing ping, ServerListUpdater serverListUpdater) { - if (this.propertiesFactory.isSet(ILoadBalancer.class, name)) { - return this.propertiesFactory.get(ILoadBalancer.class, config, name); - } - return new ZoneAwareLoadBalancer<>(config, rule, ping, serverList, - serverListFilter, serverListUpdater); - } - - @Bean - @ConditionalOnMissingBean - @SuppressWarnings("unchecked") - public ServerListFilter ribbonServerListFilter(IClientConfig config) { - if (this.propertiesFactory.isSet(ServerListFilter.class, name)) { - return this.propertiesFactory.get(ServerListFilter.class, config, name); - } - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - filter.initWithNiwsConfig(config); - return filter; - } - - @Bean - @ConditionalOnMissingBean - public RibbonLoadBalancerContext ribbonLoadBalancerContext(ILoadBalancer loadBalancer, - IClientConfig config, RetryHandler retryHandler) { - return new RibbonLoadBalancerContext(loadBalancer, config, retryHandler); - } - - @Bean - @ConditionalOnMissingBean - public RetryHandler retryHandler(IClientConfig config) { - return new DefaultLoadBalancerRetryHandler(config); - } - - @Bean - @ConditionalOnMissingBean - public ServerIntrospector serverIntrospector() { - return new DefaultServerIntrospector(); - } - - @PostConstruct - public void preprocess() { - setRibbonProperty(name, DeploymentContextBasedVipAddresses.key(), name); - } - - static class OverrideRestClient extends RestClient { - - private IClientConfig config; - - private ServerIntrospector serverIntrospector; - - protected OverrideRestClient(IClientConfig config, - ServerIntrospector serverIntrospector) { - super(); - this.config = config; - this.serverIntrospector = serverIntrospector; - initWithNiwsConfig(this.config); - } - - @Override - public URI reconstructURIWithServer(Server server, URI original) { - URI uri = updateToSecureConnectionIfNeeded(original, this.config, - this.serverIntrospector, server); - return super.reconstructURIWithServer(server, uri); - } - - @Override - protected Client apacheHttpClientSpecificInitialization() { - ApacheHttpClient4 apache = (ApacheHttpClient4) super.apacheHttpClientSpecificInitialization(); - apache.getClientHandler().getHttpClient().getParams().setParameter( - ClientPNames.COOKIE_POLICY, CookiePolicy.IGNORE_COOKIES); - return apache; - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationRegistrar.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationRegistrar.java deleted file mode 100644 index e58ba0a22..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationRegistrar.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.Map; - -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.util.StringUtils; - -/** - * @author Dave Syer - */ -public class RibbonClientConfigurationRegistrar implements ImportBeanDefinitionRegistrar { - - @Override - public void registerBeanDefinitions(AnnotationMetadata metadata, - BeanDefinitionRegistry registry) { - Map attrs = metadata - .getAnnotationAttributes(RibbonClients.class.getName(), true); - if (attrs != null && attrs.containsKey("value")) { - AnnotationAttributes[] clients = (AnnotationAttributes[]) attrs.get("value"); - for (AnnotationAttributes client : clients) { - registerClientConfiguration(registry, getClientName(client), - client.get("configuration")); - } - } - if (attrs != null && attrs.containsKey("defaultConfiguration")) { - String name; - if (metadata.hasEnclosingClass()) { - name = "default." + metadata.getEnclosingClassName(); - } - else { - name = "default." + metadata.getClassName(); - } - registerClientConfiguration(registry, name, - attrs.get("defaultConfiguration")); - } - Map client = metadata - .getAnnotationAttributes(RibbonClient.class.getName(), true); - String name = getClientName(client); - if (name != null) { - registerClientConfiguration(registry, name, client.get("configuration")); - } - } - - private String getClientName(Map client) { - if (client == null) { - return null; - } - String value = (String) client.get("value"); - if (!StringUtils.hasText(value)) { - value = (String) client.get("name"); - } - if (StringUtils.hasText(value)) { - return value; - } - throw new IllegalStateException( - "Either 'name' or 'value' must be provided in @RibbonClient"); - } - - private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name, - Object configuration) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder - .genericBeanDefinition(RibbonClientSpecification.class); - builder.addConstructorArgValue(name); - builder.addConstructorArgValue(configuration); - registry.registerBeanDefinition(name + ".RibbonClientSpecification", - builder.getBeanDefinition()); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactory.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactory.java deleted file mode 100644 index 2974cd130..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactory.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.io.IOException; -import java.net.URI; - -import com.netflix.client.config.IClientConfig; -import com.netflix.client.http.HttpRequest; -import com.netflix.niws.client.http.RestClient; - -import org.springframework.http.HttpMethod; -import org.springframework.http.client.ClientHttpRequest; -import org.springframework.http.client.ClientHttpRequestFactory; - -/** - * @author Spencer Gibb - */ -public class RibbonClientHttpRequestFactory implements ClientHttpRequestFactory { - - private final SpringClientFactory clientFactory; - - public RibbonClientHttpRequestFactory(SpringClientFactory clientFactory) { - this.clientFactory = clientFactory; - } - - @Override - @SuppressWarnings("deprecation") - public ClientHttpRequest createRequest(URI originalUri, HttpMethod httpMethod) - throws IOException { - String serviceId = originalUri.getHost(); - if (serviceId == null) { - throw new IOException( - "Invalid hostname in the URI [" + originalUri.toASCIIString() + "]"); - } - IClientConfig clientConfig = this.clientFactory.getClientConfig(serviceId); - RestClient client = this.clientFactory.getClient(serviceId, RestClient.class); - HttpRequest.Verb verb = HttpRequest.Verb.valueOf(httpMethod.name()); - - return new RibbonHttpRequest(originalUri, verb, client, clientConfig); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientName.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientName.java deleted file mode 100644 index 4ed945ed8..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientName.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2018-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.beans.factory.annotation.Value; - -/** - * Annotation at the field or method/constructor parameter level that injects the Ribbon - * Client Name that got allocated at runtime. Provides a convenient alternative for - * @Value("${ribbon.client.name}"). - * - * @author Spencer Gibb - * @since 2.0.0 - */ -@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, - ElementType.ANNOTATION_TYPE }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Value("${ribbon.client.name}") -public @interface RibbonClientName { - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientSpecification.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientSpecification.java deleted file mode 100644 index c092ea006..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientSpecification.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2013-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.Arrays; -import java.util.Objects; - -import org.springframework.cloud.context.named.NamedContextFactory; - -/** - * @author Dave Syer - */ -public class RibbonClientSpecification implements NamedContextFactory.Specification { - - private String name; - - private Class[] configuration; - - public RibbonClientSpecification() { - } - - public RibbonClientSpecification(String name, Class[] configuration) { - this.name = name; - this.configuration = configuration; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Class[] getConfiguration() { - return configuration; - } - - public void setConfiguration(Class[] configuration) { - this.configuration = configuration; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RibbonClientSpecification that = (RibbonClientSpecification) o; - return Arrays.equals(configuration, that.configuration) - && Objects.equals(name, that.name); - } - - @Override - public int hashCode() { - return Objects.hash(configuration, name); - } - - @Override - public String toString() { - return new StringBuilder("RibbonClientSpecification{").append("name='") - .append(name).append("', ").append("configuration=") - .append(Arrays.toString(configuration)).append("}").toString(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClients.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClients.java deleted file mode 100644 index 8843d4e3f..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClients.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * Convenience annotation that allows user to combine multiple @RibbonClient - * annotations on a single class (including in Java 7). - * - * @author Dave Syer - */ -@Configuration(proxyBeanMethods = false) -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE }) -@Documented -@Import(RibbonClientConfigurationRegistrar.class) -public @interface RibbonClients { - - RibbonClient[] value() default {}; - - Class[] defaultConfiguration() default {}; - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonEagerLoadProperties.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonEagerLoadProperties.java deleted file mode 100644 index 453e1db5e..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonEagerLoadProperties.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.List; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Configuration Properties to indicate which Ribbon configurations should be eagerly - * loaded up. - * - * @author Biju Kunjummen - */ -@ConfigurationProperties(prefix = "ribbon.eager-load") -public class RibbonEagerLoadProperties { - - private boolean enabled = false; - - private List clients; - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public List getClients() { - return clients; - } - - public void setClients(List clients) { - this.clients = clients; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonHttpRequest.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonHttpRequest.java deleted file mode 100644 index b321c9c17..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonHttpRequest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.net.URI; -import java.util.List; - -import com.netflix.client.config.IClientConfig; -import com.netflix.client.http.HttpRequest; -import com.netflix.client.http.HttpResponse; -import com.netflix.niws.client.http.RestClient; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.client.AbstractClientHttpRequest; -import org.springframework.http.client.ClientHttpResponse; - -/** - * @author Spencer Gibb - */ -@SuppressWarnings("deprecation") -public class RibbonHttpRequest extends AbstractClientHttpRequest { - - private HttpRequest.Builder builder; - - private URI uri; - - private HttpRequest.Verb verb; - - private RestClient client; - - private IClientConfig config; - - private ByteArrayOutputStream outputStream = null; - - public RibbonHttpRequest(URI uri, HttpRequest.Verb verb, RestClient client, - IClientConfig config) { - this.uri = uri; - this.verb = verb; - this.client = client; - this.config = config; - this.builder = HttpRequest.newBuilder().uri(uri).verb(verb); - } - - @Override - public HttpMethod getMethod() { - return HttpMethod.valueOf(verb.name()); - } - - @Override - public String getMethodValue() { - return getMethod().name(); - } - - @Override - public URI getURI() { - return uri; - } - - @Override - protected OutputStream getBodyInternal(HttpHeaders headers) throws IOException { - if (outputStream == null) { - outputStream = new ByteArrayOutputStream(); - } - return outputStream; - } - - @Override - protected ClientHttpResponse executeInternal(HttpHeaders headers) throws IOException { - try { - addHeaders(headers); - if (outputStream != null) { - outputStream.close(); - builder.entity(outputStream.toByteArray()); - } - HttpRequest request = builder.build(); - HttpResponse response = client.executeWithLoadBalancer(request, config); - return new RibbonHttpResponse(response); - } - catch (Exception e) { - throw new IOException(e); - } - } - - private void addHeaders(HttpHeaders headers) { - for (String name : headers.keySet()) { - // apache http RequestContent pukes if there is a body and - // the dynamic headers are already present - if (isDynamic(name) && outputStream != null) { - continue; - } - // Don't add content-length if the output stream is null. The RibbonClient - // does this for us. - if (name.equals("Content-Length") && outputStream == null) { - continue; - } - List values = headers.get(name); - for (String value : values) { - builder.header(name, value); - } - } - } - - private boolean isDynamic(String name) { - return "Content-Length".equalsIgnoreCase(name) - || "Transfer-Encoding".equalsIgnoreCase(name); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonHttpResponse.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonHttpResponse.java deleted file mode 100644 index 27b1e7302..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonHttpResponse.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.Map; - -import com.netflix.client.http.HttpResponse; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.client.AbstractClientHttpResponse; - -/** - * @author Spencer Gibb - */ -public class RibbonHttpResponse extends AbstractClientHttpResponse { - - private HttpResponse response; - - private HttpHeaders httpHeaders; - - public RibbonHttpResponse(HttpResponse response) { - this.response = response; - this.httpHeaders = new HttpHeaders(); - List> headers = response.getHttpHeaders() - .getAllHeaders(); - for (Map.Entry header : headers) { - this.httpHeaders.add(header.getKey(), header.getValue()); - } - } - - @Override - public InputStream getBody() throws IOException { - return response.getInputStream(); - } - - @Override - public HttpHeaders getHeaders() { - return this.httpHeaders; - } - - @Override - public int getRawStatusCode() throws IOException { - return response.getStatus(); - } - - @Override - public String getStatusText() throws IOException { - return HttpStatus.valueOf(response.getStatus()).name(); - } - - @Override - public void close() { - response.close(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryFactory.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryFactory.java deleted file mode 100644 index 6e069f97d..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryFactory.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.retry.RetryListener; -import org.springframework.retry.backoff.BackOffPolicy; - -/** - * @author Ryan Baxter - */ -public class RibbonLoadBalancedRetryFactory implements LoadBalancedRetryFactory { - - private SpringClientFactory clientFactory; - - public RibbonLoadBalancedRetryFactory(SpringClientFactory clientFactory) { - this.clientFactory = clientFactory; - } - - @Override - public LoadBalancedRetryPolicy createRetryPolicy(String service, - ServiceInstanceChooser serviceInstanceChooser) { - RibbonLoadBalancerContext lbContext = this.clientFactory - .getLoadBalancerContext(service); - return new RibbonLoadBalancedRetryPolicy(service, lbContext, - serviceInstanceChooser, clientFactory.getClientConfig(service)); - } - - @Override - public RetryListener[] createRetryListeners(String service) { - return new RetryListener[0]; - } - - @Override - public BackOffPolicy createBackOffPolicy(String service) { - return null; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicy.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicy.java deleted file mode 100644 index d04872891..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicy.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import com.netflix.client.config.IClientConfigKey; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerStats; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.RibbonServer; -import org.springframework.http.HttpMethod; -import org.springframework.util.StringUtils; - -/** - * {@link LoadBalancedRetryPolicy} for Ribbon clients. - * - * @author Ryan Baxter - */ -public class RibbonLoadBalancedRetryPolicy implements LoadBalancedRetryPolicy { - - /** - * Retrayable status codes config key. - */ - public static final IClientConfigKey RETRYABLE_STATUS_CODES = new CommonClientConfigKey( - "retryableStatusCodes") { - }; - - private static final Log log = LogFactory.getLog(RibbonLoadBalancedRetryPolicy.class); - - private int sameServerCount = 0; - - private int nextServerCount = 0; - - private String serviceId; - - private RibbonLoadBalancerContext lbContext; - - private ServiceInstanceChooser loadBalanceChooser; - - List retryableStatusCodes = new ArrayList<>(); - - private static final Log LOGGER = LogFactory - .getLog(RibbonLoadBalancedRetryPolicy.class); - - public RibbonLoadBalancedRetryPolicy(String serviceId, - RibbonLoadBalancerContext context, - ServiceInstanceChooser loadBalanceChooser) { - this.serviceId = serviceId; - this.lbContext = context; - this.loadBalanceChooser = loadBalanceChooser; - } - - public RibbonLoadBalancedRetryPolicy(String serviceId, - RibbonLoadBalancerContext context, ServiceInstanceChooser loadBalanceChooser, - IClientConfig clientConfig) { - this.serviceId = serviceId; - this.lbContext = context; - this.loadBalanceChooser = loadBalanceChooser; - String retryableStatusCodesProp = clientConfig - .getPropertyAsString(RETRYABLE_STATUS_CODES, ""); - String[] retryableStatusCodesArray = retryableStatusCodesProp.split(","); - for (String code : retryableStatusCodesArray) { - if (!StringUtils.isEmpty(code)) { - try { - retryableStatusCodes.add(Integer.valueOf(code.trim())); - } - catch (NumberFormatException e) { - log.warn("We cant add the status code because the code [ " + code - + " ] could not be converted to an integer. ", e); - } - } - } - } - - public boolean canRetry(LoadBalancedRetryContext context) { - HttpMethod method = context.getRequest().getMethod(); - return HttpMethod.GET == method || lbContext.isOkToRetryOnAllOperations(); - } - - @Override - public boolean canRetrySameServer(LoadBalancedRetryContext context) { - return sameServerCount < lbContext.getRetryHandler().getMaxRetriesOnSameServer() - && canRetry(context); - } - - @Override - public boolean canRetryNextServer(LoadBalancedRetryContext context) { - // this will be called after a failure occurs and we increment the counter - // so we check that the count is less than or equals to too make sure - // we try the next server the right number of times - return nextServerCount <= lbContext.getRetryHandler().getMaxRetriesOnNextServer() - && canRetry(context); - } - - @Override - public void close(LoadBalancedRetryContext context) { - - } - - @Override - public void registerThrowable(LoadBalancedRetryContext context, Throwable throwable) { - // if this is a circuit tripping exception then notify the load balancer - if (lbContext.getRetryHandler().isCircuitTrippingException(throwable)) { - updateServerInstanceStats(context); - } - - // Check if we need to ask the load balancer for a new server. - // Do this before we increment the counters because the first call to this method - // is not a retry it is just an initial failure. - if (!canRetrySameServer(context) && canRetryNextServer(context)) { - context.setServiceInstance(loadBalanceChooser.choose(serviceId)); - } - // This method is called regardless of whether we are retrying or making the first - // request. - // Since we do not count the initial request in the retry count we don't reset the - // counter - // until we actually equal the same server count limit. This will allow us to make - // the initial - // request plus the right number of retries. - if (sameServerCount >= lbContext.getRetryHandler().getMaxRetriesOnSameServer() - && canRetry(context)) { - // reset same server since we are moving to a new server - sameServerCount = 0; - nextServerCount++; - if (!canRetryNextServer(context)) { - context.setExhaustedOnly(); - } - } - else { - sameServerCount++; - } - - } - - private void updateServerInstanceStats(LoadBalancedRetryContext context) { - ServiceInstance serviceInstance = context.getServiceInstance(); - if (serviceInstance instanceof RibbonServer) { - Server lbServer = ((RibbonServer) serviceInstance).getServer(); - ServerStats serverStats = lbContext.getServerStats(lbServer); - serverStats.incrementSuccessiveConnectionFailureCount(); - serverStats.addToFailureCount(); - LOGGER.debug(lbServer.getHostPort() + " RetryCount: " - + context.getRetryCount() + " Successive Failures: " - + serverStats.getSuccessiveConnectionFailureCount() - + " CircuitBreakerTripped:" + serverStats.isCircuitBreakerTripped()); - } - } - - @Override - public boolean retryableStatusCode(int statusCode) { - return retryableStatusCodes.contains(statusCode); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java deleted file mode 100644 index 27006ab09..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.io.IOException; -import java.net.URI; -import java.util.Collections; -import java.util.Map; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.Server; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToSecureConnectionIfNeeded; - -/** - * @author Spencer Gibb - * @author Dave Syer - * @author Ryan Baxter - * @author Tim Ysewyn - */ -public class RibbonLoadBalancerClient implements LoadBalancerClient { - - private SpringClientFactory clientFactory; - - public RibbonLoadBalancerClient(SpringClientFactory clientFactory) { - this.clientFactory = clientFactory; - } - - @Override - public URI reconstructURI(ServiceInstance instance, URI original) { - Assert.notNull(instance, "instance can not be null"); - String serviceId = instance.getServiceId(); - RibbonLoadBalancerContext context = this.clientFactory - .getLoadBalancerContext(serviceId); - - URI uri; - Server server; - if (instance instanceof RibbonServer) { - RibbonServer ribbonServer = (RibbonServer) instance; - server = ribbonServer.getServer(); - uri = updateToSecureConnectionIfNeeded(original, ribbonServer); - } - else { - server = new Server(instance.getScheme(), instance.getHost(), - instance.getPort()); - IClientConfig clientConfig = clientFactory.getClientConfig(serviceId); - ServerIntrospector serverIntrospector = serverIntrospector(serviceId); - uri = updateToSecureConnectionIfNeeded(original, clientConfig, - serverIntrospector, server); - } - return context.reconstructURIWithServer(server, uri); - } - - @Override - public ServiceInstance choose(String serviceId) { - return choose(serviceId, null); - } - - /** - * New: Select a server using a 'key'. - * @param serviceId of the service to choose an instance for - * @param hint to specify the service instance - * @return the selected {@link ServiceInstance} - */ - public ServiceInstance choose(String serviceId, Object hint) { - Server server = getServer(getLoadBalancer(serviceId), hint); - if (server == null) { - return null; - } - return new RibbonServer(serviceId, server, isSecure(server, serviceId), - serverIntrospector(serviceId).getMetadata(server)); - } - - @Override - public T execute(String serviceId, LoadBalancerRequest request) - throws IOException { - return execute(serviceId, request, null); - } - - /** - * New: Execute a request by selecting server using a 'key'. The hint will have to be - * the last parameter to not mess with the `execute(serviceId, ServiceInstance, - * request)` method. This somewhat breaks the fluent coding style when using a lambda - * to define the LoadBalancerRequest. - * @param returned request execution result type - * @param serviceId id of the service to execute the request to - * @param request to be executed - * @param hint used to choose appropriate {@link Server} instance - * @return request execution result - * @throws IOException executing the request may result in an {@link IOException} - */ - public T execute(String serviceId, LoadBalancerRequest request, Object hint) - throws IOException { - ILoadBalancer loadBalancer = getLoadBalancer(serviceId); - Server server = getServer(loadBalancer, hint); - if (server == null) { - throw new IllegalStateException("No instances available for " + serviceId); - } - RibbonServer ribbonServer = new RibbonServer(serviceId, server, - isSecure(server, serviceId), - serverIntrospector(serviceId).getMetadata(server)); - - return execute(serviceId, ribbonServer, request); - } - - @Override - public T execute(String serviceId, ServiceInstance serviceInstance, - LoadBalancerRequest request) throws IOException { - Server server = null; - if (serviceInstance instanceof RibbonServer) { - server = ((RibbonServer) serviceInstance).getServer(); - } - if (server == null) { - throw new IllegalStateException("No instances available for " + serviceId); - } - - RibbonLoadBalancerContext context = this.clientFactory - .getLoadBalancerContext(serviceId); - RibbonStatsRecorder statsRecorder = new RibbonStatsRecorder(context, server); - - try { - T returnVal = request.apply(serviceInstance); - statsRecorder.recordStats(returnVal); - return returnVal; - } - // catch IOException and rethrow so RestTemplate behaves correctly - catch (IOException ex) { - statsRecorder.recordStats(ex); - throw ex; - } - catch (Exception ex) { - statsRecorder.recordStats(ex); - ReflectionUtils.rethrowRuntimeException(ex); - } - return null; - } - - private ServerIntrospector serverIntrospector(String serviceId) { - ServerIntrospector serverIntrospector = this.clientFactory.getInstance(serviceId, - ServerIntrospector.class); - if (serverIntrospector == null) { - serverIntrospector = new DefaultServerIntrospector(); - } - return serverIntrospector; - } - - private boolean isSecure(Server server, String serviceId) { - IClientConfig config = this.clientFactory.getClientConfig(serviceId); - ServerIntrospector serverIntrospector = serverIntrospector(serviceId); - return RibbonUtils.isSecure(config, serverIntrospector, server); - } - - // Note: This method could be removed? - protected Server getServer(String serviceId) { - return getServer(getLoadBalancer(serviceId), null); - } - - protected Server getServer(ILoadBalancer loadBalancer) { - return getServer(loadBalancer, null); - } - - protected Server getServer(ILoadBalancer loadBalancer, Object hint) { - if (loadBalancer == null) { - return null; - } - // Use 'default' on a null hint, or just pass it on? - return loadBalancer.chooseServer(hint != null ? hint : "default"); - } - - protected ILoadBalancer getLoadBalancer(String serviceId) { - return this.clientFactory.getLoadBalancer(serviceId); - } - - /** - * Ribbon-server-specific {@link ServiceInstance} implementation. - */ - public static class RibbonServer implements ServiceInstance { - - private final String serviceId; - - private final Server server; - - private final boolean secure; - - private Map metadata; - - public RibbonServer(String serviceId, Server server) { - this(serviceId, server, false, Collections.emptyMap()); - } - - public RibbonServer(String serviceId, Server server, boolean secure, - Map metadata) { - this.serviceId = serviceId; - this.server = server; - this.secure = secure; - this.metadata = metadata; - } - - @Override - public String getInstanceId() { - return this.server.getId(); - } - - @Override - public String getServiceId() { - return this.serviceId; - } - - @Override - public String getHost() { - return this.server.getHost(); - } - - @Override - public int getPort() { - return this.server.getPort(); - } - - @Override - public boolean isSecure() { - return this.secure; - } - - @Override - public URI getUri() { - return DefaultServiceInstance.getUri(this); - } - - @Override - public Map getMetadata() { - return this.metadata; - } - - public Server getServer() { - return this.server; - } - - @Override - public String getScheme() { - return this.server.getScheme(); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("RibbonServer{"); - sb.append("serviceId='").append(serviceId).append('\''); - sb.append(", server=").append(server); - sb.append(", secure=").append(secure); - sb.append(", metadata=").append(metadata); - sb.append('}'); - return sb.toString(); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerContext.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerContext.java deleted file mode 100644 index 08138a111..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerContext.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.LoadBalancerContext; -import com.netflix.loadbalancer.ServerStats; -import com.netflix.servo.monitor.Timer; - -/** - * @author Spencer Gibb - */ -public class RibbonLoadBalancerContext extends LoadBalancerContext { - - public RibbonLoadBalancerContext(ILoadBalancer lb) { - super(lb); - } - - public RibbonLoadBalancerContext(ILoadBalancer lb, IClientConfig clientConfig) { - super(lb, clientConfig); - } - - public RibbonLoadBalancerContext(ILoadBalancer lb, IClientConfig clientConfig, - RetryHandler handler) { - super(lb, clientConfig, handler); - } - - @Override - public void noteOpenConnection(ServerStats serverStats) { - super.noteOpenConnection(serverStats); - } - - @Override - public Timer getExecuteTracer() { - return super.getExecuteTracer(); - } - - @Override - public void noteRequestCompletion(ServerStats stats, Object response, Throwable e, - long responseTime) { - super.noteRequestCompletion(stats, response, e, responseTime); - } - - @Override - public void noteRequestCompletion(ServerStats stats, Object response, Throwable e, - long responseTime, RetryHandler errorHandler) { - super.noteRequestCompletion(stats, response, e, responseTime, errorHandler); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonProperties.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonProperties.java deleted file mode 100644 index 5e6437996..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonProperties.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright 2018-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.concurrent.TimeUnit; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import com.netflix.client.config.IClientConfigKey; - -import static com.netflix.client.config.CommonClientConfigKey.PoolKeepAliveTime; -import static com.netflix.client.config.CommonClientConfigKey.PoolKeepAliveTimeUnits; -import static com.netflix.client.config.CommonClientConfigKey.Port; -import static com.netflix.client.config.CommonClientConfigKey.SecurePort; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_CONNECTION_IDLE_TIMERTASK_REPEAT_IN_MSECS; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_CONNECT_TIMEOUT; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_FOLLOW_REDIRECTS; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_MAX_CONNECTIONS_PER_HOST; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_MAX_TOTAL_CONNECTIONS; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_OK_TO_RETRY_ON_ALL_OPERATIONS; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME_UNITS; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_PORT; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_READ_TIMEOUT; - -/** - * Stores and allows the access to Ribbon {@link IClientConfig}. - * - * @author Spencer Gibb - * @author Tomasz Juchniewicz - */ -public class RibbonProperties { - - private final IClientConfig config; - - public static RibbonProperties from(IClientConfig config) { - return new RibbonProperties(config); - } - - RibbonProperties(IClientConfig config) { - this.config = config; - } - - public Integer getConnectionCleanerRepeatInterval() { - return get(CommonClientConfigKey.ConnectionCleanerRepeatInterval); - } - - public int connectionCleanerRepeatInterval() { - return get(CommonClientConfigKey.ConnectionCleanerRepeatInterval, - DEFAULT_CONNECTION_IDLE_TIMERTASK_REPEAT_IN_MSECS); - } - - public Integer getConnectTimeout() { - return get(CommonClientConfigKey.ConnectTimeout); - } - - public int connectTimeout() { - return connectTimeout(DEFAULT_CONNECT_TIMEOUT); - } - - public int connectTimeout(int defaultValue) { - return get(CommonClientConfigKey.ConnectTimeout, defaultValue); - } - - public Boolean getFollowRedirects() { - return get(CommonClientConfigKey.FollowRedirects); - } - - public boolean isFollowRedirects() { - return isFollowRedirects(DEFAULT_FOLLOW_REDIRECTS); - } - - public boolean isFollowRedirects(boolean defaultValue) { - return get(CommonClientConfigKey.FollowRedirects, defaultValue); - } - - public boolean isGZipPayload() { - return isGZipPayload(RibbonClientConfiguration.DEFAULT_GZIP_PAYLOAD); - } - - public boolean isGZipPayload(boolean defaultValue) { - return get(CommonClientConfigKey.GZipPayload, defaultValue); - } - - public Integer getMaxConnectionsPerHost() { - return get(CommonClientConfigKey.MaxConnectionsPerHost); - } - - public int maxConnectionsPerHost() { - return maxConnectionsPerHost(DEFAULT_MAX_CONNECTIONS_PER_HOST); - } - - public int maxConnectionsPerHost(int defaultValue) { - return get(CommonClientConfigKey.MaxConnectionsPerHost, defaultValue); - } - - public Integer getMaxTotalConnections() { - return get(CommonClientConfigKey.MaxTotalConnections); - } - - public int maxTotalConnections() { - return maxTotalConnections(DEFAULT_MAX_TOTAL_CONNECTIONS); - } - - public int maxTotalConnections(int defaultValue) { - return get(CommonClientConfigKey.MaxTotalConnections, defaultValue); - } - - public Boolean getOkToRetryOnAllOperations() { - return get(CommonClientConfigKey.OkToRetryOnAllOperations); - } - - public boolean isOkToRetryOnAllOperations() { - return get(CommonClientConfigKey.OkToRetryOnAllOperations, - DEFAULT_OK_TO_RETRY_ON_ALL_OPERATIONS); - } - - @SuppressWarnings("deprecation") - public Long getPoolKeepAliveTime() { - Object property = this.config.getProperty(PoolKeepAliveTime); - if (property instanceof Long) { - return (Long) property; - } - else if (property instanceof String) { - return Long.valueOf((String) property); - } - return null; - } - - public long poolKeepAliveTime() { - Long poolKeepAliveTime = getPoolKeepAliveTime(); - if (poolKeepAliveTime != null) { - return poolKeepAliveTime; - } - - return DEFAULT_POOL_KEEP_ALIVE_TIME; - } - - @SuppressWarnings("deprecation") - public TimeUnit getPoolKeepAliveTimeUnits() { - Object property = this.config.getProperty(PoolKeepAliveTimeUnits); - if (property instanceof TimeUnit) { - return (TimeUnit) property; - } - return DEFAULT_POOL_KEEP_ALIVE_TIME_UNITS; - } - - public Integer getPort() { - return get(Port); - } - - public int port() { - return get(Port, DEFAULT_PORT); - } - - public Integer getReadTimeout() { - return get(CommonClientConfigKey.ReadTimeout); - } - - public int readTimeout() { - return readTimeout(DEFAULT_READ_TIMEOUT); - } - - public int readTimeout(int defaultValue) { - return get(CommonClientConfigKey.ReadTimeout, defaultValue); - } - - public Boolean getSecure() { - return get(CommonClientConfigKey.IsSecure); - } - - public boolean isSecure() { - return isSecure(false); - } - - public boolean isSecure(boolean defaultValue) { - return get(CommonClientConfigKey.IsSecure, defaultValue); - } - - public Integer getSecurePort() { - return this.config.get(SecurePort); - } - - public Boolean getUseIPAddrForServer() { - return get(CommonClientConfigKey.UseIPAddrForServer); - } - - public boolean isUseIPAddrForServer() { - return isUseIPAddrForServer(false); - } - - public boolean isUseIPAddrForServer(boolean defaultValue) { - return get(CommonClientConfigKey.UseIPAddrForServer, defaultValue); - } - - public boolean has(IClientConfigKey key) { - return this.config.containsProperty(key); - } - - public T get(IClientConfigKey key) { - return this.config.get(key); - } - - public T get(IClientConfigKey key, T defaultValue) { - return this.config.get(key, defaultValue); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonStatsRecorder.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonStatsRecorder.java deleted file mode 100644 index 73859f27d..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonStatsRecorder.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2016-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.concurrent.TimeUnit; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerStats; -import com.netflix.servo.monitor.Stopwatch; - -/** - * @author Spencer Gibb - */ -public class RibbonStatsRecorder { - - private RibbonLoadBalancerContext context; - - private ServerStats serverStats; - - private Stopwatch tracer; - - public RibbonStatsRecorder(RibbonLoadBalancerContext context, Server server) { - this.context = context; - if (server != null) { - serverStats = context.getServerStats(server); - context.noteOpenConnection(serverStats); - tracer = context.getExecuteTracer().start(); - } - } - - public void recordStats(Object entity) { - this.recordStats(entity, null); - } - - public void recordStats(Throwable t) { - this.recordStats(null, t); - } - - protected void recordStats(Object entity, Throwable exception) { - if (this.tracer != null && this.serverStats != null) { - this.tracer.stop(); - long duration = this.tracer.getDuration(TimeUnit.MILLISECONDS); - this.context.noteRequestCompletion(serverStats, entity, exception, duration, - null/* errorHandler */); - } - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonUtils.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonUtils.java deleted file mode 100644 index c29fd07fa..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonUtils.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2016-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.net.URI; -import java.util.HashMap; -import java.util.Map; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DynamicPropertyFactory; -import com.netflix.config.DynamicStringProperty; -import com.netflix.loadbalancer.Server; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.util.StringUtils; -import org.springframework.web.util.UriComponentsBuilder; - -import static com.netflix.client.config.CommonClientConfigKey.DeploymentContextBasedVipAddresses; -import static com.netflix.client.config.CommonClientConfigKey.EnableZoneAffinity; - -/** - * @author Spencer Gibb - * @author Jacques-Etienne Beaudet - * @author Tim Ysewyn - */ -public final class RibbonUtils { - - /** - * Used to verify if property value is set. - */ - public static final String VALUE_NOT_SET = "__not__set__"; - - /** - * Default Ribbon namespace. - */ - public static final String DEFAULT_NAMESPACE = "ribbon"; - - private static final Map unsecureSchemeMapping; - - static { - unsecureSchemeMapping = new HashMap<>(); - unsecureSchemeMapping.put("http", "https"); - unsecureSchemeMapping.put("ws", "wss"); - } - - private RibbonUtils() { - throw new AssertionError("Must not instantiate utility class."); - } - - public static void initializeRibbonDefaults(String serviceId) { - setRibbonProperty(serviceId, DeploymentContextBasedVipAddresses.key(), serviceId); - setRibbonProperty(serviceId, EnableZoneAffinity.key(), "true"); - } - - public static void setRibbonProperty(String serviceId, String suffix, String value) { - // how to set the namespace properly? - String key = getRibbonKey(serviceId, suffix); - DynamicStringProperty property = getProperty(key); - if (property.get().equals(VALUE_NOT_SET)) { - ConfigurationManager.getConfigInstance().setProperty(key, value); - } - } - - public static String getRibbonKey(String serviceId, String suffix) { - return serviceId + "." + DEFAULT_NAMESPACE + "." + suffix; - } - - public static DynamicStringProperty getProperty(String key) { - return DynamicPropertyFactory.getInstance().getStringProperty(key, VALUE_NOT_SET); - } - - /** - * Determine if client is secure. If the supplied {@link IClientConfig} has the - * {@link CommonClientConfigKey#IsSecure} set, return that value. Otherwise, query the - * supplied {@link ServerIntrospector}. - * @param config the supplied client configuration. - * @param serverIntrospector used to verify if the server provides secure connections - * @param server to verify - * @return true if the client is secure - */ - public static boolean isSecure(IClientConfig config, - ServerIntrospector serverIntrospector, Server server) { - if (config != null) { - Boolean isSecure = config.get(CommonClientConfigKey.IsSecure); - if (isSecure != null) { - return isSecure; - } - } - - return serverIntrospector.isSecure(server); - } - - /** - * Replace the scheme to https if needed. If the uri doesn't start with https and - * {@link #isSecure(IClientConfig, ServerIntrospector, Server)} is true, update the - * scheme. This assumes the uri is already encoded to avoid double encoding. - * @param uri to modify if required - * @param config Ribbon {@link IClientConfig} configuration - * @param serverIntrospector used to verify if the server provides secure connections - * @param server to verify - * @return {@link URI} updated to https if necessary - * @deprecated use {@link #updateToSecureConnectionIfNeeded} - */ - public static URI updateToHttpsIfNeeded(URI uri, IClientConfig config, - ServerIntrospector serverIntrospector, Server server) { - return updateToSecureConnectionIfNeeded(uri, config, serverIntrospector, server); - } - - /** - * Replace the scheme to the secure variant if needed. If the - * {@link #unsecureSchemeMapping} map contains the uri scheme and - * {@link #isSecure(IClientConfig, ServerIntrospector, Server)} is true, update the - * scheme. This assumes the uri is already encoded to avoid double encoding. - * @param uri to modify if required - * @param ribbonServer to verify if it provides secure connections - * @return {@link URI} updated if required - */ - static URI updateToSecureConnectionIfNeeded(URI uri, ServiceInstance ribbonServer) { - String scheme = uri.getScheme(); - - if (StringUtils.isEmpty(scheme)) { - scheme = "http"; - } - - if (!StringUtils.isEmpty(uri.toString()) - && unsecureSchemeMapping.containsKey(scheme) && ribbonServer.isSecure()) { - return upgradeConnection(uri, unsecureSchemeMapping.get(scheme)); - } - return uri; - } - - /** - * Replace the scheme to the secure variant if needed. If the - * {@link #unsecureSchemeMapping} map contains the uri scheme and - * {@link #isSecure(IClientConfig, ServerIntrospector, Server)} is true, update the - * scheme. This assumes the uri is already encoded to avoid double encoding. - * @param uri to modify if required - * @param config the supplied client configuration - * @param serverIntrospector used to verify if the server provides secure connections - * @param server to verify - * @return {@link URI} updated if required - */ - public static URI updateToSecureConnectionIfNeeded(URI uri, IClientConfig config, - ServerIntrospector serverIntrospector, Server server) { - String scheme = uri.getScheme(); - - if (StringUtils.isEmpty(scheme)) { - scheme = "http"; - } - - if (!StringUtils.isEmpty(uri.toString()) - && unsecureSchemeMapping.containsKey(scheme) - && isSecure(config, serverIntrospector, server)) { - return upgradeConnection(uri, unsecureSchemeMapping.get(scheme)); - } - return uri; - } - - private static URI upgradeConnection(URI uri, String scheme) { - UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUri(uri) - .scheme(scheme); - if (uri.getRawQuery() != null) { - // When building the URI, UriComponentsBuilder verify the allowed characters - // and does not - // support the '+' so we replace it for its equivalent '%20'. - // See issue https://jira.spring.io/browse/SPR-10172 - uriComponentsBuilder.replaceQuery(uri.getRawQuery().replace("+", "%20")); - } - return uriComponentsBuilder.build(true).toUri(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospector.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospector.java deleted file mode 100644 index 463453a3e..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospector.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.Map; - -import com.netflix.loadbalancer.Server; - -/** - * @author Spencer Gibb - */ -public interface ServerIntrospector { - - boolean isSecure(Server server); - - Map getMetadata(Server server); - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospectorProperties.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospectorProperties.java deleted file mode 100644 index 111750e65..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospectorProperties.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.Arrays; -import java.util.List; -import java.util.Objects; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Rico Pahlisch - * @author Gregor Zurowski - */ -@ConfigurationProperties("ribbon") -public class ServerIntrospectorProperties { - - private List securePorts = Arrays.asList(443, 8443); - - public List getSecurePorts() { - return securePorts; - } - - public void setSecurePorts(List securePorts) { - this.securePorts = securePorts; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ServerIntrospectorProperties that = (ServerIntrospectorProperties) o; - return Objects.equals(securePorts, that.securePorts); - } - - @Override - public int hashCode() { - return Objects.hash(securePorts); - } - - @Override - public String toString() { - return new StringBuilder("ServerIntrospectorProperties{").append("securePorts=") - .append(securePorts).append("}").toString(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java deleted file mode 100644 index f0b6b7c0e..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.lang.reflect.Constructor; - -import com.netflix.client.IClient; -import com.netflix.client.IClientConfigAware; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; - -import org.springframework.beans.BeanUtils; -import org.springframework.cloud.context.named.NamedContextFactory; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; - -/** - * A factory that creates client, load balancer and client configuration instances. It - * creates a Spring ApplicationContext per client name, and extracts the beans that it - * needs from there. - * - * @author Spencer Gibb - * @author Dave Syer - */ -public class SpringClientFactory extends NamedContextFactory { - - static final String NAMESPACE = "ribbon"; - - public SpringClientFactory() { - super(RibbonClientConfiguration.class, NAMESPACE, "ribbon.client.name"); - } - - /** - * Get the rest client associated with the name. - * @param name name to search by - * @param clientClass the class of the client bean - * @param {@link IClient} subtype - * @return {@link IClient} instance - * @throws RuntimeException if any error occurs - */ - public > C getClient(String name, Class clientClass) { - return getInstance(name, clientClass); - } - - /** - * Get the load balancer associated with the name. - * @param name name to search by - * @return {@link ILoadBalancer} instance - * @throws RuntimeException if any error occurs - */ - public ILoadBalancer getLoadBalancer(String name) { - return getInstance(name, ILoadBalancer.class); - } - - /** - * Get the client config associated with the name. - * @param name name to search by - * @return {@link IClientConfig} instance - * @throws RuntimeException if any error occurs - */ - public IClientConfig getClientConfig(String name) { - return getInstance(name, IClientConfig.class); - } - - /** - * Get the load balancer context associated with the name. - * @param serviceId id of the service to search by - * @return {@link RibbonLoadBalancerContext} instance - * @throws RuntimeException if any error occurs - */ - public RibbonLoadBalancerContext getLoadBalancerContext(String serviceId) { - return getInstance(serviceId, RibbonLoadBalancerContext.class); - } - - static C instantiateWithConfig(Class clazz, IClientConfig config) { - return instantiateWithConfig(null, clazz, config); - } - - static C instantiateWithConfig(AnnotationConfigApplicationContext context, - Class clazz, IClientConfig config) { - C result = null; - - try { - Constructor constructor = clazz.getConstructor(IClientConfig.class); - result = constructor.newInstance(config); - } - catch (Throwable e) { - // Ignored - } - - if (result == null) { - result = BeanUtils.instantiateClass(clazz); - - if (result instanceof IClientConfigAware) { - ((IClientConfigAware) result).initWithNiwsConfig(config); - } - - if (context != null) { - context.getAutowireCapableBeanFactory().autowireBean(result); - } - } - - return result; - } - - @Override - public C getInstance(String name, Class type) { - C instance = super.getInstance(name, type); - if (instance != null) { - return instance; - } - IClientConfig config = getInstance(name, IClientConfig.class); - return instantiateWithConfig(getContext(name), type, config); - } - - @Override - protected AnnotationConfigApplicationContext getContext(String name) { - return super.getContext(name); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/StaticServerList.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/StaticServerList.java deleted file mode 100644 index 42f585f85..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/StaticServerList.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.Arrays; -import java.util.List; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; - -/** - * Represents list of servers used by Ribbon. - * - * @param {@link Server} subtype - * @author Spencer Gibb - */ -public class StaticServerList implements ServerList { - - private final List servers; - - public StaticServerList(T... servers) { - this.servers = Arrays.asList(servers); - } - - @Override - public List getInitialListOfServers() { - return servers; - } - - @Override - public List getUpdatedListOfServers() { - return servers; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ZonePreferenceServerListFilter.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ZonePreferenceServerListFilter.java deleted file mode 100644 index c57c06f13..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ZonePreferenceServerListFilter.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import com.netflix.client.config.IClientConfig; -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DeploymentContext.ContextKey; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAffinityServerListFilter; - -/** - * A filter that actively prefers the local zone (as defined by the deployment context, or - * the Eureka instance metadata). - * - * @author Dave Syer - */ -public class ZonePreferenceServerListFilter extends ZoneAffinityServerListFilter { - - private String zone; - - @Override - public void initWithNiwsConfig(IClientConfig niwsClientConfig) { - super.initWithNiwsConfig(niwsClientConfig); - if (ConfigurationManager.getDeploymentContext() != null) { - this.zone = ConfigurationManager.getDeploymentContext() - .getValue(ContextKey.zone); - } - } - - @Override - public List getFilteredListOfServers(List servers) { - List output = super.getFilteredListOfServers(servers); - if (this.zone != null && output.size() == servers.size()) { - List local = new ArrayList<>(); - for (Server server : output) { - if (this.zone.equalsIgnoreCase(server.getZone())) { - local.add(server); - } - } - if (!local.isEmpty()) { - return local; - } - } - return output; - } - - public String getZone() { - return zone; - } - - public void setZone(String zone) { - this.zone = zone; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ZonePreferenceServerListFilter that = (ZonePreferenceServerListFilter) o; - return Objects.equals(zone, that.zone); - } - - @Override - public int hashCode() { - return Objects.hash(zone); - } - - @Override - public String toString() { - return new StringBuilder("ZonePreferenceServerListFilter{").append("zone='") - .append(zone).append("'").append("}").toString(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientRibbonConfiguration.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientRibbonConfiguration.java deleted file mode 100644 index cb1d8438f..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientRibbonConfiguration.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.apache; - -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.TimeUnit; - -import javax.annotation.PreDestroy; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.servo.monitor.Monitors; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.config.RegistryBuilder; -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.impl.client.CloseableHttpClient; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; -import org.springframework.cloud.netflix.ribbon.RibbonClientName; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.RibbonProperties; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(name = "org.apache.http.client.HttpClient") -@ConditionalOnProperty(name = "ribbon.httpclient.enabled", matchIfMissing = true) -public class HttpClientRibbonConfiguration { - - @RibbonClientName - private String name = "client"; - - @Bean - @ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class) - @ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate") - public RibbonLoadBalancingHttpClient ribbonLoadBalancingHttpClient( - IClientConfig config, ServerIntrospector serverIntrospector, - ILoadBalancer loadBalancer, RetryHandler retryHandler, - CloseableHttpClient httpClient) { - RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient( - httpClient, config, serverIntrospector); - client.setLoadBalancer(loadBalancer); - client.setRetryHandler(retryHandler); - Monitors.registerObject("Client_" + this.name, client); - return client; - } - - @Bean - @ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class) - @ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate") - public RetryableRibbonLoadBalancingHttpClient retryableRibbonLoadBalancingHttpClient( - IClientConfig config, ServerIntrospector serverIntrospector, - ILoadBalancer loadBalancer, RetryHandler retryHandler, - LoadBalancedRetryFactory loadBalancedRetryFactory, - CloseableHttpClient httpClient, - RibbonLoadBalancerContext ribbonLoadBalancerContext) { - RetryableRibbonLoadBalancingHttpClient client = new RetryableRibbonLoadBalancingHttpClient( - httpClient, config, serverIntrospector, loadBalancedRetryFactory); - client.setLoadBalancer(loadBalancer); - client.setRetryHandler(retryHandler); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - Monitors.registerObject("Client_" + this.name, client); - return client; - } - - @Configuration(proxyBeanMethods = false) - protected static class ApacheHttpClientConfiguration { - - private final Timer connectionManagerTimer = new Timer( - "RibbonApacheHttpClientConfiguration.connectionManagerTimer", true); - - private CloseableHttpClient httpClient; - - @Autowired(required = false) - private RegistryBuilder registryBuilder; - - @Bean - @ConditionalOnMissingBean(HttpClientConnectionManager.class) - public HttpClientConnectionManager httpClientConnectionManager( - IClientConfig config, - ApacheHttpClientConnectionManagerFactory connectionManagerFactory) { - RibbonProperties ribbon = RibbonProperties.from(config); - int maxTotalConnections = ribbon.maxTotalConnections(); - int maxConnectionsPerHost = ribbon.maxConnectionsPerHost(); - int timerRepeat = ribbon.connectionCleanerRepeatInterval(); - long timeToLive = ribbon.poolKeepAliveTime(); - TimeUnit ttlUnit = ribbon.getPoolKeepAliveTimeUnits(); - final HttpClientConnectionManager connectionManager = connectionManagerFactory - .newConnectionManager(false, maxTotalConnections, - maxConnectionsPerHost, timeToLive, ttlUnit, registryBuilder); - this.connectionManagerTimer.schedule(new TimerTask() { - @Override - public void run() { - connectionManager.closeExpiredConnections(); - } - }, 30000, timerRepeat); - return connectionManager; - } - - @Bean - @ConditionalOnMissingBean(CloseableHttpClient.class) - public CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory, - HttpClientConnectionManager connectionManager, IClientConfig config) { - RibbonProperties ribbon = RibbonProperties.from(config); - Boolean followRedirects = ribbon.isFollowRedirects(); - Integer connectTimeout = ribbon.connectTimeout(); - RequestConfig defaultRequestConfig = RequestConfig.custom() - .setConnectTimeout(connectTimeout) - .setRedirectsEnabled(followRedirects).build(); - this.httpClient = httpClientFactory.createBuilder() - .setDefaultRequestConfig(defaultRequestConfig) - .setConnectionManager(connectionManager).build(); - return httpClient; - } - - @PreDestroy - public void destroy() throws Exception { - connectionManagerTimer.cancel(); - if (httpClient != null) { - httpClient.close(); - } - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientStatusCodeException.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientStatusCodeException.java deleted file mode 100644 index 54cb28598..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientStatusCodeException.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.apache; - -import java.io.IOException; -import java.net.URI; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.message.BasicHttpResponse; -import org.apache.http.util.EntityUtils; - -import org.springframework.cloud.client.loadbalancer.RetryableStatusCodeException; - -/** - * A {@link RetryableStatusCodeException} for {@link HttpResponse}s. - * - * @author Ryan Baxter - */ -public class HttpClientStatusCodeException extends RetryableStatusCodeException { - - private final BasicHttpResponse response; - - public HttpClientStatusCodeException(String serviceId, HttpResponse response, - HttpEntity entity, URI uri) throws IOException { - super(serviceId, response.getStatusLine().getStatusCode(), response, uri); - this.response = new BasicHttpResponse(response.getStatusLine()); - this.response.setLocale(response.getLocale()); - this.response.setStatusCode(response.getStatusLine().getStatusCode()); - this.response.setReasonPhrase(response.getStatusLine().getReasonPhrase()); - this.response.setHeaders(response.getAllHeaders()); - EntityUtils.updateEntity(this.response, entity); - } - - @Override - public HttpResponse getResponse() { - return this.response; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientUtils.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientUtils.java deleted file mode 100644 index 05e757cf1..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientUtils.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.apache; - -import java.io.ByteArrayInputStream; -import java.io.IOException; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.entity.BasicHttpEntity; -import org.apache.http.util.EntityUtils; - -/** - * Provides basic utilities for {@link org.apache.http.client.HttpClient}. - * - * @author Ryan Baxter - */ -public final class HttpClientUtils { - - private HttpClientUtils() { - throw new AssertionError("Must not instantiate utility class."); - } - - /** - * Creates an new {@link HttpEntity} by copying the {@link HttpEntity} from the - * {@link HttpResponse}. This method will close the response after copying the entity. - * @param response The response to create the {@link HttpEntity} from - * @return A new {@link HttpEntity} - * @throws IOException thrown if there is a problem closing the response. - */ - public static HttpEntity createEntity(HttpResponse response) throws IOException { - ByteArrayInputStream is = new ByteArrayInputStream( - EntityUtils.toByteArray(response.getEntity())); - BasicHttpEntity entity = new BasicHttpEntity(); - entity.setContent(is); - entity.setContentLength(response.getEntity().getContentLength()); - if (CloseableHttpResponse.class.isInstance(response)) { - ((CloseableHttpResponse) response).close(); - } - return entity; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RetryableRibbonLoadBalancingHttpClient.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RetryableRibbonLoadBalancingHttpClient.java deleted file mode 100644 index ec1016137..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RetryableRibbonLoadBalancingHttpClient.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.apache; - -import java.net.URI; - -import com.netflix.client.RequestSpecificRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.HttpResponse; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.impl.client.CloseableHttpClient; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.InterceptorRetryPolicy; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRecoveryCallback; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.RibbonServer; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.RibbonProperties; -import org.springframework.cloud.netflix.ribbon.RibbonStatsRecorder; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.support.ContextAwareRequest; -import org.springframework.http.HttpRequest; -import org.springframework.retry.RecoveryCallback; -import org.springframework.retry.RetryCallback; -import org.springframework.retry.RetryListener; -import org.springframework.retry.backoff.BackOffPolicy; -import org.springframework.retry.backoff.NoBackOffPolicy; -import org.springframework.retry.policy.NeverRetryPolicy; -import org.springframework.retry.support.RetryTemplate; -import org.springframework.web.util.UriComponentsBuilder; - -/** - * An Apache HTTP client which leverages Spring Retry to retry failed requests. - * - * @author Ryan Baxter - * @author Gang Li - */ -public class RetryableRibbonLoadBalancingHttpClient - extends RibbonLoadBalancingHttpClient { - - private static final Log LOGGER = LogFactory - .getLog(RetryableRibbonLoadBalancingHttpClient.class); - - private LoadBalancedRetryFactory loadBalancedRetryFactory; - - private RibbonLoadBalancerContext ribbonLoadBalancerContext; - - public RetryableRibbonLoadBalancingHttpClient(CloseableHttpClient delegate, - IClientConfig config, ServerIntrospector serverIntrospector, - LoadBalancedRetryFactory loadBalancedRetryFactory) { - super(delegate, config, serverIntrospector); - this.loadBalancedRetryFactory = loadBalancedRetryFactory; - } - - @Override - public RibbonApacheHttpResponse execute(final RibbonApacheHttpRequest request, - final IClientConfig configOverride) throws Exception { - final RequestConfig.Builder builder = RequestConfig.custom(); - IClientConfig config = configOverride != null ? configOverride : this.config; - RibbonProperties ribbon = RibbonProperties.from(config); - builder.setConnectTimeout(ribbon.connectTimeout(this.connectTimeout)); - builder.setSocketTimeout(ribbon.readTimeout(this.readTimeout)); - builder.setRedirectsEnabled(ribbon.isFollowRedirects(this.followRedirects)); - builder.setContentCompressionEnabled(ribbon.isGZipPayload(this.gzipPayload)); - - final RequestConfig requestConfig = builder.build(); - final LoadBalancedRetryPolicy retryPolicy = loadBalancedRetryFactory - .createRetryPolicy(this.getClientName(), this); - - RetryCallback retryCallback = context -> { - // on retries the policy will choose the server and set it in the context - // extract the server and update the request being made - RibbonApacheHttpRequest newRequest = request; - RibbonStatsRecorder statsRecorder = null; - if (context instanceof LoadBalancedRetryContext) { - ServiceInstance service = ((LoadBalancedRetryContext) context) - .getServiceInstance(); - validateServiceInstance(service); - if (service != null) { - // Reconstruct the request URI using the host and port set in the - // retry context - newRequest = newRequest.withNewUri(UriComponentsBuilder.newInstance() - .host(service.getHost()).scheme(service.getUri().getScheme()) - .userInfo(newRequest.getURI().getUserInfo()) - .port(service.getPort()) - .path(newRequest.getURI().getRawPath()) - .query(newRequest.getURI().getQuery()) - .fragment(newRequest.getURI().getFragment()).build(true) - .encode().toUri()); - if (ribbonLoadBalancerContext == null) { - LOGGER.error( - "RibbonLoadBalancerContext is null. Unable to update load balancer stats"); - } - else if (service instanceof RibbonServer) { - statsRecorder = new RibbonStatsRecorder(ribbonLoadBalancerContext, - ((RibbonServer) service).getServer()); - } - } - } - newRequest = getSecureRequest(newRequest, configOverride); - HttpUriRequest httpUriRequest = newRequest.toRequest(requestConfig); - final HttpResponse httpResponse = RetryableRibbonLoadBalancingHttpClient.this.delegate - .execute(httpUriRequest); - if (retryPolicy - .retryableStatusCode(httpResponse.getStatusLine().getStatusCode())) { - throw new HttpClientStatusCodeException( - RetryableRibbonLoadBalancingHttpClient.this.clientName, - httpResponse, HttpClientUtils.createEntity(httpResponse), - httpUriRequest.getURI()); - } - if (statsRecorder != null) { - statsRecorder.recordStats(httpResponse); - } - return new RibbonApacheHttpResponse(httpResponse, httpUriRequest.getURI()); - }; - LoadBalancedRecoveryCallback recoveryCallback = new LoadBalancedRecoveryCallback() { - @Override - protected RibbonApacheHttpResponse createResponse(HttpResponse response, - URI uri) { - return new RibbonApacheHttpResponse(response, uri); - } - }; - return this.executeWithRetry(request, retryPolicy, retryCallback, - recoveryCallback); - } - - @Override - public boolean isClientRetryable(ContextAwareRequest request) { - return request != null && isRequestRetryable(request); - } - - private boolean isRequestRetryable(ContextAwareRequest request) { - if (request.getContext() == null || request.getContext().getRetryable() == null) { - return true; - } - return request.getContext().getRetryable(); - } - - private RibbonApacheHttpResponse executeWithRetry(RibbonApacheHttpRequest request, - LoadBalancedRetryPolicy retryPolicy, - RetryCallback callback, - RecoveryCallback recoveryCallback) - throws Exception { - RetryTemplate retryTemplate = new RetryTemplate(); - boolean retryable = isRequestRetryable(request); - retryTemplate.setRetryPolicy(retryPolicy == null || !retryable - ? new NeverRetryPolicy() - : new RetryPolicy(request, retryPolicy, this, this.getClientName())); - BackOffPolicy backOffPolicy = loadBalancedRetryFactory - .createBackOffPolicy(this.getClientName()); - retryTemplate.setBackOffPolicy( - backOffPolicy == null ? new NoBackOffPolicy() : backOffPolicy); - RetryListener[] retryListeners = this.loadBalancedRetryFactory - .createRetryListeners(this.getClientName()); - if (retryListeners != null && retryListeners.length != 0) { - retryTemplate.setListeners(retryListeners); - } - return retryTemplate.execute(callback, recoveryCallback); - } - - @Override - public RequestSpecificRetryHandler getRequestSpecificRetryHandler( - RibbonApacheHttpRequest request, IClientConfig requestConfig) { - return new RequestSpecificRetryHandler(false, false, RetryHandler.DEFAULT, null); - } - - public void setRibbonLoadBalancerContext( - RibbonLoadBalancerContext ribbonLoadBalancerContext) { - this.ribbonLoadBalancerContext = ribbonLoadBalancerContext; - } - - static class RetryPolicy extends InterceptorRetryPolicy { - - RetryPolicy(HttpRequest request, LoadBalancedRetryPolicy policy, - ServiceInstanceChooser serviceInstanceChooser, String serviceName) { - super(request, policy, serviceInstanceChooser, serviceName); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpRequest.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpRequest.java deleted file mode 100644 index ac51d6252..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpRequest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.apache; - -import java.net.URI; -import java.util.List; - -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.methods.RequestBuilder; -import org.apache.http.entity.BasicHttpEntity; - -import org.springframework.cloud.netflix.ribbon.support.ContextAwareRequest; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; - -import static org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer.Runner.customize; - -/** - * @author Christian Lohmann - */ -public class RibbonApacheHttpRequest extends ContextAwareRequest implements Cloneable { - - public RibbonApacheHttpRequest(RibbonCommandContext context) { - super(context); - } - - public HttpUriRequest toRequest(final RequestConfig requestConfig) { - final RequestBuilder builder = RequestBuilder.create(this.context.getMethod()); - builder.setUri(this.uri); - for (final String name : this.context.getHeaders().keySet()) { - final List values = this.context.getHeaders().get(name); - for (final String value : values) { - builder.addHeader(name, value); - } - } - - for (final String name : this.context.getParams().keySet()) { - final List values = this.context.getParams().get(name); - for (final String value : values) { - builder.addParameter(name, value); - } - } - - if (this.context.getRequestEntity() != null) { - final BasicHttpEntity entity; - entity = new BasicHttpEntity(); - entity.setContent(this.context.getRequestEntity()); - // if the entity contentLength isn't set, transfer-encoding will be set - // to chunked in org.apache.http.protocol.RequestContent. See gh-1042 - Long contentLength = this.context.getContentLength(); - if ("GET".equals(this.context.getMethod()) - && (contentLength == null || contentLength < 0)) { - entity.setContentLength(0); - } - else if (contentLength != null) { - entity.setContentLength(contentLength); - } - builder.setEntity(entity); - } - - customize(this.context.getRequestCustomizers(), builder); - - builder.setConfig(requestConfig); - return builder.build(); - } - - public RibbonApacheHttpRequest withNewUri(URI uri) { - return new RibbonApacheHttpRequest(newContext(uri)); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpResponse.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpResponse.java deleted file mode 100644 index ac7c10518..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpResponse.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.apache; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Type; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.google.common.reflect.TypeToken; -import com.netflix.client.ClientException; -import com.netflix.client.http.CaseInsensitiveMultiMap; -import com.netflix.client.http.HttpHeaders; -import org.apache.http.Header; -import org.apache.http.HttpResponse; - -import org.springframework.http.HttpStatus; -import org.springframework.util.Assert; - -/** - * @author Christian Lohmann - */ -public class RibbonApacheHttpResponse implements com.netflix.client.http.HttpResponse { - - private HttpResponse httpResponse; - - private URI uri; - - public RibbonApacheHttpResponse(final HttpResponse httpResponse, final URI uri) { - Assert.notNull(httpResponse, "httpResponse can not be null"); - this.httpResponse = httpResponse; - this.uri = uri; - } - - @Override - public Object getPayload() throws ClientException { - try { - if (!hasPayload()) { - return null; - } - return this.httpResponse.getEntity().getContent(); - } - catch (final IOException e) { - throw new ClientException(e.getMessage(), e); - } - } - - @Override - public boolean hasPayload() { - return this.httpResponse.getEntity() != null; - } - - @Override - public boolean isSuccess() { - return HttpStatus.valueOf(this.httpResponse.getStatusLine().getStatusCode()) - .is2xxSuccessful(); - } - - @Override - public URI getRequestedURI() { - return this.uri; - } - - public int getStatus() { - return httpResponse.getStatusLine().getStatusCode(); - } - - public String getStatusLine() { - return httpResponse.getStatusLine().toString(); - } - - @Override - public Map> getHeaders() { - final Map> headers = new HashMap<>(); - for (final Header header : this.httpResponse.getAllHeaders()) { - if (headers.containsKey(header.getName())) { - headers.get(header.getName()).add(header.getValue()); - } - else { - final List values = new ArrayList<>(); - values.add(header.getValue()); - headers.put(header.getName(), values); - } - } - - return headers; - } - - @Override - public HttpHeaders getHttpHeaders() { - final CaseInsensitiveMultiMap headers = new CaseInsensitiveMultiMap(); - for (final Header header : httpResponse.getAllHeaders()) { - headers.addHeader(header.getName(), header.getValue()); - } - - return headers; - } - - @Override - public void close() { - if (this.httpResponse != null && this.httpResponse.getEntity() != null) { - try { - this.httpResponse.getEntity().getContent().close(); - } - catch (final IOException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - } - - @Override - public InputStream getInputStream() { - try { - if (!hasPayload()) { - return null; - } - return this.httpResponse.getEntity().getContent(); - } - catch (final IOException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - @Override - public boolean hasEntity() { - return hasPayload(); - } - - /** - * Not used. - */ - @Override - public T getEntity(final Class type) throws Exception { - return null; - } - - /** - * Not used. - */ - @Override - public T getEntity(final Type type) throws Exception { - return null; - } - - /** - * Not used. - */ - @Override - public T getEntity(final TypeToken type) throws Exception { - return null; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClient.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClient.java deleted file mode 100644 index c13181165..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClient.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.apache; - -import java.net.URI; - -import com.netflix.client.RequestSpecificRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; -import org.apache.http.HttpResponse; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; - -import org.springframework.cloud.netflix.ribbon.RibbonProperties; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.support.AbstractLoadBalancingClient; -import org.springframework.web.util.UriComponentsBuilder; - -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToSecureConnectionIfNeeded; - -/** - * @author Christian Lohmann - * @author Ryan Baxter - * @author Tim Ysewyn - */ -// TODO: rename (ie new class that extends this in Dalston) to -// ApacheHttpLoadBalancingClient -public class RibbonLoadBalancingHttpClient extends - AbstractLoadBalancingClient { - - public RibbonLoadBalancingHttpClient(IClientConfig config, - ServerIntrospector serverIntrospector) { - super(config, serverIntrospector); - } - - public RibbonLoadBalancingHttpClient(CloseableHttpClient delegate, - IClientConfig config, ServerIntrospector serverIntrospector) { - super(delegate, config, serverIntrospector); - } - - protected CloseableHttpClient createDelegate(IClientConfig config) { - RibbonProperties ribbon = RibbonProperties.from(config); - return HttpClientBuilder.create() - // already defaults to 0 in builder, so resetting to 0 won't hurt - .setMaxConnTotal(ribbon.maxTotalConnections(0)) - // already defaults to 0 in builder, so resetting to 0 won't hurt - .setMaxConnPerRoute(ribbon.maxConnectionsPerHost(0)) - .disableCookieManagement().useSystemProperties() // for proxy - .build(); - } - - @Override - public RibbonApacheHttpResponse execute(RibbonApacheHttpRequest request, - final IClientConfig configOverride) throws Exception { - IClientConfig config = configOverride != null ? configOverride : this.config; - RibbonProperties ribbon = RibbonProperties.from(config); - RequestConfig requestConfig = RequestConfig.custom() - .setConnectTimeout(ribbon.connectTimeout(this.connectTimeout)) - .setSocketTimeout(ribbon.readTimeout(this.readTimeout)) - .setRedirectsEnabled(ribbon.isFollowRedirects(this.followRedirects)) - .setContentCompressionEnabled(ribbon.isGZipPayload(this.gzipPayload)) - .build(); - - request = getSecureRequest(request, configOverride); - final HttpUriRequest httpUriRequest = request.toRequest(requestConfig); - final HttpResponse httpResponse = this.delegate.execute(httpUriRequest); - return new RibbonApacheHttpResponse(httpResponse, httpUriRequest.getURI()); - } - - @Override - public URI reconstructURIWithServer(Server server, URI original) { - URI uri = updateToSecureConnectionIfNeeded(original, this.config, - this.serverIntrospector, server); - return super.reconstructURIWithServer(server, uri); - } - - @Override - public RequestSpecificRetryHandler getRequestSpecificRetryHandler( - RibbonApacheHttpRequest request, IClientConfig requestConfig) { - return new RequestSpecificRetryHandler(false, false, RetryHandler.DEFAULT, - requestConfig); - } - - protected RibbonApacheHttpRequest getSecureRequest(RibbonApacheHttpRequest request, - IClientConfig configOverride) { - if (isSecure(configOverride)) { - final URI secureUri = UriComponentsBuilder.fromUri(request.getUri()) - .scheme("https").build(true).toUri(); - return request.withNewUri(secureUri); - } - return request; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClient.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClient.java deleted file mode 100644 index 784b40e4d..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClient.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.okhttp; - -import java.net.URI; -import java.util.concurrent.TimeUnit; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; - -import org.springframework.cloud.netflix.ribbon.RibbonProperties; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.support.AbstractLoadBalancingClient; -import org.springframework.web.util.UriComponentsBuilder; - -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToSecureConnectionIfNeeded; - -/** - * @author Spencer Gibb - * @author Ryan Baxter - * @author Tim Ysewyn - */ -public class OkHttpLoadBalancingClient extends - AbstractLoadBalancingClient { - - public OkHttpLoadBalancingClient(IClientConfig config, - ServerIntrospector serverIntrospector) { - super(config, serverIntrospector); - } - - public OkHttpLoadBalancingClient(OkHttpClient delegate, IClientConfig config, - ServerIntrospector serverIntrospector) { - super(delegate, config, serverIntrospector); - } - - @Override - protected OkHttpClient createDelegate(IClientConfig config) { - return new OkHttpClient(); - } - - @Override - public OkHttpRibbonResponse execute(OkHttpRibbonRequest ribbonRequest, - final IClientConfig configOverride) throws Exception { - boolean secure = isSecure(configOverride); - if (secure) { - final URI secureUri = UriComponentsBuilder.fromUri(ribbonRequest.getUri()) - .scheme("https").build().toUri(); - ribbonRequest = ribbonRequest.withNewUri(secureUri); - } - - OkHttpClient httpClient = getOkHttpClient(configOverride, secure); - final Request request = ribbonRequest.toRequest(); - Response response = httpClient.newCall(request).execute(); - return new OkHttpRibbonResponse(response, ribbonRequest.getUri()); - } - - OkHttpClient getOkHttpClient(IClientConfig configOverride, boolean secure) { - IClientConfig config = configOverride != null ? configOverride : this.config; - RibbonProperties ribbon = RibbonProperties.from(config); - OkHttpClient.Builder builder = this.delegate.newBuilder() - .connectTimeout(ribbon.connectTimeout(this.connectTimeout), - TimeUnit.MILLISECONDS) - .readTimeout(ribbon.readTimeout(this.readTimeout), TimeUnit.MILLISECONDS) - .followRedirects(ribbon.isFollowRedirects(this.followRedirects)); - if (secure) { - builder.followSslRedirects(ribbon.isFollowRedirects(this.followRedirects)); - } - - return builder.build(); - } - - @Override - public URI reconstructURIWithServer(Server server, URI original) { - URI uri = updateToSecureConnectionIfNeeded(original, this.config, - this.serverIntrospector, server); - return super.reconstructURIWithServer(server, uri); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonConfiguration.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonConfiguration.java deleted file mode 100644 index c67857a65..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonConfiguration.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.okhttp; - -import java.util.concurrent.TimeUnit; - -import javax.annotation.PreDestroy; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.servo.monitor.Monitors; -import okhttp3.ConnectionPool; -import okhttp3.OkHttpClient; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory; -import org.springframework.cloud.commons.httpclient.OkHttpClientFactory; -import org.springframework.cloud.netflix.ribbon.RibbonClientName; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.RibbonProperties; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnProperty("ribbon.okhttp.enabled") -@ConditionalOnClass(name = "okhttp3.OkHttpClient") -public class OkHttpRibbonConfiguration { - - @RibbonClientName - private String name = "client"; - - @Bean - @ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class) - @ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate") - public RetryableOkHttpLoadBalancingClient retryableOkHttpLoadBalancingClient( - IClientConfig config, ServerIntrospector serverIntrospector, - ILoadBalancer loadBalancer, RetryHandler retryHandler, - LoadBalancedRetryFactory loadBalancedRetryFactory, OkHttpClient delegate, - RibbonLoadBalancerContext ribbonLoadBalancerContext) { - RetryableOkHttpLoadBalancingClient client = new RetryableOkHttpLoadBalancingClient( - delegate, config, serverIntrospector, loadBalancedRetryFactory); - client.setLoadBalancer(loadBalancer); - client.setRetryHandler(retryHandler); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - Monitors.registerObject("Client_" + this.name, client); - return client; - } - - @Bean - @ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class) - @ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate") - public OkHttpLoadBalancingClient okHttpLoadBalancingClient(IClientConfig config, - ServerIntrospector serverIntrospector, ILoadBalancer loadBalancer, - RetryHandler retryHandler, OkHttpClient delegate) { - OkHttpLoadBalancingClient client = new OkHttpLoadBalancingClient(delegate, config, - serverIntrospector); - client.setLoadBalancer(loadBalancer); - client.setRetryHandler(retryHandler); - Monitors.registerObject("Client_" + this.name, client); - return client; - } - - @Configuration(proxyBeanMethods = false) - protected static class OkHttpClientConfiguration { - - private OkHttpClient httpClient; - - @Bean - @ConditionalOnMissingBean(ConnectionPool.class) - public ConnectionPool httpClientConnectionPool(IClientConfig config, - OkHttpClientConnectionPoolFactory connectionPoolFactory) { - RibbonProperties ribbon = RibbonProperties.from(config); - int maxTotalConnections = ribbon.maxTotalConnections(); - long timeToLive = ribbon.poolKeepAliveTime(); - TimeUnit ttlUnit = ribbon.getPoolKeepAliveTimeUnits(); - return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit); - } - - @Bean - @ConditionalOnMissingBean(OkHttpClient.class) - public OkHttpClient client(OkHttpClientFactory httpClientFactory, - ConnectionPool connectionPool, IClientConfig config) { - RibbonProperties ribbon = RibbonProperties.from(config); - this.httpClient = httpClientFactory.createBuilder(false) - .connectTimeout(ribbon.connectTimeout(), TimeUnit.MILLISECONDS) - .readTimeout(ribbon.readTimeout(), TimeUnit.MILLISECONDS) - .followRedirects(ribbon.isFollowRedirects()) - .connectionPool(connectionPool).build(); - return this.httpClient; - } - - @PreDestroy - public void destroy() { - if (httpClient != null) { - httpClient.dispatcher().executorService().shutdown(); - httpClient.connectionPool().evictAll(); - } - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonRequest.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonRequest.java deleted file mode 100644 index 5fcc545e8..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonRequest.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.okhttp; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.util.List; - -import okhttp3.Headers; -import okhttp3.HttpUrl; -import okhttp3.MediaType; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.internal.http.HttpMethod; -import okio.BufferedSink; -import okio.Okio; -import okio.Source; - -import org.springframework.cloud.netflix.ribbon.support.ContextAwareRequest; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; - -import static org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer.Runner.customize; - -/** - * @author Spencer Gibb - */ -public class OkHttpRibbonRequest extends ContextAwareRequest implements Cloneable { - - public OkHttpRibbonRequest(RibbonCommandContext context) { - super(context); - } - - public Request toRequest() { - Headers.Builder headers = new Headers.Builder(); - for (String name : this.context.getHeaders().keySet()) { - List values = this.context.getHeaders().get(name); - for (String value : values) { - headers.add(name, value); - } - } - - HttpUrl.Builder url = HttpUrl.get(this.uri).newBuilder(); - for (String name : this.context.getParams().keySet()) { - List values = this.context.getParams().get(name); - for (String value : values) { - url.addQueryParameter(name, value); - } - } - - RequestBody requestBody = null; - - if (this.context.getRequestEntity() != null - && HttpMethod.permitsRequestBody(this.context.getMethod())) { - MediaType mediaType = null; - if (headers.get("Content-Type") != null) { - mediaType = MediaType.parse(headers.get("Content-Type")); - } - requestBody = new InputStreamRequestBody(this.context.getRequestEntity(), - mediaType, this.context.getContentLength()); - } - - Request.Builder builder = new Request.Builder().url(url.build()) - .headers(headers.build()).method(this.context.getMethod(), requestBody); - - customize(this.context.getRequestCustomizers(), builder); - - return builder.build(); - } - - public OkHttpRibbonRequest withNewUri(final URI uri) { - return new OkHttpRibbonRequest(newContext(uri)); - } - - static class InputStreamRequestBody extends RequestBody { - - private InputStream inputStream; - - private MediaType mediaType; - - private Long contentLength; - - InputStreamRequestBody(InputStream inputStream, MediaType mediaType, - Long contentLength) { - this.inputStream = inputStream; - this.mediaType = mediaType; - this.contentLength = contentLength; - } - - @Override - public MediaType contentType() { - return mediaType; - } - - @Override - public long contentLength() { - if (contentLength != null) { - return contentLength; - } - try { - return inputStream.available(); - } - catch (IOException e) { - return 0; - } - } - - @Override - public void writeTo(BufferedSink sink) throws IOException { - Source source = null; - try { - source = Okio.source(inputStream); - sink.writeAll(source); - } - finally { - if (source != null) { - source.close(); - } - } - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonResponse.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonResponse.java deleted file mode 100644 index 227fa37a7..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonResponse.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.okhttp; - -import java.io.InputStream; -import java.lang.reflect.Type; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.google.common.reflect.TypeToken; -import com.netflix.client.ClientException; -import com.netflix.client.http.CaseInsensitiveMultiMap; -import com.netflix.client.http.HttpHeaders; -import okhttp3.Response; -import okhttp3.ResponseBody; - -import org.springframework.util.Assert; - -/** - * @author Spencer Gibb - */ -public class OkHttpRibbonResponse implements com.netflix.client.http.HttpResponse { - - private final ResponseBody body; - - private URI uri; - - private Response response; - - public OkHttpRibbonResponse(Response response, URI uri) { - Assert.notNull(response, "response can not be null"); - this.response = response; - this.body = response.body(); - this.uri = uri; - } - - @Override - public int getStatus() { - return this.response.code(); - } - - @Override - public String getStatusLine() { - return this.response.message(); - } - - @Override - public Object getPayload() throws ClientException { - if (!hasPayload()) { - return null; - } - return this.body.byteStream(); - } - - @Override - public boolean hasPayload() { - return this.body != null; - } - - @Override - public boolean isSuccess() { - return this.response.isSuccessful(); - } - - @Override - public URI getRequestedURI() { - return this.uri; - } - - @Override - public Map> getHeaders() { - final Map> headers = new HashMap<>(); - for (Map.Entry> entry : this.response.headers().toMultimap() - .entrySet()) { - String name = entry.getKey(); - for (String value : entry.getValue()) { - if (headers.containsKey(name)) { - headers.get(name).add(value); - } - else { - final List values = new ArrayList<>(); - values.add(value); - headers.put(name, values); - } - } - } - - return headers; - } - - @Override - public HttpHeaders getHttpHeaders() { - final CaseInsensitiveMultiMap headers = new CaseInsensitiveMultiMap(); - for (Map.Entry> entry : this.response.headers().toMultimap() - .entrySet()) { - for (String value : entry.getValue()) { - headers.addHeader(entry.getKey(), value); - } - } - - return headers; - } - - @Override - public void close() { - this.response.close(); - } - - @Override - public InputStream getInputStream() { - if (this.body == null) { - return null; - } - return this.body.byteStream(); - } - - @Override - public boolean hasEntity() { - return hasPayload(); - } - - @Override - public T getEntity(Class type) throws Exception { - return null; - } - - @Override - public T getEntity(Type type) throws Exception { - return null; - } - - @Override - public T getEntity(TypeToken type) throws Exception { - return null; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpStatusCodeException.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpStatusCodeException.java deleted file mode 100644 index ef11b6b22..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpStatusCodeException.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.okhttp; - -import java.net.URI; - -import okhttp3.Response; -import okhttp3.ResponseBody; - -import org.springframework.cloud.client.loadbalancer.RetryableStatusCodeException; - -/** - * An {@link RetryableStatusCodeException} that captures a {@link Response}. - * - * @author Ryan Baxter - */ -public class OkHttpStatusCodeException extends RetryableStatusCodeException { - - private final Response response; - - public OkHttpStatusCodeException(String serviceId, Response response, - ResponseBody responseBody, URI uri) { - super(serviceId, response.code(), response, uri); - this.response = new Response.Builder().code(response.code()) - .message(response.message()).protocol(response.protocol()) - .request(response.request()).headers(response.headers()) - .handshake(response.handshake()).cacheResponse(response.cacheResponse()) - .networkResponse(response.networkResponse()) - .priorResponse(response.priorResponse()) - .sentRequestAtMillis(response.sentRequestAtMillis()).body(responseBody) - .build(); - } - - @Override - public Response getResponse() { - return response; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/RetryableOkHttpLoadBalancingClient.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/RetryableOkHttpLoadBalancingClient.java deleted file mode 100644 index d972b2bc7..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/RetryableOkHttpLoadBalancingClient.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.okhttp; - -import java.net.URI; - -import com.netflix.client.RequestSpecificRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.ResponseBody; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.InterceptorRetryPolicy; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRecoveryCallback; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.RibbonServer; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.RibbonStatsRecorder; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.support.ContextAwareRequest; -import org.springframework.http.HttpRequest; -import org.springframework.retry.RecoveryCallback; -import org.springframework.retry.RetryCallback; -import org.springframework.retry.RetryContext; -import org.springframework.retry.RetryListener; -import org.springframework.retry.backoff.BackOffPolicy; -import org.springframework.retry.backoff.NoBackOffPolicy; -import org.springframework.retry.policy.NeverRetryPolicy; -import org.springframework.retry.support.RetryTemplate; -import org.springframework.web.util.UriComponentsBuilder; - -/** - * An OK HTTP client which leverages Spring Retry to retry failed request. - * - * @author Ryan Baxter - * @author Gang Li - */ -public class RetryableOkHttpLoadBalancingClient extends OkHttpLoadBalancingClient { - - private static final Log LOGGER = LogFactory - .getLog(RetryableOkHttpLoadBalancingClient.class); - - private LoadBalancedRetryFactory loadBalancedRetryFactory; - - private RibbonLoadBalancerContext ribbonLoadBalancerContext; - - public RetryableOkHttpLoadBalancingClient(OkHttpClient delegate, IClientConfig config, - ServerIntrospector serverIntrospector, - LoadBalancedRetryFactory loadBalancedRetryPolicyFactory) { - super(delegate, config, serverIntrospector); - this.loadBalancedRetryFactory = loadBalancedRetryPolicyFactory; - } - - @Override - public boolean isClientRetryable(ContextAwareRequest request) { - return request != null && isRequestRetryable(request); - } - - private boolean isRequestRetryable(ContextAwareRequest request) { - if (request.getContext() == null || request.getContext().getRetryable() == null) { - return true; - } - return request.getContext().getRetryable(); - } - - private OkHttpRibbonResponse executeWithRetry(OkHttpRibbonRequest request, - LoadBalancedRetryPolicy retryPolicy, - RetryCallback callback, - RecoveryCallback recoveryCallback) throws Exception { - RetryTemplate retryTemplate = new RetryTemplate(); - BackOffPolicy backOffPolicy = loadBalancedRetryFactory - .createBackOffPolicy(this.getClientName()); - retryTemplate.setBackOffPolicy( - backOffPolicy == null ? new NoBackOffPolicy() : backOffPolicy); - RetryListener[] retryListeners = this.loadBalancedRetryFactory - .createRetryListeners(this.getClientName()); - if (retryListeners != null && retryListeners.length != 0) { - retryTemplate.setListeners(retryListeners); - } - boolean retryable = isRequestRetryable(request); - retryTemplate.setRetryPolicy(retryPolicy == null || !retryable - ? new NeverRetryPolicy() - : new RetryPolicy(request, retryPolicy, this, this.getClientName())); - return retryTemplate.execute(callback, recoveryCallback); - } - - @Override - public OkHttpRibbonResponse execute(final OkHttpRibbonRequest ribbonRequest, - final IClientConfig configOverride) throws Exception { - final LoadBalancedRetryPolicy retryPolicy = loadBalancedRetryFactory - .createRetryPolicy(this.getClientName(), this); - RetryCallback retryCallback = new RetryCallback() { - @Override - public OkHttpRibbonResponse doWithRetry(RetryContext context) - throws Exception { - // on retries the policy will choose the server and set it in the context - // extract the server and update the request being made - OkHttpRibbonRequest newRequest = ribbonRequest; - RibbonStatsRecorder statsRecorder = null; - - if (context instanceof LoadBalancedRetryContext) { - ServiceInstance service = ((LoadBalancedRetryContext) context) - .getServiceInstance(); - validateServiceInstance(service); - // Reconstruct the request URI using the host and port set in the - // retry context - newRequest = newRequest - .withNewUri(new URI(service.getUri().getScheme(), - newRequest.getURI().getUserInfo(), service.getHost(), - service.getPort(), newRequest.getURI().getPath(), - newRequest.getURI().getQuery(), - newRequest.getURI().getFragment())); - - if (ribbonLoadBalancerContext == null) { - LOGGER.error( - "RibbonLoadBalancerContext is null. Unable to update load balancer stats"); - } - else if (service instanceof RibbonServer) { - statsRecorder = new RibbonStatsRecorder(ribbonLoadBalancerContext, - ((RibbonServer) service).getServer()); - } - } - if (isSecure(configOverride)) { - final URI secureUri = UriComponentsBuilder - .fromUri(newRequest.getUri()).scheme("https").build().toUri(); - newRequest = newRequest.withNewUri(secureUri); - } - OkHttpClient httpClient = getOkHttpClient(configOverride, secure); - - final Request request = newRequest.toRequest(); - Response response = httpClient.newCall(request).execute(); - if (retryPolicy.retryableStatusCode(response.code())) { - ResponseBody responseBody = response.peekBody(Integer.MAX_VALUE); - response.close(); - throw new OkHttpStatusCodeException( - RetryableOkHttpLoadBalancingClient.this.clientName, response, - responseBody, newRequest.getURI()); - } - if (statsRecorder != null) { - statsRecorder.recordStats(response); - } - return new OkHttpRibbonResponse(response, newRequest.getUri()); - } - }; - return this.executeWithRetry(ribbonRequest, retryPolicy, retryCallback, - new LoadBalancedRecoveryCallback() { - - @Override - protected OkHttpRibbonResponse createResponse(Response response, - URI uri) { - return new OkHttpRibbonResponse(response, uri); - } - }); - } - - @Override - public RequestSpecificRetryHandler getRequestSpecificRetryHandler( - OkHttpRibbonRequest request, IClientConfig requestConfig) { - return new RequestSpecificRetryHandler(false, false, RetryHandler.DEFAULT, null); - } - - public void setRibbonLoadBalancerContext( - RibbonLoadBalancerContext ribbonLoadBalancerContext) { - this.ribbonLoadBalancerContext = ribbonLoadBalancerContext; - } - - static class RetryPolicy extends InterceptorRetryPolicy { - - RetryPolicy(HttpRequest request, LoadBalancedRetryPolicy policy, - ServiceInstanceChooser serviceInstanceChooser, String serviceName) { - super(request, policy, serviceInstanceChooser, serviceName); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/AbstractLoadBalancingClient.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/AbstractLoadBalancingClient.java deleted file mode 100644 index f61bfa586..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/AbstractLoadBalancingClient.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.support; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.ClientException; -import com.netflix.client.IResponse; -import com.netflix.client.RequestSpecificRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.reactive.LoadBalancerCommand; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient; -import org.springframework.cloud.netflix.ribbon.RibbonProperties; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; - -import static org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration.DEFAULT_CONNECT_TIMEOUT; -import static org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration.DEFAULT_GZIP_PAYLOAD; -import static org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration.DEFAULT_READ_TIMEOUT; - -/** - * @param delegate - * @param {@link ContextAwareRequest} subtype - * @param {@link ServiceInstanceChooser} subtype - * @author Spencer Gibb - * - */ -public abstract class AbstractLoadBalancingClient - extends AbstractLoadBalancerAwareClient implements ServiceInstanceChooser { - - protected int connectTimeout; - - protected int readTimeout; - - protected boolean secure; - - protected boolean followRedirects; - - protected boolean gzipPayload; - - protected boolean okToRetryOnAllOperations; - - protected final D delegate; - - protected final IClientConfig config; - - protected final ServerIntrospector serverIntrospector; - - public boolean isClientRetryable(ContextAwareRequest request) { - return false; - } - - protected AbstractLoadBalancingClient(IClientConfig config, - ServerIntrospector serverIntrospector) { - super(null); - this.delegate = createDelegate(config); - this.config = config; - this.serverIntrospector = serverIntrospector; - this.setRetryHandler(RetryHandler.DEFAULT); - initWithNiwsConfig(config); - } - - protected AbstractLoadBalancingClient(D delegate, IClientConfig config, - ServerIntrospector serverIntrospector) { - super(null); - this.delegate = delegate; - this.config = config; - this.serverIntrospector = serverIntrospector; - this.setRetryHandler(RetryHandler.DEFAULT); - initWithNiwsConfig(config); - } - - @Override - public void initWithNiwsConfig(IClientConfig clientConfig) { - super.initWithNiwsConfig(clientConfig); - RibbonProperties ribbon = RibbonProperties.from(clientConfig); - this.connectTimeout = ribbon.connectTimeout(DEFAULT_CONNECT_TIMEOUT); - this.readTimeout = ribbon.readTimeout(DEFAULT_READ_TIMEOUT); - this.secure = ribbon.isSecure(); - this.followRedirects = ribbon.isFollowRedirects(); - this.okToRetryOnAllOperations = ribbon.isOkToRetryOnAllOperations(); - this.gzipPayload = ribbon.isGZipPayload(DEFAULT_GZIP_PAYLOAD); - } - - protected abstract D createDelegate(IClientConfig config); - - public D getDelegate() { - return this.delegate; - } - - @Override - public RequestSpecificRetryHandler getRequestSpecificRetryHandler(final S request, - final IClientConfig requestConfig) { - if (this.okToRetryOnAllOperations) { - return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(), - requestConfig); - } - - if (!request.getContext().getMethod().equals("GET")) { - return new RequestSpecificRetryHandler(true, false, this.getRetryHandler(), - requestConfig); - } - else { - return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(), - requestConfig); - } - } - - protected boolean isSecure(final IClientConfig config) { - if (config != null) { - return RibbonProperties.from(config).isSecure(this.secure); - } - return this.secure; - } - - @Override - protected void customizeLoadBalancerCommandBuilder(S request, IClientConfig config, - LoadBalancerCommand.Builder builder) { - if (request.getLoadBalancerKey() != null) { - builder.withServerLocator(request.getLoadBalancerKey()); - } - } - - @Override - public ServiceInstance choose(String serviceId) { - Server server = this.getLoadBalancer().chooseServer(serviceId); - if (server != null) { - return new RibbonLoadBalancerClient.RibbonServer(serviceId, server); - } - return null; - } - - public void validateServiceInstance(ServiceInstance serviceInstance) - throws ClientException { - if (serviceInstance == null) { - throw new ClientException( - "Load balancer does not have available server for client: " - + clientName); - } - else if (serviceInstance.getHost() == null) { - throw new ClientException("Invalid Server for: " - + serviceInstance.getServiceId() + " null Host"); - } - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequest.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequest.java deleted file mode 100644 index 08cf65c16..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.support; - -import java.net.URI; - -import com.netflix.client.ClientRequest; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpRequest; -import org.springframework.util.MultiValueMap; - -/** - * @author Spencer Gibb - * @author Ryan Baxter - */ -public abstract class ContextAwareRequest extends ClientRequest implements HttpRequest { - - protected final RibbonCommandContext context; - - private HttpHeaders httpHeaders; - - public ContextAwareRequest(RibbonCommandContext context) { - this.context = context; - MultiValueMap headers = context.getHeaders(); - this.httpHeaders = new HttpHeaders(); - for (String key : headers.keySet()) { - this.httpHeaders.put(key, headers.get(key)); - } - this.uri = context.uri(); - this.isRetriable = context.getRetryable(); - this.loadBalancerKey = context.getLoadBalancerKey(); - } - - public RibbonCommandContext getContext() { - return context; - } - - @Override - public HttpMethod getMethod() { - return HttpMethod.valueOf(context.getMethod()); - } - - @Override - public String getMethodValue() { - return getMethod().name(); - } - - @Override - public URI getURI() { - return this.getUri(); - } - - @Override - public HttpHeaders getHeaders() { - return httpHeaders; - } - - protected RibbonCommandContext newContext(URI uri) { - RibbonCommandContext commandContext = new RibbonCommandContext( - this.context.getServiceId(), this.context.getMethod(), uri.toString(), - this.context.getRetryable(), this.context.getHeaders(), - this.context.getParams(), this.context.getRequestEntity(), - this.context.getRequestCustomizers(), this.context.getContentLength(), - this.context.getLoadBalancerKey()); - return commandContext; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/ResettableServletInputStreamWrapper.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/ResettableServletInputStreamWrapper.java deleted file mode 100644 index a521332b3..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/ResettableServletInputStreamWrapper.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.support; - -import java.io.ByteArrayInputStream; -import java.io.IOException; - -import javax.servlet.ReadListener; -import javax.servlet.ServletInputStream; - -/** - * A wrapper for {@link ServletInputStream} providing additional capabilities to allow for - * resetting. - * - * @author Arne Dörnbrack - * @author Spencer Gibb - */ -public class ResettableServletInputStreamWrapper extends ServletInputStream { - - private final ByteArrayInputStream input; - - public ResettableServletInputStreamWrapper(byte[] data) { - this.input = new ByteArrayInputStream(data); - } - - @Override - public boolean isFinished() { - return false; - } - - @Override - public boolean isReady() { - return false; - } - - @Override - public void setReadListener(ReadListener listener) { - } - - @Override - public int read() throws IOException { - return input.read(); - } - - @Override - public synchronized void reset() throws IOException { - input.reset(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonCommandContext.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonCommandContext.java deleted file mode 100644 index 2aed0098c..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonCommandContext.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.support; - -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import org.springframework.util.Assert; -import org.springframework.util.MultiValueMap; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StreamUtils; - -/** - * @author Spencer Gibb - * @author Yongsung Yoon - */ -public class RibbonCommandContext { - - private final String serviceId; - - private final String method; - - private final String uri; - - private final Boolean retryable; - - private final MultiValueMap headers; - - private final MultiValueMap params; - - private final List requestCustomizers; - - private InputStream requestEntity; - - private Long contentLength; - - private Object loadBalancerKey; - - /** - * Kept for backwards compatibility with Spring Cloud Sleuth 1.x versions. - * @param serviceId to be used with Ribbon request - * @param method to be used with Ribbon request - * @param uri {@link String} value of the uri to be used with Ribbon request - * @param retryable determines whether the requests should be retried - * @param headers to pass to the Ribbon request - * @param params parameters to pass to the Ribbon request - * @param requestEntity request content {@link InputStream} - */ - @Deprecated - public RibbonCommandContext(String serviceId, String method, String uri, - Boolean retryable, MultiValueMap headers, - MultiValueMap params, InputStream requestEntity) { - this(serviceId, method, uri, retryable, headers, params, requestEntity, - new ArrayList(), null, null); - } - - public RibbonCommandContext(String serviceId, String method, String uri, - Boolean retryable, MultiValueMap headers, - MultiValueMap params, InputStream requestEntity, - List requestCustomizers) { - this(serviceId, method, uri, retryable, headers, params, requestEntity, - requestCustomizers, null, null); - } - - public RibbonCommandContext(String serviceId, String method, String uri, - Boolean retryable, MultiValueMap headers, - MultiValueMap params, InputStream requestEntity, - List requestCustomizers, Long contentLength) { - this(serviceId, method, uri, retryable, headers, params, requestEntity, - requestCustomizers, contentLength, null); - } - - public RibbonCommandContext(String serviceId, String method, String uri, - Boolean retryable, MultiValueMap headers, - MultiValueMap params, InputStream requestEntity, - List requestCustomizers, Long contentLength, - Object loadBalancerKey) { - Assert.notNull(serviceId, "serviceId may not be null"); - Assert.notNull(method, "method may not be null"); - Assert.notNull(uri, "uri may not be null"); - Assert.notNull(headers, "headers may not be null"); - Assert.notNull(params, "params may not be null"); - Assert.notNull(requestCustomizers, "requestCustomizers may not be null"); - this.serviceId = serviceId; - this.method = method; - this.uri = uri; - this.retryable = retryable; - this.headers = headers; - this.params = params; - this.requestEntity = requestEntity; - this.requestCustomizers = requestCustomizers; - this.contentLength = contentLength; - this.loadBalancerKey = loadBalancerKey; - } - - public URI uri() { - try { - return new URI(this.uri); - } - catch (URISyntaxException e) { - ReflectionUtils.rethrowRuntimeException(e); - } - return null; - } - - /** - * Use {@link #getMethod()}. - * @return request method - */ - @Deprecated - public String getVerb() { - return this.method; - } - - public String getServiceId() { - return serviceId; - } - - public String getMethod() { - return method; - } - - public String getUri() { - return uri; - } - - public Boolean getRetryable() { - return retryable; - } - - public MultiValueMap getHeaders() { - return headers; - } - - public MultiValueMap getParams() { - return params; - } - - public InputStream getRequestEntity() { - if (requestEntity == null) { - return null; - } - // If the route is not retryable there is no point in copying the RequestEntity. - // This - // has memory implications in all cases but especially when uploading large files - // through - // Zuul - if (!retryable) { - return requestEntity; - } - - try { - if (!(requestEntity instanceof ResettableServletInputStreamWrapper)) { - requestEntity = new ResettableServletInputStreamWrapper( - StreamUtils.copyToByteArray(requestEntity)); - } - requestEntity.reset(); - } - finally { - return requestEntity; - } - } - - public List getRequestCustomizers() { - return requestCustomizers; - } - - public Long getContentLength() { - return contentLength; - } - - public void setContentLength(Long contentLength) { - this.contentLength = contentLength; - } - - public Object getLoadBalancerKey() { - return loadBalancerKey; - } - - public void setLoadBalancerKey(Object loadBalancerKey) { - this.loadBalancerKey = loadBalancerKey; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RibbonCommandContext that = (RibbonCommandContext) o; - return Objects.equals(serviceId, that.serviceId) - && Objects.equals(method, that.method) && Objects.equals(uri, that.uri) - && Objects.equals(retryable, that.retryable) - && Objects.equals(headers, that.headers) - && Objects.equals(params, that.params) - && Objects.equals(requestEntity, that.requestEntity) - && Objects.equals(requestCustomizers, that.requestCustomizers) - && Objects.equals(contentLength, that.contentLength) - && Objects.equals(loadBalancerKey, that.loadBalancerKey); - } - - @Override - public int hashCode() { - return Objects.hash(serviceId, method, uri, retryable, headers, params, - requestEntity, requestCustomizers, contentLength, loadBalancerKey); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("RibbonCommandContext{"); - sb.append("serviceId='").append(serviceId).append('\''); - sb.append(", method='").append(method).append('\''); - sb.append(", uri='").append(uri).append('\''); - sb.append(", retryable=").append(retryable); - sb.append(", headers=").append(headers); - sb.append(", params=").append(params); - sb.append(", requestEntity=").append(requestEntity); - sb.append(", requestCustomizers=").append(requestCustomizers); - sb.append(", contentLength=").append(contentLength); - sb.append(", loadBalancerKey=").append(loadBalancerKey); - sb.append('}'); - return sb.toString(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonRequestCustomizer.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonRequestCustomizer.java deleted file mode 100644 index 1a51b6867..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonRequestCustomizer.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.support; - -import java.util.List; - -/** - * Interface providing methods for customizing Ribbon requests. - * - * @param Request builder type - * @author Spencer Gibb - */ -public interface RibbonRequestCustomizer { - - boolean accepts(Class builderClass); - - void customize(B builder); - - class Runner { - - private Runner() { - throw new AssertionError("Must not instantiate utility class."); - } - - @SuppressWarnings("unchecked") - public static void customize(List customizers, - Object builder) { - for (RibbonRequestCustomizer customizer : customizers) { - if (customizer.accepts(builder.getClass())) { - customizer.customize(builder); - } - } - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonRetryPolicy.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonRetryPolicy.java deleted file mode 100644 index 766c9fcd8..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonRetryPolicy.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2018-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.support; - -import java.net.URI; -import java.util.HashMap; -import java.util.Map; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.InterceptorRetryPolicy; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.http.HttpRequest; -import org.springframework.retry.RetryContext; - -/** - * @author Ryan Baxter - */ -public class RibbonRetryPolicy extends InterceptorRetryPolicy { - - private HttpRequest request; - - private String serviceId; - - public RibbonRetryPolicy(HttpRequest request, LoadBalancedRetryPolicy policy, - ServiceInstanceChooser serviceInstanceChooser, String serviceName) { - super(request, policy, serviceInstanceChooser, serviceName); - this.request = request; - this.serviceId = serviceName; - } - - @Override - public boolean canRetry(RetryContext context) { - /* - * In InterceptorRetryPolicy.canRetry we ask the LoadBalancer to choose a server - * if one is not set in the retry context and then return true. RetryTemplat calls - * the canRetry method of the policy even on its first execution. So the fact that - * we didnt have a service instance set in the RetryContext signaled that it was - * the first execution and we should return true. - * - */ - if (context.getRetryCount() == 0) { - return true; - } - return super.canRetry(context); - } - - @Override - public RetryContext open(RetryContext parent) { - LoadBalancedRetryContext context = new LoadBalancedRetryContext(parent, - this.request); - context.setServiceInstance( - new RibbonRetryPolicyServiceInstance(serviceId, request)); - return context; - } - - class RibbonRetryPolicyServiceInstance implements ServiceInstance { - - private String serviceId; - - private HttpRequest request; - - private Map metadata; - - RibbonRetryPolicyServiceInstance(String serviceId, HttpRequest request) { - this.serviceId = serviceId; - this.request = request; - this.metadata = new HashMap<>(); - } - - @Override - public String getServiceId() { - return serviceId; - } - - @Override - public String getHost() { - return request.getURI().getHost(); - } - - @Override - public int getPort() { - return request.getURI().getPort(); - } - - @Override - public boolean isSecure() { - return "https".equals(request.getURI().getScheme()); - } - - @Override - public URI getUri() { - return request.getURI(); - } - - @Override - public Map getMetadata() { - return metadata; - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-netflix-ribbon/src/main/resources/META-INF/additional-spring-configuration-metadata.json deleted file mode 100644 index a98ad55cf..000000000 --- a/spring-cloud-netflix-ribbon/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "properties": [ - { - "defaultValue": true, - "name": "eureka.client.healthcheck.enabled", - "description": "Enables the Eureka health check handler.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": false, - "name": "ribbon.restclient.enabled", - "description": "Enables the use of the deprecated Ribbon RestClient.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": false, - "name": "ribbon.http.client.enabled", - "description": "Deprecated property to enable Ribbon RestClient.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": false, - "name": "ribbon.okhttp.enabled", - "description": "Enables the use of the OK HTTP Client with Ribbon.", - "type": "java.lang.Boolean" - } - ] -} \ No newline at end of file diff --git a/spring-cloud-netflix-ribbon/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-ribbon/src/main/resources/META-INF/spring.factories deleted file mode 100644 index be8c8c7bd..000000000 --- a/spring-cloud-netflix-ribbon/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration \ No newline at end of file diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospectorDefaultTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospectorDefaultTests.java deleted file mode 100644 index 878c90d67..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospectorDefaultTests.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import com.netflix.loadbalancer.Server; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * @author Rico Pahlisch - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = DefaultServerIntrospectorDefaultTests.TestConfiguration.class) -public class DefaultServerIntrospectorDefaultTests { - - @Autowired - private ServerIntrospector serverIntrospector; - - @Test - public void testDefaultSslPorts() { - Server serverMock = mock(Server.class); - when(serverMock.getPort()).thenReturn(443); - assertThat(serverIntrospector.isSecure(serverMock)).isTrue(); - when(serverMock.getPort()).thenReturn(8443); - assertThat(serverIntrospector.isSecure(serverMock)).isTrue(); - - when(serverMock.getPort()).thenReturn(16443); - assertThat(serverIntrospector.isSecure(serverMock)).isFalse(); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(ServerIntrospectorProperties.class) - protected static class TestConfiguration { - - @Bean - public DefaultServerIntrospector defaultServerIntrospector() { - return new DefaultServerIntrospector(); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospectorTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospectorTests.java deleted file mode 100644 index c8f290c4e..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospectorTests.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import com.netflix.loadbalancer.Server; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * @author Rico Pahlisch - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = DefaultServerIntrospectorTests.TestConfiguration.class) -@TestPropertySource(properties = { "ribbon.securePorts=12345,556" }) -public class DefaultServerIntrospectorTests { - - @Autowired - private ServerIntrospector serverIntrospector; - - @Test - public void testSecurePortConfiguration() { - Server serverMock = mock(Server.class); - when(serverMock.getPort()).thenReturn(12345); - assertThat(serverIntrospector.isSecure(serverMock)).isTrue(); - when(serverMock.getPort()).thenReturn(556); - assertThat(serverIntrospector.isSecure(serverMock)).isTrue(); - when(serverMock.getPort()).thenReturn(443); - assertThat(serverIntrospector.isSecure(serverMock)).isFalse(); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(ServerIntrospectorProperties.class) - protected static class TestConfiguration { - - @Bean - public DefaultServerIntrospector defaultServerIntrospector() { - return new DefaultServerIntrospector(); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/PlainRibbonClientPreprocessorIntegrationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/PlainRibbonClientPreprocessorIntegrationTests.java deleted file mode 100644 index be38fb5aa..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/PlainRibbonClientPreprocessorIntegrationTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import com.netflix.loadbalancer.ConfigurationBasedServerList; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.PlainRibbonClientPreprocessorIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TestConfiguration.class) -@DirtiesContext -public class PlainRibbonClientPreprocessorIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void serverListIsConfigured() throws Exception { - @SuppressWarnings("unchecked") - ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) this.factory - .getLoadBalancer("foo"); - ConfigurationBasedServerList.class.cast(loadBalancer.getServerListImpl()); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient("foo") - @Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - RibbonAutoConfiguration.class }) - protected static class TestConfiguration { - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonApplicationContextInitializerTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonApplicationContextInitializerTests.java deleted file mode 100644 index 29e841bd8..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonApplicationContextInitializerTests.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.Arrays; -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Biju Kunjummen - */ - -@RunWith(SpringRunner.class) -@SpringBootTest( - classes = { RibbonAutoConfiguration.class, ArchaiusAutoConfiguration.class, - RibbonApplicationContextInitializerTests.RibbonInitializerConfig.class }) -@DirtiesContext -public class RibbonApplicationContextInitializerTests { - - @Autowired - private SpringClientFactory springClientFactory; - - @Test - public void testContextShouldInitalizeChildContexts() { - - // Context should have been initialized and an instance of Foo created - assertThat(Foo.getInstanceCount()).isEqualTo(1); - ApplicationContext ctx = springClientFactory.getContext("testspec"); - - assertThat(Foo.getInstanceCount()).isEqualTo(1); - Foo foo = ctx.getBean("foo", Foo.class); - assertThat(foo).isNotNull(); - } - - static class FooConfig { - - @Bean - public Foo foo() { - return new Foo(); - } - - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient(name = "testspec", configuration = FooConfig.class) - static class RibbonInitializerConfig { - - @Bean - public RibbonApplicationContextInitializer ribbonApplicationContextInitializer( - SpringClientFactory springClientFactory) { - return new RibbonApplicationContextInitializer(springClientFactory, - Arrays.asList("testspec")); - } - - } - - static class Foo { - - private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger(); - - Foo() { - INSTANCE_COUNT.incrementAndGet(); - } - - public static int getInstanceCount() { - return INSTANCE_COUNT.get(); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfigurationIntegrationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfigurationIntegrationTests.java deleted file mode 100644 index cdaccfc2e..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfigurationIntegrationTests.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfigurationIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TestConfiguration.class, - value = { "ribbon.ConnectTimeout=25000" }) -@DirtiesContext -public class RibbonAutoConfigurationIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void serverListIsConfigured() throws Exception { - IClientConfig config = this.factory.getClientConfig("client"); - assertThat( - config.getPropertyAsInteger(CommonClientConfigKey.ConnectTimeout, 3000)) - .isEqualTo(25000); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient("client") - @Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - RibbonAutoConfiguration.class }) - protected static class TestConfiguration { - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationIntegrationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationIntegrationTests.java deleted file mode 100644 index 82220fe25..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationIntegrationTests.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.PollingServerListUpdater; -import com.netflix.loadbalancer.ServerListUpdater; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = RibbonClientConfigurationIntegrationTests.TestLBConfig.class, - properties = "test.ribbon.ServerListRefreshInterval=999") -@DirtiesContext -public class RibbonClientConfigurationIntegrationTests { - - @Autowired - private SpringClientFactory clientFactory; - - @Test - public void testLoadBalancerConstruction() { - ILoadBalancer loadBalancer = clientFactory.getInstance("test", - ILoadBalancer.class); - assertThat(loadBalancer).isInstanceOf(ZoneAwareLoadBalancer.class); - ZoneAwareLoadBalancer lb = (ZoneAwareLoadBalancer) loadBalancer; - ServerListUpdater serverListUpdater = (PollingServerListUpdater) ReflectionTestUtils - .getField(loadBalancer, "serverListUpdater"); - Long refreshIntervalMs = (Long) ReflectionTestUtils.getField(serverListUpdater, - "refreshIntervalMs"); - // assertThat(refreshIntervalMs, equalTo(999L)); - - ServerListUpdater updater = clientFactory.getInstance("test", - ServerListUpdater.class); - assertThat(updater).isSameAs(serverListUpdater); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - protected static class TestLBConfig { - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java deleted file mode 100644 index a34cfd8c0..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; -import com.netflix.niws.client.http.RestClient; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration.OverrideRestClient; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; - -/** - * @author Spencer Gibb - */ -public class RibbonClientConfigurationTests { - - private CountingConfig config; - - @Mock - private ServerIntrospector inspector; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - this.config = new CountingConfig(); - this.config.setProperty(CommonClientConfigKey.ConnectTimeout, "1"); - this.config.setProperty(CommonClientConfigKey.ReadTimeout, "1"); - this.config.setProperty(CommonClientConfigKey.MaxHttpConnectionsPerHost, "1"); - this.config.setClientName("testClient"); - } - - @Test - public void restClientInitCalledOnce() { - new TestRestClient(this.config); - assertThat(this.config.count).isEqualTo(1); - } - - @Test - public void restClientWithSecureServer() throws Exception { - CountingConfig config = new CountingConfig(); - config.setProperty(CommonClientConfigKey.ConnectTimeout, "1"); - config.setProperty(CommonClientConfigKey.ReadTimeout, "1"); - config.setProperty(CommonClientConfigKey.MaxHttpConnectionsPerHost, "1"); - config.setClientName("bar"); - Server server = new Server("example.com", 443); - URI uri = new TestRestClient(config).reconstructURIWithServer(server, - new URI("/foo")); - assertThat(uri.getScheme()).isEqualTo("https"); - assertThat(uri.getHost()).isEqualTo("example.com"); - } - - @Test - public void testSecureUriFromClientConfig() throws Exception { - Server server = new Server("foo", 7777); - when(this.inspector.isSecure(server)).thenReturn(true); - - for (AbstractLoadBalancerAwareClient client : clients()) { - URI uri = client.reconstructURIWithServer(server, new URI("https://foo/")); - assertThat(uri).as(getReason(client)).isEqualTo(new URI("https://foo:7777/")); - } - } - - @Test - public void testInSecureUriFromClientConfig() throws Exception { - Server server = new Server("foo", 7777); - when(this.inspector.isSecure(server)).thenReturn(false); - - for (AbstractLoadBalancerAwareClient client : clients()) { - URI uri = client.reconstructURIWithServer(server, new URI("https://foo/")); - assertThat(uri).as(getReason(client)).isEqualTo(new URI("https://foo:7777/")); - } - } - - String getReason(AbstractLoadBalancerAwareClient client) { - return client.getClass().getSimpleName() + " failed"; - } - - @Test - public void testNotDoubleEncodedWhenSecure() throws Exception { - Server server = new Server("foo", 7777); - when(this.inspector.isSecure(server)).thenReturn(true); - - for (AbstractLoadBalancerAwareClient client : clients()) { - URI uri = client.reconstructURIWithServer(server, - new URI("https://foo/%20bar")); - assertThat(uri).as(getReason(client)) - .isEqualTo(new URI("https://foo:7777/%20bar")); - } - } - - @Test - public void testPlusInQueryStringGetsRewrittenWhenServerIsSecure() throws Exception { - Server server = new Server("foo", 7777); - when(this.inspector.isSecure(server)).thenReturn(true); - - for (AbstractLoadBalancerAwareClient client : clients()) { - URI uri = client.reconstructURIWithServer(server, - new URI("http://foo/%20bar?hello=1+2")); - assertThat(uri).isEqualTo(new URI("https://foo:7777/%20bar?hello=1%202")); - } - } - - private List clients() { - ArrayList clients = new ArrayList<>(); - clients.add(new OverrideRestClient(this.config, this.inspector)); - clients.add(new RibbonLoadBalancingHttpClient(this.config, this.inspector)); - clients.add(new OkHttpLoadBalancingClient(this.config, this.inspector)); - return clients; - } - - @SuppressWarnings("deprecation") - @Test - public void testDefaultsToApacheHttpClient() { - testClient(RibbonLoadBalancingHttpClient.class, null, RestClient.class, - OkHttpLoadBalancingClient.class); - testClient(RibbonLoadBalancingHttpClient.class, - new String[] { "ribbon.httpclient.enabled" }, RestClient.class, - OkHttpLoadBalancingClient.class); - } - - @SuppressWarnings("deprecation") - @Test - public void testEnableRestClient() { - testClient(RestClient.class, new String[] { "ribbon.restclient.enabled" }, - RibbonLoadBalancingHttpClient.class, OkHttpLoadBalancingClient.class); - } - - @SuppressWarnings("deprecation") - @Test - public void testEnableOkHttpClient() { - testClient(OkHttpLoadBalancingClient.class, - new String[] { "ribbon.okhttp.enabled" }, - RibbonLoadBalancingHttpClient.class, RestClient.class); - } - - void testClient(Class clientType, String[] properties, Class... excludedTypes) { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - context.register(HttpClientConfiguration.class, RibbonAutoConfiguration.class, - RibbonClientConfiguration.class); - if (properties != null) { - TestPropertyValues.of(properties).applyTo(context); - } - context.refresh(); - context.getBean(clientType); - for (Class excludedType : excludedTypes) { - assertThat(hasInstance(context, excludedType)) - .as("has " + excludedType.getSimpleName() + " instance").isFalse(); - } - context.close(); - } - - private boolean hasInstance(ListableBeanFactory lbf, Class requiredType) { - return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(lbf, - requiredType).length > 0; - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - protected static class TestLBConfig { - - } - - static class CountingConfig extends DefaultClientConfigImpl { - - int count = 0; - - } - - static final class TestRestClient extends OverrideRestClient { - - private TestRestClient(IClientConfig ncc) { - super(ncc, new DefaultServerIntrospector()); - } - - @Override - public void initWithNiwsConfig(IClientConfig clientConfig) { - ((CountingConfig) clientConfig).count++; - super.initWithNiwsConfig(clientConfig); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactoryTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactoryTests.java deleted file mode 100644 index 5307a7c4a..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactoryTests.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.net.URI; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.loadbalancer.LoadBalanced; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.RequestEntity; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.ResourceAccessException; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RibbonClientHttpRequestFactoryTests.App.class, - webEnvironment = RANDOM_PORT, - value = { "spring.application.name=ribbonclienttest", "spring.jmx.enabled=true", - "spring.cloud.netflix.metrics.enabled=false", - "ribbon.restclient.enabled=true", "debug=true" }) -@DirtiesContext -public class RibbonClientHttpRequestFactoryTests { - - @Rule - /** - * JUnit rule - */ - public final ExpectedException exceptionRule = ExpectedException.none(); - - @LoadBalanced - @Autowired - protected RestTemplate restTemplate; - - @Test - public void requestFactoryIsRibbon() { - ClientHttpRequestFactory requestFactory = this.restTemplate.getRequestFactory(); - assertThat(requestFactory).isInstanceOf(RibbonClientHttpRequestFactory.class); - } - - @Test - public void vanillaRequestWorks() { - ResponseEntity response = this.restTemplate.getForEntity("http://simple/", - String.class); - assertThat(response.getStatusCode()).as("wrong response code") - .isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).as("wrong response body").isEqualTo("hello"); - } - - @Test - public void requestWithPathParamWorks() { - ResponseEntity response = this.restTemplate - .getForEntity("http://simple/path/{param}", String.class, "world"); - assertThat(response.getStatusCode()).as("wrong response code") - .isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).as("wrong response body").isEqualTo("hello world"); - } - - @Test - public void requestWithEncodedPathParamWorks() { - ResponseEntity response = this.restTemplate.getForEntity( - "http://simple/path/{param}", String.class, "world & everyone else"); - assertThat(response.getStatusCode()).as("wrong response code") - .isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).as("wrong response body") - .isEqualTo("hello world & everyone else"); - } - - @Test - public void requestWithRequestParamWorks() { - ResponseEntity response = this.restTemplate.getForEntity( - "http://simple/request?param={param}", String.class, "world"); - assertThat(response.getStatusCode()).as("wrong response code") - .isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).as("wrong response body").isEqualTo("hello world"); - } - - @Test - public void requestWithPostWorks() { - ResponseEntity response = this.restTemplate - .postForEntity("http://simple/post", "world", String.class); - assertThat(response.getStatusCode()).as("wrong response code") - .isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).as("wrong response body").isEqualTo("hello world"); - } - - @Test - public void requestWithEmptyPostWorks() { - ResponseEntity response = this.restTemplate - .postForEntity("http://simple/emptypost", "", String.class); - assertThat(response.getStatusCode()).as("wrong response code") - .isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).as("wrong response body").isEqualTo("hello empty"); - } - - @Test - public void requestWithHeaderWorks() throws Exception { - RequestEntity entity = RequestEntity.get(new URI("http://simple/header")) - .header("X-Param", "world").build(); - ResponseEntity response = this.restTemplate.exchange(entity, - String.class); - assertThat(response.getStatusCode()).as("wrong response code") - .isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).as("wrong response body").isEqualTo("hello world"); - } - - @Test - public void invalidHostNameError() { - this.exceptionRule.expect(ResourceAccessException.class); - this.exceptionRule.expectMessage("Invalid hostname"); - this.restTemplate.getForEntity("https://simple_bad", String.class); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @RibbonClient(value = "simple", configuration = SimpleRibbonClientConfiguration.class) - public static class App extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.authorizeRequests().anyRequest().permitAll().and().csrf().disable(); - } - - @LoadBalanced - @Bean - RestTemplate restTemplate() { - return new RestTemplate(); - } - - @RequestMapping("/") - public String hi() { - return "hello"; - } - - @RequestMapping("/path/{param}") - public String hiParam(@PathVariable("param") String param) { - return "hello " + param; - } - - @RequestMapping("/request") - public String hiRequest(@RequestParam("param") String param) { - return "hello " + param; - } - - @RequestMapping(value = "/post", method = RequestMethod.POST) - public String hiPost(@RequestBody String param) { - return "hello " + param; - } - - @RequestMapping(value = "/emptypost", method = RequestMethod.POST) - public String hiPostEmpty() { - return "hello empty"; - } - - @RequestMapping("/header") - public String hiHeader(@RequestHeader("X-Param") String param) { - return "hello " + param; - } - - } - - @Configuration(proxyBeanMethods = false) - static class SimpleRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port = 0; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorIntegrationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorIntegrationTests.java deleted file mode 100644 index 28818327d..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorIntegrationTests.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import com.netflix.loadbalancer.ConfigurationBasedServerList; -import com.netflix.loadbalancer.DummyPing; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAvoidanceRule; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorIntegrationTests.PlainConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = PlainConfiguration.class) -@DirtiesContext -public class RibbonClientPreprocessorIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void ruleDefaultsToZoneAvoidance() throws Exception { - ZoneAvoidanceRule.class.cast(getLoadBalancer().getRule()); - } - - @Test - public void serverListFilterDefaultsToZonePreference() throws Exception { - ZonePreferenceServerListFilter.class.cast(getLoadBalancer().getFilter()); - } - - @Test - public void pingDefaultsToDummy() throws Exception { - DummyPing.class.cast(getLoadBalancer().getPing()); - } - - @Test - public void serverListDefaultsToConfigurationBased() throws Exception { - ConfigurationBasedServerList.class.cast(getLoadBalancer().getServerListImpl()); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer() { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer("foo"); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient(name = "foo") - @Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - RibbonAutoConfiguration.class }) - protected static class PlainConfiguration { - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorOverridesIntegrationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorOverridesIntegrationTests.java deleted file mode 100644 index a8df3d2a1..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorOverridesIntegrationTests.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ConfigurationBasedServerList; -import com.netflix.loadbalancer.DummyPing; -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.IRule; -import com.netflix.loadbalancer.PingConstant; -import com.netflix.loadbalancer.RandomRule; -import com.netflix.loadbalancer.RoundRobinRule; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.loadbalancer.ServerListFilter; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest( - classes = RibbonClientPreprocessorOverridesIntegrationTests.TestConfiguration.class) -@DirtiesContext -public class RibbonClientPreprocessorOverridesIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void ruleOverridesToRandom() throws Exception { - RandomRule.class.cast(getLoadBalancer("foo").getRule()); - RoundRobinRule.class.cast(getLoadBalancer("bar").getRule()); - } - - @Test - public void pingOverridesToDummy() throws Exception { - DummyPing.class.cast(getLoadBalancer("foo").getPing()); - PingConstant.class.cast(getLoadBalancer("bar").getPing()); - } - - @Test - public void serverListOverridesToMy() throws Exception { - FooServiceList.class.cast(getLoadBalancer("foo").getServerListImpl()); - BarServiceList.class.cast(getLoadBalancer("bar").getServerListImpl()); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer(String name) { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer(name); - } - - @Test - public void serverListFilterOverride() throws Exception { - ServerListFilter filter = getLoadBalancer("foo").getFilter(); - assertThat(ZonePreferenceServerListFilter.class.cast(filter).getZone()) - .isEqualTo("FooTestZone"); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClients({ @RibbonClient(name = "foo", configuration = FooConfiguration.class), - @RibbonClient(name = "bar", configuration = BarConfiguration.class) }) - @Import({ UtilAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, - ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class }) - protected static class TestConfiguration { - - } - - @Configuration(proxyBeanMethods = false) - public static class FooConfiguration { - - @Bean - public IRule ribbonRule() { - return new RandomRule(); - } - - @Bean - public IPing ribbonPing() { - return new DummyPing(); - } - - @Bean - public ServerList ribbonServerList(IClientConfig config) { - return new FooServiceList(config); - } - - @Bean - public ZonePreferenceServerListFilter serverListFilter() { - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - filter.setZone("FooTestZone"); - return filter; - } - - } - - public static class FooServiceList extends ConfigurationBasedServerList { - - public FooServiceList(IClientConfig config) { - super.initWithNiwsConfig(config); - } - - } - - @Configuration(proxyBeanMethods = false) - public static class BarConfiguration { - - @Bean - public IRule ribbonRule() { - return new RoundRobinRule(); - } - - @Bean - public IPing ribbonPing() { - return new PingConstant(); - } - - @Bean - public ServerList ribbonServerList(IClientConfig config) { - return new BarServiceList(config); - } - - @Bean - public ZonePreferenceServerListFilter serverListFilter() { - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - filter.setZone("BarTestZone"); - return filter; - } - - } - - public static class BarServiceList extends ConfigurationBasedServerList { - - public BarServiceList(IClientConfig config) { - super.initWithNiwsConfig(config); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorOverridesRetryTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorOverridesRetryTests.java deleted file mode 100644 index 85fe76559..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorOverridesRetryTests.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.net.ConnectException; -import java.net.SocketException; -import java.net.SocketTimeoutException; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.List; - -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Tyler Van Gorder - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest( - classes = RibbonClientPreprocessorOverridesRetryTests.TestConfiguration.class, - value = { "customRetry.ribbon.MaxAutoRetries=0", - "customRetry.ribbon.MaxAutoRetriesNextServer=1", - "customRetry.ribbon.OkToRetryOnAllOperations=true" }) -@DirtiesContext -public class RibbonClientPreprocessorOverridesRetryTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void customRetryIsConfigured() throws Exception { - RibbonLoadBalancerContext context = (RibbonLoadBalancerContext) this.factory - .getLoadBalancerContext("customRetry"); - assertThat(context.getRetryHandler()) - .isInstanceOf(RetryRibbonConfiguration.CustomRetryHandler.class); - assertThat(context.getRetryHandler().getMaxRetriesOnSameServer()).isEqualTo(0); - assertThat(context.getRetryHandler().getMaxRetriesOnNextServer()).isEqualTo(1); - assertThat(context.getRetryHandler() - .isCircuitTrippingException(new UnknownHostException("Unknown Host"))) - .isTrue(); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient(name = "customRetry", configuration = RetryRibbonConfiguration.class) - @Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - RibbonAutoConfiguration.class }) - protected static class TestConfiguration { - - } - -} - -@Configuration(proxyBeanMethods = false) -class RetryRibbonConfiguration { - - @Bean - public RetryHandler retryHandler(IClientConfig config) { - return new CustomRetryHandler(config); - } - - class CustomRetryHandler extends DefaultLoadBalancerRetryHandler { - - @SuppressWarnings("unchecked") - private List> retriable = new ArrayList() { - { - add(UnknownHostException.class); - add(ConnectException.class); - add(SocketTimeoutException.class); - } - }; - - @SuppressWarnings("unchecked") - private List> circuitRelated = new ArrayList() { - { - add(UnknownHostException.class); - add(SocketException.class); - add(SocketTimeoutException.class); - } - }; - - CustomRetryHandler(IClientConfig config) { - super(config); - } - - @Override - protected List> getRetriableExceptions() { - return retriable; - } - - @Override - protected List> getCircuitRelatedExceptions() { - return circuitRelated; - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorPropertiesOverridesIntegrationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorPropertiesOverridesIntegrationTests.java deleted file mode 100644 index 8420225bc..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorPropertiesOverridesIntegrationTests.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import com.netflix.loadbalancer.ConfigurationBasedServerList; -import com.netflix.loadbalancer.DummyPing; -import com.netflix.loadbalancer.NoOpPing; -import com.netflix.loadbalancer.RandomRule; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerListSubsetFilter; -import com.netflix.loadbalancer.ZoneAvoidanceRule; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.test.TestLoadBalancer; -import org.springframework.cloud.netflix.ribbon.test.TestServerList; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.junit.Assume.assumeThat; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest( - classes = RibbonClientPreprocessorPropertiesOverridesIntegrationTests.TestConfiguration.class) -@DirtiesContext -public class RibbonClientPreprocessorPropertiesOverridesIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void ruleOverridesToRandom() throws Exception { - assumeNotTravis(); - RandomRule.class.cast(getLoadBalancer("foo2").getRule()); - ZoneAvoidanceRule.class.cast(getLoadBalancer("bar").getRule()); - } - - // TODO: why do these tests fail in travis? - void assumeNotTravis() { - assumeThat("running in travis, skipping", System.getenv("TRAVIS"), - is(not(equalTo("true")))); - } - - @Test - public void pingOverridesToNoOp() throws Exception { - NoOpPing.class.cast(getLoadBalancer("foo2").getPing()); - DummyPing.class.cast(getLoadBalancer("bar").getPing()); - } - - @Test - public void serverListOverridesToTest() throws Exception { - assumeNotTravis(); - TestServerList.class.cast(getLoadBalancer("foo2").getServerListImpl()); - ConfigurationBasedServerList.class - .cast(getLoadBalancer("bar").getServerListImpl()); - } - - @Test - public void loadBalancerOverridesToTest() throws Exception { - TestLoadBalancer.class.cast(getLoadBalancer("foo2")); - ZoneAwareLoadBalancer.class.cast(getLoadBalancer("bar")); - } - - @Test - public void serverListFilterOverride() throws Exception { - assumeNotTravis(); - ServerListSubsetFilter.class.cast(getLoadBalancer("foo2").getFilter()); - ZonePreferenceServerListFilter.class.cast(getLoadBalancer("bar").getFilter()); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer(String name) { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer(name); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClients - @Import({ UtilAutoConfiguration.class, HttpClientConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - RibbonAutoConfiguration.class }) - protected static class TestConfiguration { - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsEagerInitializationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsEagerInitializationTests.java deleted file mode 100644 index d615f29da..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsEagerInitializationTests.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Biju Kunjummen - */ - -@RunWith(SpringRunner.class) -@SpringBootTest(properties = { "ribbon.eager-load.enabled=true", - "ribbon.eager-load.clients=testspec1,testspec2" }) -@DirtiesContext -public class RibbonClientsEagerInitializationTests { - - @Test - public void contextsShouldBeInitialized() { - assertThat(Foo1.getInstanceCount()).isEqualTo(2); - } - - static class FooConfig { - - @Bean - public Foo1 foo() { - return new Foo1(); - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RibbonClients({ @RibbonClient(name = "testspec1", configuration = FooConfig.class), - @RibbonClient(name = "testspec2", configuration = FooConfig.class), - @RibbonClient(name = "testspec3", configuration = FooConfig.class) }) - static class RibbonConfig { - - } - - static class Foo1 { - - private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger(); - - Foo1() { - INSTANCE_COUNT.incrementAndGet(); - } - - public static int getInstanceCount() { - return INSTANCE_COUNT.get(); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsPreprocessorIntegrationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsPreprocessorIntegrationTests.java deleted file mode 100644 index ea58ac6f4..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsPreprocessorIntegrationTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.PingUrl; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAvoidanceRule; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClientsPreprocessorIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TestConfiguration.class) -@DirtiesContext -public class RibbonClientsPreprocessorIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void ruleDefaultsToZoneAvoidance() throws Exception { - ZoneAvoidanceRule.class.cast(getLoadBalancer().getRule()); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer() { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer("foo"); - } - - @Test - public void serverListFilterOverride() throws Exception { - assertThat(ZonePreferenceServerListFilter.class - .cast(getLoadBalancer().getFilter()).getZone()).isEqualTo("myTestZone"); - } - - @Test - public void pingOverride() throws Exception { - assertThat(getLoadBalancer().getPing()).isInstanceOf(PingUrl.class); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClients(@RibbonClient(name = "foo", configuration = FooConfiguration.class)) - @Import({ UtilAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, - ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class, - HttpClientConfiguration.class }) - protected static class TestConfiguration { - - } - - // tag::sample_override_ribbon_config[] - @Configuration(proxyBeanMethods = false) - protected static class FooConfiguration { - - @Bean - public ZonePreferenceServerListFilter serverListFilter() { - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - filter.setZone("myTestZone"); - return filter; - } - - @Bean - public IPing ribbonPing() { - return new PingUrl(); - } - - } - // end::sample_override_ribbon_config[] - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonDisabledTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonDisabledTests.java deleted file mode 100644 index 82bcce37b..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonDisabledTests.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - * @author Biju Kunjummen - */ -@RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({ "ribbon-{version:\\d.*}.jar" }) -public class RibbonDisabledTests { - - @Test - public void testRibbonDisabled() { - new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(RibbonAutoConfiguration.class)) - .run(context -> { - assertThat(context.getBeanNamesForType(SpringClientFactory.class)) - .hasSize(0); - }); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptorTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptorTests.java deleted file mode 100644 index 26303ccf3..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptorTests.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.io.IOException; -import java.net.URI; -import java.net.URL; - -import com.netflix.loadbalancer.Server; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor; -import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.RibbonServer; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.client.support.HttpRequestWrapper; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.util.UriComponentsBuilder; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.verify; - -/** - * @author Spencer Gibb - */ -public class RibbonInterceptorTests { - - @Mock - private HttpRequest request; - - @Mock - private ClientHttpRequestExecution execution; - - @Mock - private ClientHttpResponse response; - - @Before - public void init() { - MockitoAnnotations.initMocks(this); - } - - @Test - public void testIntercept() throws Exception { - RibbonServer server = new RibbonServer("myservice", new Server("myhost", 8080)); - LoadBalancerInterceptor interceptor = new LoadBalancerInterceptor( - new MyClient(server)); - given(this.request.getURI()).willReturn(new URL("https://myservice").toURI()); - given(this.execution.execute(isA(HttpRequest.class), isA(byte[].class))) - .willReturn(this.response); - ArgumentCaptor argument = ArgumentCaptor - .forClass(HttpRequestWrapper.class); - ClientHttpResponse response = interceptor.intercept(this.request, new byte[0], - this.execution); - assertThat(response).as("response was null").isNotNull(); - verify(this.execution).execute(argument.capture(), isA(byte[].class)); - HttpRequestWrapper wrapper = argument.getValue(); - assertThat(wrapper.getURI()).as("wrong constructed uri") - .isEqualTo(new URL("https://myhost:8080").toURI()); - } - - protected static class MyClient implements LoadBalancerClient { - - private ServiceInstance instance; - - public MyClient(ServiceInstance instance) { - this.instance = instance; - } - - @Override - public ServiceInstance choose(String serviceId) { - return this.instance; - } - - @Override - public T execute(String serviceId, LoadBalancerRequest request) { - try { - return request.apply(this.instance); - } - catch (Exception ex) { - ReflectionUtils.rethrowRuntimeException(ex); - } - return null; - } - - @Override - public T execute(String s, ServiceInstance serviceInstance, - LoadBalancerRequest request) throws IOException { - try { - return request.apply(this.instance); - } - catch (Exception ex) { - ReflectionUtils.rethrowRuntimeException(ex); - } - return null; - } - - @Override - public URI reconstructURI(ServiceInstance instance, URI original) { - return UriComponentsBuilder.fromUri(original).host(instance.getHost()) - .port(instance.getPort()).build().toUri(); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryFactoryTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryFactoryTests.java deleted file mode 100644 index 15e9cf65f..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryFactoryTests.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.io.IOException; -import java.net.SocketException; -import java.util.Collections; -import java.util.Map; - -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.BaseLoadBalancer; -import com.netflix.loadbalancer.LoadBalancerStats; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerStats; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.RibbonServer; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpRequest; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -/** - * @author Ryan Baxter - */ -public class RibbonLoadBalancedRetryFactoryTests { - - @Mock - private SpringClientFactory clientFactory; - - @Mock - private BaseLoadBalancer loadBalancer; - - @Mock - private LoadBalancerStats loadBalancerStats; - - @Mock - private ServerStats serverStats; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - given(this.clientFactory.getLoadBalancerContext(anyString())) - .willReturn(new RibbonLoadBalancerContext(this.loadBalancer)); - given(this.clientFactory.getInstance(anyString(), eq(ServerIntrospector.class))) - .willReturn(new DefaultServerIntrospector() { - @Override - public Map getMetadata(Server server) { - return Collections.singletonMap("mykey", "myvalue"); - } - }); - - } - - @After - public void tearDown() throws Exception { - } - - @Test - public void testGetRetryPolicyNoRetry() throws Exception { - int sameServer = 0; - int nextServer = 0; - boolean retryOnAllOps = false; - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), - anyInt()); - doReturn(sameServer).when(config) - .getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetries), anyInt()); - doReturn(nextServer).when(config) - .get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(nextServer).when(config).getPropertyAsInteger( - eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(retryOnAllOps).when(config) - .get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean()); - doReturn(retryOnAllOps).when(config).getPropertyAsBoolean( - eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean()); - doReturn("").when(config).getPropertyAsString( - eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq("")); - doReturn(server.getServiceId()).when(config).getClientName(); - doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId())); - clientFactory.getLoadBalancerContext(server.getServiceId()) - .setRetryHandler(new DefaultLoadBalancerRetryHandler(config)); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - RibbonLoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - LoadBalancedRetryPolicy policy = factory.createRetryPolicy(server.getServiceId(), - client); - HttpRequest request = mock(HttpRequest.class); - doReturn(HttpMethod.GET).when(request).getMethod(); - LoadBalancedRetryContext context = new LoadBalancedRetryContext(null, request); - assertThat(policy.canRetryNextServer(context)).isTrue(); - assertThat(policy.canRetrySameServer(context)).isFalse(); - assertThat(policy.retryableStatusCode(400)).isFalse(); - } - - @Test - public void testGetRetryPolicyNotGet() throws Exception { - int sameServer = 3; - int nextServer = 3; - boolean retryOnAllOps = false; - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), - anyInt()); - doReturn(sameServer).when(config) - .getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetries), anyInt()); - doReturn(nextServer).when(config) - .get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(nextServer).when(config).getPropertyAsInteger( - eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(retryOnAllOps).when(config) - .get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean()); - doReturn(retryOnAllOps).when(config).getPropertyAsBoolean( - eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean()); - doReturn("").when(config).getPropertyAsString( - eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq("")); - doReturn(server.getServiceId()).when(config).getClientName(); - doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId())); - clientFactory.getLoadBalancerContext(server.getServiceId()) - .setRetryHandler(new DefaultLoadBalancerRetryHandler(config)); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - RibbonLoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - LoadBalancedRetryPolicy policy = factory.createRetryPolicy(server.getServiceId(), - client); - HttpRequest request = mock(HttpRequest.class); - doReturn(HttpMethod.POST).when(request).getMethod(); - LoadBalancedRetryContext context = new LoadBalancedRetryContext(null, request); - assertThat(policy.canRetryNextServer(context)).isFalse(); - assertThat(policy.canRetrySameServer(context)).isFalse(); - assertThat(policy.retryableStatusCode(400)).isFalse(); - } - - @Test - public void testGetRetryPolicyRetryOnNonGet() throws Exception { - int sameServer = 3; - int nextServer = 3; - boolean retryOnAllOps = true; - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), - anyInt()); - doReturn(sameServer).when(config) - .getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetries), anyInt()); - doReturn(nextServer).when(config) - .get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(nextServer).when(config).getPropertyAsInteger( - eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(retryOnAllOps).when(config) - .get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean()); - doReturn(retryOnAllOps).when(config).getPropertyAsBoolean( - eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean()); - doReturn("").when(config).getPropertyAsString( - eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq("")); - doReturn(server.getServiceId()).when(config).getClientName(); - doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId())); - clientFactory.getLoadBalancerContext(server.getServiceId()) - .initWithNiwsConfig(config); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - RibbonLoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - LoadBalancedRetryPolicy policy = factory.createRetryPolicy(server.getServiceId(), - client); - HttpRequest request = mock(HttpRequest.class); - doReturn(HttpMethod.POST).when(request).getMethod(); - LoadBalancedRetryContext context = new LoadBalancedRetryContext(null, request); - assertThat(policy.canRetryNextServer(context)).isTrue(); - assertThat(policy.canRetrySameServer(context)).isTrue(); - assertThat(policy.retryableStatusCode(400)).isFalse(); - } - - @Test - public void testGetRetryPolicyRetryCount() throws Exception { - int sameServer = 3; - int nextServer = 3; - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), - anyInt()); - doReturn(nextServer).when(config) - .get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(false).when(config) - .get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false)); - doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId())); - doReturn("").when(config).getPropertyAsString( - eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq("")); - clientFactory.getLoadBalancerContext(server.getServiceId()) - .setRetryHandler(new DefaultLoadBalancerRetryHandler(config)); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - RibbonLoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - LoadBalancedRetryPolicy policy = factory.createRetryPolicy(server.getServiceId(), - client); - HttpRequest request = mock(HttpRequest.class); - doReturn(HttpMethod.GET).when(request).getMethod(); - LoadBalancedRetryContext context = spy( - new LoadBalancedRetryContext(null, request)); - // Loop through as if we are retrying a request until we exhaust the number of - // retries - // outer loop is for next server retries - // inner loop is for same server retries - for (int i = 0; i < nextServer + 1; i++) { - // iterate once time beyond the same server retry limit to cause us to reset - // the same sever counter and increment the next server counter - for (int j = 0; j < sameServer + 1; j++) { - if (j < 3) { - assertThat(policy.canRetrySameServer(context)).isTrue(); - } - else { - assertThat(policy.canRetrySameServer(context)).isFalse(); - } - policy.registerThrowable(context, new IOException()); - } - if (i < 3) { - assertThat(policy.canRetryNextServer(context)).isTrue(); - } - else { - assertThat(policy.canRetryNextServer(context)).isFalse(); - } - } - assertThat(context.isExhaustedOnly()).isTrue(); - assertThat(policy.retryableStatusCode(400)).isFalse(); - verify(context, times(4)).setServiceInstance(any(ServiceInstance.class)); - } - - @Test - public void testCiruitRelatedExceptionsUpdateServerStats() throws Exception { - int sameServer = 3; - int nextServer = 3; - - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - - doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), - anyInt()); - doReturn(nextServer).when(config) - .get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(false).when(config) - .get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false)); - doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId())); - doReturn("").when(config).getPropertyAsString( - eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq("")); - clientFactory.getLoadBalancerContext(server.getServiceId()) - .setRetryHandler(new DefaultLoadBalancerRetryHandler(config)); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - - RibbonLoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - LoadBalancedRetryPolicy policy = factory.createRetryPolicy(server.getServiceId(), - client); - HttpRequest request = mock(HttpRequest.class); - - LoadBalancedRetryContext context = spy( - new LoadBalancedRetryContext(null, request)); - doReturn(server).when(context).getServiceInstance(); - - policy.registerThrowable(context, new IOException()); - verify(serverStats, times(0)).incrementSuccessiveConnectionFailureCount(); - - // Circuit Related should increment failure count - policy.registerThrowable(context, new SocketException()); - verify(serverStats, times(1)).incrementSuccessiveConnectionFailureCount(); - } - - @Test - public void testRetryableStatusCodes() throws Exception { - int sameServer = 3; - int nextServer = 3; - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), - anyInt()); - doReturn(nextServer).when(config) - .get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(false).when(config) - .get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false)); - doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId())); - doReturn("404, 418,502,foo, ,").when(config).getPropertyAsString( - eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq("")); - clientFactory.getLoadBalancerContext(server.getServiceId()) - .setRetryHandler(new DefaultLoadBalancerRetryHandler(config)); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - RibbonLoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - LoadBalancedRetryPolicy policy = factory.createRetryPolicy(server.getServiceId(), - client); - HttpRequest request = mock(HttpRequest.class); - doReturn(HttpMethod.GET).when(request).getMethod(); - assertThat(policy.retryableStatusCode(400)).isFalse(); - assertThat(policy.retryableStatusCode(404)).isTrue(); - assertThat(policy.retryableStatusCode(418)).isTrue(); - assertThat(policy.retryableStatusCode(502)).isTrue(); - } - - protected RibbonLoadBalancerClient getRibbonLoadBalancerClient( - RibbonServer ribbonServer) { - given(this.loadBalancer.getName()).willReturn(ribbonServer.getServiceId()); - given(this.loadBalancer.chooseServer(any())).willReturn(ribbonServer.getServer()); - given(this.loadBalancer.getLoadBalancerStats()) - .willReturn(this.loadBalancerStats); - given(this.loadBalancerStats.getSingleServerStat(ribbonServer.getServer())) - .willReturn(this.serverStats); - given(this.clientFactory.getLoadBalancer(this.loadBalancer.getName())) - .willReturn(this.loadBalancer); - return new RibbonLoadBalancerClient(this.clientFactory); - } - - protected RibbonServer getRibbonServer() { - return new RibbonServer("testService", new Server("myhost", 9080), false, - Collections.singletonMap("mykey", "myvalue")); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java deleted file mode 100644 index 83db9b2c7..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.io.IOException; -import java.net.URI; -import java.net.URL; -import java.util.Collections; -import java.util.Map; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.BaseLoadBalancer; -import com.netflix.loadbalancer.LoadBalancerStats; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerStats; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.RibbonServer; -import org.springframework.web.util.DefaultUriBuilderFactory; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyDouble; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.same; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * @author Spencer Gibb - * @author Tim Ysewyn - */ -public class RibbonLoadBalancerClientTests { - - @Mock - private SpringClientFactory clientFactory; - - @Mock - private BaseLoadBalancer loadBalancer; - - @Mock - private LoadBalancerStats loadBalancerStats; - - @Mock - private ServerStats serverStats; - - private Server server = null; - - @Before - public void init() { - server = null; - MockitoAnnotations.initMocks(this); - given(this.clientFactory.getLoadBalancerContext(anyString())) - .willReturn(new RibbonLoadBalancerContext(this.loadBalancer)); - given(this.clientFactory.getInstance(anyString(), eq(ServerIntrospector.class))) - .willReturn(new DefaultServerIntrospector() { - - @Override - public boolean isSecure(Server server) { - RibbonLoadBalancerClientTests.this.server = server; - return super.isSecure(server); - } - - @Override - public Map getMetadata(Server server) { - return Collections.singletonMap("mykey", "myvalue"); - } - }); - } - - @Test - public void reconstructURI() throws Exception { - testReconstructURI("http"); - } - - @Test - public void reconstructSecureURI() throws Exception { - testReconstructURI("https"); - } - - private void testReconstructURI(String scheme) throws Exception { - RibbonServer server = getRibbonServer(); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - ServiceInstance serviceInstance = client.choose(server.getServiceId()); - URI uri = client.reconstructURI(serviceInstance, - new URL(scheme + "://" + server.getServiceId()).toURI()); - assertThat(uri).hasScheme(scheme).hasHost(serviceInstance.getHost()) - .hasPort(serviceInstance.getPort()); - assertThat(this.server).isNotNull().isInstanceOf(MyServer.class); - } - - @Test - public void testReconstructSecureUriWithSpecialCharsPath() { - testReconstructUriWithPath("https", "/foo=|"); - } - - @Test - public void testReconstructUnsecureUriWithSpecialCharsPath() { - testReconstructUriWithPath("http", "/foo=|"); - } - - private void testReconstructUriWithPath(String scheme, String path) { - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - when(config.get(CommonClientConfigKey.IsSecure)).thenReturn(true); - when(clientFactory.getClientConfig(server.getServiceId())).thenReturn(config); - - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - ServiceInstance serviceInstance = client.choose(server.getServiceId()); - - URI expanded = new DefaultUriBuilderFactory() - .expand(scheme + "://" + server.getServiceId() + path); - URI reconstructed = client.reconstructURI(serviceInstance, expanded); - assertThat(reconstructed).hasPath(path); - } - - @Test - public void testReconstructHonorsRibbonServerScheme() { - RibbonServer server = new RibbonServer("testService", - new Server("ws", "myhost", 9080), false, - Collections.singletonMap("mykey", "myvalue")); - - IClientConfig config = mock(IClientConfig.class); - when(config.get(CommonClientConfigKey.IsSecure)).thenReturn(false); - when(clientFactory.getClientConfig(server.getServiceId())).thenReturn(config); - - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - ServiceInstance serviceInstance = client.choose(server.getServiceId()); - URI uri = client.reconstructURI(serviceInstance, - URI.create("http://testService")); - - assertThat(uri).hasScheme("ws").hasHost("myhost").hasPort(9080); - } - - @Test - public void testReconstructUriWithSecureClientConfig() throws Exception { - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - when(config.get(CommonClientConfigKey.IsSecure)).thenReturn(true); - when(clientFactory.getClientConfig(server.getServiceId())).thenReturn(config); - - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - ServiceInstance serviceInstance = client.choose(server.getServiceId()); - URI uri = client.reconstructURI(serviceInstance, - new URL("http://" + server.getServiceId()).toURI()); - assertThat(uri.getHost()).isEqualTo(server.getHost()); - assertThat(uri.getPort()).isEqualTo(server.getPort()); - assertThat(uri.getScheme()).isEqualTo("https"); - } - - @Test - public void testReconstructSecureUriWithoutScheme() throws Exception { - testReconstructSchemelessUriWithoutClientConfig(getSecureRibbonServer(), "https"); - } - - @Test - public void testReconstructUnsecureSchemelessUri() throws Exception { - testReconstructSchemelessUriWithoutClientConfig(getRibbonServer(), "http"); - } - - public void testReconstructSchemelessUriWithoutClientConfig(RibbonServer server, - String expectedScheme) throws Exception { - IClientConfig config = mock(IClientConfig.class); - when(config.get(CommonClientConfigKey.IsSecure)).thenReturn(null); - when(clientFactory.getClientConfig(server.getServiceId())).thenReturn(config); - - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - ServiceInstance serviceInstance = client.choose(server.getServiceId()); - URI uri = client.reconstructURI(serviceInstance, - new URI("//" + server.getServiceId())); - assertThat(uri.getHost()).isEqualTo(server.getHost()); - assertThat(uri.getPort()).isEqualTo(server.getPort()); - assertThat(uri.getScheme()).isEqualTo(expectedScheme); - } - - @Test - public void testChoose() { - RibbonServer server = getRibbonServer(); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - ServiceInstance serviceInstance = client.choose(server.getServiceId()); - assertServiceInstance(server, serviceInstance); - verify(this.loadBalancer).chooseServer(eq("default")); - } - - @Test - public void testChooseWithHint() { - Object hint = new Object(); - RibbonServer server = getRibbonServer(); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - ServiceInstance serviceInstance = client.choose(server.getServiceId(), hint); - assertServiceInstance(server, serviceInstance); - verify(this.loadBalancer).chooseServer(same(hint)); - } - - @Test - public void testChooseMissing() { - given(this.clientFactory.getLoadBalancer(this.loadBalancer.getName())) - .willReturn(null); - given(this.loadBalancer.getName()).willReturn("missingservice"); - RibbonLoadBalancerClient client = new RibbonLoadBalancerClient( - this.clientFactory); - ServiceInstance instance = client.choose("missingservice"); - assertThat(instance).as("instance wasn't null").isNull(); - } - - @Test - public void testExecute() throws IOException { - final RibbonServer server = getRibbonServer(); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - final String returnVal = "myval"; - Object actualReturn = client.execute(server.getServiceId(), - (LoadBalancerRequest) instance -> { - assertServiceInstance(server, instance); - return returnVal; - }); - verifyServerStats(); - verify(this.loadBalancer).chooseServer(eq("default")); - assertThat(actualReturn).as("retVal was wrong").isEqualTo(returnVal); - } - - @Test - public void testExecuteWithHint() throws IOException { - Object hint = new Object(); - final RibbonServer server = getRibbonServer(); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - final String returnVal = "myval"; - Object actualReturn = client.execute(server.getServiceId(), - (LoadBalancerRequest) instance -> { - assertServiceInstance(server, instance); - return returnVal; - }, hint); - verifyServerStats(); - verify(this.loadBalancer).chooseServer(same(hint)); - assertThat(actualReturn).as("retVal was wrong").isEqualTo(returnVal); - } - - @Test - public void testExecuteException() { - final RibbonServer ribbonServer = getRibbonServer(); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(ribbonServer); - try { - client.execute(ribbonServer.getServiceId(), instance -> { - assertServiceInstance(ribbonServer, instance); - throw new RuntimeException(); - }); - fail("Should have thrown exception"); - } - catch (Exception ex) { - assertThat(ex).isNotNull(); - } - verifyServerStats(); - } - - @Test - public void testExecuteIOException() { - final RibbonServer ribbonServer = getRibbonServer(); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(ribbonServer); - try { - client.execute(ribbonServer.getServiceId(), instance -> { - assertServiceInstance(ribbonServer, instance); - throw new IOException(); - }); - fail("Should have thrown exception"); - } - catch (Exception ex) { - assertThat(ex).isInstanceOf(IOException.class); - } - verifyServerStats(); - } - - protected RibbonServer getRibbonServer() { - return new RibbonServer("testService", new MyServer("myhost", 9080), false, - Collections.singletonMap("mykey", "myvalue")); - } - - protected RibbonServer getSecureRibbonServer() { - return new RibbonServer("testService", new MyServer("myhost", 8443), false, - Collections.singletonMap("mykey", "myvalue")); - } - - protected void verifyServerStats() { - verify(this.serverStats).incrementActiveRequestsCount(); - verify(this.serverStats).decrementActiveRequestsCount(); - verify(this.serverStats).incrementNumRequests(); - verify(this.serverStats).noteResponseTime(anyDouble()); - } - - protected void assertServiceInstance(RibbonServer ribbonServer, - ServiceInstance instance) { - assertThat(instance).as("instance was null").isNotNull(); - assertThat(instance.getInstanceId()).as("instanceId was wrong") - .isEqualTo(ribbonServer.getInstanceId()); - assertThat(instance.getServiceId()).as("serviceId was wrong") - .isEqualTo(ribbonServer.getServiceId()); - assertThat(instance.getHost()).as("host was wrong") - .isEqualTo(ribbonServer.getHost()); - assertThat(instance.getPort()).as("port was wrong") - .isEqualTo(ribbonServer.getPort()); - assertThat(instance.getMetadata().get("mykey")).as("missing metadata") - .isEqualTo(ribbonServer.getMetadata().get("mykey")); - } - - protected RibbonLoadBalancerClient getRibbonLoadBalancerClient( - RibbonServer ribbonServer) { - given(this.loadBalancer.getName()).willReturn(ribbonServer.getServiceId()); - given(this.loadBalancer.chooseServer(any())).willReturn(ribbonServer.getServer()); - given(this.loadBalancer.getLoadBalancerStats()) - .willReturn(this.loadBalancerStats); - given(this.loadBalancerStats.getSingleServerStat(ribbonServer.getServer())) - .willReturn(this.serverStats); - given(this.clientFactory.getLoadBalancer(this.loadBalancer.getName())) - .willReturn(this.loadBalancer); - return new RibbonLoadBalancerClient(this.clientFactory); - } - - protected static class MyServer extends Server { - - public MyServer(String host, int port) { - super(host, port); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonPropertiesTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonPropertiesTests.java deleted file mode 100644 index eedb037bc..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonPropertiesTests.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -public class RibbonPropertiesTests { - - @Test - public void poolKeepAliveWorksWithString() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.setProperty(CommonClientConfigKey.PoolKeepAliveTime, "714"); - RibbonProperties properties = new RibbonProperties(config); - assertThat(properties.poolKeepAliveTime()).isEqualTo(714L); - assertThat(properties.getPoolKeepAliveTime()).isEqualTo(714L); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonUtilsTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonUtilsTests.java deleted file mode 100644 index 6f893fb85..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonUtilsTests.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Map; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.loadbalancer.Server; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.isSecure; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToSecureConnectionIfNeeded; - -/** - * @author Spencer Gibb - * @author Jacques-Etienne Beaudet - * @author Tim Ysewyn - */ -public class RibbonUtilsTests { - - private static final ServerIntrospector NON_SECURE_INTROSPECTOR = new StaticServerIntrospector( - false); - - private static final ServerIntrospector SECURE_INTROSPECTOR = new StaticServerIntrospector( - true); - - private static final Server SERVER = new Server("localhost", 8080); - - private static final DefaultClientConfigImpl SECURE_CONFIG = getConfig(true); - - private static final DefaultClientConfigImpl NON_SECURE_CONFIG = getConfig(false); - - private static final DefaultClientConfigImpl NO_IS_SECURE_CONFIG = new DefaultClientConfigImpl(); - - @Test - public void noRibbonPropSecureIntrospector() { - boolean secure = isSecure(NO_IS_SECURE_CONFIG, SECURE_INTROSPECTOR, SERVER); - assertThat(secure).as("isSecure was wrong").isTrue(); - } - - @Test - public void noRibbonPropNonSecureIntrospector() { - boolean secure = isSecure(NO_IS_SECURE_CONFIG, NON_SECURE_INTROSPECTOR, SERVER); - assertThat(secure).as("isSecure was wrong").isFalse(); - } - - @Test - public void isSecureRibbonPropSecureIntrospector() { - boolean secure = isSecure(SECURE_CONFIG, SECURE_INTROSPECTOR, SERVER); - assertThat(secure).as("isSecure was wrong").isTrue(); - } - - @Test - public void nonSecureRibbonPropNonSecureIntrospector() { - boolean secure = isSecure(NON_SECURE_CONFIG, NON_SECURE_INTROSPECTOR, SERVER); - assertThat(secure).as("isSecure was wrong").isFalse(); - } - - @Test - public void isSecureRibbonPropNonSecureIntrospector() { - boolean secure = isSecure(SECURE_CONFIG, NON_SECURE_INTROSPECTOR, SERVER); - assertThat(secure).as("isSecure was wrong").isTrue(); - } - - @Test - public void nonSecureRibbonPropSecureIntrospector() { - boolean secure = isSecure(NON_SECURE_CONFIG, SECURE_INTROSPECTOR, SERVER); - assertThat(secure).as("isSecure was wrong").isFalse(); - } - - @Test - public void uriIsNotChangedWhenServerIsNotSecured() throws URISyntaxException { - URI original = new URI("https://foo"); - URI updated = updateToSecureConnectionIfNeeded(original, NON_SECURE_CONFIG, - NON_SECURE_INTROSPECTOR, SERVER); - assertThat(original) - .as("URI should not have been updated since server is not secured.") - .isEqualTo(updated); - } - - @Test - public void uriIsNotChangedWhenServerIsSecuredAndUriAlreadyInHttps() - throws URISyntaxException { - URI original = new URI("https://foo"); - URI updated = updateToSecureConnectionIfNeeded(original, SECURE_CONFIG, - SECURE_INTROSPECTOR, SERVER); - assertThat(original) - .as("URI should not have been updated since uri is already in https.") - .isEqualTo(updated); - } - - @Test - public void shouldUpgradeUriToHttpsWhenServerIsSecureAndUriNotInHttps() - throws URISyntaxException { - URI original = new URI("https://foo"); - URI updated = updateToSecureConnectionIfNeeded(original, SECURE_CONFIG, - SECURE_INTROSPECTOR, SERVER); - assertThat(updated).as("URI should have been updated to https.") - .isEqualTo(new URI("https://foo")); - } - - @Test - public void shouldUpgradeUriToWssWhenServerIsSecureAndUriNotInWss() - throws URISyntaxException { - URI original = new URI("ws://foo"); - URI updated = updateToSecureConnectionIfNeeded(original, SECURE_CONFIG, - SECURE_INTROSPECTOR, SERVER); - assertThat(updated).as("URI should have been updated to wss.") - .isEqualTo(new URI("wss://foo")); - } - - @Test - public void shouldSubstitutePlusInQueryParam() throws URISyntaxException { - URI original = new URI("http://foo/%20bar?hello=1+2"); - URI updated = updateToSecureConnectionIfNeeded(original, SECURE_CONFIG, - SECURE_INTROSPECTOR, SERVER); - assertThat(updated) - .as("URI should have had its plus sign replaced in query string.") - .isEqualTo(new URI("https://foo/%20bar?hello=1%202")); - } - - @Test - public void emptyStringUri() throws URISyntaxException { - URI original = new URI(""); - URI updated = updateToSecureConnectionIfNeeded(original, SECURE_CONFIG, - SECURE_INTROSPECTOR, SERVER); - assertThat(updated).as("URI should be the emptry string").isEqualTo(new URI("")); - } - - static DefaultClientConfigImpl getConfig(boolean value) { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.setProperty(CommonClientConfigKey.IsSecure, value); - return config; - } - - static class StaticServerIntrospector implements ServerIntrospector { - - final boolean secure; - - StaticServerIntrospector(boolean secure) { - this.secure = secure; - } - - @Override - public boolean isSecure(Server server) { - return this.secure; - } - - @Override - public Map getMetadata(Server server) { - return null; - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringClientFactoryTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringClientFactoryTests.java deleted file mode 100644 index 6e34d41af..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringClientFactoryTests.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.IClientConfigAware; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.niws.client.http.RestClient; -import com.sun.jersey.client.apache4.ApacheHttpClient4; -import org.apache.http.client.params.ClientPNames; -import org.apache.http.client.params.CookiePolicy; -import org.junit.Test; - -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * - */ -public class SpringClientFactoryTests { - - @Test - public void testConfigureRetry() { - SpringClientFactory factory = new SpringClientFactory(); - AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext( - RibbonAutoConfiguration.class, ArchaiusAutoConfiguration.class, - HttpClientConfiguration.class); - TestPropertyValues.of("foo.ribbon.MaxAutoRetries:2").applyTo(parent); - factory.setApplicationContext(parent); - DefaultLoadBalancerRetryHandler retryHandler = (DefaultLoadBalancerRetryHandler) factory - .getLoadBalancerContext("foo").getRetryHandler(); - assertThat(retryHandler.getMaxRetriesOnSameServer()).isEqualTo(2); - parent.close(); - factory.destroy(); - } - - @SuppressWarnings("deprecation") - @Test - public void testCookiePolicy() { - SpringClientFactory factory = new SpringClientFactory(); - AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("ribbon.restclient.enabled=true").applyTo(parent); - parent.register(RibbonAutoConfiguration.class, ArchaiusAutoConfiguration.class); - parent.refresh(); - factory.setApplicationContext(parent); - RestClient client = factory.getClient("foo", RestClient.class); - ApacheHttpClient4 jerseyClient = (ApacheHttpClient4) client.getJerseyClient(); - assertThat(jerseyClient.getClientHandler().getHttpClient().getParams() - .getParameter(ClientPNames.COOKIE_POLICY)) - .isEqualTo(CookiePolicy.IGNORE_COOKIES); - parent.close(); - factory.destroy(); - } - - @Test - public void testInstantiateWithConfigInjectByConstructor() { - IClientConfig clientConfig = new DefaultClientConfigImpl(); - ClientConfigInjectedByConstructor instance = SpringClientFactory - .instantiateWithConfig(ClientConfigInjectedByConstructor.class, - clientConfig); - assertThat(instance.clientConfig).isSameAs(clientConfig); - } - - @Test - public void testInstantiateWithConfigInjectedByInitMethod() { - IClientConfig clientConfig = new DefaultClientConfigImpl(); - ClientConfigInjectedByInitMethod instance = SpringClientFactory - .instantiateWithConfig(ClientConfigInjectedByInitMethod.class, - clientConfig); - assertThat(instance.clientConfig).isSameAs(clientConfig); - } - - @Test - public void testInstantiateWithoutConfig() { - IClientConfig clientConfig = new DefaultClientConfigImpl(); - NoClientConfigAware instance = SpringClientFactory - .instantiateWithConfig(NoClientConfigAware.class, clientConfig); - assertThat(instance).isNotNull(); - } - - public static class ClientConfigInjectedByConstructor { - - private IClientConfig clientConfig; - - public ClientConfigInjectedByConstructor(IClientConfig clientConfig) { - this.clientConfig = clientConfig; - } - - } - - public static class ClientConfigInjectedByInitMethod implements IClientConfigAware { - - private IClientConfig clientConfig; - - @Override - public void initWithNiwsConfig(IClientConfig clientConfig) { - this.clientConfig = clientConfig; - } - - } - - public static class NoClientConfigAware { - - public NoClientConfigAware() { - // no client config - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringRetryDisabledTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringRetryDisabledTests.java deleted file mode 100644 index eb990737a..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringRetryDisabledTests.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - * @author Biju Kunjummen - */ -@RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({ "spring-retry-*.jar", "spring-boot-starter-aop-*.jar" }) -public class SpringRetryDisabledTests { - - @Test - public void testLoadBalancedRetryFactoryBean() { - new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(RibbonAutoConfiguration.class, - LoadBalancerAutoConfiguration.class, - RibbonClientConfiguration.class)) - .run(context -> { - Map factories = context - .getBeansOfType(LoadBalancedRetryFactory.class); - assertThat(factories.values()).hasSize(0); - Map clients = context - .getBeansOfType(RibbonLoadBalancingHttpClient.class); - assertThat(clients.values()).hasSize(1); - assertThat(clients.values().toArray()[0]) - .isInstanceOf(RibbonLoadBalancingHttpClient.class); - }); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringRetryEnabledTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringRetryEnabledTests.java deleted file mode 100644 index fbb588742..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringRetryEnabledTests.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.BeansException; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.ribbon.apache.RetryableRibbonLoadBalancingHttpClient; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration( - classes = { RibbonAutoConfiguration.class, RibbonClientConfiguration.class, - LoadBalancerAutoConfiguration.class, HttpClientConfiguration.class }) -public class SpringRetryEnabledTests implements ApplicationContextAware { - - private ApplicationContext context; - - @Test - public void testLoadBalancedRetryFactoryBean() throws Exception { - Map factories = context - .getBeansOfType(LoadBalancedRetryFactory.class); - assertThat(factories.values()).hasSize(1); - assertThat(factories.values().toArray()[0]) - .isInstanceOf(RibbonLoadBalancedRetryFactory.class); - Map clients = context - .getBeansOfType(RibbonLoadBalancingHttpClient.class); - assertThat(clients.values()).hasSize(1); - assertThat(clients.values().toArray()[0]) - .isInstanceOf(RetryableRibbonLoadBalancingHttpClient.class); - } - - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - this.context = context; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/ZonePreferenceServerListFilterTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/ZonePreferenceServerListFilterTests.java deleted file mode 100644 index fdb9d77a9..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/ZonePreferenceServerListFilterTests.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon; - -import java.util.Arrays; -import java.util.List; - -import com.netflix.loadbalancer.Server; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -public class ZonePreferenceServerListFilterTests { - - private Server dsyer = new Server("dsyer", 8080); - - private Server localhost = new Server("localhost", 8080); - - @Before - public void init() { - this.dsyer.setZone("dsyer"); - this.localhost.setZone("localhost"); - } - - @Test - public void noZoneSet() { - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - List result = filter - .getFilteredListOfServers(Arrays.asList(this.localhost)); - assertThat(result.size()).isEqualTo(1); - } - - @Test - public void withZoneSetAndNoMatches() { - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - ReflectionTestUtils.setField(filter, "zone", "dsyer"); - List result = filter - .getFilteredListOfServers(Arrays.asList(this.localhost)); - assertThat(result.size()).isEqualTo(1); - } - - @Test - public void withZoneSetAndMatches() { - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - ReflectionTestUtils.setField(filter, "zone", "dsyer"); - List result = filter - .getFilteredListOfServers(Arrays.asList(this.dsyer, this.localhost)); - assertThat(result.size()).isEqualTo(1); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpRequestTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpRequestTests.java deleted file mode 100644 index 95e38ef74..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpRequestTests.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.apache; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.net.URI; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Collections; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpEntityEnclosingRequest; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.methods.RequestBuilder; -import org.junit.Test; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.StreamUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -public class RibbonApacheHttpRequestTests { - - @Test - public void testNullEntity() throws Exception { - String uri = "https://example.com"; - LinkedMultiValueMap headers = new LinkedMultiValueMap<>(); - headers.add("my-header", "my-value"); - headers.add("content-length", "5192"); - LinkedMultiValueMap params = new LinkedMultiValueMap<>(); - params.add("myparam", "myparamval"); - RibbonApacheHttpRequest httpRequest = new RibbonApacheHttpRequest( - new RibbonCommandContext("example", "GET", uri, false, headers, params, - null, new ArrayList())); - - HttpUriRequest request = httpRequest.toRequest(RequestConfig.custom().build()); - - assertThat(request).as("request is wrong type") - .isNotInstanceOf(HttpEntityEnclosingRequest.class); - assertThat(request.getURI().toString()).as("uri is wrong").startsWith(uri); - assertThat(request.getFirstHeader("my-header")).as("my-header is missing") - .isNotNull(); - assertThat(request.getFirstHeader("my-header").getValue()) - .as("my-header is wrong").isEqualTo("my-value"); - assertThat(request.getFirstHeader("content-length").getValue()) - .as("Content-Length is wrong").isEqualTo("5192"); - assertThat(request.getURI().getQuery()).as("myparam is missing") - .isEqualTo("myparam=myparamval"); - - } - - @Test - // this situation happens, see - // https://github.com/spring-cloud/spring-cloud-netflix/issues/1042#issuecomment-227723877 - public void testEmptyEntityGet() throws Exception { - String entityValue = ""; - testEntity(entityValue, new ByteArrayInputStream(entityValue.getBytes()), false, - "GET"); - } - - @Test - public void testNonEmptyEntityPost() throws Exception { - String entityValue = "abcd"; - testEntity(entityValue, new ByteArrayInputStream(entityValue.getBytes()), true, - "POST"); - } - - void testEntity(String entityValue, ByteArrayInputStream requestEntity, - boolean addContentLengthHeader, String method) throws IOException { - String lengthString = String.valueOf(entityValue.length()); - Long length = null; - URI uri = URI.create("https://example.com"); - LinkedMultiValueMap headers = new LinkedMultiValueMap<>(); - if (addContentLengthHeader) { - headers.add("Content-Length", lengthString); - length = (long) entityValue.length(); - } - - RibbonRequestCustomizer requestCustomizer = new RibbonRequestCustomizer() { - @Override - public boolean accepts(Class builderClass) { - return builderClass == RequestBuilder.class; - } - - @Override - public void customize(RequestBuilder builder) { - builder.addHeader("from-customizer", "foo"); - } - }; - RibbonCommandContext context = new RibbonCommandContext("example", method, - uri.toString(), false, headers, new LinkedMultiValueMap(), - requestEntity, Collections.singletonList(requestCustomizer)); - context.setContentLength(length); - RibbonApacheHttpRequest httpRequest = new RibbonApacheHttpRequest(context); - - HttpUriRequest request = httpRequest.toRequest(RequestConfig.custom().build()); - - assertThat(request).as("request is wrong type") - .isInstanceOf(HttpEntityEnclosingRequest.class); - assertThat(request.getURI().toString()).as("uri is wrong") - .startsWith(uri.toString()); - if (addContentLengthHeader) { - assertThat(request.getFirstHeader("Content-Length")) - .as("Content-Length is missing").isNotNull(); - assertThat(request.getFirstHeader("Content-Length").getValue()) - .as("Content-Length is wrong").isEqualTo(lengthString); - } - assertThat(request.getFirstHeader("from-customizer")) - .as("from-customizer is missing").isNotNull(); - assertThat(request.getFirstHeader("from-customizer").getValue()) - .as("from-customizer is wrong").isEqualTo("foo"); - - HttpEntityEnclosingRequest entityRequest = (HttpEntityEnclosingRequest) request; - assertThat(entityRequest.getEntity()).as("entity is missing").isNotNull(); - HttpEntity entity = entityRequest.getEntity(); - assertThat(entity.getContentLength()).as("contentLength is wrong") - .isEqualTo((long) entityValue.length()); - assertThat(entity.getContent()).as("content is missing").isNotNull(); - String string = StreamUtils.copyToString(entity.getContent(), - Charset.forName("UTF-8")); - assertThat(string).as("content is wrong").isEqualTo(entityValue); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpResponseTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpResponseTests.java deleted file mode 100644 index af86f4f01..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpResponseTests.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.apache; - -import java.io.ByteArrayInputStream; -import java.net.URI; - -import org.apache.http.HttpResponse; -import org.apache.http.StatusLine; -import org.apache.http.entity.BasicHttpEntity; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.mock; - -/** - * @author Spencer Gibb - */ -public class RibbonApacheHttpResponseTests { - - @Test - public void testNullEntity() throws Exception { - StatusLine statusLine = mock(StatusLine.class); - given(statusLine.getStatusCode()).willReturn(204); - HttpResponse response = mock(HttpResponse.class); - given(response.getStatusLine()).willReturn(statusLine); - - RibbonApacheHttpResponse httpResponse = new RibbonApacheHttpResponse(response, - URI.create("https://example.com")); - - assertThat(httpResponse.isSuccess()).isTrue(); - assertThat(httpResponse.hasPayload()).isFalse(); - assertThat(httpResponse.getPayload()).isNull(); - assertThat(httpResponse.getInputStream()).isNull(); - } - - @Test - public void testNotNullEntity() throws Exception { - StatusLine statusLine = mock(StatusLine.class); - given(statusLine.getStatusCode()).willReturn(204); - HttpResponse response = mock(HttpResponse.class); - given(response.getStatusLine()).willReturn(statusLine); - BasicHttpEntity entity = new BasicHttpEntity(); - entity.setContent(new ByteArrayInputStream(new byte[0])); - given(response.getEntity()).willReturn(entity); - - RibbonApacheHttpResponse httpResponse = new RibbonApacheHttpResponse(response, - URI.create("https://example.com")); - - assertThat(httpResponse.isSuccess()).isTrue(); - assertThat(httpResponse.hasPayload()).isTrue(); - assertThat(httpResponse.getPayload()).isNotNull(); - assertThat(httpResponse.getInputStream()).isNotNull(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClientTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClientTests.java deleted file mode 100644 index f8761d0db..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClientTests.java +++ /dev/null @@ -1,1109 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.apache; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.util.ArrayList; -import java.util.Locale; -import java.util.concurrent.TimeUnit; - -import com.netflix.client.ClientException; -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.AbstractLoadBalancer; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.LoadBalancerStats; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerStats; -import com.netflix.servo.monitor.Monitors; -import org.apache.http.HttpEntity; -import org.apache.http.StatusLine; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.entity.BasicHttpEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatcher; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryFactory; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicy; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; -import org.springframework.retry.RetryCallback; -import org.springframework.retry.RetryContext; -import org.springframework.retry.RetryListener; -import org.springframework.retry.TerminatedRetryException; -import org.springframework.retry.backoff.BackOffContext; -import org.springframework.retry.backoff.BackOffInterruptedException; -import org.springframework.retry.backoff.BackOffPolicy; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.util.LinkedMultiValueMap; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * @author Sébastien Nussbaumer - * @author Ryan Baxter - * @author Gang Li - */ -public class RibbonLoadBalancingHttpClientTests { - - private ILoadBalancer loadBalancer; - - @Before - public void setup() { - loadBalancer = mock(AbstractLoadBalancer.class); - doReturn(new Server("foo.com", 8000)).when(loadBalancer) - .chooseServer(eq("default")); - doReturn(new Server("foo.com", 8000)).when(loadBalancer) - .chooseServer(eq("service")); - } - - @After - public void teardown() { - loadBalancer = null; - } - - @Test - public void testRequestConfigUseDefaultsNoOverride() throws Exception { - RequestConfig result = getBuiltRequestConfig(UseDefaults.class, null); - - assertThat(result.isRedirectsEnabled()).isFalse(); - - } - - @Test - public void testRequestConfigDoNotFollowRedirectsNoOverride() throws Exception { - RequestConfig result = getBuiltRequestConfig(DoNotFollowRedirects.class, null); - - assertThat(result.isRedirectsEnabled()).isFalse(); - } - - @Test - public void testRequestConfigFollowRedirectsNoOverride() throws Exception { - RequestConfig result = getBuiltRequestConfig(FollowRedirects.class, null); - - assertThat(result.isRedirectsEnabled()).isTrue(); - } - - @Test - public void testTimeouts() throws Exception { - RequestConfig result = getBuiltRequestConfig(Timeouts.class, null); - assertThat(result.getConnectTimeout()).isEqualTo(60000); - assertThat(result.getSocketTimeout()).isEqualTo(50000); - } - - @Test - public void testDefaultTimeouts() throws Exception { - RequestConfig result = getBuiltRequestConfig(UseDefaults.class, null); - assertThat(result.getConnectTimeout()).isEqualTo(1000); - assertThat(result.getSocketTimeout()).isEqualTo(1000); - } - - @Test - public void testCompressionDefault() throws Exception { - RequestConfig result = getBuiltRequestConfig(UseDefaults.class, null); - assertThat(result.isContentCompressionEnabled()).isTrue(); - } - - @Test - public void testCompressionDisabled() throws Exception { - IClientConfig configOverride = DefaultClientConfigImpl - .getClientConfigWithDefaultValues(); - configOverride.set(CommonClientConfigKey.GZipPayload, false); - RequestConfig result = getBuiltRequestConfig(UseDefaults.class, configOverride); - assertThat(result.isContentCompressionEnabled()).isFalse(); - } - - @Test - public void testConnections() throws Exception { - SpringClientFactory factory = new SpringClientFactory(); - factory.setApplicationContext(new AnnotationConfigApplicationContext( - RibbonAutoConfiguration.class, Connections.class)); - RetryableRibbonLoadBalancingHttpClient client = factory.getClient("service", - RetryableRibbonLoadBalancingHttpClient.class); - - HttpClient delegate = client.getDelegate(); - PoolingHttpClientConnectionManager connManager = (PoolingHttpClientConnectionManager) ReflectionTestUtils - .getField(delegate, "connManager"); - assertThat(connManager.getMaxTotal()).isEqualTo(101); - assertThat(connManager.getDefaultMaxPerRoute()).isEqualTo(201); - } - - @Test - public void testRequestConfigDoNotFollowRedirectsOverrideWithFollowRedirects() - throws Exception { - - DefaultClientConfigImpl override = new DefaultClientConfigImpl(); - override.set(CommonClientConfigKey.FollowRedirects, true); - override.set(CommonClientConfigKey.IsSecure, false); - - RequestConfig result = getBuiltRequestConfig(DoNotFollowRedirects.class, - override); - - assertThat(result.isRedirectsEnabled()).isTrue(); - } - - @Test - public void testRequestConfigFollowRedirectsOverrideWithDoNotFollowRedirects() - throws Exception { - - DefaultClientConfigImpl override = new DefaultClientConfigImpl(); - override.set(CommonClientConfigKey.FollowRedirects, false); - override.set(CommonClientConfigKey.IsSecure, false); - - RequestConfig result = getBuiltRequestConfig(FollowRedirects.class, override); - - assertThat(result.isRedirectsEnabled()).isFalse(); - } - - @Test - public void testUpdatedTimeouts() throws Exception { - SpringClientFactory factory = new SpringClientFactory(); - RequestConfig result = getBuiltRequestConfig(Timeouts.class, null, factory); - assertThat(result.getConnectTimeout()).isEqualTo(60000); - assertThat(result.getSocketTimeout()).isEqualTo(50000); - IClientConfig config = factory.getClientConfig("service"); - config.set(CommonClientConfigKey.ConnectTimeout, 60); - config.set(CommonClientConfigKey.ReadTimeout, 50); - result = getBuiltRequestConfig(Timeouts.class, null, factory); - assertThat(result.getConnectTimeout()).isEqualTo(60); - assertThat(result.getSocketTimeout()).isEqualTo(50); - } - - @Test - public void testNeverRetry() throws Exception { - ServerIntrospector introspector = mock(ServerIntrospector.class); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - doThrow(new IOException("boom")).when(delegate) - .execute(any(HttpUriRequest.class)); - DefaultClientConfigImpl clientConfig = new DefaultClientConfigImpl(); - clientConfig.setClientName("foo"); - RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient(delegate, - clientConfig, introspector); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - when(request.toRequest(any(RequestConfig.class))) - .thenReturn(mock(HttpUriRequest.class)); - try { - client.execute(request, null); - fail("Expected IOException"); - } - catch (IOException e) { - } - finally { - verify(delegate, times(1)).execute(any(HttpUriRequest.class)); - } - } - - @Test - public void testRetryFail() throws Exception { - int retriesNextServer = 0; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = false; - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.GET; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - StatusLine fourOFourStatusLine = mock(StatusLine.class); - CloseableHttpResponse fourOFourResponse = mock(CloseableHttpResponse.class); - Locale locale = new Locale("en"); - doReturn(locale).when(fourOFourResponse).getLocale(); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocationOnMock) throws Throwable { - HttpEntity entity = mock(HttpEntity.class); - doReturn(new ByteArrayInputStream("test".getBytes())).when(entity) - .getContent(); - return entity; - } - }).when(fourOFourResponse).getEntity(); - doReturn(404).when(fourOFourStatusLine).getStatusCode(); - doReturn(fourOFourStatusLine).when(fourOFourResponse).getStatusLine(); - doReturn(locale).when(fourOFourResponse).getLocale(); - doReturn(fourOFourResponse).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "404", myBackOffPolicy); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(uri).when(request).getURI(); - doReturn(method).when(request).getMethod(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uri).when(uriRequest).getURI(); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - RibbonApacheHttpResponse returnedResponse = client.execute(request, null); - verify(delegate, times(2)).execute(any(HttpUriRequest.class)); - byte[] buf = new byte[100]; - InputStream inputStream = returnedResponse.getInputStream(); - int read = inputStream.read(buf); - assertThat(new String(buf, 0, read)).isEqualTo("test"); - } - - private RetryableRibbonLoadBalancingHttpClient setupClientForRetry( - int retriesNextServer, int retriesSameServer, boolean retryable, - boolean retryOnAllOps, String serviceName, String host, int port, - CloseableHttpClient delegate, ILoadBalancer lb, String statusCodes, - BackOffPolicy backOffPolicy) throws Exception { - return setupClientForRetry(retriesNextServer, retriesSameServer, retryable, - retryOnAllOps, serviceName, host, port, delegate, lb, statusCodes, - backOffPolicy, false); - } - - private RetryableRibbonLoadBalancingHttpClient setupClientForRetry( - int retriesNextServer, int retriesSameServer, boolean retryable, - boolean retryOnAllOps, String serviceName, String host, int port, - CloseableHttpClient delegate, ILoadBalancer lb, String statusCodes, - BackOffPolicy backOffPolicy, boolean isSecure) throws Exception { - ServerIntrospector introspector = mock(ServerIntrospector.class); - RetryHandler retryHandler = new DefaultLoadBalancerRetryHandler(retriesSameServer, - retriesNextServer, retryable); - doReturn(new Server(host, port)).when(lb).chooseServer(eq(serviceName)); - DefaultClientConfigImpl clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(CommonClientConfigKey.OkToRetryOnAllOperations, retryOnAllOps); - clientConfig.set(CommonClientConfigKey.MaxAutoRetriesNextServer, - retriesNextServer); - clientConfig.set(CommonClientConfigKey.MaxAutoRetries, retriesSameServer); - clientConfig.set(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES, - statusCodes); - clientConfig.set(CommonClientConfigKey.IsSecure, isSecure); - clientConfig.setClientName(serviceName); - RibbonLoadBalancerContext context = new RibbonLoadBalancerContext(lb, - clientConfig, retryHandler); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - doReturn(context).when(clientFactory).getLoadBalancerContext(eq(serviceName)); - doReturn(clientConfig).when(clientFactory).getClientConfig(eq(serviceName)); - LoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory) { - @Override - public BackOffPolicy createBackOffPolicy(String service) { - return backOffPolicy; - } - }; - RetryableRibbonLoadBalancingHttpClient client = new RetryableRibbonLoadBalancingHttpClient( - delegate, clientConfig, introspector, factory); - client.setLoadBalancer(lb); - ReflectionTestUtils.setField(client, "delegate", delegate); - return client; - } - - private RetryableRibbonLoadBalancingHttpClient setupClientForRetry( - int retriesNextServer, int retriesSameServer, boolean retryable, - boolean retryOnAllOps, String serviceName, String host, int port, - CloseableHttpClient delegate, ILoadBalancer lb, String statusCodes, - BackOffPolicy backOffPolicy, boolean isSecure, RetryListener[] retryListeners) - throws Exception { - ServerIntrospector introspector = mock(ServerIntrospector.class); - RetryHandler retryHandler = new DefaultLoadBalancerRetryHandler(retriesSameServer, - retriesNextServer, retryable); - doReturn(new Server(host, port)).when(lb).chooseServer(eq(serviceName)); - DefaultClientConfigImpl clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(CommonClientConfigKey.OkToRetryOnAllOperations, retryOnAllOps); - clientConfig.set(CommonClientConfigKey.MaxAutoRetriesNextServer, - retriesNextServer); - clientConfig.set(CommonClientConfigKey.MaxAutoRetries, retriesSameServer); - clientConfig.set(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES, - statusCodes); - clientConfig.set(CommonClientConfigKey.IsSecure, isSecure); - clientConfig.setClientName(serviceName); - RibbonLoadBalancerContext context = new RibbonLoadBalancerContext(lb, - clientConfig, retryHandler); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - doReturn(context).when(clientFactory).getLoadBalancerContext(eq(serviceName)); - doReturn(clientConfig).when(clientFactory).getClientConfig(eq(serviceName)); - LoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory) { - @Override - public RetryListener[] createRetryListeners(String service) { - return retryListeners; - } - - @Override - public BackOffPolicy createBackOffPolicy(String service) { - return backOffPolicy; - } - }; - RetryableRibbonLoadBalancingHttpClient client = new RetryableRibbonLoadBalancingHttpClient( - delegate, clientConfig, introspector, factory); - client.setLoadBalancer(lb); - ReflectionTestUtils.setField(client, "delegate", delegate); - return client; - } - - @Test - public void testRetrySameServerOnly() throws Exception { - int retriesNextServer = 0; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = false; - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.GET; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doThrow(new IOException("boom")).doReturn(response).when(delegate) - .execute(any(HttpUriRequest.class)); - AbstractLoadBalancer lb = mock(AbstractLoadBalancer.class); - LoadBalancerStats lbStats = mock(LoadBalancerStats.class); - doReturn(lbStats).when(lb).getLoadBalancerStats(); - ServerStats serverStats = mock(ServerStats.class); - doReturn(serverStats).when(lbStats).getSingleServerStat(any(Server.class)); - RibbonLoadBalancerContext ribbonLoadBalancerContext = mock( - RibbonLoadBalancerContext.class); - doReturn(lb).when(ribbonLoadBalancerContext).getLoadBalancer(); - doReturn(Monitors.newTimer("_LoadBalancerExecutionTimer", TimeUnit.MILLISECONDS)) - .when(ribbonLoadBalancerContext).getExecuteTracer(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", null); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(uri).when(request).getURI(); - doReturn(method).when(request).getMethod(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uri).when(uriRequest).getURI(); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - RibbonApacheHttpResponse returnedResponse = client.execute(request, null); - verify(delegate, times(2)).execute(any(HttpUriRequest.class)); - verify(lb, times(1)).chooseServer(eq(serviceName)); - verify(ribbonLoadBalancerContext, times(1)).noteRequestCompletion(serverStats, - response, null, 0, null); - } - - @Test - public void testRetryNextServer() throws Exception { - int retriesNextServer = 1; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = false; - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.GET; - URI uri = new URI("http://" + host + ":" + port + "/a%2Bb"); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doThrow(new IOException("boom")).doThrow(new IOException("boom again")) - .doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", myBackOffPolicy); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(uri).when(request).getURI(); - doReturn(method).when(request).getMethod(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uri).when(uriRequest).getURI(); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - client.execute(request, null); - verify(delegate, times(3)).execute(any(HttpUriRequest.class)); - verify(lb, times(2)).chooseServer(eq(serviceName)); - assertThat(myBackOffPolicy.getCount()).isEqualTo(2); - verify(request, times(3)).withNewUri(argThat(new ArgumentMatcher() { - @Override - public boolean matches(URI argument) { - if (argument.equals(uri)) { - return true; - } - return false; - } - })); - } - - @Test - public void testRetryOnPost() throws Exception { - int retriesNextServer = 1; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = true; - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doThrow(new IOException("boom")).doThrow(new IOException("boom again")) - .doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", myBackOffPolicy); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - RibbonApacheHttpResponse returnedResponse = client.execute(request, null); - verify(response, times(0)).close(); - verify(delegate, times(3)).execute(any(HttpUriRequest.class)); - verify(lb, times(2)).chooseServer(eq(serviceName)); - assertThat(myBackOffPolicy.getCount()).isEqualTo(2); - } - - @Test - public void testDoubleEncoding() throws Exception { - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.GET; - final URI uri = new URI("https://" + host + ":" + port + "/a%2Bb"); - DefaultClientConfigImpl clientConfig = new DefaultClientConfigImpl(); - clientConfig.setClientName(serviceName); - ServerIntrospector introspector = mock(ServerIntrospector.class); - RibbonCommandContext context = new RibbonCommandContext(serviceName, - method.toString(), uri.toString(), false, - new LinkedMultiValueMap(), - new LinkedMultiValueMap(), - new ByteArrayInputStream("bar".getBytes()), - new ArrayList()); - RibbonApacheHttpRequest request = new RibbonApacheHttpRequest(context); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient(delegate, - clientConfig, introspector); - client.execute(request, null); - verify(response, times(0)).close(); - verify(delegate, times(1)).execute(argThat(new ArgumentMatcher() { - @Override - public boolean matches(HttpUriRequest argument) { - if (argument instanceof HttpUriRequest) { - HttpUriRequest arg = (HttpUriRequest) argument; - return arg.getURI().equals(uri); - } - return false; - } - })); - } - - @Test - public void testDoubleEncodingWithRetry() throws Exception { - int retriesNextServer = 0; - int retriesSameServer = 0; - boolean retryable = true; - boolean retryOnAllOps = true; - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.GET; - final URI uri = new URI("https://" + host + ":" + port + "/a%20b"); - RibbonCommandContext context = new RibbonCommandContext(serviceName, - method.toString(), uri.toString(), true, - new LinkedMultiValueMap(), - new LinkedMultiValueMap(), - new ByteArrayInputStream(new String("bar").getBytes()), - new ArrayList()); - RibbonApacheHttpRequest request = new RibbonApacheHttpRequest(context); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", null, true); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - client.execute(request, null); - verify(response, times(0)).close(); - verify(delegate, times(1)).execute(argThat(new ArgumentMatcher() { - @Override - public boolean matches(HttpUriRequest argument) { - if (argument instanceof HttpUriRequest) { - HttpUriRequest arg = (HttpUriRequest) argument; - return arg.getURI().equals(uri); - } - return false; - } - })); - } - - @Test - public void testNoRetryOnPost() throws Exception { - int retriesNextServer = 1; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = false; - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - doThrow(new IOException("boom")).doThrow(new IOException("boom again")) - .doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", null); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uri).when(uriRequest).getURI(); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - try { - client.execute(request, null); - fail("Expected IOException"); - } - catch (IOException e) { - } - finally { - verify(response, times(0)).close(); - verify(delegate, times(1)).execute(any(HttpUriRequest.class)); - verify(lb, times(1)).chooseServer(eq(serviceName)); - } - } - - @Test - public void testRetryOnStatusCode() throws Exception { - int retriesNextServer = 0; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = false; - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.GET; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - Locale locale = new Locale("en"); - doReturn(locale).when(response).getLocale(); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - final CloseableHttpResponse fourOFourResponse = mock(CloseableHttpResponse.class); - doReturn(locale).when(fourOFourResponse).getLocale(); - BasicHttpEntity entity = new BasicHttpEntity(); - entity.setContentLength(5); - entity.setContent(new ByteArrayInputStream("error".getBytes())); - doReturn(entity).when(fourOFourResponse).getEntity(); - StatusLine fourOFourStatusLine = mock(StatusLine.class); - doReturn(404).when(fourOFourStatusLine).getStatusCode(); - doReturn(fourOFourStatusLine).when(fourOFourResponse).getStatusLine(); - doReturn(fourOFourResponse).doReturn(response).when(delegate) - .execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "404", myBackOffPolicy); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(uri).when(request).getURI(); - doReturn(method).when(request).getMethod(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uri).when(uriRequest).getURI(); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - client.execute(request, null); - verify(fourOFourResponse, times(1)).close(); - verify(delegate, times(2)).execute(any(HttpUriRequest.class)); - verify(lb, times(1)).chooseServer(eq(serviceName)); - assertThat(myBackOffPolicy.getCount()).isEqualTo(1); - } - - @Test - public void retryListenerTest() throws Exception { - int retriesNextServer = 1; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = true; - String serviceName = "listener"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doThrow(new IOException("boom")).doThrow(new IOException("boom again")) - .doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - MyRetryListener myRetryListener = new MyRetryListener(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", myBackOffPolicy, false, - new RetryListener[] { myRetryListener }); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - RibbonApacheHttpResponse returnedResponse = client.execute(request, null); - verify(response, times(0)).close(); - verify(delegate, times(3)).execute(any(HttpUriRequest.class)); - verify(lb, times(2)).chooseServer(eq(serviceName)); - assertThat(myBackOffPolicy.getCount()).isEqualTo(2); - assertThat(myRetryListener.getOnError()).isEqualTo(2); - } - - @Test - public void retryDefaultListenerTest() throws Exception { - int retriesNextServer = 1; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = true; - String serviceName = "listener"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doThrow(new IOException("boom")).doThrow(new IOException("boom again")) - .doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - MyRetryListener myRetryListener = new MyRetryListener(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", myBackOffPolicy, false, - new RetryListener[] {}); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - RibbonApacheHttpResponse returnedResponse = client.execute(request, null); - verify(response, times(0)).close(); - verify(delegate, times(3)).execute(any(HttpUriRequest.class)); - verify(lb, times(2)).chooseServer(eq(serviceName)); - assertThat(myBackOffPolicy.getCount()).isEqualTo(2); - assertThat(myRetryListener.getOnError()).isEqualTo(0); - } - - @Test(expected = TerminatedRetryException.class) - public void retryListenerTestNoRetry() throws Exception { - int retriesNextServer = 1; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = true; - String serviceName = "listener"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doThrow(new IOException("boom")).doThrow(new IOException("boom again")) - .doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - MyRetryListenerNotRetry myRetryListenerNotRetry = new MyRetryListenerNotRetry(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", myBackOffPolicy, false, - new RetryListener[] { myRetryListenerNotRetry }); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - RibbonApacheHttpResponse returnedResponse = client.execute(request, null); - - } - - @Test - public void retryWithOriginalConstructorTest() throws Exception { - int retriesNextServer = 1; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = true; - String serviceName = "listener"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doThrow(new IOException("boom")).doThrow(new IOException("boom again")) - .doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", myBackOffPolicy, false); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - RibbonApacheHttpResponse returnedResponse = client.execute(request, null); - verify(response, times(0)).close(); - verify(delegate, times(3)).execute(any(HttpUriRequest.class)); - verify(lb, times(2)).chooseServer(eq(serviceName)); - assertThat(myBackOffPolicy.getCount()).isEqualTo(2); - } - - private RetryableRibbonLoadBalancingHttpClient setupClientForServerValidation( - String serviceName, String host, int port, CloseableHttpClient delegate, - ILoadBalancer lb) throws Exception { - ServerIntrospector introspector = mock(ServerIntrospector.class); - RetryHandler retryHandler = new DefaultLoadBalancerRetryHandler(1, 1, true); - DefaultClientConfigImpl clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(CommonClientConfigKey.OkToRetryOnAllOperations, true); - clientConfig.set(CommonClientConfigKey.MaxAutoRetriesNextServer, 0); - clientConfig.set(CommonClientConfigKey.MaxAutoRetries, 1); - clientConfig.set(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES, ""); - clientConfig.set(CommonClientConfigKey.IsSecure, false); - clientConfig.setClientName(serviceName); - RibbonLoadBalancerContext context = new RibbonLoadBalancerContext(lb, - clientConfig, retryHandler); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - doReturn(context).when(clientFactory).getLoadBalancerContext(eq(serviceName)); - doReturn(clientConfig).when(clientFactory).getClientConfig(eq(serviceName)); - LoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - RetryableRibbonLoadBalancingHttpClient client = new RetryableRibbonLoadBalancingHttpClient( - delegate, clientConfig, introspector, factory); - client.setLoadBalancer(lb); - client.setRibbonLoadBalancerContext(context); - ReflectionTestUtils.setField(client, "delegate", delegate); - return client; - } - - @Test - public void noServersFoundTest() throws Exception { - String serviceName = "noservers"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - ILoadBalancer lb = mock(ILoadBalancer.class); - - RetryableRibbonLoadBalancingHttpClient client = setupClientForServerValidation( - serviceName, host, port, delegate, lb); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(null).when(lb).chooseServer(eq(serviceName)); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - try { - client.execute(request, null); - fail("Expected IOException for no servers available"); - } - catch (ClientException ex) { - assertThat(ex.getMessage()) - .contains("Load balancer does not have available server for client"); - } - } - - @Test - public void invalidServerTest() throws Exception { - String serviceName = "noservers"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - ILoadBalancer lb = mock(ILoadBalancer.class); - - RetryableRibbonLoadBalancingHttpClient client = setupClientForServerValidation( - serviceName, host, port, delegate, lb); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(new Server(null, 8000)).when(lb).chooseServer(eq(serviceName)); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - try { - client.execute(request, null); - fail("Expected IOException for no servers available"); - } - catch (ClientException ex) { - assertThat(ex.getMessage()).contains("Invalid Server for: "); - } - } - - private RequestConfig getBuiltRequestConfig(Class defaultConfigurationClass, - IClientConfig configOverride) throws Exception { - return getBuiltRequestConfig(defaultConfigurationClass, configOverride, - new SpringClientFactory()); - } - - private RequestConfig getBuiltRequestConfig(Class defaultConfigurationClass, - IClientConfig configOverride, SpringClientFactory factory) throws Exception { - - factory.setApplicationContext( - new AnnotationConfigApplicationContext(HttpClientConfiguration.class, - RibbonAutoConfiguration.class, defaultConfigurationClass)); - String serviceName = "foo"; - String host = serviceName; - int port = 80; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - RibbonLoadBalancingHttpClient client = factory.getClient("service", - RibbonLoadBalancingHttpClient.class); - - ReflectionTestUtils.setField(client, "delegate", delegate); - ReflectionTestUtils.setField(client, "lb", loadBalancer); - CloseableHttpResponse httpResponse = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(httpResponse).getStatusLine(); - given(delegate.execute(any(HttpUriRequest.class))).willReturn(httpResponse); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - given(request.toRequest(any(RequestConfig.class))) - .willReturn(mock(HttpUriRequest.class)); - - client.execute(request, configOverride); - - ArgumentCaptor requestConfigCaptor = ArgumentCaptor - .forClass(RequestConfig.class); - verify(request, times(1)).toRequest(requestConfigCaptor.capture()); - return requestConfigCaptor.getValue(); - } - - class MyBackOffPolicy implements BackOffPolicy { - - private int count = 0; - - @Override - public BackOffContext start(RetryContext retryContext) { - return null; - } - - @Override - public void backOff(BackOffContext backOffContext) - throws BackOffInterruptedException { - count++; - } - - int getCount() { - return count; - } - - } - - class MyRetryListener implements RetryListener { - - private int onError = 0; - - int getOnError() { - return onError; - } - - @Override - public boolean open(RetryContext context, - RetryCallback callback) { - return true; - } - - @Override - public void close(RetryContext context, - RetryCallback callback, Throwable throwable) { - - } - - @Override - public void onError(RetryContext context, - RetryCallback callback, Throwable throwable) { - onError++; - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class DoNotFollowRedirects { - - @Bean - public IClientConfig clientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.FollowRedirects, false); - return config; - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class Connections { - - @Bean - public IClientConfig clientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.MaxTotalConnections, 101); - config.set(CommonClientConfigKey.MaxConnectionsPerHost, 201); - return config; - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class Timeouts { - - @Bean - public IClientConfig clientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.ConnectTimeout, 60000); - config.set(CommonClientConfigKey.ReadTimeout, 50000); - return config; - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class UseDefaults { - - } - - @Configuration(proxyBeanMethods = false) - protected static class FollowRedirects { - - @Bean - public IClientConfig clientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.FollowRedirects, true); - return config; - } - - } - - class MyRetryListenerNotRetry implements RetryListener { - - @Override - public boolean open(RetryContext context, - RetryCallback callback) { - return false; - } - - @Override - public void close(RetryContext context, - RetryCallback callback, Throwable throwable) { - - } - - @Override - public void onError(RetryContext context, - RetryCallback callback, Throwable throwable) { - - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClientTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClientTests.java deleted file mode 100644 index 6c142c9bc..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClientTests.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.okhttp; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import okhttp3.OkHttpClient; -import org.junit.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -public class OkHttpLoadBalancingClientTests { - - @Test - public void testOkHttpClientUseDefaultsNoOverride() throws Exception { - OkHttpClient result = getHttpClient(UseDefaults.class, null); - - assertThat(result.followRedirects()).isFalse(); - } - - @Test - public void testOkHttpClientDoNotFollowRedirectsNoOverride() throws Exception { - OkHttpClient result = getHttpClient(DoNotFollowRedirects.class, null); - - assertThat(result.followRedirects()).isFalse(); - } - - @Test - public void testOkHttpClientFollowRedirectsNoOverride() throws Exception { - OkHttpClient result = getHttpClient(FollowRedirects.class, null); - - assertThat(result.followRedirects()).isTrue(); - } - - @Test - public void testOkHttpClientDoNotFollowRedirectsOverrideWithFollowRedirects() - throws Exception { - - DefaultClientConfigImpl override = new DefaultClientConfigImpl(); - override.set(CommonClientConfigKey.FollowRedirects, true); - override.set(CommonClientConfigKey.IsSecure, false); - - OkHttpClient result = getHttpClient(DoNotFollowRedirects.class, override); - - assertThat(result.followRedirects()).isTrue(); - } - - @Test - public void testOkHttpClientFollowRedirectsOverrideWithDoNotFollowRedirects() - throws Exception { - - DefaultClientConfigImpl override = new DefaultClientConfigImpl(); - override.set(CommonClientConfigKey.FollowRedirects, false); - override.set(CommonClientConfigKey.IsSecure, false); - - OkHttpClient result = getHttpClient(FollowRedirects.class, override); - - assertThat(result.followRedirects()).isFalse(); - } - - @Test - public void testTimeouts() throws Exception { - OkHttpClient result = getHttpClient(Timeouts.class, null); - assertThat(result.readTimeoutMillis()).isEqualTo(50000); - assertThat(result.connectTimeoutMillis()).isEqualTo(60000); - } - - @Test - public void testDefaultTimeouts() throws Exception { - OkHttpClient result = getHttpClient(UseDefaults.class, null); - assertThat(result.readTimeoutMillis()).isEqualTo(1000); - assertThat(result.connectTimeoutMillis()).isEqualTo(1000); - } - - @Test - public void testTimeoutsOverride() throws Exception { - DefaultClientConfigImpl override = new DefaultClientConfigImpl(); - override.set(CommonClientConfigKey.ConnectTimeout, 60); - override.set(CommonClientConfigKey.ReadTimeout, 50); - OkHttpClient result = getHttpClient(Timeouts.class, override); - assertThat(result.readTimeoutMillis()).isEqualTo(50); - assertThat(result.connectTimeoutMillis()).isEqualTo(60); - } - - @Test - public void testUpdatedTimeouts() throws Exception { - SpringClientFactory factory = new SpringClientFactory(); - OkHttpClient result = getHttpClient(Timeouts.class, null, factory); - assertThat(result.readTimeoutMillis()).isEqualTo(50000); - assertThat(result.connectTimeoutMillis()).isEqualTo(60000); - IClientConfig config = factory.getClientConfig("service"); - config.set(CommonClientConfigKey.ConnectTimeout, 60); - config.set(CommonClientConfigKey.ReadTimeout, 50); - result = getHttpClient(Timeouts.class, null, factory); - assertThat(result.readTimeoutMillis()).isEqualTo(50); - assertThat(result.connectTimeoutMillis()).isEqualTo(60); - } - - private OkHttpClient getHttpClient(Class defaultConfigurationClass, - IClientConfig configOverride) throws Exception { - return getHttpClient(defaultConfigurationClass, configOverride, - new SpringClientFactory()); - } - - private OkHttpClient getHttpClient(Class defaultConfigurationClass, - IClientConfig configOverride, SpringClientFactory factory) throws Exception { - factory.setApplicationContext( - new AnnotationConfigApplicationContext(RibbonAutoConfiguration.class, - OkHttpClientConfiguration.class, defaultConfigurationClass)); - - OkHttpLoadBalancingClient client = factory.getClient("service", - OkHttpLoadBalancingClient.class); - - return client.getOkHttpClient(configOverride, false); - } - - @Configuration(proxyBeanMethods = false) - protected static class OkHttpClientConfiguration { - - @Autowired(required = false) - IClientConfig clientConfig; - - @Bean - public OkHttpLoadBalancingClient okHttpLoadBalancingClient() { - if (clientConfig == null) { - clientConfig = new DefaultClientConfigImpl(); - } - return new OkHttpLoadBalancingClient(new OkHttpClient(), clientConfig, - new DefaultServerIntrospector()); - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class UseDefaults { - - } - - @Configuration(proxyBeanMethods = false) - protected static class FollowRedirects { - - @Bean - public IClientConfig clientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.FollowRedirects, true); - return config; - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class DoNotFollowRedirects { - - @Bean - public IClientConfig clientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.FollowRedirects, false); - return config; - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class Timeouts { - - @Bean - public IClientConfig clientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.ConnectTimeout, 60000); - config.set(CommonClientConfigKey.ReadTimeout, 50000); - return config; - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonRequestTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonRequestTests.java deleted file mode 100644 index 857fd7ccf..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonRequestTests.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.okhttp; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; - -import okhttp3.Request; -import okhttp3.RequestBody; -import okio.Buffer; -import org.junit.Test; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer; -import org.springframework.util.LinkedMultiValueMap; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -public class OkHttpRibbonRequestTests { - - @Test - public void testNullEntity() throws Exception { - String uri = "https://example.com"; - LinkedMultiValueMap headers = new LinkedMultiValueMap<>(); - headers.add("my-header", "my-value"); - // headers.add(HttpEncoding.CONTENT_LENGTH, "5192"); - LinkedMultiValueMap params = new LinkedMultiValueMap<>(); - params.add("myparam", "myparamval"); - RibbonCommandContext context = new RibbonCommandContext("example", "GET", uri, - false, headers, params, null, new ArrayList()); - OkHttpRibbonRequest httpRequest = new OkHttpRibbonRequest(context); - - Request request = httpRequest.toRequest(); - - assertThat(request.body()).as("body is not null").isNull(); - assertThat(request.url().toString()).as("uri is wrong").startsWith(uri); - assertThat(request.header("my-header")).as("my-header is wrong") - .isEqualTo("my-value"); - assertThat(request.url().queryParameter("myparam")).as("myparam is missing") - .isEqualTo("myparamval"); - } - - @Test - // this situation happens, see - // https://github.com/spring-cloud/spring-cloud-netflix/issues/1042#issuecomment-227723877 - public void testEmptyEntityGet() throws Exception { - String entityValue = ""; - testEntity(entityValue, new ByteArrayInputStream(entityValue.getBytes()), false, - "GET"); - } - - @Test - public void testNonEmptyEntityPost() throws Exception { - String entityValue = "abcd"; - testEntity(entityValue, new ByteArrayInputStream(entityValue.getBytes()), true, - "POST"); - } - - void testEntity(String entityValue, ByteArrayInputStream requestEntity, - boolean addContentLengthHeader, String method) throws IOException { - String lengthString = String.valueOf(entityValue.length()); - Long length = null; - String uri = "https://example.com"; - LinkedMultiValueMap headers = new LinkedMultiValueMap<>(); - if (addContentLengthHeader) { - headers.add("Content-Length", lengthString); - length = (long) entityValue.length(); - } - - RibbonRequestCustomizer requestCustomizer = new RibbonRequestCustomizer() { - @Override - public boolean accepts(Class builderClass) { - return builderClass == Request.Builder.class; - } - - @Override - public void customize(Request.Builder builder) { - builder.addHeader("from-customizer", "foo"); - } - }; - RibbonCommandContext context = new RibbonCommandContext("example", method, uri, - false, headers, new LinkedMultiValueMap(), requestEntity, - Collections.singletonList(requestCustomizer)); - context.setContentLength(length); - OkHttpRibbonRequest httpRequest = new OkHttpRibbonRequest(context); - - Request request = httpRequest.toRequest(); - - assertThat(request.url().toString()).as("uri is wrong").startsWith(uri); - if (addContentLengthHeader) { - assertThat(request.header("Content-Length")).as("Content-Length is wrong") - .isEqualTo(lengthString); - } - assertThat(request.header("from-customizer")).as("from-customizer is wrong") - .isEqualTo("foo"); - - if (!method.equalsIgnoreCase("get")) { - assertThat(request.body()).as("body is null").isNotNull(); - RequestBody body = request.body(); - assertThat(body.contentLength()).as("contentLength is wrong") - .isEqualTo((long) entityValue.length()); - Buffer content = new Buffer(); - body.writeTo(content); - String string = content.readByteString().utf8(); - assertThat(string).as("content is wrong").isEqualTo(entityValue); - } - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonResponseTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonResponseTests.java deleted file mode 100644 index 91b0144d3..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonResponseTests.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.okhttp; - -import java.net.URI; - -import okhttp3.HttpUrl; -import okhttp3.MediaType; -import okhttp3.Protocol; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.ResponseBody; -import org.junit.Test; - -import org.springframework.http.HttpStatus; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -public class OkHttpRibbonResponseTests { - - @Test - public void testNullEntity() throws Exception { - URI uri = URI.create("https://example.com"); - Response response = response(uri).build(); - - OkHttpRibbonResponse httpResponse = new OkHttpRibbonResponse(response, uri); - - assertThat(httpResponse.isSuccess()).isTrue(); - assertThat(httpResponse.hasPayload()).isFalse(); - assertThat(httpResponse.getPayload()).isNull(); - assertThat(httpResponse.getInputStream()).isNull(); - } - - @Test - public void testNotNullEntity() throws Exception { - URI uri = URI.create("https://example.com"); - Response response = response(uri) - .body(ResponseBody.create(MediaType.parse("text/plain"), "abcd")).build(); - - OkHttpRibbonResponse httpResponse = new OkHttpRibbonResponse(response, uri); - - assertThat(httpResponse.isSuccess()).isTrue(); - assertThat(httpResponse.hasPayload()).isTrue(); - assertThat(httpResponse.getPayload()).isNotNull(); - assertThat(httpResponse.getInputStream()).isNotNull(); - } - - Response.Builder response(URI uri) { - return new Response.Builder() - .request(new Request.Builder().url(HttpUrl.get(uri)).build()) - .protocol(Protocol.HTTP_1_1).code(HttpStatus.OK.value()) - .message(HttpStatus.OK.getReasonPhrase()); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryDisableOkHttpClientTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryDisableOkHttpClientTests.java deleted file mode 100644 index f1ac67ff7..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryDisableOkHttpClientTests.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.okhttp; - -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - * @author Biju Kunjummen - */ -@RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({ "spring-retry-*.jar", "spring-boot-starter-aop-*.jar" }) -public class SpringRetryDisableOkHttpClientTests { - - @Test - public void testLoadBalancedRetryFactoryBean() { - new ApplicationContextRunner().withPropertyValues("ribbon.okhttp.enabled=true") - .withConfiguration(AutoConfigurations.of(RibbonAutoConfiguration.class, - LoadBalancerAutoConfiguration.class, - HttpClientConfiguration.class, RibbonClientConfiguration.class)) - .withUserConfiguration( - OkHttpLoadBalancingClientTests.OkHttpClientConfiguration.class) - .run(context -> { - Map factories = context - .getBeansOfType(LoadBalancedRetryFactory.class); - assertThat(factories.values()).hasSize(0); - Map clients = context - .getBeansOfType(OkHttpLoadBalancingClient.class); - assertThat(clients.values()).hasSize(1); - assertThat(clients.values().toArray()[0]) - .isInstanceOf(OkHttpLoadBalancingClient.class); - }); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryEnabledOkHttpClientTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryEnabledOkHttpClientTests.java deleted file mode 100644 index 211367785..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryEnabledOkHttpClientTests.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.okhttp; - -import java.net.URI; -import java.util.Map; - -import com.netflix.client.ClientException; -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.Server; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.BeansException; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryFactory; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicy; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.http.HttpMethod; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest({ "ribbon.okhttp.enabled: true", "ribbon.httpclient.enabled: false" }) -@ContextConfiguration( - classes = { RibbonAutoConfiguration.class, HttpClientConfiguration.class, - RibbonClientConfiguration.class, LoadBalancerAutoConfiguration.class }) -public class SpringRetryEnabledOkHttpClientTests implements ApplicationContextAware { - - private ApplicationContext context; - - private ILoadBalancer loadBalancer; - - @Test - public void testLoadBalancedRetryFactoryBean() throws Exception { - Map factories = context - .getBeansOfType(LoadBalancedRetryFactory.class); - assertThat(factories.values()).hasSize(1); - assertThat(factories.values().toArray()[0]) - .isInstanceOf(RibbonLoadBalancedRetryFactory.class); - Map clients = context - .getBeansOfType(OkHttpLoadBalancingClient.class); - assertThat(clients.values()).hasSize(1); - assertThat(clients.values().toArray()[0]) - .isInstanceOf(RetryableOkHttpLoadBalancingClient.class); - - RibbonLoadBalancerContext ribbonLoadBalancerContext = (RibbonLoadBalancerContext) ReflectionTestUtils - .getField(clients.values().toArray()[0], - RetryableOkHttpLoadBalancingClient.class, - "ribbonLoadBalancerContext"); - assertThat(ribbonLoadBalancerContext).as( - "RetryableOkHttpLoadBalancingClient.ribbonLoadBalancerContext should not be null") - .isNotNull(); - - } - - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - this.context = context; - } - - private RetryableOkHttpLoadBalancingClient setupClientForServerValidation( - String serviceName, String host, int port, OkHttpClient delegate, - ILoadBalancer lb) throws Exception { - ServerIntrospector introspector = mock(ServerIntrospector.class); - RetryHandler retryHandler = new DefaultLoadBalancerRetryHandler(1, 1, true); - DefaultClientConfigImpl clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(CommonClientConfigKey.OkToRetryOnAllOperations, true); - clientConfig.set(CommonClientConfigKey.MaxAutoRetriesNextServer, 0); - clientConfig.set(CommonClientConfigKey.MaxAutoRetries, 1); - clientConfig.set(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES, ""); - clientConfig.set(CommonClientConfigKey.IsSecure, false); - clientConfig.setClientName(serviceName); - RibbonLoadBalancerContext context = new RibbonLoadBalancerContext(lb, - clientConfig, retryHandler); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - doReturn(context).when(clientFactory).getLoadBalancerContext(eq(serviceName)); - doReturn(clientConfig).when(clientFactory).getClientConfig(eq(serviceName)); - LoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - RetryableOkHttpLoadBalancingClient client = new RetryableOkHttpLoadBalancingClient( - delegate, clientConfig, introspector, factory); - client.setLoadBalancer(lb); - ReflectionTestUtils.setField(client, "delegate", delegate); - return client; - } - - @Test - public void noServersFoundTest() throws Exception { - String serviceName = "noservers"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - OkHttpClient delegate = mock(OkHttpClient.class); - ILoadBalancer lb = mock(ILoadBalancer.class); - - RetryableOkHttpLoadBalancingClient client = setupClientForServerValidation( - serviceName, host, port, delegate, lb); - OkHttpRibbonRequest request = mock(OkHttpRibbonRequest.class); - doReturn(null).when(lb).chooseServer(eq(serviceName)); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - Request okRequest = new Request.Builder().url("ws:testerror.sc").build(); - doReturn(okRequest).when(request).toRequest(); - try { - client.execute(request, null); - fail("Expected ClientException for no servers available"); - } - catch (ClientException ex) { - assertThat(ex.getMessage()) - .contains("Load balancer does not have available server for client"); - } - } - - @Test - public void invalidServerTest() throws Exception { - String serviceName = "noservers"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - OkHttpClient delegate = mock(OkHttpClient.class); - ILoadBalancer lb = mock(ILoadBalancer.class); - - RetryableOkHttpLoadBalancingClient client = setupClientForServerValidation( - serviceName, host, port, delegate, lb); - OkHttpRibbonRequest request = mock(OkHttpRibbonRequest.class); - doReturn(new Server(null, 8000)).when(lb).chooseServer(eq(serviceName)); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - Request okRequest = new Request.Builder().url("ws:testerror.sc").build(); - doReturn(okRequest).when(request).toRequest(); - - try { - client.execute(request, null); - fail("Expected ClientException for no Invalid Host"); - } - catch (ClientException ex) { - assertThat(ex.getMessage()).contains("Invalid Server for: "); - } - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequestTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequestTests.java deleted file mode 100644 index 9e534b8ef..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequestTests.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.support; - -import java.net.URI; -import java.util.Arrays; -import java.util.Collections; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * @author Ryan Baxter - */ -public class ContextAwareRequestTests { - - private RibbonCommandContext context; - - private ContextAwareRequest request; - - @Before - public void setUp() throws Exception { - context = mock(RibbonCommandContext.class); - doReturn("GET").when(context).getMethod(); - MultiValueMap headers = new LinkedMultiValueMap<>(); - headers.put("header1", Collections.emptyList()); - headers.put("header2", Arrays.asList("value1", "value2")); - headers.put("header3", Arrays.asList("value1")); - doReturn(headers).when(context).getHeaders(); - doReturn(new URI("https://foo")).when(context).uri(); - doReturn("foo").when(context).getServiceId(); - doReturn(new LinkedMultiValueMap<>()).when(context).getParams(); - doReturn("testLoadBalancerKey").when(context).getLoadBalancerKey(); - request = new TestContextAwareRequest(context); - } - - @After - public void tearDown() throws Exception { - context = null; - request = null; - } - - @Test - public void getContext() throws Exception { - assertThat(request.getContext()).isEqualTo(context); - } - - @Test - public void getMethod() throws Exception { - assertThat(request.getMethod()).isEqualTo(HttpMethod.GET); - } - - @Test - public void getURI() throws Exception { - assertThat(request.getURI()).isEqualTo(new URI("https://foo")); - - RibbonCommandContext badUriContext = mock(RibbonCommandContext.class); - doReturn(new LinkedMultiValueMap()).when(badUriContext).getHeaders(); - doReturn("foobar").when(badUriContext).getUri(); - ContextAwareRequest badUriRequest = new TestContextAwareRequest(badUriContext); - - assertThat(badUriRequest.getURI()).isNull(); - - } - - @Test - public void getHeaders() throws Exception { - HttpHeaders headers = new HttpHeaders(); - headers.put("header1", Collections.emptyList()); - headers.put("header2", Arrays.asList("value1", "value2")); - headers.put("header3", Arrays.asList("value1")); - assertThat(request.getHeaders()).isEqualTo(headers); - } - - @Test - public void getLoadBalancerKey() throws Exception { - assertThat(request.getLoadBalancerKey()).isEqualTo("testLoadBalancerKey"); - - RibbonCommandContext defaultContext = mock(RibbonCommandContext.class); - doReturn(new LinkedMultiValueMap()).when(defaultContext).getHeaders(); - doReturn(null).when(defaultContext).getLoadBalancerKey(); - ContextAwareRequest defaultRequest = new TestContextAwareRequest(defaultContext); - - assertThat(defaultRequest.getLoadBalancerKey()).isNull(); - } - - static class TestContextAwareRequest extends ContextAwareRequest { - - TestContextAwareRequest(RibbonCommandContext context) { - super(context); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/support/RibbonCommandContextTest.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/support/RibbonCommandContextTest.java deleted file mode 100644 index d6c1a671b..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/support/RibbonCommandContextTest.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.support; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collections; - -import okhttp3.Request; -import org.junit.Test; - -import org.springframework.http.HttpMethod; -import org.springframework.util.LinkedMultiValueMap; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Andre Dörnbrack - */ -public class RibbonCommandContextTest { - - private static final byte[] TEST_CONTENT = { 42, 42, 42, 42, 42 }; - - private RibbonCommandContext ribbonCommandContext; - - @Test - public void testMultipleReadsOnRequestEntity() throws Exception { - givenRibbonCommandContextIsSetup(); - - InputStream requestEntity = ribbonCommandContext.getRequestEntity(); - assertThat(requestEntity instanceof ResettableServletInputStreamWrapper).isTrue(); - - whenInputStreamIsConsumed(requestEntity); - assertThat(requestEntity.read()).isEqualTo(-1); - - requestEntity.reset(); - assertThat(requestEntity.read()).isNotEqualTo(-1); - - whenInputStreamIsConsumed(requestEntity); - assertThat(requestEntity.read()).isEqualTo(-1); - - requestEntity.reset(); - assertThat(requestEntity.read()).isNotEqualTo(-1); - - whenInputStreamIsConsumed(requestEntity); - assertThat(requestEntity.read()).isEqualTo(-1); - } - - private void whenInputStreamIsConsumed(InputStream requestEntity) throws IOException { - while (requestEntity.read() != -1) { - requestEntity.read(); - } - } - - private void givenRibbonCommandContextIsSetup() { - LinkedMultiValueMap headers = new LinkedMultiValueMap(); - LinkedMultiValueMap params = new LinkedMultiValueMap(); - - RibbonRequestCustomizer requestCustomizer = new RibbonRequestCustomizer() { - @Override - public boolean accepts(Class builderClass) { - return builderClass == Request.Builder.class; - } - - @Override - public void customize(Request.Builder builder) { - builder.addHeader("from-customizer", "foo"); - } - }; - - ribbonCommandContext = new RibbonCommandContext("serviceId", - HttpMethod.POST.toString(), "/my/route", true, headers, params, - new ByteArrayInputStream(TEST_CONTENT), - Collections.singletonList(requestCustomizer)); - } - - @Test - public void testNullSafetyWithNullableParameters() throws Exception { - LinkedMultiValueMap headers = new LinkedMultiValueMap(); - LinkedMultiValueMap params = new LinkedMultiValueMap(); - - RibbonCommandContext testContext = new RibbonCommandContext("serviceId", - HttpMethod.POST.toString(), "/my/route", true, headers, params, - new ByteArrayInputStream(TEST_CONTENT), - Collections.emptyList(), null, null); - - assertThat(testContext.hashCode()).isNotEqualTo(0); - assertThat(testContext.toString()).isNotNull(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/RibbonClientDefaultConfigurationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/RibbonClientDefaultConfigurationTests.java deleted file mode 100644 index 9a4aa2623..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/RibbonClientDefaultConfigurationTests.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.test; - -import com.netflix.loadbalancer.BestAvailableRule; -import com.netflix.loadbalancer.PingUrl; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerListSubsetFilter; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.test.RibbonClientDefaultConfigurationTestsConfig.BazServiceList; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RibbonClientDefaultConfigurationTestsConfig.class, - value = "ribbon.eureka.enabled=true") -@DirtiesContext -public class RibbonClientDefaultConfigurationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void ruleOverridesDefault() throws Exception { - assertThat(getLoadBalancer("baz").getRule()).as("wrong rule type") - .isInstanceOf(BestAvailableRule.class); - } - - @Test - public void pingOverridesDefault() throws Exception { - assertThat(getLoadBalancer("baz").getPing()).as("wrong ping type") - .isInstanceOf(PingUrl.class); - } - - @Test - public void serverListOverridesDefault() throws Exception { - assertThat(getLoadBalancer("baz").getServerListImpl()) - .as("wrong server list type").isInstanceOf(BazServiceList.class); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer(String name) { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer(name); - } - - @Test - public void serverListFilterOverride() throws Exception { - assertThat(getLoadBalancer("baz").getFilter()).as("wrong filter type") - .isInstanceOf(ServerListSubsetFilter.class); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/RibbonClientDefaultConfigurationTestsConfig.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/RibbonClientDefaultConfigurationTestsConfig.java deleted file mode 100644 index 2c062223c..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/RibbonClientDefaultConfigurationTestsConfig.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.test; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.BestAvailableRule; -import com.netflix.loadbalancer.ConfigurationBasedServerList; -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.IRule; -import com.netflix.loadbalancer.PingUrl; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.loadbalancer.ServerListSubsetFilter; - -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - UtilAutoConfiguration.class, RibbonAutoConfiguration.class, - HttpClientConfiguration.class }) -// tag::sample_default_ribbon_config[] -@RibbonClients(defaultConfiguration = DefaultRibbonConfig.class) -public class RibbonClientDefaultConfigurationTestsConfig { - - public static class BazServiceList extends ConfigurationBasedServerList { - - public BazServiceList(IClientConfig config) { - super.initWithNiwsConfig(config); - } - - } - -} - -@Configuration(proxyBeanMethods = false) -class DefaultRibbonConfig { - - @Bean - public IRule ribbonRule() { - return new BestAvailableRule(); - } - - @Bean - public IPing ribbonPing() { - return new PingUrl(); - } - - @Bean - public ServerList ribbonServerList(IClientConfig config) { - return new RibbonClientDefaultConfigurationTestsConfig.BazServiceList(config); - } - - @Bean - public ServerListSubsetFilter serverListFilter() { - ServerListSubsetFilter filter = new ServerListSubsetFilter(); - return filter; - } - -} -// end::sample_default_ribbon_config[] diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestAutoConfiguration.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestAutoConfiguration.java deleted file mode 100644 index b03118c97..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestAutoConfiguration.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.test; - -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@Import({ NoopDiscoveryClientAutoConfiguration.class }) -@AutoConfigureBefore(SecurityAutoConfiguration.class) -public class TestAutoConfiguration { - - /** - * User name - */ - public static final String USER = "user"; - - /** - * Password - */ - public static final String PASSWORD = "{noop}password"; - - @Configuration(proxyBeanMethods = false) - @Order(Ordered.HIGHEST_PRECEDENCE) - static class TestSecurityConfiguration extends WebSecurityConfigurerAdapter { - - TestSecurityConfiguration() { - super(true); - } - - @Bean - public UserDetailsService userDetailsService() { - InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); - manager.createUser( - User.withUsername(USER).password(PASSWORD).roles("USER").build()); - return manager; - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - // super.configure(http); - http.antMatcher("/proxy-username").httpBasic().and().authorizeRequests() - .antMatchers("/**").permitAll(); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestLoadBalancer.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestLoadBalancer.java deleted file mode 100644 index ab73e5309..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestLoadBalancer.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.test; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; - -/** - * @author Spencer Gibb - */ -public class TestLoadBalancer extends ZoneAwareLoadBalancer { - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestServerList.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestServerList.java deleted file mode 100644 index 4595dc197..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestServerList.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.ribbon.test; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; - -/** - * @author Spencer Gibb - */ -public class TestServerList implements ServerList { - - private final List servers; - - public TestServerList() { - this.servers = new ArrayList<>(); - } - - public void add(T server) { - this.servers.add(server); - } - - @Override - public List getInitialListOfServers() { - return servers; - } - - @Override - public List getUpdatedListOfServers() { - return servers; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/resources/META-INF/spring.factories b/spring-cloud-netflix-ribbon/src/test/resources/META-INF/spring.factories deleted file mode 100644 index 8e405ed6e..000000000 --- a/spring-cloud-netflix-ribbon/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.ribbon.test.TestAutoConfiguration diff --git a/spring-cloud-netflix-ribbon/src/test/resources/application.yml b/spring-cloud-netflix-ribbon/src/test/resources/application.yml deleted file mode 100644 index 30a3f68a6..000000000 --- a/spring-cloud-netflix-ribbon/src/test/resources/application.yml +++ /dev/null @@ -1,8 +0,0 @@ -# for RibbonClientPreprocessorPropertiesOverridesIntegrationTests -foo2: - ribbon: - NFLoadBalancerPingClassName: com.netflix.loadbalancer.NoOpPing - NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule - NIWSServerListClassName: org.springframework.cloud.netflix.ribbon.test.TestServerList - NIWSServerListFilterClassName: com.netflix.loadbalancer.ServerListSubsetFilter - NFLoadBalancerClassName: org.springframework.cloud.netflix.ribbon.test.TestLoadBalancer diff --git a/spring-cloud-netflix-sidecar/pom.xml b/spring-cloud-netflix-sidecar/pom.xml deleted file mode 100644 index 5b616a3b8..000000000 --- a/spring-cloud-netflix-sidecar/pom.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - spring-cloud-netflix-sidecar - jar - Spring Cloud Netflix Sidecar - https://projects.spring.io/spring-cloud/ - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework.cloud - spring-cloud-context - - - org.springframework.cloud - spring-cloud-netflix-zuul - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework - spring-web - - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.springframework.cloud - spring-cloud-netflix-eureka-client - - - com.netflix.eureka - eureka-client - - - com.netflix.hystrix - hystrix-core - - - com.netflix.hystrix - hystrix-metrics-event-stream - - - com.netflix.hystrix - hystrix-javanica - - - com.netflix.ribbon - ribbon - - - com.netflix.ribbon - ribbon-core - - - com.netflix.ribbon - ribbon-eureka - - - com.netflix.ribbon - ribbon-httpclient - - - com.netflix.zuul - zuul-core - - - org.apache.tomcat.embed - tomcat-embed-el - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.cloud - spring-cloud-config-client - test - - - diff --git a/spring-cloud-netflix-sidecar/run-server.sh b/spring-cloud-netflix-sidecar/run-server.sh deleted file mode 100755 index 8bacc042a..000000000 --- a/spring-cloud-netflix-sidecar/run-server.sh +++ /dev/null @@ -1 +0,0 @@ -python -m SimpleHTTPServer diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/EnableSidecar.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/EnableSidecar.java deleted file mode 100644 index 255de4239..000000000 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/EnableSidecar.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2013-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.context.annotation.Import; - -/** - * @author Spencer Gibb - */ -@EnableCircuitBreaker -@EnableZuulProxy -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Import(SidecarMarkerConfiguration.class) -public @interface EnableSidecar { - -} diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandler.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandler.java deleted file mode 100644 index cd525bc7e..000000000 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandler.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import com.netflix.appinfo.HealthCheckHandler; -import com.netflix.appinfo.InstanceInfo.InstanceStatus; - -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; - -import static com.netflix.appinfo.InstanceInfo.InstanceStatus.DOWN; -import static com.netflix.appinfo.InstanceInfo.InstanceStatus.OUT_OF_SERVICE; -import static com.netflix.appinfo.InstanceInfo.InstanceStatus.UNKNOWN; -import static com.netflix.appinfo.InstanceInfo.InstanceStatus.UP; - -/** - * Eureka HealthCheckHandler that translates boot health status to InstanceStatus so the - * proper status of the non-JVM app is sent to Eureka. - * - * @author Spencer Gibb - */ -class LocalApplicationHealthCheckHandler implements HealthCheckHandler { - - private final HealthIndicator healthIndicator; - - LocalApplicationHealthCheckHandler(HealthIndicator healthIndicator) { - this.healthIndicator = healthIndicator; - } - - @Override - public InstanceStatus getStatus(InstanceStatus currentStatus) { - Status status = healthIndicator.health().getStatus(); - if (status.equals(Status.UP)) { - return UP; - } - else if (status.equals(Status.OUT_OF_SERVICE)) { - return OUT_OF_SERVICE; - } - else if (status.equals(Status.DOWN)) { - return DOWN; - } - return UNKNOWN; - } - -} diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthIndicator.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthIndicator.java deleted file mode 100644 index 947b29b9e..000000000 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthIndicator.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import java.net.URI; -import java.util.Map; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.web.client.RestTemplate; - -/** - * @author Spencer Gibb - * @author Fabrizio Di Napoli - */ -public class LocalApplicationHealthIndicator extends AbstractHealthIndicator { - - @Autowired - private SidecarProperties properties; - - @Autowired - private RestTemplate restTemplate; - - @SuppressWarnings("unchecked") - @Override - protected void doHealthCheck(Health.Builder builder) throws Exception { - URI uri = this.properties.getHealthUri(); - if (uri == null) { - builder.up(); - return; - } - - Map map = restTemplate.getForObject(uri, Map.class); - Object status = map.get("status"); - if (status instanceof String) { - builder.status(status.toString()); - } - else if (status instanceof Map) { - Map statusMap = (Map) status; - Object code = statusMap.get("code"); - if (code != null) { - builder.status(code.toString()); - } - else { - getWarning(builder); - } - } - else { - getWarning(builder); - } - } - - private Health.Builder getWarning(Health.Builder builder) { - return builder.unknown().withDetail("warning", "no status field in response"); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarAutoConfiguration.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarAutoConfiguration.java deleted file mode 100644 index 4211e06a8..000000000 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarAutoConfiguration.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import java.util.Map; - -import com.netflix.appinfo.HealthCheckHandler; -import com.netflix.discovery.EurekaClientConfig; -import org.apache.http.client.HttpClient; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.commons.util.InetUtils; -import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.cloud.netflix.eureka.metadata.DefaultManagementMetadataProvider; -import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadata; -import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadataProvider; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.util.StringUtils; -import org.springframework.web.client.RestTemplate; - -import static org.springframework.cloud.commons.util.IdUtils.getDefaultInstanceId; - -/** - * Sidecar Configuration that setting up {@link com.netflix.appinfo.EurekaInstanceConfig}. - *

- * Depends on {@link SidecarProperties} and {@code eureka.instance.hostname} property. - * Since there is two way to configure hostname: - *

    - *
  1. {@code eureka.instance.hostname} property
  2. - *
  3. {@link SidecarProperties#hostname}
  4. - *
- * {@code eureka.instance.hostname} will always win against - * {@link SidecarProperties#hostname} due to - * {@code @ConfigurationProperties("eureka.instance")} on - * {@link EurekaInstanceConfigBeanConfiguration}. - * - * @author Spencer Gibb - * @author Ryan Baxter - * @author Fabrizio Di Napoli - * @see EurekaInstanceConfigBeanConfiguration - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnBean(SidecarMarkerConfiguration.Marker.class) -@EnableConfigurationProperties(SidecarProperties.class) -@AutoConfigureBefore(EurekaClientAutoConfiguration.class) -@ConditionalOnProperty(value = "spring.cloud.netflix.sidecar.enabled", - matchIfMissing = true) -public class SidecarAutoConfiguration { - - @Bean - public HasFeatures Feature() { - return HasFeatures.namedFeature("Netflix Sidecar", - SidecarAutoConfiguration.class); - } - - @Bean - @ConditionalOnMissingClass("org.apache.http.client.HttpClient") - public RestTemplate restTemplate() { - return new RestTemplateBuilder().build(); - } - - @Bean - @ConditionalOnClass(HttpClient.class) - public RestTemplate sslRestTemplate(SidecarProperties properties) { - RestTemplateBuilder builder = new RestTemplateBuilder(); - if (properties.acceptAllSslCertificates()) { - CloseableHttpClient httpClient = HttpClients.custom() - .setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); - HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); - requestFactory.setHttpClient(httpClient); - builder = builder.requestFactory(() -> requestFactory); - } - return builder.build(); - } - - @Bean - public LocalApplicationHealthIndicator localApplicationHealthIndicator() { - return new LocalApplicationHealthIndicator(); - } - - @Bean - public SidecarController sidecarController() { - return new SidecarController(); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(EurekaClientConfig.class) - protected static class EurekaInstanceConfigBeanConfiguration { - - @Autowired - private SidecarProperties sidecarProperties; - - @Autowired - private InetUtils inetUtils; - - @Value("${management.server.port:${MANAGEMENT_PORT:#{null}}}") - private Integer managementPort; - - @Value("${server.port:${SERVER_PORT:${PORT:8080}}}") - private int serverPort = 8080; - - @Value("${management.server.servlet.context-path:${MANAGEMENT_CONTEXT_PATH:#{null}}}") - private String managementContextPath; - - @Value("${server.servlet.context-path:${SERVER_CONTEXT_PATH:/}}") - private String serverContextPath = "/"; - - @Value("${eureka.instance.hostname:${EUREKA_INSTANCE_HOSTNAME:}}") - private String hostname; - - @Autowired - private ConfigurableEnvironment env; - - @Bean - @ConditionalOnMissingBean - public ManagementMetadataProvider serviceManagementMetadataProvider() { - return new DefaultManagementMetadataProvider(); - } - - @Bean - @ConditionalOnMissingBean - public EurekaInstanceConfigBean eurekaInstanceConfigBean( - ManagementMetadataProvider managementMetadataProvider) { - EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inetUtils); - String springAppName = this.env.getProperty("spring.application.name", ""); - int port = this.sidecarProperties.getPort(); - config.setNonSecurePort(port); - config.setSecurePortEnabled(this.sidecarProperties.isSecurePortEnabled()); - config.setInstanceId(getDefaultInstanceId(this.env)); - if (StringUtils.hasText(springAppName)) { - config.setAppname(springAppName); - config.setVirtualHostName(springAppName); - config.setSecureVirtualHostName(springAppName); - } - String hostname = this.sidecarProperties.getHostname(); - String ipAddress = this.sidecarProperties.getIpAddress(); - if (!StringUtils.hasText(hostname) && StringUtils.hasText(this.hostname)) { - hostname = this.hostname; - } - if (StringUtils.hasText(hostname)) { - config.setHostname(hostname); - } - if (StringUtils.hasText(ipAddress)) { - config.setIpAddress(ipAddress); - } - String scheme = config.getSecurePortEnabled() ? "https" : "http"; - ManagementMetadata metadata = managementMetadataProvider.get(config, - serverPort, serverContextPath, managementContextPath, managementPort); - - if (metadata != null) { - config.setStatusPageUrl(metadata.getStatusPageUrl()); - config.setHealthCheckUrl(metadata.getHealthCheckUrl()); - if (config.isSecurePortEnabled()) { - config.setSecureHealthCheckUrl(metadata.getSecureHealthCheckUrl()); - } - Map metadataMap = config.getMetadataMap(); - metadataMap.computeIfAbsent("management.port", - k -> String.valueOf(metadata.getManagementPort())); - } - config.setHomePageUrl(scheme + "://" + config.getHostname() + ":" + port - + config.getHomePageUrlPath()); - return config; - } - - @Bean - public HealthCheckHandler healthCheckHandler( - final LocalApplicationHealthIndicator healthIndicator) { - return new LocalApplicationHealthCheckHandler(healthIndicator); - } - - } - -} diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarController.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarController.java deleted file mode 100644 index d5dbe3cdd..000000000 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarController.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2013-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -/** - * @author Spencer Gibb - */ -@RestController -public class SidecarController { - - @Autowired - private DiscoveryClient discovery; - - @Value("${spring.application.name}") - private String appName; - - @RequestMapping("/ping") - public String ping() { - return "OK"; - } - - @RequestMapping("/hosts/{appName}") - public List hosts(@PathVariable("appName") String appName) { - return hosts2(appName); - } - - @RequestMapping("/hosts") - public List hosts2(@RequestParam("appName") String appName) { - List instances = this.discovery.getInstances(appName); - return instances; - } - - @RequestMapping(value = "/", produces = "text/html") - public String home() { - return "Sidecar\n" - + "ping
\n" - + "health
\n" + "hosts/" + this.appName + "
\n" + ""; - } - -} diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarMarkerConfiguration.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarMarkerConfiguration.java deleted file mode 100644 index 0c1fb02d1..000000000 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarMarkerConfiguration.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Annotation to activate Eureka Server related configuration. - * {@link SidecarAutoConfiguration} - * - * @author Greg Adams - */ -@Configuration(proxyBeanMethods = false) -public class SidecarMarkerConfiguration { - - @Bean - public Marker sidecarMarkerBean() { - return new Marker(); - } - - class Marker { - - } - -} diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarProperties.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarProperties.java deleted file mode 100644 index 7968e7670..000000000 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarProperties.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import java.net.URI; -import java.util.Objects; - -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Spencer Gibb - * @author Gregor Zurowski - * @author Fabrizio Di Napoli - */ -@ConfigurationProperties("sidecar") -public class SidecarProperties { - - private URI healthUri; - - private URI homePageUri; - - @Max(65535) - @Min(1) - private int port; - - private String hostname; - - private String ipAddress; - - private boolean acceptAllSslCertificates; - - private boolean securePortEnabled; - - public boolean isSecurePortEnabled() { - return securePortEnabled; - } - - public void setSecurePortEnabled(boolean securePortEnabled) { - this.securePortEnabled = securePortEnabled; - } - - public URI getHealthUri() { - return healthUri; - } - - public void setHealthUri(URI healthUri) { - this.healthUri = healthUri; - } - - public URI getHomePageUri() { - return homePageUri; - } - - public void setHomePageUri(URI homePageUri) { - this.homePageUri = homePageUri; - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - public String getHostname() { - return hostname; - } - - public void setHostname(String hostname) { - this.hostname = hostname; - } - - public String getIpAddress() { - return ipAddress; - } - - public void setIpAddress(String ipAddress) { - this.ipAddress = ipAddress; - } - - public boolean acceptAllSslCertificates() { - return acceptAllSslCertificates; - } - - public void setAcceptAllSslCertificates(boolean acceptAllSslCertificates) { - this.acceptAllSslCertificates = acceptAllSslCertificates; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SidecarProperties that = (SidecarProperties) o; - return Objects.equals(healthUri, that.healthUri) - && Objects.equals(homePageUri, that.homePageUri) && port == that.port - && Objects.equals(securePortEnabled, that.securePortEnabled) - && Objects.equals(hostname, that.hostname) - && Objects.equals(ipAddress, that.ipAddress) && Objects - .equals(acceptAllSslCertificates, that.acceptAllSslCertificates); - } - - @Override - public int hashCode() { - return Objects.hash(healthUri, homePageUri, port, hostname, ipAddress, - acceptAllSslCertificates, securePortEnabled); - } - - @Override - public String toString() { - return new StringBuilder("SidecarProperties{").append("healthUri=") - .append(healthUri).append(", ").append("homePageUri=").append(homePageUri) - .append(", ").append("port=").append(port).append(", ") - .append("hostname='").append(hostname).append("', ").append("ipAddress='") - .append(ipAddress).append("', ").append("securePortEnabled='") - .append(securePortEnabled).append("', ") - .append("acceptAllSslCertificates='").append(acceptAllSslCertificates) - .append("'}").toString(); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-sidecar/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 17e18fd22..000000000 --- a/spring-cloud-netflix-sidecar/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - org.springframework.cloud.netflix.sidecar.SidecarAutoConfiguration \ No newline at end of file diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/AcceptAllSslCertificatesContextTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/AcceptAllSslCertificatesContextTests.java deleted file mode 100644 index 358ae6061..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/AcceptAllSslCertificatesContextTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import java.lang.reflect.Field; -import java.util.Map; - -import javax.net.ssl.HostnameVerifier; - -import org.apache.http.config.Registry; -import org.apache.http.conn.ssl.DefaultHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.conn.DefaultHttpClientConnectionOperator; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "sidecar.accept-all-ssl-certificates=false" }) -public class AcceptAllSslCertificatesContextTests { - - @Autowired - RestTemplate restTemplate; - - @Test - public void testUseRestTemplateWhenHttpClientIsNotAvailable() { - HttpComponentsClientHttpRequestFactory requestFactory = (HttpComponentsClientHttpRequestFactory) restTemplate - .getRequestFactory(); - CloseableHttpClient client = (CloseableHttpClient) requestFactory.getHttpClient(); - PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = getHttpClientConnectionManager( - client); - DefaultHttpClientConnectionOperator httpClientConnectionOperator = getHttpClientConnectionOperator( - poolingHttpClientConnectionManager); - Registry registry = getRegistry(httpClientConnectionOperator); - Map registryMap = getRegistryMap(registry); - SSLConnectionSocketFactory connectionSocketFactory = (SSLConnectionSocketFactory) registryMap - .get("https"); - HostnameVerifier hostnameVerifier = getHostnameVerifier(connectionSocketFactory); - assertThat(hostnameVerifier).isInstanceOf(DefaultHostnameVerifier.class); - } - - private HostnameVerifier getHostnameVerifier( - SSLConnectionSocketFactory connectionSocketFactory) { - return getField(connectionSocketFactory, "hostnameVerifier"); - } - - private PoolingHttpClientConnectionManager getHttpClientConnectionManager( - CloseableHttpClient httpClient) { - return getField(httpClient, "connManager"); - } - - private DefaultHttpClientConnectionOperator getHttpClientConnectionOperator( - PoolingHttpClientConnectionManager connectionManager) { - return getField(connectionManager, "connectionOperator"); - } - - private Registry getRegistry( - DefaultHttpClientConnectionOperator httpClientConnectionOperator) { - return getField(httpClientConnectionOperator, "socketFactoryRegistry"); - } - - private Map getRegistryMap(Registry registry) { - return getField(registry, "map"); - } - - private T getField(Object target, String name) { - Field field = ReflectionUtils.findField(target.getClass(), name); - ReflectionUtils.makeAccessible(field); - Object value = ReflectionUtils.getField(field, target); - return (T) value; - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/BothPropertiesEurekaTestConfigBeanTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/BothPropertiesEurekaTestConfigBeanTests.java deleted file mode 100644 index 332888a9d..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/BothPropertiesEurekaTestConfigBeanTests.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", "spring.application.instance_id=1", - "eureka.instance.hostname=mhhost1", "sidecar.hostname=mhhost2", - "sidecar.port=7000", "sidecar.ip-address=127.0.0.1" }) -public class BothPropertiesEurekaTestConfigBeanTests { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBeanEurekaInstanceHostnamePropertyShouldBeUsed() { - assertThat(config.getAppname()).isEqualTo("mytest"); - assertThat(config.getHostname()).isEqualTo("mhhost1"); - assertThat(config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(config.getNonSecurePort()).isEqualTo(7000); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/EurekaTestConfigBeanTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/EurekaTestConfigBeanTests.java deleted file mode 100644 index 3d11cb7a6..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/EurekaTestConfigBeanTests.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", "spring.application.instance_id=1", - "eureka.instance.hostname=mhhost", "sidecar.port=7000", - "sidecar.ip-address=127.0.0.1" }) -public class EurekaTestConfigBeanTests { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBean() { - assertThat(this.config.getAppname()).isEqualTo("mytest"); - assertThat(this.config.getHostname()).isEqualTo("mhhost"); - assertThat(this.config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(this.config.getNonSecurePort()).isEqualTo(7000); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandlerTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandlerTests.java deleted file mode 100644 index 9c4b49c52..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandlerTests.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import com.netflix.appinfo.InstanceInfo.InstanceStatus; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; - -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.MockitoAnnotations.initMocks; - -/** - * @author Spencer Gibb - */ -public class LocalApplicationHealthCheckHandlerTests { - - @Mock - private HealthIndicator healthIndicator; - - @Before - public void setup() { - initMocks(this); - } - - @Test - public void upMappingWorks() { - assertStatus(InstanceStatus.UP, Health.up()); - } - - @Test - public void downMappingWorks() { - assertStatus(InstanceStatus.DOWN, Health.down()); - } - - @Test - public void outOfServiceMappingWorks() { - assertStatus(InstanceStatus.OUT_OF_SERVICE, Health.outOfService()); - } - - @Test - public void unknownMappingWorks() { - assertStatus(InstanceStatus.UNKNOWN, Health.unknown()); - } - - private void assertStatus(InstanceStatus expected, Health.Builder builder) { - given(healthIndicator.health()).willReturn(builder.build()); - - LocalApplicationHealthCheckHandler handler = new LocalApplicationHealthCheckHandler( - healthIndicator); - InstanceStatus status = handler.getStatus(InstanceStatus.UP); - assertThat(status).isEqualTo(expected); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/ManagementContextPathStatusAndHealthCheckUrlsTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/ManagementContextPathStatusAndHealthCheckUrlsTests.java deleted file mode 100644 index b133a47f4..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/ManagementContextPathStatusAndHealthCheckUrlsTests.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "spring.application.name=mytest", "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", "eureka.instance.hostname=mhhost1", - "sidecar.hostname=mhhost2", "sidecar.port=7000", - "sidecar.ipAddress=127.0.0.1", - "management.server.servlet.context-path=/foo" }) -public class ManagementContextPathStatusAndHealthCheckUrlsTests { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testStatusAndHealthCheckUrls() { - assertThat(config.getStatusPageUrl()) - .isEqualTo("http://mhhost2:0/foo/actuator/info"); - assertThat(config.getHealthCheckUrl()) - .isEqualTo("http://mhhost2:0/foo/actuator/health"); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/NewPropertyEurekaTestConfigBeanTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/NewPropertyEurekaTestConfigBeanTests.java deleted file mode 100644 index 1240f535c..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/NewPropertyEurekaTestConfigBeanTests.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", "spring.application.instance_id=1", - "sidecar.hostname=mhhost", "sidecar.port=7000", - "sidecar.ip-address=127.0.0.1" }) -public class NewPropertyEurekaTestConfigBeanTests { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBean() { - assertThat(config.getAppname()).isEqualTo("mytest"); - assertThat(config.getHostname()).isEqualTo("mhhost"); - assertThat(config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(config.getNonSecurePort()).isEqualTo(7000); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/PreferIpAddressTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/PreferIpAddressTests.java deleted file mode 100644 index 3b84b0717..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/PreferIpAddressTests.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", "spring.application.instance_id=1", - "eureka.instance.hostname=mhhost1", "sidecar.hostname=mhhost2", - "sidecar.port=7000", "sidecar.ip-address=10.0.0.1", - "eureka.instance.prefer-ip-address=true" }) -public class PreferIpAddressTests { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBeanPreferIpAddress() { - assertThat(config.getAppname()).isEqualTo("mytest"); - assertThat(config.getHostname()).isEqualTo("10.0.0.1"); - assertThat(config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(config.getNonSecurePort()).isEqualTo(7000); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SecurePortEnableds.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SecurePortEnableds.java deleted file mode 100644 index 6bce2d2ca..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SecurePortEnableds.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "sidecar.port=7000", "sidecar.ip-address=127.0.0.1", - "sidecar.secure-port-enabled=true" }) -public class SecurePortEnableds { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testThatSecureEnabledOptionIsSetFromPropertyFile() { - assertThat(this.config.isSecurePortEnabled()).isEqualTo(true); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/ServerContextPathStatusAndHealthCheckUrlsTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/ServerContextPathStatusAndHealthCheckUrlsTests.java deleted file mode 100644 index 08ef061f6..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/ServerContextPathStatusAndHealthCheckUrlsTests.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "spring.application.name=mytest", "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", "eureka.instance.hostname=mhhost1", - "sidecar.hostname=mhhost2", "sidecar.port=7000", - "sidecar.ipAddress=127.0.0.1", "server.servlet.context-path=/foo" }) -public class ServerContextPathStatusAndHealthCheckUrlsTests { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testStatusAndHealthCheckUrls() { - assertThat(config.getStatusPageUrl()) - .isEqualTo("http://mhhost2:0/foo/actuator/info"); - assertThat(config.getHealthCheckUrl()) - .isEqualTo("http://mhhost2:0/foo/actuator/health"); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplication.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplication.java deleted file mode 100644 index c2ee06b2f..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplication.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.cloud.netflix.eureka.metadata.DefaultManagementMetadataProvider; -import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadata; -import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadataProvider; -import org.springframework.context.annotation.Bean; -import org.springframework.web.bind.annotation.RestController; - -@SpringBootConfiguration -@EnableAutoConfiguration -@EnableSidecar -@RestController -public class SidecarApplication { - - public static void main(String[] args) { - SpringApplication.run(SidecarApplication.class, args); - } - - @Bean - public ManagementMetadataProvider managementMetadataProvider() { - // The default management metadata provider checks for random ports, we dont care - // about this in tests - return new DefaultManagementMetadataProvider() { - @Override - public ManagementMetadata get(EurekaInstanceConfigBean instance, - int serverPort, String serverContextPath, - String managementContextPath, Integer managementPort) { - String healthCheckUrl = getHealthCheckUrl(instance, serverPort, - serverContextPath, managementContextPath, managementPort, false); - String statusPageUrl = getStatusPageUrl(instance, serverPort, - serverContextPath, managementContextPath, managementPort); - - ManagementMetadata metadata = new ManagementMetadata(healthCheckUrl, - statusPageUrl, - managementPort == null ? serverPort : managementPort); - if (instance.isSecurePortEnabled()) { - metadata.setSecureHealthCheckUrl( - getHealthCheckUrl(instance, serverPort, serverContextPath, - managementContextPath, managementPort, true)); - } - return metadata; - } - }; - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplicationTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplicationTests.java deleted file mode 100644 index 6a7c222ee..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplicationTests.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.util.InetUtils; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -public class SidecarApplicationTests { - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", "eureka.instance.hostname=mhhost", - "sidecar.port=7000", "sidecar.ip-address=127.0.0.1" }) - public static class EurekaTestConfigBeanTest { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBean() { - assertThat(this.config.getAppname()).isEqualTo("mytest"); - assertThat(this.config.getHostname()).isEqualTo("mhhost"); - assertThat(this.config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(this.config.getNonSecurePort()).isEqualTo(7000); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", "sidecar.hostname=mhhost", - "sidecar.port=7000", "sidecar.ip-address=127.0.0.1" }) - public static class NewPropertyEurekaTestConfigBeanTest { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBean() { - assertThat(config.getAppname()).isEqualTo("mytest"); - assertThat(config.getHostname()).isEqualTo("mhhost"); - assertThat(config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(config.getNonSecurePort()).isEqualTo(7000); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", - "eureka.instance.hostname=mhhost1", "sidecar.hostname=mhhost2", - "sidecar.port=7000", "sidecar.ip-address=127.0.0.1" }) - public static class BothPropertiesEurekaTestConfigBeanTest { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBeanEurekaInstanceHostnamePropertyShouldBeUsed() { - assertThat(config.getAppname()).isEqualTo("mytest"); - assertThat(config.getHostname()).isEqualTo("mhhost1"); - assertThat(config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(config.getNonSecurePort()).isEqualTo(7000); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", - "eureka.instance.hostname=mhhost1", "sidecar.hostname=mhhost2", - "sidecar.port=7000", "sidecar.ip-address=10.0.0.1", - "eureka.instance.prefer-ip-address=true" }) - public static class PreferIpAddressTest { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBeanPreferIpAddress() { - assertThat(config.getAppname()).isEqualTo("mytest"); - assertThat(config.getHostname()).isEqualTo("10.0.0.1"); - assertThat(config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(config.getNonSecurePort()).isEqualTo(7000); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", - "eureka.instance.hostname=mhhost1", "sidecar.hostname=mhhost2", - "sidecar.port=7000", "sidecar.ipAddress=127.0.0.1", - "management.context-path=/foo" }) - public static class ManagementContextPathStatusAndHealthCheckUrls { - - @Autowired - EurekaInstanceConfigBean config; - - public void testStatusAndHealthCheckUrls() { - assertThat(config.getStatusPageUrl()).isEqualTo("https://mhhost2:0/foo/info"); - assertThat(config.getHealthCheckUrl()) - .isEqualTo("https://mhhost2:0/foo/health"); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", - "eureka.instance.hostname=mhhost1", "sidecar.hostname=mhhost2", - "sidecar.port=7000", "sidecar.ipAddress=127.0.0.1", - "server.context-path=/foo" }) - public static class ServerContextPathStatusAndHealthCheckUrls { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testStatusAndHealthCheckUrls() { - assertThat(config.getStatusPageUrl()).isEqualTo("https://mhhost2:0/foo/info"); - assertThat(config.getHealthCheckUrl()) - .isEqualTo("https://mhhost2:0/foo/health"); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "sidecar.accept-all-ssl-certificates=false" }) - public static class AcceptAllSslCertificatesContext { - - @Autowired - RestTemplate restTemplate; - - @Test - public void testUseRestTemplateWhenHttpClientIsNotAvailable() { - assertThat(restTemplate.getRequestFactory()).isNull(); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "sidecar.port=7000", "sidecar.ip-address=127.0.0.1", - "sidecar.secure-port-enabled=true" }) - public static class SecurePortEnabled { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testThatSecureEnabledOptionIsSetFromPropertyFile() { - assertThat(this.config.isSecurePortEnabled()).isEqualTo(true); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = EurekaInstanceConfigBeanOverrideApplication.class, - webEnvironment = RANDOM_PORT) - public static class EurekaInstanceConfigBeanOverrideTest { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBeanOverride() { - assertThat(this.config.getHostname()).isEqualTo("overridden"); - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @EnableSidecar - protected static class EurekaInstanceConfigBeanOverrideApplication { - - @Bean - public EurekaInstanceConfigBean eurekaInstanceConfigBean(InetUtils inetUtils) { - EurekaInstanceConfigBean eurekaInstanceConfigBean = new EurekaInstanceConfigBean( - inetUtils); - eurekaInstanceConfigBean.setHostname("overridden"); - return eurekaInstanceConfigBean; - } - - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/resources/application.yml b/spring-cloud-netflix-sidecar/src/test/resources/application.yml deleted file mode 100644 index 2ea917289..000000000 --- a/spring-cloud-netflix-sidecar/src/test/resources/application.yml +++ /dev/null @@ -1,30 +0,0 @@ -server: - port: 5678 -spring: - application: - name: sidecarTest - -sidecar: - port: 8000 - health-uri: http://localhost:8000/src/test/resources/health.json - accept-all-ssl-certificates: true - -eureka: - instance: - app-group-name: mysidecargroup - client: - serviceUrl: - defaultZone: https://user:password@localhost:8761/eureka/ - -ribbon: - ServerListRefreshInterval: 5000 - ReadTimeout: 7777 - -endpoints: - refresh: - enabled: true - shutdown: - enabled: true - health: - sensitive: false - diff --git a/spring-cloud-netflix-sidecar/src/test/resources/bootstrap.yml b/spring-cloud-netflix-sidecar/src/test/resources/bootstrap.yml deleted file mode 100644 index bbd589280..000000000 --- a/spring-cloud-netflix-sidecar/src/test/resources/bootstrap.yml +++ /dev/null @@ -1,7 +0,0 @@ -spring: - #application: - # name: sideCarTest - cloud: - config: - username: user - password: password diff --git a/spring-cloud-netflix-sidecar/src/test/resources/health.json b/spring-cloud-netflix-sidecar/src/test/resources/health.json deleted file mode 100644 index 41f3615e9..000000000 --- a/spring-cloud-netflix-sidecar/src/test/resources/health.json +++ /dev/null @@ -1 +0,0 @@ -{"status":"UP"} \ No newline at end of file diff --git a/spring-cloud-netflix-turbine-stream/.jdk8 b/spring-cloud-netflix-turbine-stream/.jdk8 deleted file mode 100644 index e69de29bb..000000000 diff --git a/spring-cloud-netflix-turbine-stream/pom.xml b/spring-cloud-netflix-turbine-stream/pom.xml deleted file mode 100644 index 512e78c50..000000000 --- a/spring-cloud-netflix-turbine-stream/pom.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - spring-cloud-netflix-turbine-stream - jar - Spring Cloud Netflix Turbine Stream - Spring Cloud Netflix Turbine Stream - - 2.0.0-DP.2 - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.20 - - - ${project.version} - - - - - - - - - com.netflix.turbine - turbine-core - ${turbine.version} - - - com.netflix.rxjava - rxjava-core - - - org.slf4j - slf4j-simple - - - - - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.cloud - spring-cloud-commons - true - - - org.springframework.integration - spring-integration-core - - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.springframework.cloud - spring-cloud-stream - - - org.springframework.boot - spring-boot-starter-web - - - - - com.netflix.turbine - turbine-core - - - io.reactivex - rxjava - - - org.springframework.boot - spring-boot-starter-webflux - - - io.reactivex - rxjava-reactive-streams - - - org.springframework.cloud - spring-cloud-stream-binder-rabbit - true - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - org.springframework.boot - spring-boot-starter-test - test - - - io.projectreactor - reactor-test - test - - - org.springframework.cloud - spring-cloud-starter-contract-stub-runner - test - - - org.springframework.cloud - spring-cloud-netflix-hystrix-contract - test - - - org.springframework.cloud - spring-cloud-stream-test-support - test - - - diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/EnableTurbineStream.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/EnableTurbineStream.java deleted file mode 100644 index 188a06b9b..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/EnableTurbineStream.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine.stream; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.context.annotation.Import; - -/** - * Run the RxNetty based Spring Cloud Turbine Stream server. Based on Netflix Turbine 2 - * and Spring Cloud Stream - * - * @author Spencer Gibb - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Import(TurbineStreamConfiguration.class) -public @interface EnableTurbineStream { - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/HystrixStreamAggregator.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/HystrixStreamAggregator.java deleted file mode 100644 index fd154c761..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/HystrixStreamAggregator.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine.stream; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.Map; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import rx.subjects.PublishSubject; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.messaging.handler.annotation.Payload; -import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; - -/** - * @author Spencer Gibb - */ -@Component // needed for ServiceActivator to be picked up -public class HystrixStreamAggregator { - - private static final Log log = LogFactory.getLog(HystrixStreamAggregator.class); - - private ObjectMapper objectMapper; - - private PublishSubject> subject; - - @Autowired - public HystrixStreamAggregator(ObjectMapper objectMapper, - PublishSubject> subject) { - this.objectMapper = objectMapper; - this.subject = subject; - } - - @ServiceActivator(inputChannel = TurbineStreamClient.INPUT) - public void sendToSubject(@Payload byte[] bytePayload) { - String payload = new String(bytePayload, StandardCharsets.UTF_8); - if (log.isTraceEnabled()) { - log.trace("Received hystrix stream payload string: " + payload); - } - if (payload.startsWith("\"")) { - // Legacy payload from an Angel client - payload = payload.substring(1, payload.length() - 1); - payload = payload.replace("\\\"", "\""); - } - try { - if (payload.startsWith("[")) { - @SuppressWarnings("unchecked") - List> list = this.objectMapper.readValue(payload, - List.class); - for (Map map : list) { - sendMap(map); - } - } - else { - @SuppressWarnings("unchecked") - Map map = this.objectMapper.readValue(payload, Map.class); - sendMap(map); - } - } - catch (IOException ex) { - log.error("Error receiving hystrix stream payload: " + payload, ex); - } - } - - private void sendMap(Map map) { - Map data = getPayloadData(map); - if (log.isDebugEnabled()) { - log.debug("Received hystrix stream payload: " + data); - } - this.subject.onNext(data); - } - - public static Map getPayloadData(Map jsonMap) { - @SuppressWarnings("unchecked") - Map origin = (Map) jsonMap.get("origin"); - String instanceId = null; - if (origin.containsKey("id")) { - instanceId = origin.get("id").toString(); - } - if (!StringUtils.hasText(instanceId)) { - // TODO: instanceid template - instanceId = origin.get("serviceId") + ":" + origin.get("host") + ":" - + origin.get("port"); - } - @SuppressWarnings("unchecked") - Map data = (Map) jsonMap.get("data"); - data.put("instanceId", instanceId); - return data; - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineApplication.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineApplication.java deleted file mode 100644 index de0219304..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineApplication.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2015-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine.stream; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.context.annotation.Configuration; - -/** - * Turbine application class. - * - * @author Dave Syer - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@EnableAutoConfiguration -@EnableTurbineStream -public class TurbineApplication { - - public static void main(String[] args) { - new SpringApplicationBuilder(TurbineApplication.class) - .properties("spring.config.name=turbine").run(args); - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineController.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineController.java deleted file mode 100644 index e6fd609db..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineController.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2014-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine.stream; - -import java.time.Duration; -import java.util.Collections; -import java.util.Map; - -import com.netflix.turbine.aggregator.InstanceKey; -import com.netflix.turbine.aggregator.StreamAggregator; -import com.netflix.turbine.internal.JsonUtility; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Flux; -import rx.Observable; -import rx.RxReactiveStreams; -import rx.subjects.PublishSubject; - -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * Turbine stream controller. - * - * @author Spencer Gibb - * @author Ryan Baxter - */ -@RestController -public class TurbineController { - - private static final Log log = LogFactory.getLog(TurbineController.class); - - private final Flux flux; - - public TurbineController(PublishSubject> hystrixSubject) { - Observable> stream = StreamAggregator - .aggregateGroupedStreams(hystrixSubject.groupBy( - data -> InstanceKey.create((String) data.get("instanceId")))) - .doOnUnsubscribe(() -> log.info("Unsubscribing aggregation.")) - .doOnSubscribe(() -> log.info("Starting aggregation")).flatMap(o -> o); - Flux> ping = Flux - .interval(Duration.ofSeconds(5), Duration.ofSeconds(10)) - .map(l -> Collections.singletonMap("type", (Object) "ping")).share(); - flux = Flux.merge(RxReactiveStreams.toPublisher(stream), ping).share() - .map(JsonUtility::mapToJson); - } - - @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE) - public Flux stream() { - return this.flux; - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamAutoConfiguration.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamAutoConfiguration.java deleted file mode 100644 index fbaa59616..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamAutoConfiguration.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine.stream; - -import java.util.Map; - -import javax.annotation.PostConstruct; - -import com.fasterxml.jackson.databind.ObjectMapper; -import rx.subjects.PublishSubject; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.stream.annotation.EnableBinding; -import org.springframework.cloud.stream.config.BindingProperties; -import org.springframework.cloud.stream.config.BindingServiceProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Autoconfiguration for a Spring Cloud Turbine using Spring Cloud Stream. Enabled by - * default if spring-cloud-stream is on the classpath, and can be switched off with - * turbine.stream.enabled. - * - * @author Spencer Gibb - * @author Dave Syer - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(EnableBinding.class) -@ConditionalOnProperty(value = "turbine.stream.enabled", matchIfMissing = true) -@EnableBinding(TurbineStreamClient.class) -public class TurbineStreamAutoConfiguration { - - @Autowired - private BindingServiceProperties bindings; - - @Autowired - private TurbineStreamProperties properties; - - @PostConstruct - public void init() { - BindingProperties inputBinding = this.bindings.getBindings() - .get(TurbineStreamClient.INPUT); - if (inputBinding == null) { - this.bindings.getBindings().put(TurbineStreamClient.INPUT, - new BindingProperties()); - } - BindingProperties input = this.bindings.getBindings() - .get(TurbineStreamClient.INPUT); - if (input.getDestination() == null) { - input.setDestination(this.properties.getDestination()); - } - if (input.getContentType() == null) { - input.setContentType(this.properties.getContentType()); - } - } - - @Bean - public HystrixStreamAggregator hystrixStreamAggregator(ObjectMapper mapper, - PublishSubject> publisher) { - return new HystrixStreamAggregator(mapper, publisher); - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamClient.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamClient.java deleted file mode 100644 index c60dd2d9a..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamClient.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine.stream; - -import org.springframework.cloud.stream.annotation.Input; -import org.springframework.messaging.SubscribableChannel; - -/** - * @author Dave Syer - * - */ -public interface TurbineStreamClient { - - /** - * Turbine Stream Input name. - */ - String INPUT = "turbineStreamInput"; - - @Input(INPUT) - SubscribableChannel turbineStreamInput(); - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamConfiguration.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamConfiguration.java deleted file mode 100644 index e36fad900..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamConfiguration.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine.stream; - -import java.util.Map; - -import rx.subjects.PublishSubject; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - * @author Daniel Lavoie - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties(TurbineStreamProperties.class) -public class TurbineStreamConfiguration { - - @Bean - public HasFeatures Feature() { - return HasFeatures.namedFeature("Turbine (Stream)", - TurbineStreamProperties.class); - } - - @Bean - public PublishSubject> hystrixSubject() { - return PublishSubject.create(); - } - - @Bean - public TurbineController turbineController( - PublishSubject> hystrixSubject) { - return new TurbineController(hystrixSubject); - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamProperties.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamProperties.java deleted file mode 100644 index d05939765..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamProperties.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine.stream; - -import java.util.Objects; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.netflix.hystrix.HystrixConstants; -import org.springframework.http.MediaType; - -/** - * @author Dave Syer - * @author Gregor Zurowski - */ -@ConfigurationProperties("turbine.stream") -public class TurbineStreamProperties { - - private String destination = HystrixConstants.HYSTRIX_STREAM_DESTINATION; - - private String contentType = MediaType.APPLICATION_JSON_VALUE; - - public String getDestination() { - return destination; - } - - public void setDestination(String destination) { - this.destination = destination; - } - - public String getContentType() { - return contentType; - } - - public void setContentType(String contentType) { - this.contentType = contentType; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - TurbineStreamProperties that = (TurbineStreamProperties) o; - return Objects.equals(destination, that.destination) - && Objects.equals(contentType, that.contentType); - } - - @Override - public int hashCode() { - return Objects.hash(destination, contentType); - } - - @Override - public String toString() { - return new StringBuilder("TurbineStreamProperties{").append(", ") - .append("destination='").append(destination).append("', ") - .append("contentType='").append(contentType).append("'}").toString(); - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-turbine-stream/src/main/resources/META-INF/spring.factories deleted file mode 100644 index e4ee427e2..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.turbine.stream.TurbineStreamAutoConfiguration diff --git a/spring-cloud-netflix-turbine-stream/src/main/resources/turbine.yml b/spring-cloud-netflix-turbine-stream/src/main/resources/turbine.yml deleted file mode 100644 index 0f4cef40c..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/resources/turbine.yml +++ /dev/null @@ -1,10 +0,0 @@ -info: - component: Turbine Stream -spring: - application: - name: turbine - jmx: - default_domain: cloud.turbine.stream - -server: - port: 8989 diff --git a/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/HystrixStreamAggregatorTests.java b/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/HystrixStreamAggregatorTests.java deleted file mode 100644 index ae87f7ca9..000000000 --- a/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/HystrixStreamAggregatorTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine.stream; - -import java.util.Map; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Rule; -import org.junit.Test; -import rx.subjects.PublishSubject; - -import org.springframework.boot.test.system.OutputCaptureRule; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.core.IsNot.not; - -public class HystrixStreamAggregatorTests { - - private ObjectMapper mapper = new ObjectMapper(); - - private PublishSubject> publisher = PublishSubject.create(); - - private HystrixStreamAggregator aggregator = new HystrixStreamAggregator(this.mapper, - this.publisher); - - @Rule - public OutputCaptureRule output = new OutputCaptureRule(); - - private static String PAYLOAD = "{\"origin\":{\"host\":\"dsyer\",\"port\":-1," - + "\"serviceId\":\"application\",\"id\":\"application\"},\"data\":{\"type\":" - + "\"HystrixCommand\",\"name\":\"application.ok\",\"group\":\"MyService\"," - + "\"currentTime\":1457089387160,\"isCircuitBreakerOpen\":false," - + "\"errorPercentage\":0,\"errorCount\":0,\"requestCount\":0," - + "\"rollingCountCollapsedRequests\":0,\"rollingCountExceptionsThrown\":0," - + "\"rollingCountFailure\":0,\"rollingCountFallbackFailure\":0," - + "\"rollingCountFallbackRejection\":0,\"rollingCountFallbackSuccess\":0," - + "\"rollingCountResponsesFromCache\":0,\"rollingCountSemaphoreRejected\":0," - + "\"rollingCountShortCircuited\":0,\"rollingCountSuccess\":1," - + "\"rollingCountThreadPoolRejected\":0,\"rollingCountTimeout\":0," - + "\"currentConcurrentExecutionCount\":0,\"latencyExecute_mean\":0," - + "\"latencyExecute\":{\"0\":0,\"25\":0,\"50\":0,\"75\":0,\"90\":0,\"95\":0," - + "\"99\":0,\"99.5\":0,\"100\":0},\"latencyTotal_mean\":0,\"latencyTotal" - + "\":{\"0\":0,\"25\":0,\"50\":0,\"75\":0,\"90\":0,\"95\":0,\"99\":0,\"99.5" - + "\":0,\"100\":0},\"propertyValue_circuitBreakerRequestVolumeThreshold\":20," - + "\"propertyValue_circuitBreakerSleepWindowInMilliseconds\":5000," - + "\"propertyValue_circuitBreakerErrorThresholdPercentage\":50," - + "\"propertyValue_circuitBreakerForceOpen\":false," - + "\"propertyValue_circuitBreakerForceClosed\":false," - + "\"propertyValue_circuitBreakerEnabled\":true," - + "\"propertyValue_executionIsolationStrategy\":\"THREAD\"," - + "\"propertyValue_executionIsolationThreadTimeoutInMilliseconds\":1000," - + "\"propertyValue_executionIsolationThreadInterruptOnTimeout\":true," - + "\"propertyValue_executionIsolationThreadPoolKeyOverride\":null," - + "\"propertyValue_executionIsolationSemaphoreMaxConcurrentRequests\":10," - + "\"propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests\":10," - + "\"propertyValue_metricsRollingStatisticalWindowInMilliseconds\":10000," - + "\"propertyValue_requestCacheEnabled\":true," - + "\"propertyValue_requestLogEnabled\":true,\"reportingHosts\":1}}"; - - @Test - public void messageDecoded() throws Exception { - this.publisher.subscribe( - map -> assertThat(map.get("type")).isEqualTo("HystrixCommand")); - this.aggregator.sendToSubject(PAYLOAD.getBytes()); - this.output.expect(not(containsString("ERROR"))); - } - - @Test - public void messageWrappedInArray() throws Exception { - this.publisher.subscribe( - map -> assertThat(map.get("type")).isEqualTo("HystrixCommand")); - this.aggregator.sendToSubject(new StringBuilder().append("[").append(PAYLOAD) - .append("]").toString().getBytes()); - this.output.expect(not(containsString("ERROR"))); - } - - @Test - public void doubleEncodedMessage() throws Exception { - this.publisher.subscribe( - map -> assertThat(map.get("type")).isEqualTo("HystrixCommand")); - // If The JSON is embedded in a JSON String this is what it looks like - String payload = "\"" + PAYLOAD.replace("\"", "\\\"") + "\""; - this.aggregator.sendToSubject(payload.getBytes()); - this.output.expect(not(containsString("ERROR"))); - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamConfigurationTest.java b/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamConfigurationTest.java deleted file mode 100644 index f37c8ac60..000000000 --- a/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamConfigurationTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine.stream; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Before; - -/** - * @author Yongsung Yoon - */ -public class TurbineStreamConfigurationTest { - - TurbineStreamConfiguration turbineStreamConfiguration; - - List> testMetricList; - - @Before - public void setUp() { - turbineStreamConfiguration = new TurbineStreamConfiguration(); - testMetricList = createBasicTestMetricList(); - } - - private List> createBasicTestMetricList() { - List> testDataList = new ArrayList<>(); - HashMap map = new HashMap<>(); - map.put("instanceId", "abc:127.0.0.1:8080"); - map.put("type", "HystrixCommand"); - testDataList.add(map); - - map = new HashMap<>(); - map.put("instanceId", "def:127.0.0.1:8080"); - map.put("type", "HystrixCommand"); - testDataList.add(map); - - map = new HashMap<>(); - map.put("instanceId", "xyz:127.0.0.1:8080"); - map.put("type", "HystrixThreadPool"); - testDataList.add(map); - - map = new HashMap<>(); - map.put("type", "ping"); - testDataList.add(map); - - map = new HashMap<>(); - map.put("dummy", "data"); - testDataList.add(map); - - return testDataList; - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamTests.java b/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamTests.java deleted file mode 100644 index 8b2a00250..000000000 --- a/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamTests.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine.stream; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URI; -import java.util.Map; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.contract.stubrunner.StubTrigger; -import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner; -import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties.StubsMode; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpRequest; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.integration.support.management.MessageChannelMetrics; -import org.springframework.messaging.SubscribableChannel; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Spencer Gibb - * @author Daniel Lavoie - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, properties = { - // TODO: we don't need this if we harmonize the turbine and hystrix - // destinations - // https://github.com/spring-cloud/spring-cloud-netflix/issues/1948 - "spring.cloud.stream.bindings.turbineStreamInput.destination=hystrixStreamOutput", - "spring.jmx.enabled=true", "stubrunner.workOffline=true", - "stubrunner.ids=org.springframework.cloud:spring-cloud-netflix-hystrix-stream:${projectVersion:2.1.3.BUILD-SNAPSHOT}:stubs" }) -@AutoConfigureStubRunner(stubsMode = StubsMode.LOCAL) -public class TurbineStreamTests { - - @Autowired - StubTrigger stubTrigger; - - @Autowired - ObjectMapper mapper; - - @Autowired - @Qualifier(TurbineStreamClient.INPUT) - SubscribableChannel input; - - RestTemplate rest = new RestTemplate(); - - @Autowired - TurbineStreamConfiguration turbine; - - @LocalServerPort - int port; - - @Test - public void contextLoads() throws Exception { - rest.getInterceptors().add(new NonClosingInterceptor()); - int count = ((MessageChannelMetrics) input).getSendCount(); - ResponseEntity response = rest.execute( - new URI("http://localhost:" + port + "/"), HttpMethod.GET, null, - this::extract); - assertThat(response.getHeaders().getContentType() - .isCompatibleWith(MediaType.TEXT_EVENT_STREAM)).isTrue(); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - Map metrics = extractMetrics(response.getBody()); - assertThat(metrics).containsEntry("type", "HystrixCommand"); - assertThat(((MessageChannelMetrics) input).getSendCount()).isEqualTo(count + 1); - } - - private boolean containsMetrics(String line) { - return line.startsWith("data:") && !line.contains("ping"); - } - - @SuppressWarnings("unchecked") - private Map extractMetrics(String body) throws Exception { - for (String value : body.split("\n")) { - if (containsMetrics(value)) { - return mapper.readValue(value.split("data:")[1], Map.class); - } - } - return null; - } - - private ResponseEntity extract(ClientHttpResponse response) - throws IOException { - // The message has to be sent after the endpoint is activated, so this is a - // convenient place to put it - stubTrigger.trigger("metrics"); - - String responseBody = ""; - boolean metricFound = false; - try (BufferedReader buffer = new BufferedReader( - new InputStreamReader(response.getBody()))) { - do { - String line = buffer.readLine(); - responseBody += line + "\n"; - if (containsMetrics(line)) { - metricFound = true; - } - } - while (!metricFound); - } - - return ResponseEntity.status(response.getStatusCode()) - .headers(response.getHeaders()).body(responseBody); - } - - @EnableAutoConfiguration - @EnableTurbineStream - @Configuration(proxyBeanMethods = false) - public static class TestConfig { - - } - - /** - * Special interceptor that prevents the response from being closed and allows us to - * assert on the contents of an event stream. - */ - private class NonClosingInterceptor implements ClientHttpRequestInterceptor { - - @Override - public ClientHttpResponse intercept(HttpRequest request, byte[] body, - ClientHttpRequestExecution execution) throws IOException { - return new NonClosingResponse(execution.execute(request, body)); - } - - private class NonClosingResponse implements ClientHttpResponse { - - private ClientHttpResponse delegate; - - NonClosingResponse(ClientHttpResponse delegate) { - this.delegate = delegate; - } - - @Override - public InputStream getBody() throws IOException { - return delegate.getBody(); - } - - @Override - public HttpHeaders getHeaders() { - return delegate.getHeaders(); - } - - @Override - public HttpStatus getStatusCode() throws IOException { - return delegate.getStatusCode(); - } - - @Override - public int getRawStatusCode() throws IOException { - return delegate.getRawStatusCode(); - } - - @Override - public String getStatusText() throws IOException { - return delegate.getStatusText(); - } - - @Override - public void close() { - } - - } - - } - -} diff --git a/spring-cloud-netflix-turbine/pom.xml b/spring-cloud-netflix-turbine/pom.xml deleted file mode 100644 index 68277b580..000000000 --- a/spring-cloud-netflix-turbine/pom.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - spring-cloud-netflix-turbine - jar - Spring Cloud Netflix Turbine - https://projects.spring.io/spring-cloud/ - - 1.0.0 - - - - - com.netflix.turbine - turbine-core - ${turbine.version} - - - javax.servlet - servlet-api - - - log4j - log4j - - - com.netflix.rxjava - rxjava-core - - - org.slf4j - slf4j-simple - - - org.mockito - mockito-all - - - - - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework.cloud - spring-cloud-context - true - - - org.springframework.cloud - spring-cloud-netflix-hystrix - true - - - org.springframework.cloud - spring-cloud-netflix-eureka-client - true - - - com.netflix.eureka - eureka-client - true - - - org.apache.httpcomponents - httpclient - - - com.netflix.turbine - turbine-core - - - org.springframework.boot - spring-boot-starter-test - test - - - diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/ClusterInformation.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/ClusterInformation.java deleted file mode 100644 index cb4a57f75..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/ClusterInformation.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.util.Objects; - -/** - * @author Anastasiia Smirnova - * @author Ryan Baxter Contains cluster-relevant information, such as name and link. - */ -public class ClusterInformation { - - private String name; - - private String link; - - public ClusterInformation() { - } - - public ClusterInformation(String name, String link) { - this.name = name; - this.link = link; - } - - public String getName() { - return name; - } - - public String getLink() { - return link; - } - - public void setName(String name) { - this.name = name; - } - - public void setLink(String link) { - this.link = link; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ClusterInformation that = (ClusterInformation) o; - return Objects.equals(name, that.name) && Objects.equals(link, that.link); - } - - @Override - public int hashCode() { - return Objects.hash(name, link); - } - - @Override - public String toString() { - return "ClusterInformation{" + "name='" + name + '\'' + ", link='" + link + '\'' - + '}'; - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscovery.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscovery.java deleted file mode 100644 index d03e3df76..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscovery.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import com.netflix.turbine.discovery.Instance; -import com.netflix.turbine.discovery.InstanceDiscovery; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.expression.Expression; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; - -/** - * Class that encapsulates an {@link InstanceDiscovery} implementation that uses Spring - * Cloud Commons (see https://github.com/spring-cloud/spring-cloud-commons) The plugin - * requires a list of applications configured. It then queries the set of instances for * - * each application. Instance information retrieved from the {@link DiscoveryClient} must - * be translated to * something that Turbine can understand i.e the {@link Instance} - * class. - *

- * All the logic to perform this translation can be overriden here, so that you can - * provide your own implementation if needed. - * - * @author Spencer Gibb - */ -public class CommonsInstanceDiscovery implements InstanceDiscovery { - - private static final Log log = LogFactory.getLog(CommonsInstanceDiscovery.class); - - private static final String DEFAULT_CLUSTER_NAME_EXPRESSION = "serviceId"; - - protected static final String PORT_KEY = "port"; - - protected static final String SECURE_PORT_KEY = "securePort"; - - protected static final String FUSED_HOST_PORT_KEY = "fusedHostPort"; - - private final Expression clusterNameExpression; - - private DiscoveryClient discoveryClient; - - private TurbineProperties turbineProperties; - - private final boolean combineHostPort; - - public CommonsInstanceDiscovery(TurbineProperties turbineProperties, - DiscoveryClient discoveryClient) { - this(turbineProperties, DEFAULT_CLUSTER_NAME_EXPRESSION); - this.discoveryClient = discoveryClient; - } - - protected CommonsInstanceDiscovery(TurbineProperties turbineProperties, - String defaultExpression) { - this.turbineProperties = turbineProperties; - SpelExpressionParser parser = new SpelExpressionParser(); - String clusterNameExpression = turbineProperties.getClusterNameExpression(); - if (clusterNameExpression == null) { - clusterNameExpression = defaultExpression; - } - this.clusterNameExpression = parser.parseExpression(clusterNameExpression); - this.combineHostPort = turbineProperties.isCombineHostPort(); - } - - protected Expression getClusterNameExpression() { - return clusterNameExpression; - } - - public TurbineProperties getTurbineProperties() { - return turbineProperties; - } - - protected boolean isCombineHostPort() { - return combineHostPort; - } - - /** - * Method that queries DiscoveryClient for a list of configured application names. - * @return Collection of instances - */ - @Override - public Collection getInstanceList() throws Exception { - List instances = new ArrayList<>(); - List appNames = getApplications(); - if (appNames == null || appNames.size() == 0) { - log.info("No apps configured, returning an empty instance list"); - return instances; - } - log.info("Fetching instance list for apps: " + appNames); - for (String appName : appNames) { - try { - instances.addAll(getInstancesForApp(appName)); - } - catch (Exception ex) { - log.error("Failed to fetch instances for app: " + appName - + ", retrying once more", ex); - try { - instances.addAll(getInstancesForApp(appName)); - } - catch (Exception retryException) { - log.error("Failed again to fetch instances for app: " + appName - + ", giving up", ex); - } - } - } - return instances; - } - - protected List getApplications() { - return turbineProperties.getAppConfigList(); - } - - /** - * helper that fetches the Instances for each application from DiscoveryClient. - * @param serviceId Id of the service whose instances should be returned - * @return List of instances - * @throws Exception - retrieving and marshalling service instances may result in an - * Exception - */ - protected List getInstancesForApp(String serviceId) throws Exception { - List instances = new ArrayList<>(); - log.info("Fetching instances for app: " + serviceId); - List serviceInstances = discoveryClient.getInstances(serviceId); - if (serviceInstances == null || serviceInstances.isEmpty()) { - log.warn("DiscoveryClient returned null or empty for service: " + serviceId); - return instances; - } - try { - log.info("Received instance list for service: " + serviceId + ", size=" - + serviceInstances.size()); - for (ServiceInstance serviceInstance : serviceInstances) { - Instance instance = marshall(serviceInstance); - if (instance != null) { - instances.add(instance); - } - } - } - catch (Exception e) { - log.warn("Failed to retrieve instances from DiscoveryClient", e); - } - return instances; - } - - /** - * Private helper that marshals the information from each instance into something that - * Turbine can understand. Override this method for your own implementation. - * @param serviceInstance whose information should be marshaled - * @return Instance - */ - Instance marshall(ServiceInstance serviceInstance) { - String hostname = serviceInstance.getHost(); - String managementPort = serviceInstance.getMetadata().get("management.port"); - String port = managementPort == null ? String.valueOf(serviceInstance.getPort()) - : managementPort; - String cluster = getClusterName(serviceInstance); - Boolean status = Boolean.TRUE; // TODO: where to get? - if (hostname != null && cluster != null && status != null) { - Instance instance = getInstance(hostname, port, cluster, status); - - Map metadata = serviceInstance.getMetadata(); - boolean securePortEnabled = serviceInstance.isSecure(); - - addMetadata(instance, hostname, port, securePortEnabled, port, metadata); - - return instance; - } - else { - return null; - } - } - - protected void addMetadata(Instance instance, String hostname, String port, - boolean securePortEnabled, String securePort, Map metadata) { - // add metadata - if (metadata != null) { - instance.getAttributes().putAll(metadata); - } - - // add ports - instance.getAttributes().put(PORT_KEY, port); - if (securePortEnabled) { - instance.getAttributes().put(SECURE_PORT_KEY, securePort); - } - if (this.isCombineHostPort()) { - String fusedHostPort = securePortEnabled ? hostname + ":" + securePort - : instance.getHostname(); - instance.getAttributes().put(FUSED_HOST_PORT_KEY, fusedHostPort); - } - } - - protected Instance getInstance(String hostname, String port, String cluster, - Boolean status) { - String hostPart = this.isCombineHostPort() ? hostname + ":" + port : hostname; - return new Instance(hostPart, cluster, status); - } - - /** - * Helper that fetches the cluster name. Cluster is a Turbine concept and not a - * commons concept. By default we choose the amazon serviceId as the cluster. A custom - * implementation can be plugged in by overriding this method. - * @param object cluster whose name should be evaluated - * @return String name of the cluster - */ - protected String getClusterName(Object object) { - StandardEvaluationContext context = new StandardEvaluationContext(object); - Object value = this.clusterNameExpression.getValue(context); - if (value != null) { - return value.toString(); - } - return null; - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/ConfigurationBasedTurbineClustersProvider.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/ConfigurationBasedTurbineClustersProvider.java deleted file mode 100644 index ed755a4a2..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/ConfigurationBasedTurbineClustersProvider.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Provides clusters names for Turbine based on configuration value. - * - * @author Anastasiia Smirnova - */ -public class ConfigurationBasedTurbineClustersProvider - implements TurbineClustersProvider { - - private static final Log log = LogFactory - .getLog(ConfigurationBasedTurbineClustersProvider.class); - - private final TurbineAggregatorProperties properties; - - public ConfigurationBasedTurbineClustersProvider( - TurbineAggregatorProperties turbineAggregatorProperties) { - this.properties = turbineAggregatorProperties; - } - - @Override - public List getClusterNames() { - List clusterNames = properties.getClusterConfig(); - log.trace("Using clusters names: " + clusterNames); - return clusterNames; - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EnableTurbine.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EnableTurbine.java deleted file mode 100644 index c653c5c0f..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EnableTurbine.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2013-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.context.annotation.Import; - -/** - * @author Spencer Gibb - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Import(TurbineHttpConfiguration.class) -public @interface EnableTurbine { - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaBasedTurbineClustersProvider.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaBasedTurbineClustersProvider.java deleted file mode 100644 index f8f9bd5b8..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaBasedTurbineClustersProvider.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.discovery.EurekaClient; -import com.netflix.discovery.shared.Application; -import com.netflix.discovery.shared.Applications; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Provides clusters names for Turbine based on applications names registered in Eureka. - * - * @author Anastasiia Smirnova - */ -public class EurekaBasedTurbineClustersProvider implements TurbineClustersProvider { - - private static final Log log = LogFactory - .getLog(EurekaBasedTurbineClustersProvider.class); - - private final EurekaClient eurekaClient; - - public EurekaBasedTurbineClustersProvider(EurekaClient eurekaClient) { - this.eurekaClient = eurekaClient; - } - - @Override - public List getClusterNames() { - Applications applications = eurekaClient.getApplications(); - List registeredApplications = applications - .getRegisteredApplications(); - List appNames = new ArrayList<>(registeredApplications.size()); - for (Application application : registeredApplications) { - appNames.add(application.getName()); - } - log.trace("Using clusters names: " + appNames); - return appNames; - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java deleted file mode 100644 index 4693017e8..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import com.netflix.appinfo.AmazonInfo; -import com.netflix.appinfo.DataCenterInfo; -import com.netflix.appinfo.InstanceInfo; -import com.netflix.appinfo.InstanceInfo.InstanceStatus; -import com.netflix.discovery.EurekaClient; -import com.netflix.discovery.shared.Application; -import com.netflix.turbine.discovery.Instance; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Class that encapsulates an {@link com.netflix.turbine.discovery.InstanceDiscovery} - * implementation that uses Eureka (see https://github.com/Netflix/eureka) The plugin - * requires a list of applications configured. It then queries the set of instances for - * each application. Instance information retrieved from Eureka must be translated to - * something that Turbine can understand i.e the - * {@link com.netflix.turbine.discovery.Instance} class. - *

- * All the logic to perform this translation can be overriden here, so that you can - * provide your own implementation if needed. - * - * @author Spencer Gibb - */ -public class EurekaInstanceDiscovery extends CommonsInstanceDiscovery { - - private static final Log log = LogFactory.getLog(EurekaInstanceDiscovery.class); - - private static final String EUREKA_DEFAULT_CLUSTER_NAME_EXPRESSION = "appName"; - - private static final String ASG_KEY = "asg"; - - private final EurekaClient eurekaClient; - - public EurekaInstanceDiscovery(TurbineProperties turbineProperties, - EurekaClient eurekaClient) { - super(turbineProperties, EUREKA_DEFAULT_CLUSTER_NAME_EXPRESSION); - this.eurekaClient = eurekaClient; - } - - /** - * Private helper that fetches the Instances for each application. - * @param serviceId of the service that the instance list should be returned for - * @return List of instances for a given service id - * @throws Exception - retrieving and marshalling service instances may result in an - * Exception - */ - @Override - protected List getInstancesForApp(String serviceId) throws Exception { - List instances = new ArrayList<>(); - log.info("Fetching instances for app: " + serviceId); - Application app = eurekaClient.getApplication(serviceId); - if (app == null) { - log.warn("Eureka returned null for app: " + serviceId); - return instances; - } - try { - List instancesForApp = app.getInstances(); - if (instancesForApp != null) { - log.info("Received instance list for app: " + serviceId + ", size=" - + instancesForApp.size()); - for (InstanceInfo iInfo : instancesForApp) { - Instance instance = marshall(iInfo); - if (instance != null) { - instances.add(instance); - } - } - } - } - catch (Exception e) { - log.warn("Failed to retrieve instances from Eureka", e); - } - return instances; - } - - /** - * Private helper that marshals the information from each instance into something that - * Turbine can understand. Override this method for your own implementation for - * parsing Eureka info. - * @param instanceInfo {@link InstanceInfo} to marshal - * @return {@link Instance} marshaled from provided {@link InstanceInfo} - */ - Instance marshall(InstanceInfo instanceInfo) { - String hostname = instanceInfo.getHostName(); - final String managementPort = instanceInfo.getMetadata().get("management.port"); - String port = managementPort == null ? String.valueOf(instanceInfo.getPort()) - : managementPort; - String cluster = getClusterName(instanceInfo); - Boolean status = parseInstanceStatus(instanceInfo.getStatus()); - if (hostname != null && cluster != null && status != null) { - Instance instance = getInstance(hostname, port, cluster, status); - - Map metadata = instanceInfo.getMetadata(); - boolean securePortEnabled = instanceInfo - .isPortEnabled(InstanceInfo.PortType.SECURE); - String securePort = String.valueOf(instanceInfo.getSecurePort()); - - addMetadata(instance, hostname, port, securePortEnabled, securePort, - metadata); - - // add amazon metadata - String asgName = instanceInfo.getASGName(); - if (asgName != null) { - instance.getAttributes().put(ASG_KEY, asgName); - } - - DataCenterInfo dcInfo = instanceInfo.getDataCenterInfo(); - if (dcInfo != null && dcInfo.getName().equals(DataCenterInfo.Name.Amazon)) { - AmazonInfo amznInfo = (AmazonInfo) dcInfo; - instance.getAttributes().putAll(amznInfo.getMetadata()); - } - - return instance; - } - else { - return null; - } - } - - /** - * Helper that returns whether the instance is Up of Down. - * @param status {@link InstanceStatus} instance to evaluate the status from - * @return {@code true} if {@link InstanceStatus} is UP - */ - protected Boolean parseInstanceStatus(InstanceStatus status) { - if (status == null) { - return null; - } - return status == InstanceStatus.UP; - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringAggregatorFactory.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringAggregatorFactory.java deleted file mode 100644 index e264183a2..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringAggregatorFactory.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.util.Collection; - -import com.netflix.turbine.data.AggDataFromCluster; -import com.netflix.turbine.discovery.Instance; -import com.netflix.turbine.handler.PerformanceCriteria; -import com.netflix.turbine.handler.TurbineDataHandler; -import com.netflix.turbine.monitor.TurbineDataMonitor; -import com.netflix.turbine.monitor.cluster.AggregateClusterMonitor; -import com.netflix.turbine.monitor.cluster.ClusterMonitor; -import com.netflix.turbine.monitor.cluster.ClusterMonitorFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import static com.netflix.turbine.monitor.cluster.AggregateClusterMonitor.AggregatorClusterMonitorConsole; - -/** - * @author Spencer Gibb - */ -public class SpringAggregatorFactory - implements ClusterMonitorFactory { - - private static final Log log = LogFactory.getLog(SpringAggregatorFactory.class); - - private final TurbineClustersProvider clustersProvider; - - public SpringAggregatorFactory(TurbineClustersProvider clustersProvider) { - this.clustersProvider = clustersProvider; - } - - /** - * @return {@link com.netflix.turbine.monitor.cluster.ClusterMonitor} - * {@link com.netflix.turbine.data.AggDataFromCluster} - */ - @Override - public ClusterMonitor getClusterMonitor(String name) { - TurbineDataMonitor clusterMonitor = AggregateClusterMonitor.AggregatorClusterMonitorConsole - .findMonitor(name + "_agg"); - return (ClusterMonitor) clusterMonitor; - } - - public static TurbineDataMonitor findOrRegisterAggregateMonitor( - String clusterName) { - TurbineDataMonitor clusterMonitor = AggregatorClusterMonitorConsole - .findMonitor(clusterName + "_agg"); - if (clusterMonitor == null) { - log.info("Could not find monitors: " - + AggregatorClusterMonitorConsole.toString()); - clusterMonitor = new SpringClusterMonitor(clusterName + "_agg", clusterName); - clusterMonitor = AggregatorClusterMonitorConsole - .findOrRegisterMonitor(clusterMonitor); - } - return clusterMonitor; - } - - @Override - public void initClusterMonitors() { - for (String clusterName : clustersProvider.getClusterNames()) { - - ClusterMonitor clusterMonitor = (ClusterMonitor) findOrRegisterAggregateMonitor( - clusterName); - clusterMonitor.registerListenertoClusterMonitor(this.StaticListener); - try { - clusterMonitor.startMonitor(); - } - catch (Exception ex) { - log.warn("Could not init cluster monitor for: " + clusterName); - clusterMonitor.stopMonitor(); - clusterMonitor.getDispatcher().stopDispatcher(); - } - } - } - - /** - * shutdown all configured cluster monitors. - */ - @Override - public void shutdownClusterMonitors() { - for (String clusterName : clustersProvider.getClusterNames()) { - ClusterMonitor clusterMonitor = (ClusterMonitor) AggregateClusterMonitor - .findOrRegisterAggregateMonitor(clusterName); - clusterMonitor.stopMonitor(); - clusterMonitor.getDispatcher().stopDispatcher(); - } - } - - private TurbineDataHandler StaticListener = new TurbineDataHandler() { - - @Override - public String getName() { - return "StaticListener_For_Aggregator"; - } - - @Override - public void handleData(Collection stats) { - } - - @Override - public void handleHostLost(Instance host) { - } - - @Override - public PerformanceCriteria getCriteria() { - return SpringAggregatorFactory.this.NonCriticalCriteria; - } - - }; - - private PerformanceCriteria NonCriticalCriteria = new PerformanceCriteria() { - - @Override - public boolean isCritical() { - return false; - } - - @Override - public int getMaxQueueSize() { - return 0; - } - - @Override - public int numThreads() { - return 0; - } - - }; - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringClusterMonitor.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringClusterMonitor.java deleted file mode 100644 index a476609af..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringClusterMonitor.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import com.netflix.config.DynamicBooleanProperty; -import com.netflix.config.DynamicPropertyFactory; -import com.netflix.config.DynamicStringProperty; -import com.netflix.turbine.discovery.Instance; -import com.netflix.turbine.handler.PerformanceCriteria; -import com.netflix.turbine.monitor.MonitorConsole; -import com.netflix.turbine.monitor.cluster.AggregateClusterMonitor; -import com.netflix.turbine.monitor.cluster.ObservationCriteria; -import com.netflix.turbine.monitor.instance.InstanceUrlClosure; - -/** - * @author Spencer Gibb - */ -public class SpringClusterMonitor extends AggregateClusterMonitor { - - // TODO: convert to ConfigurationProperties (how to do per-cluster configuration? - - public SpringClusterMonitor(String name, String clusterName) { - super(name, new ObservationCriteria.ClusterBasedObservationCriteria(clusterName), - new PerformanceCriteria.AggClusterPerformanceCriteria(clusterName), - new MonitorConsole<>(), InstanceMonitorDispatcher, - SpringClusterMonitor.ClusterConfigBasedUrlClosure); - } - - /** - * TODO: make this a template of some kind (secure, management port, etc...) Helper - * class that decides how to connect to a server based on injected config. Note that - * the cluster name must be provided here since one can have different configs for - * different clusters - */ - public static InstanceUrlClosure ClusterConfigBasedUrlClosure = new InstanceUrlClosure() { - - private final DynamicStringProperty defaultUrlClosureConfig = DynamicPropertyFactory - .getInstance().getStringProperty("turbine.instanceUrlSuffix", - "actuator/hystrix.stream"); - - private final DynamicBooleanProperty instanceInsertPort = DynamicPropertyFactory - .getInstance().getBooleanProperty("turbine.instanceInsertPort", true); - - @Override - public String getUrlPath(Instance host) { - if (host.getCluster() == null) { - throw new RuntimeException( - "Host must have cluster name in order to use ClusterConfigBasedUrlClosure"); - } - - // find url - String key = "turbine.instanceUrlSuffix." + host.getCluster(); - DynamicStringProperty urlClosureConfig = DynamicPropertyFactory.getInstance() - .getStringProperty(key, null); - String url = urlClosureConfig.get(); - if (url == null) { - url = this.defaultUrlClosureConfig.get(); - } - if (url == null) { - throw new RuntimeException("Config property: " - + urlClosureConfig.getName() + " or " - + this.defaultUrlClosureConfig.getName() + " must be set"); - } - - // find port and scheme - String port; - String scheme; - if (host.getAttributes().containsKey("securePort")) { - port = host.getAttributes().get("securePort"); - scheme = "https"; - } - else { - port = host.getAttributes().get("port"); - scheme = "http"; - } - - if (host.getAttributes().containsKey("fusedHostPort")) { - return String.format("%s://%s/%s", scheme, - host.getAttributes().get("fusedHostPort"), url); - } - - // determine if to insert port - String insertPortKey = "turbine.instanceInsertPort." + host.getCluster(); - DynamicStringProperty insertPortProp = DynamicPropertyFactory.getInstance() - .getStringProperty(insertPortKey, null); - boolean insertPort; - if (insertPortProp.get() == null) { - insertPort = this.instanceInsertPort.get(); - } - else { - insertPort = Boolean.parseBoolean(insertPortProp.get()); - } - - // format url with port - if (insertPort) { - if (url.startsWith("/")) { - url = url.substring(1); - } - if (port == null) { - throw new RuntimeException( - "Configured to use port, but port or securePort is not in host attributes"); - } - - return String.format("%s://%s:%s/%s", scheme, host.getHostname(), port, - url); - } - - // format url without port - return scheme + "://" + host.getHostname() + url; - } - }; - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineAggregatorProperties.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineAggregatorProperties.java deleted file mode 100644 index 739202baa..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineAggregatorProperties.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Anastasiia Smirnova - */ -@ConfigurationProperties("turbine.aggregator") -public class TurbineAggregatorProperties { - - private static final String DEFAULT = "default"; - - /** - * The list of cluster names. - */ - private List clusterConfig = Collections.singletonList(DEFAULT); - - public List getClusterConfig() { - return clusterConfig; - } - - public void setClusterConfig(List clusterConfig) { - this.clusterConfig = clusterConfig; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - TurbineAggregatorProperties that = (TurbineAggregatorProperties) o; - return Objects.equals(clusterConfig, that.clusterConfig); - } - - @Override - public int hashCode() { - return Objects.hash(clusterConfig); - } - - @Override - public String toString() { - return "TurbineAggregatorProperties{" + "clusterConfig='" + clusterConfig + '\'' - + '}'; - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineClustersProvider.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineClustersProvider.java deleted file mode 100644 index 760c05870..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineClustersProvider.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.util.List; - -/** - * Interface that gives possibility to customize which clusters names Turbine will use. - * - * @author Anastasiia Smirnova - */ -public interface TurbineClustersProvider { - - List getClusterNames(); - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineController.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineController.java deleted file mode 100644 index ad6928cd4..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineController.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2018-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.util.Collection; - -import javax.servlet.http.HttpServletRequest; - -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * Defines endpoints to use with the Turbine. - * - * @author Anastasiia Smirnova - */ -@RestController -public class TurbineController { - - private final TurbineInformationService turbineInformationService; - - public TurbineController(TurbineInformationService turbineInformationService) { - this.turbineInformationService = turbineInformationService; - } - - @GetMapping(value = "/clusters", produces = MediaType.APPLICATION_JSON_VALUE) - public Collection clusters(HttpServletRequest request) { - return turbineInformationService.getClusterInformations(request); - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineHttpConfiguration.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineHttpConfiguration.java deleted file mode 100644 index e4affe6c7..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineHttpConfiguration.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import com.netflix.discovery.EurekaClient; -import com.netflix.turbine.discovery.InstanceDiscovery; -import com.netflix.turbine.monitor.cluster.ClusterMonitorFactory; -import com.netflix.turbine.streaming.servlet.TurbineStreamServlet; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties -public class TurbineHttpConfiguration { - - @Bean - public HasFeatures Feature() { - return HasFeatures.namedFeature("Turbine (HTTP)", TurbineHttpConfiguration.class); - } - - @Bean - @ConditionalOnMissingBean(name = "turbineStreamServlet") - public ServletRegistrationBean turbineStreamServlet() { - return new ServletRegistrationBean(new TurbineStreamServlet(), "/turbine.stream"); - } - - @Bean - @ConditionalOnMissingBean - public TurbineProperties turbineProperties() { - return new TurbineProperties(); - } - - @Bean - @ConditionalOnMissingBean - public TurbineInformationService turbineInformationService() { - return new TurbineInformationService(); - } - - @Bean - @ConditionalOnProperty(value = "turbine.endpoints.clusters.enabled", - matchIfMissing = true) - public TurbineController turbineController(TurbineInformationService service) { - return new TurbineController(service); - } - - @Bean - @ConditionalOnMissingBean - public TurbineAggregatorProperties turbineAggregatorProperties() { - return new TurbineAggregatorProperties(); - } - - @Bean - @ConditionalOnMissingBean - public TurbineLifecycle turbineLifecycle(InstanceDiscovery instanceDiscovery, - ClusterMonitorFactory factory) { - return new TurbineLifecycle(instanceDiscovery, factory); - } - - @Bean - @ConditionalOnMissingBean - public ClusterMonitorFactory clusterMonitorFactory( - TurbineClustersProvider clustersProvider) { - return new SpringAggregatorFactory(clustersProvider); - } - - @Bean - @ConditionalOnMissingBean - public TurbineClustersProvider clustersProvider( - TurbineAggregatorProperties turbineAggregatorProperties) { - return new ConfigurationBasedTurbineClustersProvider(turbineAggregatorProperties); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(EurekaClient.class) - protected static class EurekaTurbineConfiguration { - - @Bean - @ConditionalOnMissingBean - public InstanceDiscovery instanceDiscovery(TurbineProperties turbineProperties, - EurekaClient eurekaClient) { - return new EurekaInstanceDiscovery(turbineProperties, eurekaClient); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnMissingClass("com.netflix.discovery.EurekaClient") - protected static class DiscoveryClientTurbineConfiguration { - - @Bean - @ConditionalOnMissingBean - public InstanceDiscovery instanceDiscovery(TurbineProperties turbineProperties, - DiscoveryClient discoveryClient) { - return new CommonsInstanceDiscovery(turbineProperties, discoveryClient); - } - - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineInformationService.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineInformationService.java deleted file mode 100644 index ae403153c..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineInformationService.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2018-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.turbine.data.AggDataFromCluster; -import com.netflix.turbine.data.DataFromSingleInstance; -import com.netflix.turbine.monitor.MonitorConsole; -import com.netflix.turbine.monitor.TurbineDataMonitor; -import com.netflix.turbine.monitor.cluster.ClusterMonitor; - -import org.springframework.http.server.ServletServerHttpRequest; -import org.springframework.web.util.UriComponents; -import org.springframework.web.util.UriComponentsBuilder; - -import static com.netflix.turbine.monitor.cluster.AggregateClusterMonitor.AggregatorClusterMonitorConsole; - -/** - * Service providing information on Turbine clusters. - * - * @author Anastasiia Smirnova - */ -public class TurbineInformationService { - - public Collection getClusterInformations( - HttpServletRequest request) { - String hostName = getHostName(request); - return getClusterInformations(hostName); - } - - private Collection getClusterInformations(String hostName) { - Collection> monitors = AggregatorClusterMonitorConsole - .getAllMonitors(); - List clusterInformations = new ArrayList<>(); - for (TurbineDataMonitor monitor : monitors) { - ClusterMonitor clusterMonitor = (ClusterMonitor) monitor; - MonitorConsole instanceConsole = clusterMonitor - .getInstanceMonitors(); - for (TurbineDataMonitor single : instanceConsole - .getAllMonitors()) { - String cluster = single.getStatsInstance().getCluster(); - ClusterInformation info = new ClusterInformation(cluster, - getLink(hostName, cluster)); - clusterInformations.add(info); - } - } - return clusterInformations; - } - - private String getLink(String hostName, String cluster) { - return hostName + "/turbine.stream?cluster=" + cluster; - } - - private String getHostName(HttpServletRequest request) { - UriComponents components = UriComponentsBuilder - .fromHttpRequest(new ServletServerHttpRequest(request)).build(); - String host = components.getHost(); - int port = components.getPort(); - String scheme = components.getScheme(); - if (port > -1) { - return String.format("%s://%s:%d", scheme, host, port); - } - return String.format("%s://%s", scheme, host); - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineLifecycle.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineLifecycle.java deleted file mode 100644 index f6290064b..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineLifecycle.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import com.netflix.turbine.discovery.InstanceDiscovery; -import com.netflix.turbine.init.TurbineInit; -import com.netflix.turbine.monitor.cluster.ClusterMonitorFactory; -import com.netflix.turbine.plugins.PluginsFactory; - -import org.springframework.context.SmartLifecycle; -import org.springframework.core.Ordered; - -/** - * @author Spencer Gibb - */ -public class TurbineLifecycle implements SmartLifecycle, Ordered { - - private final InstanceDiscovery instanceDiscovery; - - private final ClusterMonitorFactory factory; - - private volatile boolean running; - - public TurbineLifecycle(InstanceDiscovery instanceDiscovery, - ClusterMonitorFactory factory) { - this.instanceDiscovery = instanceDiscovery; - this.factory = factory; - } - - @Override - public boolean isAutoStartup() { - return true; - } - - @Override - public void stop(Runnable callback) { - callback.run(); - } - - @Override - public void start() { - PluginsFactory.setClusterMonitorFactory(factory); - PluginsFactory.setInstanceDiscovery(instanceDiscovery); - TurbineInit.init(); - } - - @Override - public void stop() { - this.running = false; - } - - @Override - public boolean isRunning() { - return this.running; - } - - @Override - public int getPhase() { - return 0; - } - - @Override - public int getOrder() { - return -1; - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineProperties.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineProperties.java deleted file mode 100644 index cd27d300b..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineProperties.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2013-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.util.Arrays; -import java.util.List; -import java.util.Objects; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.util.StringUtils; - -/** - * @author Spencer Gibb - * @author Gregor Zurowski - */ -@ConfigurationProperties("turbine") -public class TurbineProperties { - - private String clusterNameExpression; - - private String appConfig; - - private boolean combineHostPort = true; - - public List getAppConfigList() { - if (!StringUtils.hasText(this.appConfig)) { - return null; - } - String[] parts = StringUtils.commaDelimitedListToStringArray(this.appConfig); - if (parts != null && parts.length > 0) { - parts = StringUtils.trimArrayElements(parts); - return Arrays.asList(parts); - } - return null; - } - - public String getClusterNameExpression() { - return clusterNameExpression; - } - - public void setClusterNameExpression(String clusterNameExpression) { - this.clusterNameExpression = clusterNameExpression; - } - - public String getAppConfig() { - return appConfig; - } - - public void setAppConfig(String appConfig) { - this.appConfig = appConfig; - } - - public boolean isCombineHostPort() { - return combineHostPort; - } - - public void setCombineHostPort(boolean combineHostPort) { - this.combineHostPort = combineHostPort; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - TurbineProperties that = (TurbineProperties) o; - return Objects.equals(clusterNameExpression, that.clusterNameExpression) - && Objects.equals(appConfig, that.appConfig) - && Objects.equals(combineHostPort, that.combineHostPort); - } - - @Override - public int hashCode() { - return Objects.hash(clusterNameExpression, appConfig, combineHostPort); - } - - @Override - public String toString() { - return new StringBuilder("TurbineProperties{").append("clusterNameExpression='") - .append(clusterNameExpression).append("', ").append("appConfig='") - .append(appConfig).append("', ").append("combineHostPort=") - .append(combineHostPort).append("}").toString(); - } - -} diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/AdhocTurbineTestSuite.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/AdhocTurbineTestSuite.java deleted file mode 100644 index 3248216c1..000000000 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/AdhocTurbineTestSuite.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import org.junit.Ignore; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -@RunWith(Suite.class) -@Suite.SuiteClasses({ - // org.springframework.cloud.netflix.turbine.EurekaBasedTurbineClustersProviderTest.class, - // org.springframework.cloud.netflix.turbine.ConfigurationBasedTurbineClustersProviderTest.class, - // org.springframework.cloud.netflix.turbine.CommonsInstanceDiscoveryTests.class, - // org.springframework.cloud.netflix.turbine.TurbineAggregatorPropertiesTest.class, - // org.springframework.cloud.netflix.turbine.TurbineHttpTests.class, - // org.springframework.cloud.netflix.turbine.EurekaInstanceDiscoveryTests.class, -}) -@Ignore -public class AdhocTurbineTestSuite { - -} diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscoveryTests.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscoveryTests.java deleted file mode 100644 index 5893b340f..000000000 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscoveryTests.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.util.Collections; - -import com.netflix.turbine.discovery.Instance; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * @author Spencer Gibb - */ -public class CommonsInstanceDiscoveryTests { - - private DiscoveryClient discoveryClient; - - private TurbineProperties turbineProperties; - - @Before - public void setUp() throws Exception { - this.discoveryClient = mock(DiscoveryClient.class); - this.turbineProperties = new TurbineProperties(); - } - - @Test - public void testSecureCombineHostPort() { - turbineProperties.setCombineHostPort(true); - CommonsInstanceDiscovery discovery = createDiscovery(); - String appName = "testAppName"; - int port = 8443; - String hostName = "myhost"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - hostName, port, true); - Instance instance = discovery.marshall(serviceInstance); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - assertThat(instance.getAttributes().get("securePort")).as("securePort is wrong") - .isEqualTo(String.valueOf(port)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "https://" + hostName + ":" + port + "/actuator/hystrix.stream"); - } - - @Test - public void testCombineHostPort() { - turbineProperties.setCombineHostPort(true); - CommonsInstanceDiscovery discovery = createDiscovery(); - String appName = "testAppName"; - int port = 8080; - String hostName = "myhost"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - hostName, port, false); - Instance instance = discovery.marshall(serviceInstance); - assertThat(instance.getHostname()).as("hostname is wrong") - .isEqualTo(hostName + ":" + port); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "http://" + hostName + ":" + port + "/actuator/hystrix.stream"); - - String clusterName = discovery.getClusterName(serviceInstance); - assertThat(clusterName).as("clusterName is wrong").isEqualTo(appName); - } - - @Test - public void testGetClusterName() { - CommonsInstanceDiscovery discovery = createDiscovery(); - String appName = "testAppName"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - "myhost", 8080, false); - String clusterName = discovery.getClusterName(serviceInstance); - assertThat(clusterName).as("clusterName is wrong").isEqualTo(appName); - } - - @Test - public void testGetPort() { - CommonsInstanceDiscovery discovery = createDiscovery(); - String appName = "testAppName"; - int port = 8080; - String hostName = "myhost"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - hostName, port, false); - Instance instance = discovery.marshall(serviceInstance); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "http://" + hostName + ":" + port + "/actuator/hystrix.stream"); - } - - @Test - public void testUseManagementPortFromMetadata() { - CommonsInstanceDiscovery discovery = createDiscovery(); - String appName = "testAppName"; - int port = 8080; - int managementPort = 8081; - String hostName = "myhost"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - hostName, port, false); - serviceInstance.getMetadata().put("management.port", - String.valueOf(managementPort)); - Instance instance = discovery.marshall(serviceInstance); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(managementPort)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "http://" + hostName + ":" + managementPort + "/actuator/hystrix.stream"); - } - - @Test - public void testGetSecurePort() { - CommonsInstanceDiscovery discovery = createDiscovery(); - String appName = "testAppName"; - // int port = 8080; - int port = 8443; - String hostName = "myhost"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - hostName, port, true); - Instance instance = discovery.marshall(serviceInstance); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - assertThat(instance.getAttributes().get("securePort")).as("securePort is wrong") - .isEqualTo(String.valueOf(port)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "https://" + hostName + ":" + port + "/actuator/hystrix.stream"); - } - - @Test - public void testGetClusterNameCustomExpression() { - turbineProperties.setClusterNameExpression("host"); - CommonsInstanceDiscovery discovery = createDiscovery(); - String appName = "testAppName"; - String hostName = "myhost"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - hostName, 8080, true); - String clusterName = discovery.getClusterName(serviceInstance); - assertThat(clusterName).as("clusterName is wrong").isEqualTo(hostName); - } - - @Test - public void testGetClusterNameInstanceMetadataMapExpression() { - turbineProperties.setClusterNameExpression("metadata['cluster']"); - CommonsInstanceDiscovery discovery = createDiscovery(); - String metadataProperty = "myCluster"; - String appName = "testAppName"; - String hostName = "myhost"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - hostName, 8080, true, - Collections.singletonMap("cluster", metadataProperty)); - String clusterName = discovery.getClusterName(serviceInstance); - assertThat(clusterName).as("clusterName is wrong").isEqualTo(metadataProperty); - } - - private CommonsInstanceDiscovery createDiscovery() { - return new CommonsInstanceDiscovery(turbineProperties, discoveryClient); - } - -} diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/ConfigurationBasedTurbineClustersProviderTest.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/ConfigurationBasedTurbineClustersProviderTest.java deleted file mode 100644 index d2507c8fa..000000000 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/ConfigurationBasedTurbineClustersProviderTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.util.Arrays; -import java.util.List; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class ConfigurationBasedTurbineClustersProviderTest { - - @Test - public void shouldReturnDefaultClusterIfConfigurationIsEmpty() throws Exception { - TurbineAggregatorProperties properties = new TurbineAggregatorProperties(); - TurbineClustersProvider provider = new ConfigurationBasedTurbineClustersProvider( - properties); - List clusterNames = provider.getClusterNames(); - - assertThat(clusterNames).containsOnly("default"); - } - - @Test - public void shouldReturnConfiguredClusters() throws Exception { - TurbineAggregatorProperties properties = new TurbineAggregatorProperties(); - properties.setClusterConfig(Arrays.asList("cluster1", "cluster2", "cluster3")); - TurbineClustersProvider provider = new ConfigurationBasedTurbineClustersProvider( - properties); - List clusterNames = provider.getClusterNames(); - - assertThat(clusterNames).containsOnly("cluster1", "cluster2", "cluster3"); - } - -} diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaBasedTurbineClustersProviderTest.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaBasedTurbineClustersProviderTest.java deleted file mode 100644 index 75550c321..000000000 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaBasedTurbineClustersProviderTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.util.List; - -import com.netflix.discovery.EurekaClient; -import com.netflix.discovery.shared.Application; -import com.netflix.discovery.shared.Applications; -import org.junit.Test; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class EurekaBasedTurbineClustersProviderTest { - - EurekaClient eurekaClient = mock(EurekaClient.class); - - TurbineClustersProvider provider = new EurekaBasedTurbineClustersProvider( - eurekaClient); - - @Test - public void shouldProvideAllClustersNames() throws Exception { - Applications applications = registeredApplications(asList(application("service1"), - application("service2"), application("service3"))); - when(eurekaClient.getApplications()).thenReturn(applications); - - List clusterNames = provider.getClusterNames(); - - assertThat(clusterNames).containsOnly("service1", "service2", "service3"); - } - - private Applications registeredApplications(List registered) { - Applications applications = mock(Applications.class); - when(applications.getRegisteredApplications()).thenReturn(registered); - return applications; - } - - private Application application(String name) { - Application application = mock(Application.class); - when(application.getName()).thenReturn(name); - return application; - } - -} diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTests.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTests.java deleted file mode 100644 index 9df959959..000000000 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTests.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import com.netflix.appinfo.InstanceInfo; -import com.netflix.discovery.EurekaClient; -import com.netflix.turbine.discovery.Instance; -import org.junit.Before; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * @author Spencer Gibb - */ -public class EurekaInstanceDiscoveryTests { - - private EurekaClient eurekaClient; - - private TurbineProperties turbineProperties; - - private InstanceInfo.Builder builder; - - @Before - public void setUp() throws Exception { - eurekaClient = mock(EurekaClient.class); - turbineProperties = new TurbineProperties(); - builder = InstanceInfo.Builder.newBuilder(); - } - - @Test - public void testSecureCombineHostPort() { - turbineProperties.setCombineHostPort(true); - EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, - eurekaClient); - String appName = "testAppName"; - int port = 8080; - int securePort = 8443; - String hostName = "myhost"; - InstanceInfo instanceInfo = builder.setAppName(appName).setHostName(hostName) - .setPort(port).setSecurePort(securePort) - .enablePort(InstanceInfo.PortType.SECURE, true).build(); - Instance instance = discovery.marshall(instanceInfo); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - assertThat(instance.getAttributes().get("securePort")).as("securePort is wrong") - .isEqualTo(String.valueOf(securePort)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "https://" + hostName + ":" + securePort + "/actuator/hystrix.stream"); - } - - @Test - public void testCombineHostPort() { - turbineProperties.setCombineHostPort(true); - EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, - eurekaClient); - String appName = "testAppName"; - int port = 8080; - String hostName = "myhost"; - InstanceInfo instanceInfo = builder.setAppName(appName).setHostName(hostName) - .setPort(port).build(); - Instance instance = discovery.marshall(instanceInfo); - assertThat(instance.getHostname()).as("hostname is wrong") - .isEqualTo(hostName + ":" + port); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "http://" + hostName + ":" + port + "/actuator/hystrix.stream"); - - String clusterName = discovery.getClusterName(instanceInfo); - assertThat(clusterName).as("clusterName is wrong") - .isEqualTo(appName.toUpperCase()); - } - - @Test - public void testUseManagementPortFromMetadata() { - EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, - eurekaClient); - String appName = "testAppName"; - int port = 8080; - int managementPort = 8081; - String hostName = "myhost"; - InstanceInfo instanceInfo = builder.setAppName(appName).setHostName(hostName) - .setPort(port).build(); - instanceInfo.getMetadata().put("management.port", "8081"); - Instance instance = discovery.marshall(instanceInfo); - assertThat(instance.getHostname()).as("hostname is wrong") - .isEqualTo(hostName + ":" + managementPort); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(managementPort)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "http://" + hostName + ":" + managementPort + "/actuator/hystrix.stream"); - - String clusterName = discovery.getClusterName(instanceInfo); - assertThat(clusterName).as("clusterName is wrong") - .isEqualTo(appName.toUpperCase()); - } - - @Test - public void testGetClusterName() { - EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, - eurekaClient); - String appName = "testAppName"; - InstanceInfo instanceInfo = builder.setAppName(appName).build(); - String clusterName = discovery.getClusterName(instanceInfo); - assertThat(clusterName).as("clusterName is wrong") - .isEqualTo(appName.toUpperCase()); - } - - @Test - public void testGetPort() { - EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, - eurekaClient); - String appName = "testAppName"; - int port = 8080; - String hostName = "myhost"; - InstanceInfo instanceInfo = builder.setAppName(appName).setHostName(hostName) - .setPort(port).build(); - Instance instance = discovery.marshall(instanceInfo); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "http://" + hostName + ":" + port + "/actuator/hystrix.stream"); - } - - @Test - public void testGetSecurePort() { - EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, - eurekaClient); - String appName = "testAppName"; - int port = 8080; - int securePort = 8443; - String hostName = "myhost"; - InstanceInfo instanceInfo = builder.setAppName(appName).setHostName(hostName) - .setPort(port).setSecurePort(securePort) - .enablePort(InstanceInfo.PortType.SECURE, true).build(); - Instance instance = discovery.marshall(instanceInfo); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - assertThat(instance.getAttributes().get("securePort")).as("securePort is wrong") - .isEqualTo(String.valueOf(securePort)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "https://" + hostName + ":" + securePort + "/actuator/hystrix.stream"); - } - - @Test - public void testGetClusterNameCustomExpression() { - turbineProperties.setClusterNameExpression("aSGName"); - EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, - eurekaClient); - String asgName = "myAsgName"; - InstanceInfo instanceInfo = builder.setAppName("testApp").setASGName(asgName) - .build(); - String clusterName = discovery.getClusterName(instanceInfo); - assertThat(clusterName).as("clusterName is wrong").isEqualTo(asgName); - } - - @Test - public void testGetClusterNameInstanceMetadataMapExpression() { - turbineProperties.setClusterNameExpression("metadata['cluster']"); - EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, - eurekaClient); - String metadataProperty = "myCluster"; - InstanceInfo instanceInfo = builder.setAppName("testApp") - .add("cluster", metadataProperty).build(); - String clusterName = discovery.getClusterName(instanceInfo); - assertThat(clusterName).as("clusterName is wrong").isEqualTo(metadataProperty); - } - -} diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/TurbineAggregatorPropertiesTest.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/TurbineAggregatorPropertiesTest.java deleted file mode 100644 index 39e4108ed..000000000 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/TurbineAggregatorPropertiesTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import org.junit.After; -import org.junit.Test; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -public class TurbineAggregatorPropertiesTest { - - private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - - @After - public void clear() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - public void shouldHaveDefaultConfiguration() throws Exception { - setupContext(); - - TurbineAggregatorProperties actual = getProperties(); - assertThat(actual.getClusterConfig()).containsOnly("default"); - } - - @Test - public void shouldLoadCustomProperties() { - TestPropertyValues - .of("turbine.aggregator.clusterConfig=cluster1, cluster2, cluster3") - .applyTo(this.context); - setupContext(); - - TurbineAggregatorProperties actual = getProperties(); - assertThat(actual.getClusterConfig()).containsOnly("cluster1", "cluster2", - "cluster3"); - } - - private void setupContext() { - this.context.register(TestConfiguration.class); - this.context.refresh(); - } - - private TurbineAggregatorProperties getProperties() { - return this.context.getBean(TurbineAggregatorProperties.class); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(TurbineAggregatorProperties.class) - static class TestConfiguration { - - } - -} diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/TurbineHttpTests.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/TurbineHttpTests.java deleted file mode 100644 index ebf0a5aad..000000000 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/TurbineHttpTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.turbine; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TurbineHttpTests.TurbineHttpSampleApplication.class, - webEnvironment = WebEnvironment.RANDOM_PORT) -public class TurbineHttpTests { - - private static final ClusterInformation foo = new ClusterInformation("foo", - "https://foo"); - - private static final ClusterInformation bar = new ClusterInformation("bar", - "https://bar"); - - @Autowired - TestRestTemplate rest; - - @Test - public void contextLoads() { - ClusterInformation[] clusters = rest.getForObject("/clusters", - ClusterInformation[].class); - System.err.println(Arrays.asList(clusters)); - assertThat(clusters.length).isEqualTo(2); - assertThat(clusters[0]).isEqualTo(foo); - assertThat(clusters[1]).isEqualTo(bar); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableTurbine - protected static class TurbineHttpSampleApplication { - - @Bean - @Primary - TurbineInformationService myInfoService() { - return new TurbineInformationService() { - @Override - public Collection getClusterInformations( - HttpServletRequest request) { - List clusterInformationList = new ArrayList<>(); - clusterInformationList.add(foo); - clusterInformationList.add(bar); - return clusterInformationList; - } - }; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/pom.xml b/spring-cloud-netflix-zuul/pom.xml deleted file mode 100644 index 904f77acb..000000000 --- a/spring-cloud-netflix-zuul/pom.xml +++ /dev/null @@ -1,128 +0,0 @@ - - - 4.0.0 - - spring-cloud-netflix - org.springframework.cloud - 2.2.2.BUILD-SNAPSHOT - .. - - - - spring-cloud-netflix-zuul - jar - Spring Cloud Netflix Zuul - Spring Cloud Netflix Zuul - - - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.apache.httpcomponents - httpclient - - - org.springframework.boot - spring-boot-configuration-processor - true - - - com.netflix.hystrix - hystrix-core - true - - - com.netflix.ribbon - ribbon-loadbalancer - true - - - com.netflix.ribbon - ribbon-core - true - - - com.netflix.ribbon - ribbon-httpclient - true - - - org.springframework.boot - spring-boot-starter-actuator - true - - - org.springframework.boot - spring-boot-starter-web - true - - - org.springframework.boot - spring-boot-starter-security - true - - - org.springframework.cloud - spring-cloud-commons - true - - - org.springframework.cloud - spring-cloud-context - true - - - com.netflix.zuul - zuul-core - true - - - groovy-all - org.codehaus.groovy - - - mockito-all - org.mockito - - - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - true - - - com.netflix.netflix-commons - netflix-commons-util - - - org.springframework.cloud - spring-cloud-starter-netflix-hystrix - - - org.springframework.retry - spring-retry - true - - - org.springframework.cloud - spring-cloud-test-support - test - - - org.springframework.boot - spring-boot-starter-test - test - - - com.squareup.okhttp3 - okhttp - true - - - - diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulProxy.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulProxy.java deleted file mode 100644 index 778ed471a..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulProxy.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.context.annotation.Import; - -/** - * Sets up a Zuul server endpoint and installs some reverse proxy filters in it, so it can - * forward requests to backend servers. The backends can be registered manually through - * configuration or via DiscoveryClient. - * - * @see EnableZuulServer for how to get a Zuul server without any proxying - * - * @author Spencer Gibb - * @author Dave Syer - * @author Biju Kunjummen - */ -@EnableCircuitBreaker -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Import(ZuulProxyMarkerConfiguration.class) -public @interface EnableZuulProxy { - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulServer.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulServer.java deleted file mode 100644 index 0e6a00b85..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulServer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.context.annotation.Import; - -/** - * Set up the application to act as a generic Zuul server without any built-in reverse - * proxy features. The routes into the Zuul server can be configured through - * {@link ZuulProperties} (by default there are none). - * - * @see EnableZuulProxy to see how to get reverse proxy out of the box - * - * @author Spencer Gibb - * @author Biju Kunjummen - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Import(ZuulServerMarkerConfiguration.class) -public @interface EnableZuulServer { - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/FiltersEndpoint.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/FiltersEndpoint.java deleted file mode 100644 index 5006071a6..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/FiltersEndpoint.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.filters.FilterRegistry; - -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; - -/** - * Endpoint for listing Zuul filters. - * - * @author Daryl Robbins - * @author Gregor Zurowski - */ -@Endpoint(id = "filters") -public class FiltersEndpoint { - - private final FilterRegistry filterRegistry; - - public FiltersEndpoint(FilterRegistry filterRegistry) { - this.filterRegistry = filterRegistry; - } - - @ReadOperation - public Map>> invoke() { - // Map of filters by type - final Map>> filterMap = new TreeMap<>(); - - for (ZuulFilter filter : this.filterRegistry.getAllFilters()) { - // Ensure that we have a list to store filters of each type - if (!filterMap.containsKey(filter.filterType())) { - filterMap.put(filter.filterType(), new ArrayList<>()); - } - - final Map filterInfo = new LinkedHashMap<>(); - filterInfo.put("class", filter.getClass().getName()); - filterInfo.put("order", filter.filterOrder()); - filterInfo.put("disabled", filter.isFilterDisabled()); - filterInfo.put("static", filter.isStaticFilter()); - - filterMap.get(filter.filterType()).add(filterInfo); - } - - return filterMap; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RibbonCommandFactoryConfiguration.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RibbonCommandFactoryConfiguration.java deleted file mode 100644 index 691344e27..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RibbonCommandFactoryConfiguration.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2015-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.Collections; -import java.util.Set; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; - -/** - * @author Dave Syer - * - */ -public class RibbonCommandFactoryConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnRibbonRestClient - protected static class RestClientRibbonConfiguration { - - @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); - - @Bean - @ConditionalOnMissingBean - public RibbonCommandFactory ribbonCommandFactory( - SpringClientFactory clientFactory, ZuulProperties zuulProperties) { - return new RestClientRibbonCommandFactory(clientFactory, zuulProperties, - zuulFallbackProviders); - } - - } - - @Target({ ElementType.TYPE, ElementType.METHOD }) - @Retention(RetentionPolicy.RUNTIME) - @Documented - @Conditional(OnRibbonHttpClientCondition.class) - @interface ConditionalOnRibbonHttpClient { - - } - - private static class OnRibbonHttpClientCondition extends AnyNestedCondition { - - OnRibbonHttpClientCondition() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnProperty(name = "ribbon.httpclient.enabled", matchIfMissing = true) - static class RibbonProperty { - - } - - } - - @Target({ ElementType.TYPE, ElementType.METHOD }) - @Retention(RetentionPolicy.RUNTIME) - @Documented - @Conditional(OnRibbonOkHttpClientCondition.class) - @interface ConditionalOnRibbonOkHttpClient { - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnRibbonOkHttpClient - @ConditionalOnClass(name = "okhttp3.OkHttpClient") - protected static class OkHttpRibbonConfiguration { - - @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); - - @Bean - @ConditionalOnMissingBean - public RibbonCommandFactory ribbonCommandFactory( - SpringClientFactory clientFactory, ZuulProperties zuulProperties) { - return new OkHttpRibbonCommandFactory(clientFactory, zuulProperties, - zuulFallbackProviders); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnRibbonHttpClient - protected static class HttpClientRibbonConfiguration { - - @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); - - @Bean - @ConditionalOnMissingBean - public RibbonCommandFactory ribbonCommandFactory( - SpringClientFactory clientFactory, ZuulProperties zuulProperties) { - return new HttpClientRibbonCommandFactory(clientFactory, zuulProperties, - zuulFallbackProviders); - } - - } - - private static class OnRibbonOkHttpClientCondition extends AnyNestedCondition { - - OnRibbonOkHttpClientCondition() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnProperty("ribbon.okhttp.enabled") - static class RibbonProperty { - - } - - } - - @Target({ ElementType.TYPE, ElementType.METHOD }) - @Retention(RetentionPolicy.RUNTIME) - @Documented - @Conditional(OnRibbonRestClientCondition.class) - @interface ConditionalOnRibbonRestClient { - - } - - private static class OnRibbonRestClientCondition extends AnyNestedCondition { - - OnRibbonRestClientCondition() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnProperty("ribbon.restclient.enabled") - static class RibbonProperty { - - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RoutesEndpoint.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RoutesEndpoint.java deleted file mode 100644 index c7bb70d81..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RoutesEndpoint.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; - -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; -import org.springframework.boot.actuate.endpoint.annotation.Selector; -import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; - -/** - * Endpoint to display the zuul proxy routes. - * - * @author Spencer Gibb - * @author Dave Syer - * @author Ryan Baxter - * @author Gregor Zurowski - */ -@Endpoint(id = RoutesEndpoint.ID) -public class RoutesEndpoint implements ApplicationEventPublisherAware { - - static final String ID = "routes"; - static final String FORMAT_DETAILS = "details"; - - private RouteLocator routes; - - private ApplicationEventPublisher publisher; - - public RoutesEndpoint(RouteLocator routes) { - this.routes = routes; - } - - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { - this.publisher = publisher; - } - - @ReadOperation - public Map invoke() { - Map map = new LinkedHashMap<>(); - for (Route route : this.routes.getRoutes()) { - map.put(route.getFullPath(), route.getLocation()); - } - return map; - } - - Map invokeRouteDetails() { - Map map = new LinkedHashMap<>(); - for (Route route : this.routes.getRoutes()) { - map.put(route.getFullPath(), new RouteDetails(route)); - } - return map; - } - - @WriteOperation - public Object reset() { - this.publisher.publishEvent(new RoutesRefreshedEvent(this.routes)); - return invoke(); - } - - /** - * Expose Zuul {@link Route} information with details. - * @param format used to determine whether only locations or route details should be - * provided - * @return a map of routes and their details - */ - @ReadOperation - public Object invokeRouteDetails(@Selector String format) { - if (FORMAT_DETAILS.equalsIgnoreCase(format)) { - return invokeRouteDetails(); - } - else { - return invoke(); - } - } - - /** - * Container for exposing Zuul {@link Route} details as JSON. - */ - @JsonPropertyOrder({ "id", "fullPath", "location" }) - @JsonInclude(JsonInclude.Include.NON_EMPTY) - public static class RouteDetails { - - private String id; - - private String fullPath; - - private String path; - - private String location; - - private String prefix; - - private Boolean retryable; - - private Set sensitiveHeaders; - - private boolean customSensitiveHeaders; - - private boolean prefixStripped; - - public RouteDetails() { - } - - RouteDetails(final Route route) { - this.id = route.getId(); - this.fullPath = route.getFullPath(); - this.path = route.getPath(); - this.location = route.getLocation(); - this.prefix = route.getPrefix(); - this.retryable = route.getRetryable(); - this.sensitiveHeaders = route.getSensitiveHeaders(); - this.customSensitiveHeaders = route.isCustomSensitiveHeaders(); - this.prefixStripped = route.isPrefixStripped(); - } - - public String getId() { - return id; - } - - public String getFullPath() { - return fullPath; - } - - public String getPath() { - return path; - } - - public String getLocation() { - return location; - } - - public String getPrefix() { - return prefix; - } - - public Boolean getRetryable() { - return retryable; - } - - public Set getSensitiveHeaders() { - return sensitiveHeaders; - } - - public boolean isCustomSensitiveHeaders() { - return customSensitiveHeaders; - } - - public boolean isPrefixStripped() { - return prefixStripped; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RouteDetails that = (RouteDetails) o; - return Objects.equals(id, that.id) && Objects.equals(fullPath, that.fullPath) - && Objects.equals(path, that.path) - && Objects.equals(location, that.location) - && Objects.equals(prefix, that.prefix) - && Objects.equals(retryable, that.retryable) - && Objects.equals(sensitiveHeaders, that.sensitiveHeaders) - && customSensitiveHeaders == that.customSensitiveHeaders - && prefixStripped == that.prefixStripped; - } - - @Override - public int hashCode() { - return Objects.hash(id, fullPath, path, location, prefix, retryable, - sensitiveHeaders, customSensitiveHeaders, prefixStripped); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RoutesRefreshedEvent.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RoutesRefreshedEvent.java deleted file mode 100644 index 7e66d9d9f..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RoutesRefreshedEvent.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2013-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.context.ApplicationEvent; - -/** - * @author Dave Syer - */ -@SuppressWarnings("serial") -public class RoutesRefreshedEvent extends ApplicationEvent { - - private RouteLocator locator; - - public RoutesRefreshedEvent(RouteLocator locator) { - super(locator); - this.locator = locator; - } - - public RouteLocator getLocator() { - return this.locator; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializer.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializer.java deleted file mode 100644 index 0c381bd98..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializer.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.lang.reflect.Field; -import java.util.Map; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; - -import com.netflix.zuul.FilterLoader; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.filters.FilterRegistry; -import com.netflix.zuul.monitoring.CounterFactory; -import com.netflix.zuul.monitoring.TracerFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.util.ReflectionUtils; - -/** - * Initializes various Zuul components including {@link ZuulFilter}. - * - * @author Spencer Gibb - * - */ -public class ZuulFilterInitializer { - - private static final Log log = LogFactory.getLog(ZuulFilterInitializer.class); - - private final Map filters; - - private final CounterFactory counterFactory; - - private final TracerFactory tracerFactory; - - private final FilterLoader filterLoader; - - private final FilterRegistry filterRegistry; - - public ZuulFilterInitializer(Map filters, - CounterFactory counterFactory, TracerFactory tracerFactory, - FilterLoader filterLoader, FilterRegistry filterRegistry) { - this.filters = filters; - this.counterFactory = counterFactory; - this.tracerFactory = tracerFactory; - this.filterLoader = filterLoader; - this.filterRegistry = filterRegistry; - } - - @PostConstruct - public void contextInitialized() { - log.info("Starting filter initializer"); - - TracerFactory.initialize(tracerFactory); - CounterFactory.initialize(counterFactory); - - for (Map.Entry entry : this.filters.entrySet()) { - filterRegistry.put(entry.getKey(), entry.getValue()); - } - } - - @PreDestroy - public void contextDestroyed() { - log.info("Stopping filter initializer"); - for (Map.Entry entry : this.filters.entrySet()) { - filterRegistry.remove(entry.getKey()); - } - clearLoaderCache(); - - TracerFactory.initialize(null); - CounterFactory.initialize(null); - } - - private void clearLoaderCache() { - Field field = ReflectionUtils.findField(FilterLoader.class, "hashFiltersByType"); - ReflectionUtils.makeAccessible(field); - @SuppressWarnings("rawtypes") - Map cache = (Map) ReflectionUtils.getField(field, filterLoader); - cache.clear(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfiguration.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfiguration.java deleted file mode 100644 index 0d0759111..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfiguration.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.util.Collections; -import java.util.List; - -import com.netflix.zuul.filters.FilterRegistry; -import org.apache.http.impl.client.CloseableHttpClient; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.trace.http.HttpTraceRepository; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer; -import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.TraceProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.discovery.ServiceRouteMapper; -import org.springframework.cloud.netflix.zuul.filters.discovery.SimpleServiceRouteMapper; -import org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter; -import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * @author Spencer Gibb - * @author Dave Syer - * @author Biju Kunjummen - */ -@Configuration(proxyBeanMethods = false) -@Import({ RibbonCommandFactoryConfiguration.RestClientRibbonConfiguration.class, - RibbonCommandFactoryConfiguration.OkHttpRibbonConfiguration.class, - RibbonCommandFactoryConfiguration.HttpClientRibbonConfiguration.class, - HttpClientConfiguration.class }) -@ConditionalOnBean(ZuulProxyMarkerConfiguration.Marker.class) -public class ZuulProxyAutoConfiguration extends ZuulServerAutoConfiguration { - - @SuppressWarnings("rawtypes") - @Autowired(required = false) - private List requestCustomizers = Collections.emptyList(); - - @Autowired(required = false) - private Registration registration; - - @Autowired - private DiscoveryClient discovery; - - @Autowired - private ServiceRouteMapper serviceRouteMapper; - - @Override - public HasFeatures zuulFeature() { - return HasFeatures.namedFeature("Zuul (Discovery)", - ZuulProxyAutoConfiguration.class); - } - - @Bean - @ConditionalOnMissingBean(DiscoveryClientRouteLocator.class) - public DiscoveryClientRouteLocator discoveryRouteLocator() { - return new DiscoveryClientRouteLocator(this.server.getServlet().getContextPath(), - this.discovery, this.zuulProperties, this.serviceRouteMapper, - this.registration); - } - - // pre filters - @Bean - @ConditionalOnMissingBean(PreDecorationFilter.class) - public PreDecorationFilter preDecorationFilter(RouteLocator routeLocator, - ProxyRequestHelper proxyRequestHelper) { - return new PreDecorationFilter(routeLocator, - this.server.getServlet().getContextPath(), this.zuulProperties, - proxyRequestHelper); - } - - // route filters - @Bean - @ConditionalOnMissingBean(RibbonRoutingFilter.class) - public RibbonRoutingFilter ribbonRoutingFilter(ProxyRequestHelper helper, - RibbonCommandFactory ribbonCommandFactory) { - RibbonRoutingFilter filter = new RibbonRoutingFilter(helper, ribbonCommandFactory, - this.requestCustomizers); - return filter; - } - - @Bean - @ConditionalOnMissingBean({ SimpleHostRoutingFilter.class, - CloseableHttpClient.class }) - public SimpleHostRoutingFilter simpleHostRoutingFilter(ProxyRequestHelper helper, - ZuulProperties zuulProperties, - ApacheHttpClientConnectionManagerFactory connectionManagerFactory, - ApacheHttpClientFactory httpClientFactory) { - return new SimpleHostRoutingFilter(helper, zuulProperties, - connectionManagerFactory, httpClientFactory); - } - - @Bean - @ConditionalOnMissingBean({ SimpleHostRoutingFilter.class }) - public SimpleHostRoutingFilter simpleHostRoutingFilter2(ProxyRequestHelper helper, - ZuulProperties zuulProperties, CloseableHttpClient httpClient) { - return new SimpleHostRoutingFilter(helper, zuulProperties, httpClient); - } - - @Bean - @ConditionalOnMissingBean(ServiceRouteMapper.class) - public ServiceRouteMapper serviceRouteMapper() { - return new SimpleServiceRouteMapper(); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnMissingClass("org.springframework.boot.actuate.health.Health") - protected static class NoActuatorConfiguration { - - @Bean - public ProxyRequestHelper proxyRequestHelper(ZuulProperties zuulProperties) { - ProxyRequestHelper helper = new ProxyRequestHelper(zuulProperties); - return helper; - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(Health.class) - protected static class EndpointConfiguration { - - @Autowired(required = false) - private HttpTraceRepository traces; - - @Bean - @ConditionalOnAvailableEndpoint - public RoutesEndpoint routesEndpoint(RouteLocator routeLocator) { - return new RoutesEndpoint(routeLocator); - } - - @ConditionalOnAvailableEndpoint - @Bean - public FiltersEndpoint filtersEndpoint() { - FilterRegistry filterRegistry = FilterRegistry.instance(); - return new FiltersEndpoint(filterRegistry); - } - - @Bean - public ProxyRequestHelper proxyRequestHelper(ZuulProperties zuulProperties) { - TraceProxyRequestHelper helper = new TraceProxyRequestHelper(zuulProperties); - if (this.traces != null) { - helper.setTraces(this.traces); - } - return helper; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyMarkerConfiguration.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyMarkerConfiguration.java deleted file mode 100644 index aedf5e154..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyMarkerConfiguration.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Responsible for adding in a marker bean to trigger activation of - * {@link ZuulProxyAutoConfiguration}. - * - * @author Biju Kunjummen - */ - -@Configuration(proxyBeanMethods = false) -public class ZuulProxyMarkerConfiguration { - - @Bean - public Marker zuulProxyMarkerBean() { - return new Marker(); - } - - class Marker { - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulRouteApplicationContextInitializer.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulRouteApplicationContextInitializer.java deleted file mode 100644 index 77cbb63f7..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulRouteApplicationContextInitializer.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import org.springframework.cloud.netflix.ribbon.RibbonApplicationContextInitializer; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; - -/** - * Responsible for taking in the list of registered serviceid's (Ribbon client names) and - * creating the Spring {@link org.springframework.context.ApplicationContext} on start-up. - * - * @author Biju Kunjummen - */ - -public class ZuulRouteApplicationContextInitializer - extends RibbonApplicationContextInitializer { - - public ZuulRouteApplicationContextInitializer(SpringClientFactory springClientFactory, - ZuulProperties zuulProperties) { - super(springClientFactory, getServiceIdsFromZuulProps(zuulProperties)); - } - - private static List getServiceIdsFromZuulProps( - ZuulProperties zuulProperties) { - Map zuulRoutes = zuulProperties.getRoutes(); - Collection registeredRoutes = zuulRoutes.values(); - List serviceIds = new ArrayList<>(); - if (registeredRoutes != null) { - for (ZuulProperties.ZuulRoute route : registeredRoutes) { - String serviceId = route.getServiceId(); - if (serviceId != null) { - serviceIds.add(serviceId); - } - } - } - return serviceIds; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServerAutoConfiguration.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServerAutoConfiguration.java deleted file mode 100644 index 79373a608..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServerAutoConfiguration.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import com.netflix.zuul.FilterLoader; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.filters.FilterRegistry; -import com.netflix.zuul.filters.ZuulServletFilter; -import com.netflix.zuul.http.ZuulServlet; -import com.netflix.zuul.monitoring.CounterFactory; -import com.netflix.zuul.monitoring.TracerFactory; -import io.micrometer.core.instrument.MeterRegistry; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.boot.web.servlet.error.ErrorController; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.discovery.event.HeartbeatEvent; -import org.springframework.cloud.client.discovery.event.HeartbeatMonitor; -import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; -import org.springframework.cloud.client.discovery.event.ParentHeartbeatEvent; -import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.zuul.filters.CompositeRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter; -import org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter; -import org.springframework.cloud.netflix.zuul.filters.pre.DebugFilter; -import org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilter; -import org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter; -import org.springframework.cloud.netflix.zuul.filters.pre.ServletDetectionFilter; -import org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter; -import org.springframework.cloud.netflix.zuul.metrics.DefaultCounterFactory; -import org.springframework.cloud.netflix.zuul.metrics.EmptyCounterFactory; -import org.springframework.cloud.netflix.zuul.metrics.EmptyTracerFactory; -import org.springframework.cloud.netflix.zuul.web.ZuulController; -import org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.core.Ordered; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.servlet.config.annotation.CorsRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -import static java.util.Collections.emptyList; - -/** - * @author Spencer Gibb - * @author Dave Syer - * @author Biju Kunjummen - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties({ ZuulProperties.class }) -@ConditionalOnClass({ ZuulServlet.class, ZuulServletFilter.class }) -@ConditionalOnBean(ZuulServerMarkerConfiguration.Marker.class) -// Make sure to get the ServerProperties from the same place as a normal web app would -// FIXME @Import(ServerPropertiesAutoConfiguration.class) -public class ZuulServerAutoConfiguration { - - @Autowired - protected ZuulProperties zuulProperties; - - @Autowired - protected ServerProperties server; - - @Autowired(required = false) - private ErrorController errorController; - - private Map corsConfigurations; - - @Autowired(required = false) - private List configurers = emptyList(); - - @Bean - public HasFeatures zuulFeature() { - return HasFeatures.namedFeature("Zuul (Simple)", - ZuulServerAutoConfiguration.class); - } - - @Bean - @Primary - public CompositeRouteLocator primaryRouteLocator( - Collection routeLocators) { - return new CompositeRouteLocator(routeLocators); - } - - @Bean - @ConditionalOnMissingBean(SimpleRouteLocator.class) - public SimpleRouteLocator simpleRouteLocator() { - return new SimpleRouteLocator(this.server.getServlet().getContextPath(), - this.zuulProperties); - } - - @Bean - public ZuulController zuulController() { - return new ZuulController(); - } - - @Bean - public ZuulHandlerMapping zuulHandlerMapping(RouteLocator routes, - ZuulController zuulController) { - ZuulHandlerMapping mapping = new ZuulHandlerMapping(routes, zuulController); - mapping.setErrorController(this.errorController); - mapping.setCorsConfigurations(getCorsConfigurations()); - return mapping; - } - - protected final Map getCorsConfigurations() { - if (this.corsConfigurations == null) { - ZuulCorsRegistry registry = new ZuulCorsRegistry(); - this.configurers.forEach(configurer -> configurer.addCorsMappings(registry)); - this.corsConfigurations = registry.getCorsConfigurations(); - } - return this.corsConfigurations; - } - - @Bean - public ApplicationListener zuulRefreshRoutesListener() { - return new ZuulRefreshListener(); - } - - @Bean - @ConditionalOnMissingBean(name = "zuulServlet") - @ConditionalOnProperty(name = "zuul.use-filter", havingValue = "false", - matchIfMissing = true) - public ServletRegistrationBean zuulServlet() { - ServletRegistrationBean servlet = new ServletRegistrationBean<>( - new ZuulServlet(), this.zuulProperties.getServletPattern()); - // The whole point of exposing this servlet is to provide a route that doesn't - // buffer requests. - servlet.addInitParameter("buffer-requests", "false"); - return servlet; - } - - @Bean - @ConditionalOnMissingBean(name = "zuulServletFilter") - @ConditionalOnProperty(name = "zuul.use-filter", havingValue = "true", - matchIfMissing = false) - public FilterRegistrationBean zuulServletFilter() { - final FilterRegistrationBean filterRegistration = new FilterRegistrationBean<>(); - filterRegistration.setUrlPatterns( - Collections.singleton(this.zuulProperties.getServletPattern())); - filterRegistration.setFilter(new ZuulServletFilter()); - filterRegistration.setOrder(Ordered.LOWEST_PRECEDENCE); - // The whole point of exposing this servlet is to provide a route that doesn't - // buffer requests. - filterRegistration.addInitParameter("buffer-requests", "false"); - return filterRegistration; - } - - // pre filters - - @Bean - public ServletDetectionFilter servletDetectionFilter() { - return new ServletDetectionFilter(); - } - - @Bean - @ConditionalOnMissingBean - public FormBodyWrapperFilter formBodyWrapperFilter() { - return new FormBodyWrapperFilter(); - } - - @Bean - @ConditionalOnMissingBean - public DebugFilter debugFilter() { - return new DebugFilter(); - } - - @Bean - @ConditionalOnMissingBean - public Servlet30WrapperFilter servlet30WrapperFilter() { - return new Servlet30WrapperFilter(); - } - - // post filters - - @Bean - public SendResponseFilter sendResponseFilter(ZuulProperties properties) { - return new SendResponseFilter(zuulProperties); - } - - @Bean - public SendErrorFilter sendErrorFilter() { - return new SendErrorFilter(); - } - - @Bean - public SendForwardFilter sendForwardFilter() { - return new SendForwardFilter(); - } - - @Bean - @ConditionalOnProperty("zuul.ribbon.eager-load.enabled") - public ZuulRouteApplicationContextInitializer zuulRoutesApplicationContextInitiazer( - SpringClientFactory springClientFactory) { - return new ZuulRouteApplicationContextInitializer(springClientFactory, - zuulProperties); - } - - @Configuration(proxyBeanMethods = false) - protected static class ZuulFilterConfiguration { - - @Autowired - private Map filters; - - @Bean - public ZuulFilterInitializer zuulFilterInitializer(CounterFactory counterFactory, - TracerFactory tracerFactory) { - FilterLoader filterLoader = FilterLoader.getInstance(); - FilterRegistry filterRegistry = FilterRegistry.instance(); - return new ZuulFilterInitializer(this.filters, counterFactory, tracerFactory, - filterLoader, filterRegistry); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(MeterRegistry.class) - protected static class ZuulCounterFactoryConfiguration { - - @Bean - @ConditionalOnBean(MeterRegistry.class) - @ConditionalOnMissingBean(CounterFactory.class) - public CounterFactory counterFactory(MeterRegistry meterRegistry) { - return new DefaultCounterFactory(meterRegistry); - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class ZuulMetricsConfiguration { - - @Bean - @ConditionalOnMissingClass("io.micrometer.core.instrument.MeterRegistry") - @ConditionalOnMissingBean(CounterFactory.class) - public CounterFactory counterFactory() { - return new EmptyCounterFactory(); - } - - @ConditionalOnMissingBean(TracerFactory.class) - @Bean - public TracerFactory tracerFactory() { - return new EmptyTracerFactory(); - } - - } - - private static class ZuulRefreshListener - implements ApplicationListener { - - @Autowired - private ZuulHandlerMapping zuulHandlerMapping; - - private HeartbeatMonitor heartbeatMonitor = new HeartbeatMonitor(); - - @Override - public void onApplicationEvent(ApplicationEvent event) { - if (event instanceof ContextRefreshedEvent - || event instanceof RefreshScopeRefreshedEvent - || event instanceof RoutesRefreshedEvent - || event instanceof InstanceRegisteredEvent) { - reset(); - } - else if (event instanceof ParentHeartbeatEvent) { - ParentHeartbeatEvent e = (ParentHeartbeatEvent) event; - resetIfNeeded(e.getValue()); - } - else if (event instanceof HeartbeatEvent) { - HeartbeatEvent e = (HeartbeatEvent) event; - resetIfNeeded(e.getValue()); - } - } - - private void resetIfNeeded(Object value) { - if (this.heartbeatMonitor.update(value)) { - reset(); - } - } - - private void reset() { - this.zuulHandlerMapping.setDirty(true); - } - - } - - private static class ZuulCorsRegistry extends CorsRegistry { - - @Override - protected Map getCorsConfigurations() { - return super.getCorsConfigurations(); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServerMarkerConfiguration.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServerMarkerConfiguration.java deleted file mode 100644 index c622fee9c..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServerMarkerConfiguration.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Responsible for adding in a marker bean to trigger activation of - * {@link ZuulServerAutoConfiguration}. - * - * @author Biju Kunjummen - */ - -@Configuration(proxyBeanMethods = false) -public class ZuulServerMarkerConfiguration { - - @Bean - public Marker zuulServerMarkerBean() { - return new Marker(); - } - - class Marker { - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServletFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServletFilter.java deleted file mode 100644 index 3e79fed3a..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServletFilter.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2018-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.io.IOException; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import com.netflix.zuul.context.RequestContext; - -/** - * @author Craig Andrews - */ -public class ZuulServletFilter extends com.netflix.zuul.filters.ZuulServletFilter { - - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, - FilterChain filterChain) throws IOException, ServletException { - - // Workaround https://github.com/Netflix/zuul/pull/430 - // This class can be removed, and com.netflix.zuul.filters.ZuulServletFilter used - // in its place, - // when using a Zuul release with that change in it. - - // Marks this request as having passed through the "Zuul engine", as opposed to - // servlets - // explicitly bound in web.xml, for which requests will not have the same data - // attached - RequestContext context = RequestContext.getCurrentContext(); - context.setZuulEngineRan(); - - super.doFilter(servletRequest, servletResponse, filterChain); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/CompositeRouteLocator.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/CompositeRouteLocator.java deleted file mode 100644 index 29e858cc9..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/CompositeRouteLocator.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.util.Assert; - -/** - * RouteLocator that composes multiple RouteLocators. - * - * @author Johannes Edmeier - * - */ -public class CompositeRouteLocator implements RefreshableRouteLocator { - - private final Collection routeLocators; - - private ArrayList rl; - - public CompositeRouteLocator(Collection routeLocators) { - Assert.notNull(routeLocators, "'routeLocators' must not be null"); - rl = new ArrayList<>(routeLocators); - AnnotationAwareOrderComparator.sort(rl); - this.routeLocators = rl; - } - - @Override - public Collection getIgnoredPaths() { - List ignoredPaths = new ArrayList<>(); - for (RouteLocator locator : routeLocators) { - ignoredPaths.addAll(locator.getIgnoredPaths()); - } - return ignoredPaths; - } - - @Override - public List getRoutes() { - List route = new ArrayList<>(); - for (RouteLocator locator : routeLocators) { - route.addAll(locator.getRoutes()); - } - return route; - } - - @Override - public Route getMatchingRoute(String path) { - for (RouteLocator locator : routeLocators) { - Route route = locator.getMatchingRoute(path); - if (route != null) { - return route; - } - } - return null; - } - - @Override - public void refresh() { - for (RouteLocator locator : routeLocators) { - if (locator instanceof RefreshableRouteLocator) { - ((RefreshableRouteLocator) locator).refresh(); - } - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java deleted file mode 100755 index ad67f55b1..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.regex.Pattern; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.util.HTTPRequestUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.netflix.zuul.util.RequestUtils; -import org.springframework.http.HttpHeaders; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.util.UriTemplate; -import org.springframework.web.util.UriUtils; -import org.springframework.web.util.WebUtils; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY; - -/** - * @author Dave Syer - * @author Marcos Barbero - * @author Spencer Gibb - */ -public class ProxyRequestHelper { - - private static final Log log = LogFactory.getLog(ProxyRequestHelper.class); - - /** - * Zuul context key for a collection of ignored headers for the current request. - * Pre-filters can set this up as a set of lowercase strings. - */ - public static final String IGNORED_HEADERS = "ignoredHeaders"; - - /** - * Form feed pattern. - */ - public static final Pattern FORM_FEED_PATTERN = Pattern.compile("\f"); - - /** - * Colon pattern. - */ - public static final Pattern COLON_PATTERN = Pattern.compile(":"); - - private Set ignoredHeaders = new LinkedHashSet<>(); - - private Set sensitiveHeaders = new LinkedHashSet<>(); - - private Set whitelistHosts = new LinkedHashSet<>(); - - private boolean traceRequestBody = true; - - private boolean addHostHeader = false; - - private boolean urlDecoded = true; - - @Deprecated - // TODO Remove in 2.1.x - public ProxyRequestHelper() { - } - - public ProxyRequestHelper(ZuulProperties zuulProperties) { - this.ignoredHeaders.addAll(zuulProperties.getIgnoredHeaders()); - this.traceRequestBody = zuulProperties.isTraceRequestBody(); - this.addHostHeader = zuulProperties.isAddHostHeader(); - this.urlDecoded = zuulProperties.isDecodeUrl(); - } - - public void setWhitelistHosts(Set whitelistHosts) { - this.whitelistHosts.addAll(whitelistHosts); - } - - public void setSensitiveHeaders(Set sensitiveHeaders) { - this.sensitiveHeaders.addAll(sensitiveHeaders); - } - - @Deprecated - // TODO Remove in 2.1.x - public void setIgnoredHeaders(Set ignoredHeaders) { - this.ignoredHeaders.addAll(ignoredHeaders); - } - - @Deprecated - // TODO Remove in 2.1.x - public void setTraceRequestBody(boolean traceRequestBody) { - this.traceRequestBody = traceRequestBody; - } - - public String buildZuulRequestURI(HttpServletRequest request) { - RequestContext context = RequestContext.getCurrentContext(); - String uri = request.getRequestURI(); - String contextURI = (String) context.get(REQUEST_URI_KEY); - if (contextURI != null) { - try { - uri = contextURI; - if (this.urlDecoded) { - uri = UriUtils.encodePath(contextURI, characterEncoding(request)); - } - } - catch (Exception e) { - log.debug( - "unable to encode uri path from context, falling back to uri from request", - e); - } - } - return uri; - } - - private String characterEncoding(HttpServletRequest request) { - return request.getCharacterEncoding() != null ? request.getCharacterEncoding() - : WebUtils.DEFAULT_CHARACTER_ENCODING; - } - - public MultiValueMap buildZuulRequestQueryParams( - HttpServletRequest request) { - Map> map = HTTPRequestUtils.getInstance().getQueryParams(); - MultiValueMap params = new LinkedMultiValueMap<>(); - if (map == null) { - return params; - } - for (String key : map.keySet()) { - for (String value : map.get(key)) { - params.add(key, value); - } - } - return params; - } - - public MultiValueMap buildZuulRequestHeaders( - HttpServletRequest request) { - RequestContext context = RequestContext.getCurrentContext(); - MultiValueMap headers = new HttpHeaders(); - Enumeration headerNames = request.getHeaderNames(); - if (headerNames != null) { - while (headerNames.hasMoreElements()) { - String name = headerNames.nextElement(); - if (isIncludedHeader(name)) { - Enumeration values = request.getHeaders(name); - while (values.hasMoreElements()) { - String value = values.nextElement(); - headers.add(name, value); - } - } - } - } - Map zuulRequestHeaders = context.getZuulRequestHeaders(); - for (String header : zuulRequestHeaders.keySet()) { - if (isIncludedHeader(header)) { - headers.set(header, zuulRequestHeaders.get(header)); - } - } - if (!headers.containsKey(HttpHeaders.ACCEPT_ENCODING)) { - headers.set(HttpHeaders.ACCEPT_ENCODING, "gzip"); - } - return headers; - } - - public void setResponse(int status, InputStream entity, - MultiValueMap headers) throws IOException { - RequestContext context = RequestContext.getCurrentContext(); - context.setResponseStatusCode(status); - if (entity != null) { - context.setResponseDataStream(entity); - } - - boolean isOriginResponseGzipped = false; - for (Entry> header : headers.entrySet()) { - String name = header.getKey(); - for (String value : header.getValue()) { - context.addOriginResponseHeader(name, value); - - if (name.equalsIgnoreCase(HttpHeaders.CONTENT_ENCODING) - && HTTPRequestUtils.getInstance().isGzipped(value)) { - isOriginResponseGzipped = true; - } - if (name.equalsIgnoreCase(HttpHeaders.CONTENT_LENGTH)) { - context.setOriginContentLength(value); - } - if (isIncludedHeader(name)) { - context.addZuulResponseHeader(name, value); - } - } - } - context.setResponseGZipped(isOriginResponseGzipped); - } - - public void addIgnoredHeaders(String... names) { - RequestContext ctx = RequestContext.getCurrentContext(); - if (!ctx.containsKey(IGNORED_HEADERS)) { - ctx.set(IGNORED_HEADERS, new HashSet()); - } - @SuppressWarnings("unchecked") - Set set = (Set) ctx.get(IGNORED_HEADERS); - for (String name : this.ignoredHeaders) { - set.add(name.toLowerCase()); - } - for (String name : names) { - set.add(name.toLowerCase()); - } - } - - public boolean isIncludedHeader(String headerName) { - String name = headerName.toLowerCase(); - RequestContext ctx = RequestContext.getCurrentContext(); - if (ctx.containsKey(IGNORED_HEADERS)) { - Object object = ctx.get(IGNORED_HEADERS); - if (object instanceof Collection && ((Collection) object).contains(name)) { - return false; - } - } - switch (name) { - case "host": - if (addHostHeader) { - return true; - } - case "connection": - case "content-length": - case "server": - case "transfer-encoding": - case "x-application-context": - return false; - default: - return true; - } - } - - public Map debug(String verb, String uri, - MultiValueMap headers, MultiValueMap params, - InputStream requestEntity) throws IOException { - Map info = new LinkedHashMap<>(); - return info; - } - - protected boolean shouldDebugBody(RequestContext ctx) { - HttpServletRequest request = ctx.getRequest(); - if (!this.traceRequestBody || ctx.isChunkedRequestBody() - || RequestUtils.isZuulServletRequest()) { - return false; - } - if (request == null || request.getContentType() == null) { - return true; - } - return !request.getContentType().toLowerCase().contains("multipart"); - } - - public void appendDebug(Map info, int status, - MultiValueMap headers) { - } - - /** - * Get url encoded query string. Pay special attention to single parameters with no - * values and parameter names with colon (:) from use of UriTemplate. - * @param params Un-encoded request parameters - * @return url-encoded query String built from provided parameters - */ - public String getQueryString(MultiValueMap params) { - if (params.isEmpty()) { - return ""; - } - StringBuilder query = new StringBuilder(); - Map singles = new HashMap<>(); - for (String param : params.keySet()) { - int i = 0; - for (String value : params.get(param)) { - query.append("&"); - query.append(param); - if (!"".equals(value)) { // don't add =, if original is ?wsdl, output is - // not ?wsdl= - String key = param; - // if form feed is already part of param name double - // since form feed is used as the colon replacement below - if (key.contains("\f")) { - key = (FORM_FEED_PATTERN.matcher(key).replaceAll("\f\f")); - } - // colon is special to UriTemplate - if (key.contains(":")) { - key = COLON_PATTERN.matcher(key).replaceAll("\f"); - } - key = key + i; - singles.put(key, value); - query.append("={"); - query.append(key); - query.append("}"); - } - i++; - } - } - - UriTemplate template = new UriTemplate("?" + query.toString().substring(1)); - return template.expand(singles).toString(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/RefreshableRouteLocator.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/RefreshableRouteLocator.java deleted file mode 100644 index 6f368958e..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/RefreshableRouteLocator.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2013-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters; - -/** - * Interface for a route locator that can be refreshed if routes change. - * - * @author Dave Syer - */ -public interface RefreshableRouteLocator extends RouteLocator { - - void refresh(); - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/Route.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/Route.java deleted file mode 100644 index e26c7c054..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/Route.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters; - -import java.util.LinkedHashSet; -import java.util.Objects; -import java.util.Set; - -import org.springframework.util.StringUtils; - -/** - * Represents Zuul route. - * - * @author Dave Syer - * @author Biju Kunjummen - * @author Gregor Zurowski - */ -public class Route { - - public Route(String id, String path, String location, String prefix, - Boolean retryable, Set ignoredHeaders) { - this.id = id; - this.prefix = StringUtils.hasText(prefix) ? prefix : ""; - this.path = path; - this.fullPath = prefix + path; - this.location = location; - this.retryable = retryable; - this.sensitiveHeaders = new LinkedHashSet<>(); - if (ignoredHeaders != null) { - this.customSensitiveHeaders = true; - for (String header : ignoredHeaders) { - this.sensitiveHeaders.add(header.toLowerCase()); - } - } - } - - public Route(String id, String path, String location, String prefix, - Boolean retryable, Set ignoredHeaders, boolean prefixStripped) { - this(id, path, location, prefix, retryable, ignoredHeaders); - this.prefixStripped = prefixStripped; - } - - private String id; - - private String fullPath; - - private String path; - - private String location; - - private String prefix; - - private Boolean retryable; - - private Set sensitiveHeaders = new LinkedHashSet<>(); - - private boolean customSensitiveHeaders; - - private boolean prefixStripped = true; - - public boolean isCustomSensitiveHeaders() { - return this.customSensitiveHeaders; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getFullPath() { - return fullPath; - } - - public void setFullPath(String fullPath) { - this.fullPath = fullPath; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getPrefix() { - return prefix; - } - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - public Boolean getRetryable() { - return retryable; - } - - public void setRetryable(Boolean retryable) { - this.retryable = retryable; - } - - public Set getSensitiveHeaders() { - return sensitiveHeaders; - } - - public void setSensitiveHeaders(Set sensitiveHeaders) { - this.sensitiveHeaders = sensitiveHeaders; - } - - public void setCustomSensitiveHeaders(boolean customSensitiveHeaders) { - this.customSensitiveHeaders = customSensitiveHeaders; - } - - public boolean isPrefixStripped() { - return prefixStripped; - } - - public void setPrefixStripped(boolean prefixStripped) { - this.prefixStripped = prefixStripped; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Route that = (Route) o; - return customSensitiveHeaders == that.customSensitiveHeaders - && prefixStripped == that.prefixStripped && Objects.equals(id, that.id) - && Objects.equals(fullPath, that.fullPath) - && Objects.equals(path, that.path) - && Objects.equals(location, that.location) - && Objects.equals(prefix, that.prefix) - && Objects.equals(retryable, that.retryable) - && Objects.equals(sensitiveHeaders, that.sensitiveHeaders); - } - - @Override - public int hashCode() { - return Objects.hash(id, fullPath, path, location, prefix, retryable, - sensitiveHeaders, customSensitiveHeaders, prefixStripped); - } - - @Override - public String toString() { - return new StringBuilder("Route{").append("id='").append(id).append("', ") - .append("fullPath='").append(fullPath).append("', ").append("path='") - .append(path).append("', ").append("location='").append(location) - .append("', ").append("prefix='").append(prefix).append("', ") - .append("retryable=").append(retryable).append(", ") - .append("sensitiveHeaders=").append(sensitiveHeaders).append(", ") - .append("customSensitiveHeaders=").append(customSensitiveHeaders) - .append(", ").append("prefixStripped=").append(prefixStripped).append("}") - .toString(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/RouteLocator.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/RouteLocator.java deleted file mode 100644 index cd5be3dab..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/RouteLocator.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters; - -import java.util.Collection; -import java.util.List; - -/** - * @author Dave Syer - */ -public interface RouteLocator { - - /** - * Ignored route paths (or patterns), if any. - * @return {@link Collection} of ignored paths - */ - Collection getIgnoredPaths(); - - /** - * A map of route path (pattern) to location (e.g. service id or URL). - * @return {@link List} of routes - */ - List getRoutes(); - - /** - * Maps a path to an actual route with full metadata. - * @param path used to match the {@link Route} - * @return matching {@link Route} based on the provided path - */ - Route getMatchingRoute(String path); - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocator.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocator.java deleted file mode 100644 index a7c3290c2..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocator.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.atomic.AtomicReference; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; -import org.springframework.cloud.netflix.zuul.util.RequestUtils; -import org.springframework.core.Ordered; -import org.springframework.util.AntPathMatcher; -import org.springframework.util.PathMatcher; -import org.springframework.util.StringUtils; - -/** - * Simple {@link RouteLocator} based on configuration data held in {@link ZuulProperties}. - * - * @author Dave Syer - */ -public class SimpleRouteLocator implements RouteLocator, Ordered { - - private static final Log log = LogFactory.getLog(SimpleRouteLocator.class); - - private static final int DEFAULT_ORDER = 0; - - private ZuulProperties properties; - - private PathMatcher pathMatcher = new AntPathMatcher(); - - private String dispatcherServletPath = "/"; - - private String zuulServletPath; - - private AtomicReference> routes = new AtomicReference<>(); - - private int order = DEFAULT_ORDER; - - public SimpleRouteLocator(String servletPath, ZuulProperties properties) { - this.properties = properties; - if (StringUtils.hasText(servletPath)) { - this.dispatcherServletPath = servletPath; - } - - this.zuulServletPath = properties.getServletPath(); - } - - @Override - public List getRoutes() { - List values = new ArrayList<>(); - for (Entry entry : getRoutesMap().entrySet()) { - ZuulRoute route = entry.getValue(); - String path = route.getPath(); - try { - values.add(getRoute(route, path)); - } - catch (Exception e) { - if (log.isWarnEnabled()) { - log.warn("Invalid route, routeId: " + route.getId() - + ", routeServiceId: " + route.getServiceId() + ", msg: " - + e.getMessage()); - } - if (log.isDebugEnabled()) { - log.debug("", e); - } - } - } - return values; - } - - @Override - public Collection getIgnoredPaths() { - return this.properties.getIgnoredPatterns(); - } - - @Override - public Route getMatchingRoute(final String path) { - - return getSimpleMatchingRoute(path); - - } - - protected Map getRoutesMap() { - if (this.routes.get() == null) { - this.routes.set(locateRoutes()); - } - return this.routes.get(); - } - - protected Route getSimpleMatchingRoute(final String path) { - if (log.isDebugEnabled()) { - log.debug("Finding route for path: " + path); - } - - // This is called for the initialization done in getRoutesMap() - getRoutesMap(); - - if (log.isDebugEnabled()) { - log.debug("servletPath=" + this.dispatcherServletPath); - log.debug("zuulServletPath=" + this.zuulServletPath); - log.debug("RequestUtils.isDispatcherServletRequest()=" - + RequestUtils.isDispatcherServletRequest()); - log.debug("RequestUtils.isZuulServletRequest()=" - + RequestUtils.isZuulServletRequest()); - } - - String adjustedPath = adjustPath(path); - - ZuulRoute route = getZuulRoute(adjustedPath); - - return getRoute(route, adjustedPath); - } - - protected ZuulRoute getZuulRoute(String adjustedPath) { - if (!matchesIgnoredPatterns(adjustedPath)) { - for (Entry entry : getRoutesMap().entrySet()) { - String pattern = entry.getKey(); - log.debug("Matching pattern:" + pattern); - if (this.pathMatcher.match(pattern, adjustedPath)) { - return entry.getValue(); - } - } - } - return null; - } - - protected Route getRoute(ZuulRoute route, String path) { - if (route == null) { - return null; - } - if (log.isDebugEnabled()) { - log.debug("route matched=" + route); - } - String targetPath = path; - String prefix = this.properties.getPrefix(); - if (prefix.endsWith("/")) { - prefix = prefix.substring(0, prefix.length() - 1); - } - if (path.startsWith(prefix + "/") && this.properties.isStripPrefix()) { - targetPath = path.substring(prefix.length()); - } - if (route.isStripPrefix()) { - int index = route.getPath().indexOf("*") - 1; - if (index > 0) { - String routePrefix = route.getPath().substring(0, index); - targetPath = targetPath.replaceFirst(routePrefix, ""); - prefix = prefix + routePrefix; - } - } - Boolean retryable = this.properties.getRetryable(); - if (route.getRetryable() != null) { - retryable = route.getRetryable(); - } - return new Route(route.getId(), targetPath, route.getLocation(), prefix, - retryable, - route.isCustomSensitiveHeaders() ? route.getSensitiveHeaders() : null, - route.isStripPrefix()); - } - - /** - * Calculate all the routes and set up a cache for the values. Subclasses can call - * this method if they need to implement {@link RefreshableRouteLocator}. - */ - protected void doRefresh() { - this.routes.set(locateRoutes()); - } - - /** - * Compute a map of path pattern to route. The default is just a static map from the - * {@link ZuulProperties}, but subclasses can add dynamic calculations. - * @return map of Zuul routes - */ - protected Map locateRoutes() { - LinkedHashMap routesMap = new LinkedHashMap<>(); - for (ZuulRoute route : this.properties.getRoutes().values()) { - routesMap.put(route.getPath(), route); - } - return routesMap; - } - - protected boolean matchesIgnoredPatterns(String path) { - for (String pattern : this.properties.getIgnoredPatterns()) { - log.debug("Matching ignored pattern:" + pattern); - if (this.pathMatcher.match(pattern, path)) { - log.debug("Path " + path + " matches ignored pattern " + pattern); - return true; - } - } - return false; - } - - private String adjustPath(final String path) { - String adjustedPath = path; - - if (RequestUtils.isDispatcherServletRequest() - && StringUtils.hasText(this.dispatcherServletPath)) { - if (!this.dispatcherServletPath.equals("/") - && path.startsWith(this.dispatcherServletPath)) { - adjustedPath = path.substring(this.dispatcherServletPath.length()); - log.debug("Stripped dispatcherServletPath"); - } - } - else if (RequestUtils.isZuulServletRequest()) { - if (StringUtils.hasText(this.zuulServletPath) - && !this.zuulServletPath.equals("/")) { - adjustedPath = path.substring(this.zuulServletPath.length()); - log.debug("Stripped zuulServletPath"); - } - } - else { - // do nothing - } - - log.debug("adjustedPath=" + adjustedPath); - return adjustedPath; - } - - @Override - public int getOrder() { - return order; - } - - public void setOrder(int order) { - this.order = order; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/TraceProxyRequestHelper.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/TraceProxyRequestHelper.java deleted file mode 100644 index 428394775..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/TraceProxyRequestHelper.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URI; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Enumeration; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.context.RequestContext; - -import org.springframework.boot.actuate.trace.http.HttpExchangeTracer; -import org.springframework.boot.actuate.trace.http.HttpTrace; -import org.springframework.boot.actuate.trace.http.HttpTraceRepository; -import org.springframework.boot.actuate.trace.http.Include; -import org.springframework.boot.actuate.trace.http.TraceableRequest; -import org.springframework.util.MultiValueMap; -import org.springframework.util.StringUtils; - -/** - * @author Spencer Gibb - */ -public class TraceProxyRequestHelper extends ProxyRequestHelper { - - private HttpTraceRepository traces; - - @Deprecated - // TODO Remove in 2.1.x - public TraceProxyRequestHelper() { - } - - public TraceProxyRequestHelper(ZuulProperties zuulProperties) { - super(zuulProperties); - } - - private final HttpExchangeTracer tracer = new HttpExchangeTracer( - Include.defaultIncludes()); - - public void setTraces(HttpTraceRepository traces) { - this.traces = traces; - } - - @Override - public Map debug(String verb, String uri, - MultiValueMap headers, MultiValueMap params, - InputStream requestEntity) throws IOException { - Map info = new LinkedHashMap<>(); - if (this.traces != null) { - RequestContext context = RequestContext.getCurrentContext(); - info.put("method", verb); - info.put("path", uri); - info.put("query", getQueryString(params)); - info.put("remote", true); - info.put("proxy", context.get("proxy")); - Map trace = new LinkedHashMap<>(); - Map input = new LinkedHashMap<>(); - trace.put("request", input); - info.put("headers", trace); - debugHeaders(headers, input); - HttpServletRequest request = context.getRequest(); - if (shouldDebugBody(context)) { - // Prevent input stream from being read if it needs to go downstream - if (requestEntity != null) { - debugRequestEntity(info, request.getInputStream()); - } - } - HttpTrace httpTrace = tracer - .receivedRequest(new ServletTraceableRequest(request)); - this.traces.add(httpTrace); - return info; - } - return info; - } - - void debugHeaders(MultiValueMap headers, Map map) { - for (Entry> entry : headers.entrySet()) { - Collection collection = entry.getValue(); - Object value = collection; - if (collection.size() < 2) { - value = collection.isEmpty() ? "" : collection.iterator().next(); - } - map.put(entry.getKey(), value); - } - } - - public void appendDebug(Map info, int status, - MultiValueMap headers) { - if (this.traces != null) { - @SuppressWarnings("unchecked") - Map trace = (Map) info.get("headers"); - Map output = new LinkedHashMap<>(); - trace.put("response", output); - debugHeaders(headers, output); - output.put("status", "" + status); - } - } - - private void debugRequestEntity(Map info, InputStream inputStream) - throws IOException { - if (RequestContext.getCurrentContext().isChunkedRequestBody()) { - info.put("body", ""); - return; - } - char[] buffer = new char[4096]; - int count = new InputStreamReader(inputStream, Charset.forName("UTF-8")) - .read(buffer, 0, buffer.length); - if (count > 0) { - String entity = new String(buffer).substring(0, count); - info.put("body", entity.length() < 4096 ? entity : entity + ""); - } - } - - private class ServletTraceableRequest implements TraceableRequest { - - private HttpServletRequest request; - - ServletTraceableRequest(HttpServletRequest request) { - this.request = request; - } - - @Override - public String getMethod() { - return request.getMethod(); - } - - @Override - public URI getUri() { - StringBuffer urlBuffer = request.getRequestURL(); - if (StringUtils.hasText(request.getQueryString())) { - urlBuffer.append("?"); - urlBuffer.append(request.getQueryString()); - } - return URI.create(urlBuffer.toString()); - } - - @Override - public Map> getHeaders() { - return extractHeaders(); - } - - @Override - public String getRemoteAddress() { - return request.getRemoteAddr(); - } - - private Map> extractHeaders() { - Map> headers = new LinkedHashMap<>(); - Enumeration names = request.getHeaderNames(); - while (names.hasMoreElements()) { - String name = names.nextElement(); - headers.put(name, toList(request.getHeaders(name))); - } - return headers; - } - - private List toList(Enumeration enumeration) { - List list = new ArrayList<>(); - while (enumeration.hasMoreElements()) { - list.add(enumeration.nextElement()); - } - return list; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java deleted file mode 100755 index 5d1926c97..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java +++ /dev/null @@ -1,967 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters; - -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import javax.annotation.PostConstruct; - -import com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.core.style.ToStringCreator; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; - -import static com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE; - -/** - * @author Spencer Gibb - * @author Dave Syer - * @author Mathias Düsterhöft - * @author Bilal Alp - * @author Gregor Zurowski - */ -@ConfigurationProperties("zuul") -public class ZuulProperties { - - /** - * Headers that are generally expected to be added by Spring Security, and hence often - * duplicated if the proxy and the backend are secured with Spring. By default they - * are added to the ignored headers if Spring Security is present and - * ignoreSecurityHeaders = true. - */ - public static final List SECURITY_HEADERS = Arrays.asList("Pragma", - "Cache-Control", "X-Frame-Options", "X-Content-Type-Options", - "X-XSS-Protection", "Expires"); - - /** - * A common prefix for all routes. - */ - private String prefix = ""; - - /** - * Flag saying whether to strip the prefix from the path before forwarding. - */ - private boolean stripPrefix = true; - - /** - * Flag for whether retry is supported by default (assuming the routes themselves - * support it). - */ - private Boolean retryable = false; - - /** - * Map of route names to properties. - */ - private Map routes = new LinkedHashMap<>(); - - /** - * Flag to determine whether the proxy adds X-Forwarded-* headers. - */ - private boolean addProxyHeaders = true; - - /** - * Flag to determine whether the proxy forwards the Host header. - */ - private boolean addHostHeader = false; - - /** - * Set of service names not to consider for proxying automatically. By default all - * services in the discovery client will be proxied. - */ - private Set ignoredServices = new LinkedHashSet<>(); - - private Set ignoredPatterns = new LinkedHashSet<>(); - - /** - * Names of HTTP headers to ignore completely (i.e. leave them out of downstream - * requests and drop them from downstream responses). - */ - private Set ignoredHeaders = new LinkedHashSet<>(); - - /** - * Flag to say that SECURITY_HEADERS are added to ignored headers if spring security - * is on the classpath. By setting ignoreSecurityHeaders to false we can switch off - * this default behaviour. This should be used together with disabling the default - * spring security headers see - * https://docs.spring.io/spring-security/site/docs/current/reference/html/headers.html#default-security-headers - */ - private boolean ignoreSecurityHeaders = true; - - /** - * Flag to force the original query string encoding when building the backend URI in - * SimpleHostRoutingFilter. When activated, query string will be built using - * HttpServletRequest getQueryString() method instead of UriTemplate. Note that this - * flag is not used in RibbonRoutingFilter with services found via DiscoveryClient - * (like Eureka). - */ - private boolean forceOriginalQueryStringEncoding = false; - - /** - * Path to install Zuul as a servlet (not part of Spring MVC). The servlet is more - * memory efficient for requests with large bodies, e.g. file uploads. - */ - private String servletPath = "/zuul"; - - private boolean ignoreLocalService = true; - - /** - * Host properties controlling default connection pool properties. - */ - private Host host = new Host(); - - /** - * Flag to say that request bodies can be traced. - */ - private boolean traceRequestBody = false; - - /** - * Flag to say that path elements past the first semicolon can be dropped. - */ - private boolean removeSemicolonContent = true; - - /** - * Flag to indicate whether to decode the matched URL or use it as is. - */ - private boolean decodeUrl = true; - - /** - * List of sensitive headers that are not passed to downstream requests. Defaults to a - * "safe" set of headers that commonly contain user credentials. It's OK to remove - * those from the list if the downstream service is part of the same system as the - * proxy, so they are sharing authentication data. If using a physical URL outside - * your own domain, then generally it would be a bad idea to leak user credentials. - */ - private Set sensitiveHeaders = new LinkedHashSet<>( - Arrays.asList("Cookie", "Set-Cookie", "Authorization")); - - /** - * Flag to say whether the hostname for ssl connections should be verified or not. - * Default is true. This should only be used in test setups! - */ - private boolean sslHostnameValidationEnabled = true; - - private ExecutionIsolationStrategy ribbonIsolationStrategy = SEMAPHORE; - - private HystrixSemaphore semaphore = new HystrixSemaphore(); - - private HystrixThreadPool threadPool = new HystrixThreadPool(); - - /** - * Setting for SendResponseFilter to conditionally set Content-Length header. - */ - private boolean setContentLength = false; - - /** - * Setting for SendResponseFilter to conditionally include X-Zuul-Debug-Header header. - */ - private boolean includeDebugHeader = false; - - /** - * Setting for SendResponseFilter for the initial stream buffer size. - */ - private int initialStreamBufferSize = 8192; - - public Set getIgnoredHeaders() { - Set ignoredHeaders = new LinkedHashSet<>(this.ignoredHeaders); - if (ClassUtils.isPresent( - "org.springframework.security.config.annotation.web.WebSecurityConfigurer", - null) && Collections.disjoint(ignoredHeaders, SECURITY_HEADERS) - && ignoreSecurityHeaders) { - // Allow Spring Security in the gateway to control these headers - ignoredHeaders.addAll(SECURITY_HEADERS); - } - return ignoredHeaders; - } - - public void setIgnoredHeaders(Set ignoredHeaders) { - this.ignoredHeaders.addAll(ignoredHeaders); - } - - @PostConstruct - public void init() { - for (Entry entry : this.routes.entrySet()) { - ZuulRoute value = entry.getValue(); - if (!StringUtils.hasText(value.getLocation())) { - value.serviceId = entry.getKey(); - } - if (!StringUtils.hasText(value.getId())) { - value.id = entry.getKey(); - } - if (!StringUtils.hasText(value.getPath())) { - value.path = "/" + entry.getKey() + "/**"; - } - } - } - - public String getServletPattern() { - String path = this.servletPath; - if (!path.startsWith("/")) { - path = "/" + path; - } - if (!path.contains("*")) { - path = path.endsWith("/") ? (path + "*") : (path + "/*"); - } - return path; - } - - public String getPrefix() { - return prefix; - } - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - public boolean isStripPrefix() { - return stripPrefix; - } - - public void setStripPrefix(boolean stripPrefix) { - this.stripPrefix = stripPrefix; - } - - public Boolean getRetryable() { - return retryable; - } - - public void setRetryable(Boolean retryable) { - this.retryable = retryable; - } - - public Map getRoutes() { - return routes; - } - - public void setRoutes(Map routes) { - this.routes = routes; - } - - public boolean isAddProxyHeaders() { - return addProxyHeaders; - } - - public void setAddProxyHeaders(boolean addProxyHeaders) { - this.addProxyHeaders = addProxyHeaders; - } - - public boolean isAddHostHeader() { - return addHostHeader; - } - - public void setAddHostHeader(boolean addHostHeader) { - this.addHostHeader = addHostHeader; - } - - public Set getIgnoredServices() { - return ignoredServices; - } - - public void setIgnoredServices(Set ignoredServices) { - this.ignoredServices = ignoredServices; - } - - public Set getIgnoredPatterns() { - return ignoredPatterns; - } - - public void setIgnoredPatterns(Set ignoredPatterns) { - this.ignoredPatterns = ignoredPatterns; - } - - public boolean isIgnoreSecurityHeaders() { - return ignoreSecurityHeaders; - } - - public void setIgnoreSecurityHeaders(boolean ignoreSecurityHeaders) { - this.ignoreSecurityHeaders = ignoreSecurityHeaders; - } - - public boolean isForceOriginalQueryStringEncoding() { - return forceOriginalQueryStringEncoding; - } - - public void setForceOriginalQueryStringEncoding( - boolean forceOriginalQueryStringEncoding) { - this.forceOriginalQueryStringEncoding = forceOriginalQueryStringEncoding; - } - - public String getServletPath() { - return servletPath; - } - - public void setServletPath(String servletPath) { - this.servletPath = servletPath; - } - - public boolean isIgnoreLocalService() { - return ignoreLocalService; - } - - public void setIgnoreLocalService(boolean ignoreLocalService) { - this.ignoreLocalService = ignoreLocalService; - } - - public Host getHost() { - return host; - } - - public void setHost(Host host) { - this.host = host; - } - - public boolean isTraceRequestBody() { - return traceRequestBody; - } - - public void setTraceRequestBody(boolean traceRequestBody) { - this.traceRequestBody = traceRequestBody; - } - - public boolean isRemoveSemicolonContent() { - return removeSemicolonContent; - } - - public void setRemoveSemicolonContent(boolean removeSemicolonContent) { - this.removeSemicolonContent = removeSemicolonContent; - } - - public boolean isDecodeUrl() { - return decodeUrl; - } - - public void setDecodeUrl(boolean decodeUrl) { - this.decodeUrl = decodeUrl; - } - - public Set getSensitiveHeaders() { - return sensitiveHeaders; - } - - public void setSensitiveHeaders(Set sensitiveHeaders) { - this.sensitiveHeaders = sensitiveHeaders; - } - - public boolean isSslHostnameValidationEnabled() { - return sslHostnameValidationEnabled; - } - - public void setSslHostnameValidationEnabled(boolean sslHostnameValidationEnabled) { - this.sslHostnameValidationEnabled = sslHostnameValidationEnabled; - } - - public ExecutionIsolationStrategy getRibbonIsolationStrategy() { - return ribbonIsolationStrategy; - } - - public void setRibbonIsolationStrategy( - ExecutionIsolationStrategy ribbonIsolationStrategy) { - this.ribbonIsolationStrategy = ribbonIsolationStrategy; - } - - public HystrixSemaphore getSemaphore() { - return semaphore; - } - - public void setSemaphore(HystrixSemaphore semaphore) { - this.semaphore = semaphore; - } - - public HystrixThreadPool getThreadPool() { - return threadPool; - } - - public void setThreadPool(HystrixThreadPool threadPool) { - this.threadPool = threadPool; - } - - public boolean isSetContentLength() { - return setContentLength; - } - - public void setSetContentLength(boolean setContentLength) { - this.setContentLength = setContentLength; - } - - public boolean isIncludeDebugHeader() { - return includeDebugHeader; - } - - public void setIncludeDebugHeader(boolean includeDebugHeader) { - this.includeDebugHeader = includeDebugHeader; - } - - public int getInitialStreamBufferSize() { - return initialStreamBufferSize; - } - - public void setInitialStreamBufferSize(int initialStreamBufferSize) { - this.initialStreamBufferSize = initialStreamBufferSize; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ZuulProperties that = (ZuulProperties) o; - return addHostHeader == that.addHostHeader - && addProxyHeaders == that.addProxyHeaders - && forceOriginalQueryStringEncoding == that.forceOriginalQueryStringEncoding - && Objects.equals(host, that.host) - && Objects.equals(ignoredHeaders, that.ignoredHeaders) - && Objects.equals(ignoredPatterns, that.ignoredPatterns) - && Objects.equals(ignoredServices, that.ignoredServices) - && ignoreLocalService == that.ignoreLocalService - && ignoreSecurityHeaders == that.ignoreSecurityHeaders - && Objects.equals(prefix, that.prefix) - && removeSemicolonContent == that.removeSemicolonContent - && Objects.equals(retryable, that.retryable) - && Objects.equals(ribbonIsolationStrategy, that.ribbonIsolationStrategy) - && Objects.equals(routes, that.routes) - && Objects.equals(semaphore, that.semaphore) - && Objects.equals(sensitiveHeaders, that.sensitiveHeaders) - && Objects.equals(servletPath, that.servletPath) - && sslHostnameValidationEnabled == that.sslHostnameValidationEnabled - && stripPrefix == that.stripPrefix - && setContentLength == that.setContentLength - && includeDebugHeader == that.includeDebugHeader - && initialStreamBufferSize == that.initialStreamBufferSize - && Objects.equals(threadPool, that.threadPool) - && traceRequestBody == that.traceRequestBody; - } - - @Override - public int hashCode() { - return Objects.hash(addHostHeader, addProxyHeaders, - forceOriginalQueryStringEncoding, host, ignoredHeaders, ignoredPatterns, - ignoredServices, ignoreLocalService, ignoreSecurityHeaders, prefix, - removeSemicolonContent, retryable, ribbonIsolationStrategy, routes, - semaphore, sensitiveHeaders, servletPath, sslHostnameValidationEnabled, - stripPrefix, threadPool, traceRequestBody, setContentLength, - includeDebugHeader, initialStreamBufferSize); - } - - @Override - public String toString() { - return new StringBuilder("ZuulProperties{").append("prefix='").append(prefix) - .append("', ").append("stripPrefix=").append(stripPrefix).append(", ") - .append("retryable=").append(retryable).append(", ").append("routes=") - .append(routes).append(", ").append("addProxyHeaders=") - .append(addProxyHeaders).append(", ").append("addHostHeader=") - .append(addHostHeader).append(", ").append("ignoredServices=") - .append(ignoredServices).append(", ").append("ignoredPatterns=") - .append(ignoredPatterns).append(", ").append("ignoredHeaders=") - .append(ignoredHeaders).append(", ").append("ignoreSecurityHeaders=") - .append(ignoreSecurityHeaders).append(", ") - .append("forceOriginalQueryStringEncoding=") - .append(forceOriginalQueryStringEncoding).append(", ") - .append("servletPath='").append(servletPath).append("', ") - .append("ignoreLocalService=").append(ignoreLocalService).append(", ") - .append("host=").append(host).append(", ").append("traceRequestBody=") - .append(traceRequestBody).append(", ").append("removeSemicolonContent=") - .append(removeSemicolonContent).append(", ").append("sensitiveHeaders=") - .append(sensitiveHeaders).append(", ") - .append("sslHostnameValidationEnabled=") - .append(sslHostnameValidationEnabled).append(", ") - .append("ribbonIsolationStrategy=").append(ribbonIsolationStrategy) - .append(", ").append("semaphore=").append(semaphore).append(", ") - .append("threadPool=").append(threadPool).append(", ") - .append("setContentLength=").append(setContentLength).append(", ") - .append("includeDebugHeader=").append(includeDebugHeader).append(", ") - .append("initialStreamBufferSize=").append(initialStreamBufferSize) - .append(", ").append("}").toString(); - } - - /** - * Represents a Zuul route. - */ - public static class ZuulRoute { - - /** - * The ID of the route (the same as its map key by default). - */ - private String id; - - /** - * The path (pattern) for the route, e.g. /foo/**. - */ - private String path; - - /** - * The service ID (if any) to map to this route. You can specify a physical URL or - * a service, but not both. - */ - private String serviceId; - - /** - * A full physical URL to map to the route. An alternative is to use a service ID - * and service discovery to find the physical address. - */ - private String url; - - /** - * Flag to determine whether the prefix for this route (the path, minus pattern - * patcher) should be stripped before forwarding. - */ - private boolean stripPrefix = true; - - /** - * Flag to indicate that this route should be retryable (if supported). Generally - * retry requires a service ID and ribbon. - */ - private Boolean retryable; - - /** - * List of sensitive headers that are not passed to downstream requests. Defaults - * to a "safe" set of headers that commonly contain user credentials. It's OK to - * remove those from the list if the downstream service is part of the same system - * as the proxy, so they are sharing authentication data. If using a physical URL - * outside your own domain, then generally it would be a bad idea to leak user - * credentials. - */ - private Set sensitiveHeaders = new LinkedHashSet<>(); - - private boolean customSensitiveHeaders = false; - - public ZuulRoute() { - } - - public ZuulRoute(String id, String path, String serviceId, String url, - boolean stripPrefix, Boolean retryable, Set sensitiveHeaders) { - this.id = id; - this.path = path; - this.serviceId = serviceId; - this.url = url; - this.stripPrefix = stripPrefix; - this.retryable = retryable; - this.sensitiveHeaders = sensitiveHeaders; - this.customSensitiveHeaders = sensitiveHeaders != null; - } - - public ZuulRoute(String text) { - String location = null; - String path = text; - if (text.contains("=")) { - String[] values = StringUtils - .trimArrayElements(StringUtils.split(text, "=")); - location = values[1]; - path = values[0]; - } - this.id = extractId(path); - if (!path.startsWith("/")) { - path = "/" + path; - } - setLocation(location); - this.path = path; - } - - public ZuulRoute(String path, String location) { - this.id = extractId(path); - this.path = path; - setLocation(location); - } - - public String getLocation() { - if (StringUtils.hasText(this.url)) { - return this.url; - } - return this.serviceId; - } - - public void setLocation(String location) { - if (location != null - && (location.startsWith("http:") || location.startsWith("https:"))) { - this.url = location; - } - else { - this.serviceId = location; - } - } - - private String extractId(String path) { - path = path.startsWith("/") ? path.substring(1) : path; - path = path.replace("/*", "").replace("*", ""); - return path; - } - - public Route getRoute(String prefix) { - return new Route(this.id, this.path, getLocation(), prefix, this.retryable, - isCustomSensitiveHeaders() ? this.sensitiveHeaders : null, - this.stripPrefix); - } - - public boolean isCustomSensitiveHeaders() { - return this.customSensitiveHeaders; - } - - public void setCustomSensitiveHeaders(boolean customSensitiveHeaders) { - this.customSensitiveHeaders = customSensitiveHeaders; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public String getServiceId() { - return serviceId; - } - - public void setServiceId(String serviceId) { - this.serviceId = serviceId; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public boolean isStripPrefix() { - return stripPrefix; - } - - public void setStripPrefix(boolean stripPrefix) { - this.stripPrefix = stripPrefix; - } - - public Boolean getRetryable() { - return retryable; - } - - public void setRetryable(Boolean retryable) { - this.retryable = retryable; - } - - public Set getSensitiveHeaders() { - return sensitiveHeaders; - } - - public void setSensitiveHeaders(Set headers) { - this.customSensitiveHeaders = true; - this.sensitiveHeaders = new LinkedHashSet<>(headers); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ZuulRoute that = (ZuulRoute) o; - return customSensitiveHeaders == that.customSensitiveHeaders - && Objects.equals(id, that.id) && Objects.equals(path, that.path) - && Objects.equals(retryable, that.retryable) - && Objects.equals(sensitiveHeaders, that.sensitiveHeaders) - && Objects.equals(serviceId, that.serviceId) - && stripPrefix == that.stripPrefix && Objects.equals(url, that.url); - } - - @Override - public int hashCode() { - return Objects.hash(customSensitiveHeaders, id, path, retryable, - sensitiveHeaders, serviceId, stripPrefix, url); - } - - @Override - public String toString() { - return new StringBuilder("ZuulRoute{").append("id='").append(id).append("', ") - .append("path='").append(path).append("', ").append("serviceId='") - .append(serviceId).append("', ").append("url='").append(url) - .append("', ").append("stripPrefix=").append(stripPrefix).append(", ") - .append("retryable=").append(retryable).append(", ") - .append("sensitiveHeaders=").append(sensitiveHeaders).append(", ") - .append("customSensitiveHeaders=").append(customSensitiveHeaders) - .append(", ").append("}").toString(); - } - - } - - /** - * Represents a host. - */ - public static class Host { - - /** - * The maximum number of total connections the proxy can hold open to backends. - */ - private int maxTotalConnections = 200; - - /** - * The maximum number of connections that can be used by a single route. - */ - private int maxPerRouteConnections = 20; - - /** - * The socket timeout in millis. Defaults to 10000. - */ - private int socketTimeoutMillis = 10000; - - /** - * The connection timeout in millis. Defaults to 2000. - */ - private int connectTimeoutMillis = 2000; - - /** - * The timeout in milliseconds used when requesting a connection from the - * connection manager. Defaults to -1, undefined use the system default. - */ - private int connectionRequestTimeoutMillis = -1; - - /** - * The lifetime for the connection pool. - */ - private long timeToLive = -1; - - /** - * The time unit for timeToLive. - */ - private TimeUnit timeUnit = TimeUnit.MILLISECONDS; - - public Host() { - } - - public Host(int maxTotalConnections, int maxPerRouteConnections, - int socketTimeoutMillis, int connectTimeoutMillis, long timeToLive, - TimeUnit timeUnit) { - this.maxTotalConnections = maxTotalConnections; - this.maxPerRouteConnections = maxPerRouteConnections; - this.socketTimeoutMillis = socketTimeoutMillis; - this.connectTimeoutMillis = connectTimeoutMillis; - this.timeToLive = timeToLive; - this.timeUnit = timeUnit; - } - - public int getMaxTotalConnections() { - return maxTotalConnections; - } - - public void setMaxTotalConnections(int maxTotalConnections) { - this.maxTotalConnections = maxTotalConnections; - } - - public int getMaxPerRouteConnections() { - return maxPerRouteConnections; - } - - public void setMaxPerRouteConnections(int maxPerRouteConnections) { - this.maxPerRouteConnections = maxPerRouteConnections; - } - - public int getSocketTimeoutMillis() { - return socketTimeoutMillis; - } - - public void setSocketTimeoutMillis(int socketTimeoutMillis) { - this.socketTimeoutMillis = socketTimeoutMillis; - } - - public int getConnectTimeoutMillis() { - return connectTimeoutMillis; - } - - public void setConnectTimeoutMillis(int connectTimeoutMillis) { - this.connectTimeoutMillis = connectTimeoutMillis; - } - - public int getConnectionRequestTimeoutMillis() { - return connectionRequestTimeoutMillis; - } - - public void setConnectionRequestTimeoutMillis( - int connectionRequestTimeoutMillis) { - this.connectionRequestTimeoutMillis = connectionRequestTimeoutMillis; - } - - public long getTimeToLive() { - return timeToLive; - } - - public void setTimeToLive(long timeToLive) { - this.timeToLive = timeToLive; - } - - public TimeUnit getTimeUnit() { - return timeUnit; - } - - public void setTimeUnit(TimeUnit timeUnit) { - this.timeUnit = timeUnit; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Host host = (Host) o; - return maxTotalConnections == host.maxTotalConnections - && maxPerRouteConnections == host.maxPerRouteConnections - && socketTimeoutMillis == host.socketTimeoutMillis - && connectTimeoutMillis == host.connectTimeoutMillis - && connectionRequestTimeoutMillis == host.connectionRequestTimeoutMillis - && timeToLive == host.timeToLive && timeUnit == host.timeUnit; - } - - @Override - public int hashCode() { - return Objects.hash(maxTotalConnections, maxPerRouteConnections, - socketTimeoutMillis, connectTimeoutMillis, - connectionRequestTimeoutMillis, timeToLive, timeUnit); - } - - @Override - public String toString() { - return new ToStringCreator(this) - .append("maxTotalConnections", maxTotalConnections) - .append("maxPerRouteConnections", maxPerRouteConnections) - .append("socketTimeoutMillis", socketTimeoutMillis) - .append("connectTimeoutMillis", connectTimeoutMillis) - .append("connectionRequestTimeoutMillis", - connectionRequestTimeoutMillis) - .append("timeToLive", timeToLive).append("timeUnit", timeUnit) - .toString(); - } - - } - - /** - * Represents Hystrix Sempahores. - */ - public static class HystrixSemaphore { - - /** - * The maximum number of total semaphores for Hystrix. - */ - private int maxSemaphores = 100; - - public HystrixSemaphore() { - } - - public HystrixSemaphore(int maxSemaphores) { - this.maxSemaphores = maxSemaphores; - } - - public int getMaxSemaphores() { - return maxSemaphores; - } - - public void setMaxSemaphores(int maxSemaphores) { - this.maxSemaphores = maxSemaphores; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - HystrixSemaphore that = (HystrixSemaphore) o; - return maxSemaphores == that.maxSemaphores; - } - - @Override - public int hashCode() { - return Objects.hash(maxSemaphores); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("HystrixSemaphore{"); - sb.append("maxSemaphores=").append(maxSemaphores); - sb.append('}'); - return sb.toString(); - } - - } - - /** - * Represents Hystrix ThreadPool. - */ - public static class HystrixThreadPool { - - /** - * Flag to determine whether RibbonCommands should use separate thread pools for - * hystrix. By setting to true, RibbonCommands will be executed in a hystrix's - * thread pool that it is associated with. Each RibbonCommand will be associated - * with a thread pool according to its commandKey (serviceId). As default, all - * commands will be executed in a single thread pool whose threadPoolKey is - * "RibbonCommand". This property is only applicable when using THREAD as - * ribbonIsolationStrategy - */ - private boolean useSeparateThreadPools = false; - - /** - * A prefix for HystrixThreadPoolKey of hystrix's thread pool that is allocated to - * each service Id. This property is only applicable when using THREAD as - * ribbonIsolationStrategy and useSeparateThreadPools = true - */ - private String threadPoolKeyPrefix = ""; - - public boolean isUseSeparateThreadPools() { - return useSeparateThreadPools; - } - - public void setUseSeparateThreadPools(boolean useSeparateThreadPools) { - this.useSeparateThreadPools = useSeparateThreadPools; - } - - public String getThreadPoolKeyPrefix() { - return threadPoolKeyPrefix; - } - - public void setThreadPoolKeyPrefix(String threadPoolKeyPrefix) { - this.threadPoolKeyPrefix = threadPoolKeyPrefix; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/DiscoveryClientRouteLocator.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/DiscoveryClientRouteLocator.java deleted file mode 100644 index 89e9ff041..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/DiscoveryClientRouteLocator.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.discovery; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; -import org.springframework.util.PatternMatchUtils; -import org.springframework.util.StringUtils; - -/** - * A {@link RouteLocator} that combines static, configured routes with those from a - * {@link DiscoveryClient}. The discovery client takes precedence. - * - * @author Spencer Gibb - * @author Dave Syer - */ -public class DiscoveryClientRouteLocator extends SimpleRouteLocator - implements RefreshableRouteLocator { - - private static final Log log = LogFactory.getLog(DiscoveryClientRouteLocator.class); - - /** - * Default route. - */ - public static final String DEFAULT_ROUTE = "/**"; - - private DiscoveryClient discovery; - - private ZuulProperties properties; - - private ServiceRouteMapper serviceRouteMapper; - - @Deprecated - public DiscoveryClientRouteLocator(String servletPath, DiscoveryClient discovery, - ZuulProperties properties) { - this(servletPath, discovery, properties, (ServiceInstance) null); - } - - public DiscoveryClientRouteLocator(String servletPath, DiscoveryClient discovery, - ZuulProperties properties, ServiceInstance localServiceInstance) { - super(servletPath, properties); - - if (properties.isIgnoreLocalService() && localServiceInstance != null) { - String localServiceId = localServiceInstance.getServiceId(); - if (!properties.getIgnoredServices().contains(localServiceId)) { - properties.getIgnoredServices().add(localServiceId); - } - } - this.serviceRouteMapper = new SimpleServiceRouteMapper(); - this.discovery = discovery; - this.properties = properties; - } - - @Deprecated - public DiscoveryClientRouteLocator(String servletPath, DiscoveryClient discovery, - ZuulProperties properties, ServiceRouteMapper serviceRouteMapper) { - this(servletPath, discovery, properties, (ServiceInstance) null); - this.serviceRouteMapper = serviceRouteMapper; - } - - public DiscoveryClientRouteLocator(String servletPath, DiscoveryClient discovery, - ZuulProperties properties, ServiceRouteMapper serviceRouteMapper, - ServiceInstance localServiceInstance) { - this(servletPath, discovery, properties, localServiceInstance); - this.serviceRouteMapper = serviceRouteMapper; - } - - public void addRoute(String path, String location) { - this.properties.getRoutes().put(path, new ZuulRoute(path, location)); - refresh(); - } - - public void addRoute(ZuulRoute route) { - this.properties.getRoutes().put(route.getPath(), route); - refresh(); - } - - @Override - protected LinkedHashMap locateRoutes() { - LinkedHashMap routesMap = new LinkedHashMap<>(); - routesMap.putAll(super.locateRoutes()); - if (this.discovery != null) { - Map staticServices = new LinkedHashMap<>(); - for (ZuulRoute route : routesMap.values()) { - String serviceId = route.getServiceId(); - if (serviceId == null) { - serviceId = route.getId(); - } - if (serviceId != null) { - staticServices.put(serviceId, route); - } - } - // Add routes for discovery services by default - List services = this.discovery.getServices(); - String[] ignored = this.properties.getIgnoredServices() - .toArray(new String[0]); - for (String serviceId : services) { - // Ignore specifically ignored services and those that were manually - // configured - String key = "/" + mapRouteToService(serviceId) + "/**"; - if (staticServices.containsKey(serviceId) - && staticServices.get(serviceId).getUrl() == null) { - // Explicitly configured with no URL, cannot be ignored - // all static routes are already in routesMap - // Update location using serviceId if location is null - ZuulRoute staticRoute = staticServices.get(serviceId); - if (!StringUtils.hasText(staticRoute.getLocation())) { - staticRoute.setLocation(serviceId); - } - } - if (!PatternMatchUtils.simpleMatch(ignored, serviceId) - && !routesMap.containsKey(key)) { - // Not ignored - routesMap.put(key, new ZuulRoute(key, serviceId)); - } - } - } - if (routesMap.get(DEFAULT_ROUTE) != null) { - ZuulRoute defaultRoute = routesMap.get(DEFAULT_ROUTE); - // Move the defaultServiceId to the end - routesMap.remove(DEFAULT_ROUTE); - routesMap.put(DEFAULT_ROUTE, defaultRoute); - } - LinkedHashMap values = new LinkedHashMap<>(); - for (Entry entry : routesMap.entrySet()) { - String path = entry.getKey(); - // Prepend with slash if not already present. - if (!path.startsWith("/")) { - path = "/" + path; - } - if (StringUtils.hasText(this.properties.getPrefix())) { - path = this.properties.getPrefix() + path; - if (!path.startsWith("/")) { - path = "/" + path; - } - } - values.put(path, entry.getValue()); - } - return values; - } - - @Override - public void refresh() { - doRefresh(); - } - - protected String mapRouteToService(String serviceId) { - return this.serviceRouteMapper.apply(serviceId); - } - - protected void addConfiguredRoutes(Map routes) { - Map routeEntries = this.properties.getRoutes(); - for (ZuulRoute entry : routeEntries.values()) { - String route = entry.getPath(); - if (routes.containsKey(route)) { - log.warn("Overwriting route " + route + ": already defined by " - + routes.get(route)); - } - routes.put(route, entry); - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapper.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapper.java deleted file mode 100644 index 4ee261c56..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapper.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2015-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.discovery; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.springframework.util.StringUtils; - -/** - * @author Stéphane Leroy - * - * This service route mapper use Java 7 RegEx named group feature to rewrite a discovered - * service Id into a route. - * - * Ex : If we want to map service Id [rest-service-v1] to - * /v1/rest-service/** route service pattern : - * "(?.*)-(?v.*$)" route pattern : - * "${version}/${name}" - * - * This implementation uses Matcher.replaceFirst so only one match will be - * replaced. - */ -public class PatternServiceRouteMapper implements ServiceRouteMapper { - - private static final Pattern MULTIPLE_SLASH_PATTERN = Pattern.compile("/{2,}"); - - /** - * A RegExp Pattern that extract needed information from a service ID. Ex : - * "(?.*)-(?v.*$)" - */ - private Pattern servicePattern; - - /** - * A RegExp that refer to named groups define in servicePattern. Ex : - * "${version}/${name}" - */ - private String routePattern; - - public PatternServiceRouteMapper(String servicePattern, String routePattern) { - this.servicePattern = Pattern.compile(servicePattern); - this.routePattern = routePattern; - } - - /** - * Use servicePattern to extract groups and routePattern to construct the route. - * - * If there is no matches, the serviceId is returned. - * @param serviceId service discovered name - * @return route path - */ - @Override - public String apply(String serviceId) { - Matcher matcher = this.servicePattern.matcher(serviceId); - String route = matcher.replaceFirst(this.routePattern); - route = cleanRoute(route); - return (StringUtils.hasText(route) ? route : serviceId); - } - - /** - * Route with regex and replace can be a bit messy when used with conditional named - * group. We clean here first and trailing '/' and remove multiple consecutive '/'. - * @param route a {@link String} representation of the route to be cleaned - * @return cleaned up route {@link String} - */ - private String cleanRoute(final String route) { - String routeToClean = MULTIPLE_SLASH_PATTERN.matcher(route).replaceAll("/"); - if (routeToClean.startsWith("/")) { - routeToClean = routeToClean.substring(1); - } - if (routeToClean.endsWith("/")) { - routeToClean = routeToClean.substring(0, routeToClean.length() - 1); - } - return routeToClean; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/ServiceRouteMapper.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/ServiceRouteMapper.java deleted file mode 100644 index 32997d0c0..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/ServiceRouteMapper.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2015-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.discovery; - -/** - * Provide a way to apply convention between routes and discovered services name. - * - * @author Stéphane LEROY - * - */ -public interface ServiceRouteMapper { - - /** - * Take a service Id (its discovered name) and return a route path. - * @param serviceId service discovered name - * @return route path - */ - String apply(String serviceId); - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/SimpleServiceRouteMapper.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/SimpleServiceRouteMapper.java deleted file mode 100644 index a34efa39d..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/SimpleServiceRouteMapper.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2015-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.discovery; - -/** - * @author Stéphane Leroy - * - * A simple passthru service route mapper. - */ -public class SimpleServiceRouteMapper implements ServiceRouteMapper { - - @Override - public String apply(String serviceId) { - return serviceId; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilter.java deleted file mode 100644 index 91b897f5b..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilter.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.post; - -import java.net.URI; - -import com.netflix.util.Pair; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.http.HttpStatus; -import org.springframework.http.server.ServletServerHttpRequest; -import org.springframework.util.StringUtils; -import org.springframework.web.util.UriComponents; -import org.springframework.web.util.UriComponentsBuilder; -import org.springframework.web.util.UrlPathHelper; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER; - -/** - * {@link ZuulFilter} Responsible for rewriting the Location header to be the Zuul URL. - * - * @author Biju Kunjummen - */ -public class LocationRewriteFilter extends ZuulFilter { - - private final UrlPathHelper urlPathHelper = new UrlPathHelper(); - - @Autowired - private ZuulProperties zuulProperties; - - @Autowired - private RouteLocator routeLocator; - - private static final String LOCATION_HEADER = "Location"; - - public LocationRewriteFilter() { - } - - public LocationRewriteFilter(ZuulProperties zuulProperties, - RouteLocator routeLocator) { - this.routeLocator = routeLocator; - this.zuulProperties = zuulProperties; - } - - @Override - public String filterType() { - return POST_TYPE; - } - - @Override - public int filterOrder() { - return SEND_RESPONSE_FILTER_ORDER - 100; - } - - @Override - public boolean shouldFilter() { - RequestContext ctx = RequestContext.getCurrentContext(); - int statusCode = ctx.getResponseStatusCode(); - return HttpStatus.valueOf(statusCode).is3xxRedirection(); - } - - @Override - public Object run() { - RequestContext ctx = RequestContext.getCurrentContext(); - Route route = routeLocator.getMatchingRoute( - urlPathHelper.getPathWithinApplication(ctx.getRequest())); - - if (route != null) { - Pair lh = locationHeader(ctx); - if (lh != null) { - String location = lh.second(); - URI originalRequestUri = UriComponentsBuilder - .fromHttpRequest(new ServletServerHttpRequest(ctx.getRequest())) - .build().toUri(); - - UriComponentsBuilder redirectedUriBuilder = UriComponentsBuilder - .fromUriString(location); - - UriComponents redirectedUriComps = redirectedUriBuilder.build(); - - String newPath = getRestoredPath(this.zuulProperties, route, - redirectedUriComps); - - String modifiedLocation = redirectedUriBuilder - .scheme(originalRequestUri.getScheme()) - .host(originalRequestUri.getHost()) - .port(originalRequestUri.getPort()).replacePath(newPath).build() - .toUriString(); - - lh.setSecond(modifiedLocation); - } - } - return null; - } - - private String getRestoredPath(ZuulProperties zuulProperties, Route route, - UriComponents redirectedUriComps) { - StringBuilder path = new StringBuilder(); - String redirectedPathWithoutGlobal = downstreamHasGlobalPrefix(zuulProperties) - ? redirectedUriComps.getPath() - .substring(("/" + zuulProperties.getPrefix()).length()) - : redirectedUriComps.getPath(); - - if (downstreamHasGlobalPrefix(zuulProperties)) { - path.append("/").append(zuulProperties.getPrefix()); - } - else { - path.append(zuulHasGlobalPrefix(zuulProperties) - ? "/" + zuulProperties.getPrefix() : ""); - } - - path.append(downstreamHasRoutePrefix(route) ? "" : "/" + route.getPrefix()) - .append(redirectedPathWithoutGlobal); - - return path.toString(); - } - - private boolean downstreamHasGlobalPrefix(ZuulProperties zuulProperties) { - return (!zuulProperties.isStripPrefix() - && StringUtils.hasText(zuulProperties.getPrefix())); - } - - private boolean zuulHasGlobalPrefix(ZuulProperties zuulProperties) { - return StringUtils.hasText(zuulProperties.getPrefix()); - } - - private boolean downstreamHasRoutePrefix(Route route) { - return (!route.isPrefixStripped() && StringUtils.hasText(route.getPrefix())); - } - - private Pair locationHeader(RequestContext ctx) { - if (ctx.getZuulResponseHeaders() != null) { - for (Pair pair : ctx.getZuulResponseHeaders()) { - if (pair.first().equals(LOCATION_HEADER)) { - return pair; - } - } - } - return null; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java deleted file mode 100644 index 1fa58b521..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.post; - -import java.net.SocketTimeoutException; - -import javax.servlet.RequestDispatcher; -import javax.servlet.http.HttpServletRequest; - -import com.netflix.client.ClientException; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.exception.ZuulException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.cloud.netflix.zuul.util.ZuulRuntimeException; -import org.springframework.http.HttpStatus; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ERROR_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_ERROR_FILTER_ORDER; - -/** - * Error {@link ZuulFilter} that forwards to /error (by default) if - * {@link RequestContext#getThrowable()} is not null. - * - * @author Spencer Gibb - */ -// TODO: move to error package in Edgware -public class SendErrorFilter extends ZuulFilter { - - private static final Log log = LogFactory.getLog(SendErrorFilter.class); - - protected static final String SEND_ERROR_FILTER_RAN = "sendErrorFilter.ran"; - - @Value("${error.path:/error}") - private String errorPath; - - @Override - public String filterType() { - return ERROR_TYPE; - } - - @Override - public int filterOrder() { - return SEND_ERROR_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - RequestContext ctx = RequestContext.getCurrentContext(); - // only forward to errorPath if it hasn't been forwarded to already - return ctx.getThrowable() != null - && !ctx.getBoolean(SEND_ERROR_FILTER_RAN, false); - } - - @Override - public Object run() { - try { - RequestContext ctx = RequestContext.getCurrentContext(); - ExceptionHolder exception = findZuulException(ctx.getThrowable()); - HttpServletRequest request = ctx.getRequest(); - - request.setAttribute("javax.servlet.error.status_code", - exception.getStatusCode()); - - log.warn("Error during filtering", exception.getThrowable()); - request.setAttribute("javax.servlet.error.exception", - exception.getThrowable()); - - if (StringUtils.hasText(exception.getErrorCause())) { - request.setAttribute("javax.servlet.error.message", - exception.getErrorCause()); - } - - RequestDispatcher dispatcher = request.getRequestDispatcher(this.errorPath); - if (dispatcher != null) { - ctx.set(SEND_ERROR_FILTER_RAN, true); - if (!ctx.getResponse().isCommitted()) { - ctx.setResponseStatusCode(exception.getStatusCode()); - dispatcher.forward(request, ctx.getResponse()); - } - } - } - catch (Exception ex) { - ReflectionUtils.rethrowRuntimeException(ex); - } - return null; - } - - protected ExceptionHolder findZuulException(Throwable throwable) { - if (throwable.getCause() instanceof ZuulRuntimeException) { - Throwable cause = null; - if (throwable.getCause().getCause() != null) { - cause = throwable.getCause().getCause().getCause(); - } - if (cause instanceof ClientException && cause.getCause() != null - && cause.getCause().getCause() instanceof SocketTimeoutException) { - - ZuulException zuulException = new ZuulException("", 504, - ZuulException.class.getName() + ": Hystrix Readed time out"); - return new ZuulExceptionHolder(zuulException); - } - // this was a failure initiated by one of the local filters - if (throwable.getCause().getCause() instanceof ZuulException) { - return new ZuulExceptionHolder( - (ZuulException) throwable.getCause().getCause()); - } - } - - if (throwable.getCause() instanceof ZuulException) { - // wrapped zuul exception - return new ZuulExceptionHolder((ZuulException) throwable.getCause()); - } - - if (throwable instanceof ZuulException) { - // exception thrown by zuul lifecycle - return new ZuulExceptionHolder((ZuulException) throwable); - } - - // fallback - return new DefaultExceptionHolder(throwable); - } - - public void setErrorPath(String errorPath) { - this.errorPath = errorPath; - } - - protected interface ExceptionHolder { - - Throwable getThrowable(); - - default int getStatusCode() { - return HttpStatus.INTERNAL_SERVER_ERROR.value(); - } - - default String getErrorCause() { - return null; - } - - } - - protected static class DefaultExceptionHolder implements ExceptionHolder { - - private final Throwable throwable; - - public DefaultExceptionHolder(Throwable throwable) { - this.throwable = throwable; - } - - @Override - public Throwable getThrowable() { - return this.throwable; - } - - } - - protected static class ZuulExceptionHolder implements ExceptionHolder { - - private final ZuulException exception; - - public ZuulExceptionHolder(ZuulException exception) { - this.exception = exception; - } - - @Override - public Throwable getThrowable() { - return this.exception; - } - - @Override - public int getStatusCode() { - return this.exception.nStatusCode; - } - - @Override - public String getErrorCause() { - return this.exception.errorCause; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilter.java deleted file mode 100644 index 4151d89ab..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilter.java +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.post; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.SequenceInputStream; -import java.util.List; -import java.util.Objects; -import java.util.zip.GZIPInputStream; - -import javax.servlet.http.HttpServletResponse; - -import com.netflix.util.Pair; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.constants.ZuulHeaders; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.util.HTTPRequestUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.util.ReflectionUtils; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTING_DEBUG_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_ZUUL_DEBUG_HEADER; - -/** - * Post {@link ZuulFilter} that writes responses from proxied requests to the current - * response. - * - * @author Spencer Gibb - * @author Dave Syer - * @author Ryan Baxter - */ -public class SendResponseFilter extends ZuulFilter { - - private static final Log log = LogFactory.getLog(SendResponseFilter.class); - - private boolean useServlet31 = true; - - private ZuulProperties zuulProperties; - - private ThreadLocal buffers; - - @Deprecated - public SendResponseFilter() { - this(new ZuulProperties()); - } - - public SendResponseFilter(ZuulProperties zuulProperties) { - this.zuulProperties = zuulProperties; - // To support Servlet API 3.1 we need to check if setContentLengthLong exists - // minimum support in Spring 5 is 3.0 so we need to keep tihs - try { - HttpServletResponse.class.getMethod("setContentLengthLong", long.class); - } - catch (NoSuchMethodException e) { - useServlet31 = false; - } - buffers = ThreadLocal - .withInitial(() -> new byte[zuulProperties.getInitialStreamBufferSize()]); - } - - /* for testing */ boolean isUseServlet31() { - return useServlet31; - } - - @Override - public String filterType() { - return POST_TYPE; - } - - @Override - public int filterOrder() { - return SEND_RESPONSE_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - RequestContext context = RequestContext.getCurrentContext(); - return context.getThrowable() == null - && (!context.getZuulResponseHeaders().isEmpty() - || context.getResponseDataStream() != null - || context.getResponseBody() != null); - } - - @Override - public Object run() { - try { - addResponseHeaders(); - writeResponse(); - } - catch (Exception ex) { - ReflectionUtils.rethrowRuntimeException(ex); - } - return null; - } - - private void writeResponse() throws Exception { - RequestContext context = RequestContext.getCurrentContext(); - // there is no body to send - if (context.getResponseBody() == null - && context.getResponseDataStream() == null) { - return; - } - HttpServletResponse servletResponse = context.getResponse(); - if (servletResponse.getCharacterEncoding() == null) { // only set if not set - servletResponse.setCharacterEncoding("UTF-8"); - } - - String servletResponseContentEncoding = getResponseContentEncoding(context); - OutputStream outStream = servletResponse.getOutputStream(); - InputStream is = null; - try { - if (context.getResponseBody() != null) { - String body = context.getResponseBody(); - is = new ByteArrayInputStream( - body.getBytes(servletResponse.getCharacterEncoding())); - } - else { - is = context.getResponseDataStream(); - if (is != null && context.getResponseGZipped()) { - // if origin response is gzipped, and client has not requested gzip, - // decompress stream before sending to client - // else, stream gzip directly to client - if (isGzipRequested(context)) { - servletResponseContentEncoding = "gzip"; - } - else { - servletResponseContentEncoding = null; - is = handleGzipStream(is); - } - } - } - if (servletResponseContentEncoding != null) { - servletResponse.setHeader(ZuulHeaders.CONTENT_ENCODING, - servletResponseContentEncoding); - } - - if (is != null) { - writeResponse(is, outStream); - } - } - finally { - /** - * We must ensure that the InputStream provided by our upstream pooling - * mechanism is ALWAYS closed even in the case of wrapped streams, which are - * supplied by pooled sources such as Apache's - * PoolingHttpClientConnectionManager. In that particular case, the underlying - * HTTP connection will be returned back to the connection pool iif either - * close() is explicitly called, a read error occurs, or the end of the - * underlying stream is reached. If, however a write error occurs, we will end - * up leaking a connection from the pool without an explicit close() - * - * @author Johannes Edmeier - */ - if (is != null) { - try { - is.close(); - } - catch (Exception ex) { - log.warn("Error while closing upstream input stream", ex); - } - } - - // cleanup ThreadLocal when we are all done - if (buffers != null) { - buffers.remove(); - } - - try { - Object zuulResponse = context.get("zuulResponse"); - if (zuulResponse instanceof Closeable) { - ((Closeable) zuulResponse).close(); - } - outStream.flush(); - // The container will close the stream for us - } - catch (IOException ex) { - log.warn("Error while sending response to client: " + ex.getMessage()); - } - } - } - - protected InputStream handleGzipStream(InputStream in) throws Exception { - // Record bytes read during GZip initialization to allow to rewind the stream if - // needed - // - RecordingInputStream stream = new RecordingInputStream(in); - try { - return new GZIPInputStream(stream); - } - catch (java.util.zip.ZipException | java.io.EOFException ex) { - - if (stream.getBytesRead() == 0) { - // stream was empty, return the original "empty" stream - return in; - } - else { - // reset the stream and assume an unencoded response - log.warn( - "gzip response expected but failed to read gzip headers, assuming unencoded response for request " - + RequestContext.getCurrentContext().getRequest() - .getRequestURL().toString()); - - stream.reset(); - return stream; - } - } - finally { - stream.stopRecording(); - } - } - - protected boolean isGzipRequested(RequestContext context) { - final String requestEncoding = context.getRequest() - .getHeader(ZuulHeaders.ACCEPT_ENCODING); - - return requestEncoding != null - && HTTPRequestUtils.getInstance().isGzipped(requestEncoding); - } - - private String getResponseContentEncoding(RequestContext context) { - List> zuulResponseHeaders = context.getZuulResponseHeaders(); - if (zuulResponseHeaders != null) { - for (Pair it : zuulResponseHeaders) { - if (ZuulHeaders.CONTENT_ENCODING.equalsIgnoreCase(it.first())) { - return it.second(); - } - } - } - return null; - } - - private void writeResponse(InputStream zin, OutputStream out) throws Exception { - byte[] bytes = buffers.get(); - int bytesRead = -1; - while ((bytesRead = zin.read(bytes)) != -1) { - out.write(bytes, 0, bytesRead); - } - } - - private void addResponseHeaders() { - RequestContext context = RequestContext.getCurrentContext(); - HttpServletResponse servletResponse = context.getResponse(); - if (this.zuulProperties.isIncludeDebugHeader()) { - @SuppressWarnings("unchecked") - List rd = (List) context.get(ROUTING_DEBUG_KEY); - if (rd != null) { - StringBuilder debugHeader = new StringBuilder(); - for (String it : rd) { - debugHeader.append("[[[").append(it).append("]]]"); - } - servletResponse.addHeader(X_ZUUL_DEBUG_HEADER, debugHeader.toString()); - } - } - List> zuulResponseHeaders = context.getZuulResponseHeaders(); - if (zuulResponseHeaders != null) { - for (Pair it : zuulResponseHeaders) { - if (!ZuulHeaders.CONTENT_ENCODING.equalsIgnoreCase(it.first())) { - servletResponse.addHeader(it.first(), it.second()); - } - } - } - if (includeContentLengthHeader(context)) { - Long contentLength = context.getOriginContentLength(); - if (useServlet31) { - servletResponse.setContentLengthLong(contentLength); - } - else { - // Try and set some kind of content length if we can safely convert the - // Long to an int - if (isLongSafe(contentLength)) { - servletResponse.setContentLength(contentLength.intValue()); - } - } - } - } - - private boolean isLongSafe(long value) { - return value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE; - } - - protected boolean includeContentLengthHeader(RequestContext context) { - // Not configured to forward the header - if (!this.zuulProperties.isSetContentLength()) { - return false; - } - - // Only if Content-Length is provided - if (context.getOriginContentLength() == null) { - return false; - } - - // If response is compressed, include header only if we are not about to - // decompress it - if (context.getResponseGZipped()) { - return context.isGzipRequested(); - } - - // Forward it in all other cases - return true; - } - - /** - * InputStream recording bytes read to allow for a reset() until recording is stopped. - */ - private static class RecordingInputStream extends InputStream { - - private InputStream delegate; - - private ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - RecordingInputStream(InputStream delegate) { - super(); - this.delegate = Objects.requireNonNull(delegate); - } - - @Override - public int read() throws IOException { - int read = delegate.read(); - - if (buffer != null && read != -1) { - buffer.write(read); - } - - return read; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - int read = delegate.read(b, off, len); - - if (buffer != null && read != -1) { - buffer.write(b, off, read); - } - - return read; - } - - public void reset() { - if (buffer == null) { - throw new IllegalStateException("Stream is not recording"); - } - - this.delegate = new SequenceInputStream( - new ByteArrayInputStream(buffer.toByteArray()), delegate); - this.buffer = new ByteArrayOutputStream(); - } - - public int getBytesRead() { - return (buffer == null) ? -1 : buffer.size(); - } - - public void stopRecording() { - this.buffer = null; - } - - @Override - public void close() throws IOException { - this.delegate.close(); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/DebugFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/DebugFilter.java deleted file mode 100644 index 6484b0961..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/DebugFilter.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.pre; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.config.DynamicBooleanProperty; -import com.netflix.config.DynamicPropertyFactory; -import com.netflix.config.DynamicStringProperty; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.constants.ZuulConstants; -import com.netflix.zuul.context.RequestContext; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.DEBUG_FILTER_ORDER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; - -/** - * Pre {@link ZuulFilter} that sets {@link RequestContext} debug attributes to true if the - * "debug" request parameter is set. - * - * @author Spencer Gibb - */ -public class DebugFilter extends ZuulFilter { - - private static final DynamicBooleanProperty ROUTING_DEBUG = DynamicPropertyFactory - .getInstance().getBooleanProperty(ZuulConstants.ZUUL_DEBUG_REQUEST, false); - - private static final DynamicStringProperty DEBUG_PARAMETER = DynamicPropertyFactory - .getInstance().getStringProperty(ZuulConstants.ZUUL_DEBUG_PARAMETER, "debug"); - - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public int filterOrder() { - return DEBUG_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - HttpServletRequest request = RequestContext.getCurrentContext().getRequest(); - if ("true".equals(request.getParameter(DEBUG_PARAMETER.get()))) { - return true; - } - return ROUTING_DEBUG.get(); - } - - @Override - public Object run() { - RequestContext ctx = RequestContext.getCurrentContext(); - ctx.setDebugRouting(true); - ctx.setDebugRequest(true); - return null; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java deleted file mode 100644 index 984a82a4a..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.pre; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.Field; - -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletRequestWrapper; -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.http.HttpServletRequestWrapper; -import com.netflix.zuul.http.ServletInputStreamWrapper; - -import org.springframework.cloud.netflix.zuul.util.RequestContentDataExtractor; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpOutputMessage; -import org.springframework.http.InvalidMediaTypeException; -import org.springframework.http.MediaType; -import org.springframework.http.converter.FormHttpMessageConverter; -import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; -import org.springframework.util.Assert; -import org.springframework.util.MultiValueMap; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.servlet.DispatcherServlet; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORM_BODY_WRAPPER_FILTER_ORDER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; - -/** - * Pre {@link ZuulFilter} that parses form data and reencodes it for downstream services. - * - * @author Dave Syer - */ -public class FormBodyWrapperFilter extends ZuulFilter { - - private FormHttpMessageConverter formHttpMessageConverter; - - private Field requestField; - - private Field servletRequestField; - - public FormBodyWrapperFilter() { - this(new AllEncompassingFormHttpMessageConverter()); - } - - public FormBodyWrapperFilter(FormHttpMessageConverter formHttpMessageConverter) { - this.formHttpMessageConverter = formHttpMessageConverter; - this.requestField = ReflectionUtils.findField(HttpServletRequestWrapper.class, - "req", HttpServletRequest.class); - this.servletRequestField = ReflectionUtils.findField(ServletRequestWrapper.class, - "request", ServletRequest.class); - Assert.notNull(this.requestField, - "HttpServletRequestWrapper.req field not found"); - Assert.notNull(this.servletRequestField, - "ServletRequestWrapper.request field not found"); - this.requestField.setAccessible(true); - this.servletRequestField.setAccessible(true); - } - - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public int filterOrder() { - return FORM_BODY_WRAPPER_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - RequestContext ctx = RequestContext.getCurrentContext(); - HttpServletRequest request = ctx.getRequest(); - String contentType = request.getContentType(); - // Don't use this filter on GET method - if (contentType == null) { - return false; - } - // Only use this filter for form data and only for multipart data in a - // DispatcherServlet handler - try { - MediaType mediaType = MediaType.valueOf(contentType); - return MediaType.APPLICATION_FORM_URLENCODED.includes(mediaType) - || (isDispatcherServletRequest(request) - && MediaType.MULTIPART_FORM_DATA.includes(mediaType)); - } - catch (InvalidMediaTypeException ex) { - return false; - } - } - - private boolean isDispatcherServletRequest(HttpServletRequest request) { - return request.getAttribute( - DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null; - } - - @Override - public Object run() { - RequestContext ctx = RequestContext.getCurrentContext(); - HttpServletRequest request = ctx.getRequest(); - FormBodyRequestWrapper wrapper = null; - if (request instanceof HttpServletRequestWrapper) { - HttpServletRequest wrapped = (HttpServletRequest) ReflectionUtils - .getField(this.requestField, request); - wrapper = new FormBodyRequestWrapper(wrapped); - ReflectionUtils.setField(this.requestField, request, wrapper); - if (request instanceof ServletRequestWrapper) { - ReflectionUtils.setField(this.servletRequestField, request, wrapper); - } - } - else { - wrapper = new FormBodyRequestWrapper(request); - ctx.setRequest(wrapper); - } - if (wrapper != null) { - ctx.getZuulRequestHeaders().put("content-type", wrapper.getContentType()); - } - return null; - } - - private class FormBodyRequestWrapper extends Servlet30RequestWrapper { - - private HttpServletRequest request; - - private volatile byte[] contentData; - - private MediaType contentType; - - private int contentLength; - - FormBodyRequestWrapper(HttpServletRequest request) { - super(request); - this.request = request; - } - - @Override - public String getContentType() { - if (this.contentData == null) { - buildContentData(); - } - return this.contentType.toString(); - } - - @Override - public int getContentLength() { - if (super.getContentLength() <= 0) { - return super.getContentLength(); - } - if (this.contentData == null) { - buildContentData(); - } - return this.contentLength; - } - - public long getContentLengthLong() { - return getContentLength(); - } - - @Override - public ServletInputStream getInputStream() throws IOException { - if (this.contentData == null) { - buildContentData(); - } - return new ServletInputStreamWrapper(this.contentData); - } - - private synchronized void buildContentData() { - if (this.contentData != null) { - return; - } - try { - MultiValueMap builder = RequestContentDataExtractor - .extract(this.request); - FormHttpOutputMessage data = new FormHttpOutputMessage(); - - this.contentType = MediaType.valueOf(this.request.getContentType()); - data.getHeaders().setContentType(this.contentType); - FormBodyWrapperFilter.this.formHttpMessageConverter.write(builder, - this.contentType, data); - // copy new content type including multipart boundary - this.contentType = data.getHeaders().getContentType(); - byte[] input = data.getInput(); - this.contentLength = input.length; - this.contentData = input; - } - catch (Exception e) { - throw new IllegalStateException("Cannot convert form data", e); - } - } - - private class FormHttpOutputMessage implements HttpOutputMessage { - - private HttpHeaders headers = new HttpHeaders(); - - private ByteArrayOutputStream output = new ByteArrayOutputStream(); - - @Override - public HttpHeaders getHeaders() { - return this.headers; - } - - @Override - public OutputStream getBody() throws IOException { - return this.output; - } - - public byte[] getInput() throws IOException { - this.output.flush(); - return this.output.toByteArray(); - } - - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java deleted file mode 100755 index 0fa378080..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.pre; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.regex.Pattern; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; -import org.springframework.cloud.netflix.zuul.util.RequestUtils; -import org.springframework.http.HttpHeaders; -import org.springframework.util.StringUtils; -import org.springframework.web.util.UrlPathHelper; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_LOCATION_PREFIX; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_TO_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.HTTPS_PORT; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.HTTPS_SCHEME; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.HTTP_PORT; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.HTTP_SCHEME; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PROXY_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.RETRYABLE_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_HEADER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_HEADER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_FOR_HEADER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_HOST_HEADER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_PORT_HEADER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_PREFIX_HEADER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_PROTO_HEADER; - -/** - * Pre {@link ZuulFilter} that determines where and how to route based on the supplied - * {@link RouteLocator}. Also sets various proxy related headers for downstream requests. - * - * @author Spencer Gibb - * @author Dave Syer - * @author Philip Webb - * @author Stefan Fussenegger - * @author Adrian Ivan - * @author Jacques-Etienne Beaudet - * @author Durigon Durigon - */ -public class PreDecorationFilter extends ZuulFilter { - - private static final Log log = LogFactory.getLog(PreDecorationFilter.class); - - /** - * @deprecated use {@link FilterConstants#PRE_DECORATION_FILTER_ORDER} - */ - @Deprecated - public static final int FILTER_ORDER = PRE_DECORATION_FILTER_ORDER; - - /** - * A double slash pattern. - */ - public static final Pattern DOUBLE_SLASH = Pattern.compile("//"); - - private RouteLocator routeLocator; - - private String dispatcherServletPath; - - private ZuulProperties properties; - - private UrlPathHelper urlPathHelper = new UrlPathHelper(); - - private ProxyRequestHelper proxyRequestHelper; - - public PreDecorationFilter(RouteLocator routeLocator, String dispatcherServletPath, - ZuulProperties properties, ProxyRequestHelper proxyRequestHelper) { - this.routeLocator = routeLocator; - this.properties = properties; - this.urlPathHelper - .setRemoveSemicolonContent(properties.isRemoveSemicolonContent()); - this.urlPathHelper.setUrlDecode(properties.isDecodeUrl()); - this.dispatcherServletPath = dispatcherServletPath; - this.proxyRequestHelper = proxyRequestHelper; - } - - @Override - public int filterOrder() { - return PRE_DECORATION_FILTER_ORDER; - } - - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public boolean shouldFilter() { - RequestContext ctx = RequestContext.getCurrentContext(); - return !ctx.containsKey(FORWARD_TO_KEY) // a filter has already forwarded - && !ctx.containsKey(SERVICE_ID_KEY); // a filter has already determined - // serviceId - } - - @Override - public Object run() { - RequestContext ctx = RequestContext.getCurrentContext(); - final String requestURI = this.urlPathHelper - .getPathWithinApplication(ctx.getRequest()); - Route route = this.routeLocator.getMatchingRoute(requestURI); - if (route != null) { - String location = route.getLocation(); - if (location != null) { - ctx.put(REQUEST_URI_KEY, route.getPath()); - ctx.put(PROXY_KEY, route.getId()); - if (!route.isCustomSensitiveHeaders()) { - this.proxyRequestHelper.addIgnoredHeaders( - this.properties.getSensitiveHeaders().toArray(new String[0])); - } - else { - this.proxyRequestHelper.addIgnoredHeaders( - route.getSensitiveHeaders().toArray(new String[0])); - } - - if (route.getRetryable() != null) { - ctx.put(RETRYABLE_KEY, route.getRetryable()); - } - - if (location.startsWith(HTTP_SCHEME + ":") - || location.startsWith(HTTPS_SCHEME + ":")) { - ctx.setRouteHost(getUrl(location)); - ctx.addOriginResponseHeader(SERVICE_HEADER, location); - } - else if (location.startsWith(FORWARD_LOCATION_PREFIX)) { - ctx.set(FORWARD_TO_KEY, - StringUtils.cleanPath( - location.substring(FORWARD_LOCATION_PREFIX.length()) - + route.getPath())); - ctx.setRouteHost(null); - return null; - } - else { - // set serviceId for use in filters.route.RibbonRequest - ctx.set(SERVICE_ID_KEY, location); - ctx.setRouteHost(null); - ctx.addOriginResponseHeader(SERVICE_ID_HEADER, location); - } - if (this.properties.isAddProxyHeaders()) { - addProxyHeaders(ctx, route); - String xforwardedfor = ctx.getRequest() - .getHeader(X_FORWARDED_FOR_HEADER); - String remoteAddr = ctx.getRequest().getRemoteAddr(); - if (xforwardedfor == null) { - xforwardedfor = remoteAddr; - } - else if (!xforwardedfor.contains(remoteAddr)) { // Prevent duplicates - xforwardedfor += ", " + remoteAddr; - } - ctx.addZuulRequestHeader(X_FORWARDED_FOR_HEADER, xforwardedfor); - } - if (this.properties.isAddHostHeader()) { - ctx.addZuulRequestHeader(HttpHeaders.HOST, - toHostHeader(ctx.getRequest())); - } - } - } - else { - log.warn("No route found for uri: " + requestURI); - String forwardURI = getForwardUri(requestURI); - - ctx.set(FORWARD_TO_KEY, forwardURI); - } - return null; - } - - /* for testing */ String getForwardUri(String requestURI) { - // default fallback servlet is DispatcherServlet - String fallbackPrefix = this.dispatcherServletPath; - - String fallBackUri = requestURI; - if (RequestUtils.isZuulServletRequest()) { - // remove the Zuul servletPath from the requestUri - log.debug("zuulServletPath=" + this.properties.getServletPath()); - fallBackUri = fallBackUri.replaceFirst(this.properties.getServletPath(), ""); - log.debug("Replaced Zuul servlet path:" + fallBackUri); - } - else if (this.dispatcherServletPath != null) { - // remove the DispatcherServlet servletPath from the requestUri - log.debug("dispatcherServletPath=" + this.dispatcherServletPath); - fallBackUri = fallBackUri.replaceFirst(this.dispatcherServletPath, ""); - log.debug("Replaced DispatcherServlet servlet path:" + fallBackUri); - } - if (!fallBackUri.startsWith("/")) { - fallBackUri = "/" + fallBackUri; - } - - String forwardURI = (fallbackPrefix == null) ? fallBackUri - : fallbackPrefix + fallBackUri; - forwardURI = DOUBLE_SLASH.matcher(forwardURI).replaceAll("/"); - return forwardURI; - } - - private void addProxyHeaders(RequestContext ctx, Route route) { - HttpServletRequest request = ctx.getRequest(); - String host = toHostHeader(request); - String port = String.valueOf(request.getServerPort()); - String proto = request.getScheme(); - if (hasHeader(request, X_FORWARDED_HOST_HEADER)) { - host = request.getHeader(X_FORWARDED_HOST_HEADER) + "," + host; - } - if (!hasHeader(request, X_FORWARDED_PORT_HEADER)) { - if (hasHeader(request, X_FORWARDED_PROTO_HEADER)) { - StringBuilder builder = new StringBuilder(); - for (String previous : StringUtils.commaDelimitedListToStringArray( - request.getHeader(X_FORWARDED_PROTO_HEADER))) { - if (builder.length() > 0) { - builder.append(","); - } - builder.append( - HTTPS_SCHEME.equals(previous) ? HTTPS_PORT : HTTP_PORT); - } - builder.append(",").append(port); - port = builder.toString(); - } - } - else { - port = request.getHeader(X_FORWARDED_PORT_HEADER) + "," + port; - } - if (hasHeader(request, X_FORWARDED_PROTO_HEADER)) { - proto = request.getHeader(X_FORWARDED_PROTO_HEADER) + "," + proto; - } - ctx.addZuulRequestHeader(X_FORWARDED_HOST_HEADER, host); - ctx.addZuulRequestHeader(X_FORWARDED_PORT_HEADER, port); - ctx.addZuulRequestHeader(X_FORWARDED_PROTO_HEADER, proto); - addProxyPrefix(ctx, route); - } - - private boolean hasHeader(HttpServletRequest request, String name) { - return StringUtils.hasLength(request.getHeader(name)); - } - - private void addProxyPrefix(RequestContext ctx, Route route) { - String forwardedPrefix = ctx.getRequest().getHeader(X_FORWARDED_PREFIX_HEADER); - String contextPath = ctx.getRequest().getContextPath(); - String prefix = StringUtils.hasLength(forwardedPrefix) ? forwardedPrefix - : (StringUtils.hasLength(contextPath) ? contextPath : null); - if (StringUtils.hasText(route.getPrefix())) { - StringBuilder newPrefixBuilder = new StringBuilder(); - if (prefix != null) { - if (prefix.endsWith("/") && route.getPrefix().startsWith("/")) { - newPrefixBuilder.append(prefix, 0, prefix.length() - 1); - } - else { - newPrefixBuilder.append(prefix); - } - } - newPrefixBuilder.append(route.getPrefix()); - prefix = newPrefixBuilder.toString(); - } - if (prefix != null) { - ctx.addZuulRequestHeader(X_FORWARDED_PREFIX_HEADER, prefix); - } - } - - private String toHostHeader(HttpServletRequest request) { - int port = request.getServerPort(); - if ((port == HTTP_PORT && HTTP_SCHEME.equals(request.getScheme())) - || (port == HTTPS_PORT && HTTPS_SCHEME.equals(request.getScheme()))) { - return request.getServerName(); - } - else { - return request.getServerName() + ":" + port; - } - } - - private URL getUrl(String target) { - try { - return new URL(target); - } - catch (MalformedURLException ex) { - throw new IllegalStateException("Target URL is malformed", ex); - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30RequestWrapper.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30RequestWrapper.java deleted file mode 100644 index 11d084369..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30RequestWrapper.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.pre; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.http.HttpServletRequestWrapper; - -/** - * A Servlet 3.0 compliant wrapper. - */ -class Servlet30RequestWrapper extends HttpServletRequestWrapper { - - private HttpServletRequest request; - - Servlet30RequestWrapper(HttpServletRequest request) { - super(request); - this.request = request; - } - - /** - * There is a bug in zuul 1.2.2 where HttpServletRequestWrapper.getRequest returns a - * wrapped request rather than the raw one. - * @return the original HttpServletRequest - */ - @Override - public HttpServletRequest getRequest() { - return this.request; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30WrapperFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30WrapperFilter.java deleted file mode 100644 index d9145ae09..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30WrapperFilter.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.pre; - -import java.lang.reflect.Field; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.http.HttpServletRequestWrapper; - -import org.springframework.cloud.netflix.zuul.util.RequestUtils; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_30_WRAPPER_FILTER_ORDER; - -/** - * Pre {@link ZuulFilter} that wraps requests in a Servlet 3.0 compliant wrapper. Zuul's - * default wrapper is only Servlet 2.5 compliant. - * - * @author Spencer Gibb - */ -public class Servlet30WrapperFilter extends ZuulFilter { - - private Field requestField = null; - - public Servlet30WrapperFilter() { - this.requestField = ReflectionUtils.findField(HttpServletRequestWrapper.class, - "req", HttpServletRequest.class); - Assert.notNull(this.requestField, - "HttpServletRequestWrapper.req field not found"); - this.requestField.setAccessible(true); - } - - protected Field getRequestField() { - return this.requestField; - } - - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public int filterOrder() { - return SERVLET_30_WRAPPER_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - return true; // TODO: only if in servlet 3.0 env - } - - @Override - public Object run() { - RequestContext ctx = RequestContext.getCurrentContext(); - HttpServletRequest request = ctx.getRequest(); - if (request instanceof HttpServletRequestWrapper) { - request = (HttpServletRequest) ReflectionUtils.getField(this.requestField, - request); - ctx.setRequest(new Servlet30RequestWrapper(request)); - } - else if (RequestUtils.isDispatcherServletRequest()) { - // If it's going through the dispatcher we need to buffer the body - ctx.setRequest(new Servlet30RequestWrapper(request)); - } - return null; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/ServletDetectionFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/ServletDetectionFilter.java deleted file mode 100644 index e8d5f15d8..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/ServletDetectionFilter.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.pre; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.http.HttpServletRequestWrapper; -import com.netflix.zuul.http.ZuulServlet; - -import org.springframework.web.servlet.DispatcherServlet; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.IS_DISPATCHER_SERVLET_REQUEST_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_DETECTION_FILTER_ORDER; - -/** - * Detects whether a request is ran through the {@link DispatcherServlet} or - * {@link ZuulServlet}. The purpose was to detect this up-front at the very beginning of - * Zuul filter processing and rely on this information in all filters. RequestContext is - * used such that the information is accessible to classes which do not have a request - * reference. - * - * @author Adrian Ivan - */ -public class ServletDetectionFilter extends ZuulFilter { - - public ServletDetectionFilter() { - } - - @Override - public String filterType() { - return PRE_TYPE; - } - - /** - * Must run before other filters that rely on the difference between DispatcherServlet - * and ZuulServlet. - */ - @Override - public int filterOrder() { - return SERVLET_DETECTION_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - RequestContext ctx = RequestContext.getCurrentContext(); - HttpServletRequest request = ctx.getRequest(); - if (!(request instanceof HttpServletRequestWrapper) - && isDispatcherServletRequest(request)) { - ctx.set(IS_DISPATCHER_SERVLET_REQUEST_KEY, true); - } - else { - ctx.set(IS_DISPATCHER_SERVLET_REQUEST_KEY, false); - } - - return null; - } - - private boolean isDispatcherServletRequest(HttpServletRequest request) { - return request.getAttribute( - DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/FallbackProvider.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/FallbackProvider.java deleted file mode 100644 index 781410cd8..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/FallbackProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import org.springframework.http.client.ClientHttpResponse; - -/** - * Provides fallback when a failure occurs on a route. - * - * @author Ryan Baxter - * @author Dominik Mostek - */ -public interface FallbackProvider { - - /** - * The route this fallback will be used for. - * @return The route the fallback will be used for. - */ - String getRoute(); - - /** - * Provides a fallback response based on the cause of the failed execution. - * @param route The route the fallback is for - * @param cause cause of the main method failure, may be null - * @return the fallback response - */ - ClientHttpResponse fallbackResponse(String route, Throwable cause); - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommand.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommand.java deleted file mode 100644 index d93137651..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommand.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import java.io.InputStream; -import java.net.URI; -import java.util.List; - -import com.netflix.client.config.IClientConfig; -import com.netflix.client.http.HttpRequest; -import com.netflix.client.http.HttpResponse; -import com.netflix.niws.client.http.RestClient; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommand; -import org.springframework.http.HttpMethod; -import org.springframework.util.MultiValueMap; - -import static org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer.Runner.customize; - -/** - * Hystrix wrapper around Eureka Ribbon command. - * - * see original - * - * @author Spencer Gibb - * @author Stephane Lagraulet - * @author Ryan Baxter - */ -@SuppressWarnings("deprecation") -public class RestClientRibbonCommand - extends AbstractRibbonCommand { - - public RestClientRibbonCommand(String commandKey, RestClient client, - RibbonCommandContext context, ZuulProperties zuulProperties) { - super(commandKey, client, context, zuulProperties); - } - - public RestClientRibbonCommand(String commandKey, RestClient client, - RibbonCommandContext context, ZuulProperties zuulProperties, - FallbackProvider zuulFallbackProvider) { - super(commandKey, client, context, zuulProperties, zuulFallbackProvider); - } - - public RestClientRibbonCommand(String commandKey, RestClient client, - RibbonCommandContext context, ZuulProperties zuulProperties, - FallbackProvider zuulFallbackProvider, IClientConfig config) { - super(commandKey, client, context, zuulProperties, zuulFallbackProvider, config); - } - - @Deprecated - public RestClientRibbonCommand(String commandKey, RestClient restClient, - HttpRequest.Verb verb, String uri, Boolean retryable, - MultiValueMap headers, MultiValueMap params, - InputStream requestEntity) { - this(commandKey, restClient, new RibbonCommandContext(commandKey, verb.verb(), - uri, retryable, headers, params, requestEntity), new ZuulProperties()); - } - - @Override - protected HttpRequest createRequest() throws Exception { - final InputStream requestEntity; - // ApacheHttpClient4Handler does not support body in delete requests - if (getContext().getMethod().equalsIgnoreCase(HttpMethod.DELETE.toString())) { - requestEntity = null; - } - else { - requestEntity = this.context.getRequestEntity(); - } - - HttpRequest.Builder builder = HttpRequest.newBuilder() - .verb(getVerb(this.context.getMethod())).uri(this.context.uri()) - .entity(requestEntity); - - if (this.context.getRetryable() != null) { - builder.setRetriable(this.context.getRetryable()); - } - - for (String name : this.context.getHeaders().keySet()) { - List values = this.context.getHeaders().get(name); - for (String value : values) { - builder.header(name, value); - } - } - for (String name : this.context.getParams().keySet()) { - List values = this.context.getParams().get(name); - for (String value : values) { - builder.queryParams(name, value); - } - } - - customizeRequest(builder); - - return builder.build(); - } - - protected void customizeRequest(HttpRequest.Builder requestBuilder) { - customize(this.context.getRequestCustomizers(), requestBuilder); - } - - @Deprecated - public URI getUri() { - return this.context.uri(); - } - - @SuppressWarnings("unused") - @Deprecated - public HttpRequest.Verb getVerb() { - return getVerb(this.context.getVerb()); - } - - protected static HttpRequest.Verb getVerb(String method) { - if (method == null) { - return HttpRequest.Verb.GET; - } - try { - return HttpRequest.Verb.valueOf(method.toUpperCase()); - } - catch (IllegalArgumentException e) { - return HttpRequest.Verb.GET; - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommandFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommandFactory.java deleted file mode 100644 index 5f341e4e6..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommandFactory.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import java.util.Collections; -import java.util.Set; - -import com.netflix.client.http.HttpRequest; -import com.netflix.niws.client.http.RestClient; - -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommandFactory; - -/** - * @author Spencer Gibb - * @author Ryan Baxter - */ -public class RestClientRibbonCommandFactory extends AbstractRibbonCommandFactory { - - private SpringClientFactory clientFactory; - - private ZuulProperties zuulProperties; - - public RestClientRibbonCommandFactory(SpringClientFactory clientFactory) { - this(clientFactory, new ZuulProperties(), - Collections.emptySet()); - } - - public RestClientRibbonCommandFactory(SpringClientFactory clientFactory, - ZuulProperties zuulProperties, Set zuulFallbackProviders) { - super(zuulFallbackProviders); - this.clientFactory = clientFactory; - this.zuulProperties = zuulProperties; - } - - @Override - @SuppressWarnings("deprecation") - public RestClientRibbonCommand create(RibbonCommandContext context) { - String serviceId = context.getServiceId(); - FallbackProvider fallbackProvider = getFallbackProvider(serviceId); - RestClient restClient = this.clientFactory.getClient(serviceId, RestClient.class); - return new RestClientRibbonCommand(context.getServiceId(), restClient, context, - this.zuulProperties, fallbackProvider, - clientFactory.getClientConfig(serviceId)); - } - - public SpringClientFactory getClientFactory() { - return clientFactory; - } - - public void setZuulProperties(ZuulProperties zuulProperties) { - this.zuulProperties = zuulProperties; - } - - protected static HttpRequest.Verb getVerb(String method) { - return RestClientRibbonCommand.getVerb(method); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommand.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommand.java deleted file mode 100644 index 89919f4e3..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommand.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import com.netflix.hystrix.HystrixExecutable; - -import org.springframework.http.client.ClientHttpResponse; - -/** - * @author Spencer Gibb - */ -public interface RibbonCommand extends HystrixExecutable { - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommandFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommandFactory.java deleted file mode 100644 index 126b4921f..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommandFactory.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; - -/** - * @param a {@link RibbonCommand subtype} - * @author Spencer Gibb - * - */ -public interface RibbonCommandFactory { - - T create(RibbonCommandContext context); - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java deleted file mode 100644 index 8c440c775..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.client.ClientException; -import com.netflix.hystrix.exception.HystrixRuntimeException; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.exception.ZuulException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer; -import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.util.ZuulRuntimeException; -import org.springframework.http.HttpStatus; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.util.MultiValueMap; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.LOAD_BALANCER_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_ENTITY_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.RETRYABLE_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.RIBBON_ROUTING_FILTER_ORDER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY; - -/** - * Route {@link ZuulFilter} that uses Ribbon, Hystrix and pluggable http clients to send - * requests. ServiceIds are found in the {@link RequestContext} attribute - * {@link org.springframework.cloud.netflix.zuul.filters.support.FilterConstants#SERVICE_ID_KEY}. - * - * @author Spencer Gibb - * @author Dave Syer - * @author Ryan Baxter - */ -public class RibbonRoutingFilter extends ZuulFilter { - - private static final Log log = LogFactory.getLog(RibbonRoutingFilter.class); - - protected ProxyRequestHelper helper; - - protected RibbonCommandFactory ribbonCommandFactory; - - protected List requestCustomizers; - - private boolean useServlet31 = true; - - public RibbonRoutingFilter(ProxyRequestHelper helper, - RibbonCommandFactory ribbonCommandFactory, - List requestCustomizers) { - this.helper = helper; - this.ribbonCommandFactory = ribbonCommandFactory; - this.requestCustomizers = requestCustomizers; - // To support Servlet API 3.1 we need to check if getContentLengthLong exists - // Spring 5 minimum support is 3.0, so this stays - try { - HttpServletRequest.class.getMethod("getContentLengthLong"); - } - catch (NoSuchMethodException e) { - useServlet31 = false; - } - } - - @Deprecated - // TODO Remove in 2.1.x - public RibbonRoutingFilter(RibbonCommandFactory ribbonCommandFactory) { - this(new ProxyRequestHelper(), ribbonCommandFactory, null); - } - - /* for testing */ boolean isUseServlet31() { - return useServlet31; - } - - @Override - public String filterType() { - return ROUTE_TYPE; - } - - @Override - public int filterOrder() { - return RIBBON_ROUTING_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - RequestContext ctx = RequestContext.getCurrentContext(); - return (ctx.getRouteHost() == null && ctx.get(SERVICE_ID_KEY) != null - && ctx.sendZuulResponse()); - } - - @Override - public Object run() { - RequestContext context = RequestContext.getCurrentContext(); - this.helper.addIgnoredHeaders(); - try { - RibbonCommandContext commandContext = buildCommandContext(context); - ClientHttpResponse response = forward(commandContext); - setResponse(response); - return response; - } - catch (ZuulException ex) { - throw new ZuulRuntimeException(ex); - } - catch (Exception ex) { - throw new ZuulRuntimeException(ex); - } - } - - protected RibbonCommandContext buildCommandContext(RequestContext context) { - HttpServletRequest request = context.getRequest(); - - MultiValueMap headers = this.helper - .buildZuulRequestHeaders(request); - MultiValueMap params = this.helper - .buildZuulRequestQueryParams(request); - String verb = getVerb(request); - InputStream requestEntity = getRequestBody(request); - if (request.getContentLength() < 0 && !verb.equalsIgnoreCase("GET")) { - context.setChunkedRequestBody(); - } - - String serviceId = (String) context.get(SERVICE_ID_KEY); - Boolean retryable = (Boolean) context.get(RETRYABLE_KEY); - Object loadBalancerKey = context.get(LOAD_BALANCER_KEY); - - String uri = this.helper.buildZuulRequestURI(request); - - // remove double slashes - uri = uri.replace("//", "/"); - - long contentLength = useServlet31 ? request.getContentLengthLong() - : request.getContentLength(); - - return new RibbonCommandContext(serviceId, verb, uri, retryable, headers, params, - requestEntity, this.requestCustomizers, contentLength, loadBalancerKey); - } - - protected ClientHttpResponse forward(RibbonCommandContext context) throws Exception { - Map info = this.helper.debug(context.getMethod(), - context.getUri(), context.getHeaders(), context.getParams(), - context.getRequestEntity()); - - RibbonCommand command = this.ribbonCommandFactory.create(context); - try { - ClientHttpResponse response = command.execute(); - this.helper.appendDebug(info, response.getRawStatusCode(), - response.getHeaders()); - return response; - } - catch (HystrixRuntimeException ex) { - return handleException(info, ex); - } - - } - - protected ClientHttpResponse handleException(Map info, - HystrixRuntimeException ex) throws ZuulException { - int statusCode = HttpStatus.INTERNAL_SERVER_ERROR.value(); - Throwable cause = ex; - String message = ex.getFailureType().toString(); - - ClientException clientException = findClientException(ex); - if (clientException == null) { - clientException = findClientException(ex.getFallbackException()); - } - - if (clientException != null) { - if (clientException - .getErrorType() == ClientException.ErrorType.SERVER_THROTTLED) { - statusCode = HttpStatus.SERVICE_UNAVAILABLE.value(); - } - cause = clientException; - message = clientException.getErrorType().toString(); - } - info.put("status", String.valueOf(statusCode)); - throw new ZuulException(cause, "Forwarding error", statusCode, message); - } - - protected ClientException findClientException(Throwable t) { - if (t == null) { - return null; - } - if (t instanceof ClientException) { - return (ClientException) t; - } - return findClientException(t.getCause()); - } - - protected InputStream getRequestBody(HttpServletRequest request) { - InputStream requestEntity = null; - try { - requestEntity = (InputStream) RequestContext.getCurrentContext() - .get(REQUEST_ENTITY_KEY); - if (requestEntity == null) { - requestEntity = request.getInputStream(); - } - } - catch (IOException ex) { - log.error("Error during getRequestBody", ex); - } - return requestEntity; - } - - protected String getVerb(HttpServletRequest request) { - String method = request.getMethod(); - if (method == null) { - return "GET"; - } - return method; - } - - protected void setResponse(ClientHttpResponse resp) - throws ClientException, IOException { - RequestContext.getCurrentContext().set("zuulResponse", resp); - this.helper.setResponse(resp.getRawStatusCode(), resp.getBody(), - resp.getHeaders()); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SendForwardFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SendForwardFilter.java deleted file mode 100644 index 6b4b6e70a..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SendForwardFilter.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import javax.servlet.RequestDispatcher; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; - -import org.springframework.util.ReflectionUtils; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_TO_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_FORWARD_FILTER_ORDER; - -/** - * Route {@link ZuulFilter} that forwards requests using the {@link RequestDispatcher}. - * Forwarding location is located in the {@link RequestContext} attribute - * {@link org.springframework.cloud.netflix.zuul.filters.support.FilterConstants#FORWARD_TO_KEY}. - * Useful for forwarding to endpoints in the current application. - * - * @author Dave Syer - */ -public class SendForwardFilter extends ZuulFilter { - - protected static final String SEND_FORWARD_FILTER_RAN = "sendForwardFilter.ran"; - - @Override - public String filterType() { - return ROUTE_TYPE; - } - - @Override - public int filterOrder() { - return SEND_FORWARD_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - RequestContext ctx = RequestContext.getCurrentContext(); - return ctx.containsKey(FORWARD_TO_KEY) - && !ctx.getBoolean(SEND_FORWARD_FILTER_RAN, false); - } - - @Override - public Object run() { - try { - RequestContext ctx = RequestContext.getCurrentContext(); - String path = (String) ctx.get(FORWARD_TO_KEY); - RequestDispatcher dispatcher = ctx.getRequest().getRequestDispatcher(path); - if (dispatcher != null) { - ctx.set(SEND_FORWARD_FILTER_RAN, true); - if (!ctx.getResponse().isCommitted()) { - dispatcher.forward(ctx.getRequest(), ctx.getResponse()); - ctx.getResponse().flushBuffer(); - } - } - } - catch (Exception ex) { - ReflectionUtils.rethrowRuntimeException(ex); - } - return null; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java deleted file mode 100644 index f6809d791..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java +++ /dev/null @@ -1,490 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Timer; -import java.util.TimerTask; -import java.util.regex.Pattern; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.servlet.http.HttpServletRequest; - -import com.netflix.client.ClientException; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.exception.ZuulException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.Header; -import org.apache.http.HttpHost; -import org.apache.http.HttpRequest; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPatch; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpPut; -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.InputStreamEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.message.BasicHeader; -import org.apache.http.message.BasicHttpEntityEnclosingRequest; -import org.apache.http.message.BasicHttpRequest; - -import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.Host; -import org.springframework.cloud.netflix.zuul.util.ZuulRuntimeException; -import org.springframework.context.ApplicationListener; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.util.StringUtils; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_ENTITY_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SIMPLE_HOST_ROUTING_FILTER_ORDER; - -/** - * Route {@link ZuulFilter} that sends requests to predetermined URLs via apache - * {@link HttpClient}. URLs are found in {@link RequestContext#getRouteHost()}. - * - * @author Spencer Gibb - * @author Dave Syer - * @author Bilal Alp - * @author Gang Li - * @author Denys Ivano - */ -public class SimpleHostRoutingFilter extends ZuulFilter - implements ApplicationListener { - - private static final Log log = LogFactory.getLog(SimpleHostRoutingFilter.class); - - private static final Pattern MULTIPLE_SLASH_PATTERN = Pattern.compile("/{2,}"); - - private final Timer connectionManagerTimer = new Timer( - "SimpleHostRoutingFilter.connectionManagerTimer", true); - - private boolean sslHostnameValidationEnabled; - - private boolean forceOriginalQueryStringEncoding; - - private ProxyRequestHelper helper; - - private Host hostProperties; - - private ApacheHttpClientConnectionManagerFactory connectionManagerFactory; - - private ApacheHttpClientFactory httpClientFactory; - - private HttpClientConnectionManager connectionManager; - - private CloseableHttpClient httpClient; - - private boolean customHttpClient = false; - - private boolean useServlet31 = true; - - @Override - @SuppressWarnings("Deprecation") - public void onApplicationEvent(EnvironmentChangeEvent event) { - onPropertyChange(event); - } - - @Deprecated - public void onPropertyChange(EnvironmentChangeEvent event) { - if (!customHttpClient) { - boolean createNewClient = false; - - for (String key : event.getKeys()) { - if (key.startsWith("zuul.host.")) { - createNewClient = true; - break; - } - } - - if (createNewClient) { - try { - this.httpClient.close(); - } - catch (IOException ex) { - log.error("error closing client", ex); - } - // Re-create connection manager (may be shut down on HTTP client close) - try { - this.connectionManager.shutdown(); - } - catch (RuntimeException ex) { - log.error("error shutting down connection manager", ex); - } - this.connectionManager = newConnectionManager(); - this.httpClient = newClient(); - } - } - } - - public SimpleHostRoutingFilter(ProxyRequestHelper helper, ZuulProperties properties, - ApacheHttpClientConnectionManagerFactory connectionManagerFactory, - ApacheHttpClientFactory httpClientFactory) { - this.helper = helper; - this.hostProperties = properties.getHost(); - this.sslHostnameValidationEnabled = properties.isSslHostnameValidationEnabled(); - this.forceOriginalQueryStringEncoding = properties - .isForceOriginalQueryStringEncoding(); - this.connectionManagerFactory = connectionManagerFactory; - this.httpClientFactory = httpClientFactory; - checkServletVersion(); - } - - public SimpleHostRoutingFilter(ProxyRequestHelper helper, ZuulProperties properties, - CloseableHttpClient httpClient) { - this.helper = helper; - this.hostProperties = properties.getHost(); - this.sslHostnameValidationEnabled = properties.isSslHostnameValidationEnabled(); - this.forceOriginalQueryStringEncoding = properties - .isForceOriginalQueryStringEncoding(); - this.httpClient = httpClient; - this.customHttpClient = true; - checkServletVersion(); - } - - @PostConstruct - private void initialize() { - if (!customHttpClient) { - this.connectionManager = newConnectionManager(); - this.httpClient = newClient(); - this.connectionManagerTimer.schedule(new TimerTask() { - @Override - public void run() { - if (SimpleHostRoutingFilter.this.connectionManager == null) { - return; - } - SimpleHostRoutingFilter.this.connectionManager - .closeExpiredConnections(); - } - }, 30000, 5000); - } - } - - @PreDestroy - public void stop() { - this.connectionManagerTimer.cancel(); - } - - @Override - public String filterType() { - return ROUTE_TYPE; - } - - @Override - public int filterOrder() { - return SIMPLE_HOST_ROUTING_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - return RequestContext.getCurrentContext().getRouteHost() != null - && RequestContext.getCurrentContext().sendZuulResponse(); - } - - @Override - public Object run() { - RequestContext context = RequestContext.getCurrentContext(); - HttpServletRequest request = context.getRequest(); - MultiValueMap headers = this.helper - .buildZuulRequestHeaders(request); - MultiValueMap params = this.helper - .buildZuulRequestQueryParams(request); - String verb = getVerb(request); - InputStream requestEntity = getRequestBody(request); - if (getContentLength(request) < 0) { - context.setChunkedRequestBody(); - } - - String uri = this.helper.buildZuulRequestURI(request); - this.helper.addIgnoredHeaders(); - - try { - CloseableHttpResponse response = forward(this.httpClient, verb, uri, request, - headers, params, requestEntity); - setResponse(response); - } - catch (Exception ex) { - throw new ZuulRuntimeException(handleException(ex)); - } - return null; - } - - protected ZuulException handleException(Exception ex) { - int statusCode = HttpStatus.INTERNAL_SERVER_ERROR.value(); - Throwable cause = ex; - String message = ex.getMessage(); - - ClientException clientException = findClientException(ex); - - if (clientException != null) { - if (clientException - .getErrorType() == ClientException.ErrorType.SERVER_THROTTLED) { - statusCode = HttpStatus.SERVICE_UNAVAILABLE.value(); - } - cause = clientException; - message = clientException.getErrorType().toString(); - } - return new ZuulException(cause, "Forwarding error", statusCode, message); - } - - protected ClientException findClientException(Throwable t) { - if (t == null) { - return null; - } - if (t instanceof ClientException) { - return (ClientException) t; - } - return findClientException(t.getCause()); - } - - protected void checkServletVersion() { - // To support Servlet API 3.1 we need to check if getContentLengthLong exists - // Spring 5 minimum support is 3.0, so this stays - try { - HttpServletRequest.class.getMethod("getContentLengthLong"); - useServlet31 = true; - } - catch (NoSuchMethodException e) { - useServlet31 = false; - } - } - - protected void setUseServlet31(boolean useServlet31) { - this.useServlet31 = useServlet31; - } - - protected HttpClientConnectionManager getConnectionManager() { - return connectionManager; - } - - protected HttpClientConnectionManager newConnectionManager() { - return connectionManagerFactory.newConnectionManager( - !this.sslHostnameValidationEnabled, - this.hostProperties.getMaxTotalConnections(), - this.hostProperties.getMaxPerRouteConnections(), - this.hostProperties.getTimeToLive(), this.hostProperties.getTimeUnit(), - null); - } - - protected CloseableHttpClient newClient() { - final RequestConfig requestConfig = RequestConfig.custom() - .setConnectionRequestTimeout( - this.hostProperties.getConnectionRequestTimeoutMillis()) - .setSocketTimeout(this.hostProperties.getSocketTimeoutMillis()) - .setConnectTimeout(this.hostProperties.getConnectTimeoutMillis()) - .setCookieSpec(CookieSpecs.IGNORE_COOKIES).build(); - return httpClientFactory.createBuilder().setDefaultRequestConfig(requestConfig) - .setConnectionManager(this.connectionManager).disableRedirectHandling() - .build(); - } - - private CloseableHttpResponse forward(CloseableHttpClient httpclient, String verb, - String uri, HttpServletRequest request, MultiValueMap headers, - MultiValueMap params, InputStream requestEntity) - throws Exception { - Map info = this.helper.debug(verb, uri, headers, params, - requestEntity); - URL host = RequestContext.getCurrentContext().getRouteHost(); - HttpHost httpHost = getHttpHost(host); - uri = StringUtils.cleanPath( - MULTIPLE_SLASH_PATTERN.matcher(host.getPath() + uri).replaceAll("/")); - long contentLength = getContentLength(request); - - ContentType contentType = null; - - if (request.getContentType() != null) { - contentType = ContentType.parse(request.getContentType()); - } - - InputStreamEntity entity = new InputStreamEntity(requestEntity, contentLength, - contentType); - - HttpRequest httpRequest = buildHttpRequest(verb, uri, entity, headers, params, - request); - try { - log.debug(httpHost.getHostName() + " " + httpHost.getPort() + " " - + httpHost.getSchemeName()); - CloseableHttpResponse zuulResponse = forwardRequest(httpclient, httpHost, - httpRequest); - this.helper.appendDebug(info, zuulResponse.getStatusLine().getStatusCode(), - revertHeaders(zuulResponse.getAllHeaders())); - return zuulResponse; - } - finally { - // When HttpClient instance is no longer needed, - // shut down the connection manager to ensure - // immediate deallocation of all system resources - // httpclient.getConnectionManager().shutdown(); - } - } - - protected HttpRequest buildHttpRequest(String verb, String uri, - InputStreamEntity entity, MultiValueMap headers, - MultiValueMap params, HttpServletRequest request) { - HttpRequest httpRequest; - String uriWithQueryString = uri + (this.forceOriginalQueryStringEncoding - ? getEncodedQueryString(request) : this.helper.getQueryString(params)); - - switch (verb.toUpperCase()) { - case "POST": - HttpPost httpPost = new HttpPost(uriWithQueryString); - httpRequest = httpPost; - httpPost.setEntity(entity); - break; - case "PUT": - HttpPut httpPut = new HttpPut(uriWithQueryString); - httpRequest = httpPut; - httpPut.setEntity(entity); - break; - case "PATCH": - HttpPatch httpPatch = new HttpPatch(uriWithQueryString); - httpRequest = httpPatch; - httpPatch.setEntity(entity); - break; - case "DELETE": - BasicHttpEntityEnclosingRequest entityRequest = new BasicHttpEntityEnclosingRequest( - verb, uriWithQueryString); - httpRequest = entityRequest; - entityRequest.setEntity(entity); - break; - default: - httpRequest = new BasicHttpRequest(verb, uriWithQueryString); - log.debug(uriWithQueryString); - } - - httpRequest.setHeaders(convertHeaders(headers)); - return httpRequest; - } - - private String getEncodedQueryString(HttpServletRequest request) { - String query = request.getQueryString(); - return (query != null) ? "?" + query : ""; - } - - private MultiValueMap revertHeaders(Header[] headers) { - MultiValueMap map = new LinkedMultiValueMap<>(); - for (Header header : headers) { - String name = header.getName(); - if (!map.containsKey(name)) { - map.put(name, new ArrayList()); - } - map.get(name).add(header.getValue()); - } - return map; - } - - private Header[] convertHeaders(MultiValueMap headers) { - List

list = new ArrayList<>(); - for (String name : headers.keySet()) { - for (String value : headers.get(name)) { - list.add(new BasicHeader(name, value)); - } - } - return list.toArray(new BasicHeader[0]); - } - - private CloseableHttpResponse forwardRequest(CloseableHttpClient httpclient, - HttpHost httpHost, HttpRequest httpRequest) throws IOException { - return httpclient.execute(httpHost, httpRequest); - } - - private HttpHost getHttpHost(URL host) { - HttpHost httpHost = new HttpHost(host.getHost(), host.getPort(), - host.getProtocol()); - return httpHost; - } - - protected InputStream getRequestBody(HttpServletRequest request) { - InputStream requestEntity = null; - try { - requestEntity = (InputStream) RequestContext.getCurrentContext() - .get(REQUEST_ENTITY_KEY); - if (requestEntity == null) { - requestEntity = request.getInputStream(); - } - } - catch (IOException ex) { - log.error("error during getRequestBody", ex); - } - return requestEntity; - } - - private String getVerb(HttpServletRequest request) { - String sMethod = request.getMethod(); - return sMethod.toUpperCase(); - } - - private void setResponse(HttpResponse response) throws IOException { - RequestContext.getCurrentContext().set("zuulResponse", response); - this.helper.setResponse(response.getStatusLine().getStatusCode(), - response.getEntity() == null ? null : response.getEntity().getContent(), - revertHeaders(response.getAllHeaders())); - } - - /** - * Add header names to exclude from proxied response in the current request. - * @param names names of headers to exclude - */ - protected void addIgnoredHeaders(String... names) { - this.helper.addIgnoredHeaders(names); - } - - /** - * Determines whether the filter enables the validation for ssl hostnames. - * @return true if enabled - */ - boolean isSslHostnameValidationEnabled() { - return this.sslHostnameValidationEnabled; - } - - // Get the header value as a long in order to more correctly proxy very large requests - protected long getContentLength(HttpServletRequest request) { - if (useServlet31) { - return request.getContentLengthLong(); - } - String contentLengthHeader = request.getHeader(HttpHeaders.CONTENT_LENGTH); - if (contentLengthHeader != null) { - try { - return Long.parseLong(contentLengthHeader); - } - catch (NumberFormatException ignored) { - } - } - return request.getContentLength(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommand.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommand.java deleted file mode 100644 index efd45e5eb..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommand.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.apache; - -import com.netflix.client.config.IClientConfig; - -import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpRequest; -import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpResponse; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommand; - -/** - * @author Spencer Gibb - * @author Ryan Baxter - */ -public class HttpClientRibbonCommand extends - AbstractRibbonCommand { - - public HttpClientRibbonCommand(final String commandKey, - final RibbonLoadBalancingHttpClient client, - final RibbonCommandContext context, final ZuulProperties zuulProperties) { - super(commandKey, client, context, zuulProperties); - } - - public HttpClientRibbonCommand(final String commandKey, - final RibbonLoadBalancingHttpClient client, - final RibbonCommandContext context, final ZuulProperties zuulProperties, - final FallbackProvider zuulFallbackProvider) { - super(commandKey, client, context, zuulProperties, zuulFallbackProvider); - } - - public HttpClientRibbonCommand(final String commandKey, - final RibbonLoadBalancingHttpClient client, - final RibbonCommandContext context, final ZuulProperties zuulProperties, - final FallbackProvider zuulFallbackProvider, final IClientConfig config) { - super(commandKey, client, context, zuulProperties, zuulFallbackProvider, config); - } - - @Override - protected RibbonApacheHttpRequest createRequest() throws Exception { - return new RibbonApacheHttpRequest(this.context); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactory.java deleted file mode 100644 index 01881f47d..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactory.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.apache; - -import java.util.Collections; -import java.util.Set; - -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommandFactory; - -/** - * @author Christian Lohmann - * @author Ryan Baxter - */ -public class HttpClientRibbonCommandFactory extends AbstractRibbonCommandFactory { - - private final SpringClientFactory clientFactory; - - private final ZuulProperties zuulProperties; - - public HttpClientRibbonCommandFactory(SpringClientFactory clientFactory, - ZuulProperties zuulProperties) { - this(clientFactory, zuulProperties, Collections.emptySet()); - } - - public HttpClientRibbonCommandFactory(SpringClientFactory clientFactory, - ZuulProperties zuulProperties, Set fallbackProviders) { - super(fallbackProviders); - this.clientFactory = clientFactory; - this.zuulProperties = zuulProperties; - } - - @Override - public HttpClientRibbonCommand create(final RibbonCommandContext context) { - FallbackProvider zuulFallbackProvider = getFallbackProvider( - context.getServiceId()); - final String serviceId = context.getServiceId(); - final RibbonLoadBalancingHttpClient client = this.clientFactory - .getClient(serviceId, RibbonLoadBalancingHttpClient.class); - client.setLoadBalancer(this.clientFactory.getLoadBalancer(serviceId)); - - return new HttpClientRibbonCommand(serviceId, client, context, zuulProperties, - zuulFallbackProvider, clientFactory.getClientConfig(serviceId)); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommand.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommand.java deleted file mode 100644 index ff85abe8e..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommand.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.okhttp; - -import com.netflix.client.config.IClientConfig; - -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonRequest; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonResponse; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommand; - -/** - * @author Spencer Gibb - * @author Ryan Baxter - */ -public class OkHttpRibbonCommand extends - AbstractRibbonCommand { - - public OkHttpRibbonCommand(final String commandKey, - final OkHttpLoadBalancingClient client, final RibbonCommandContext context, - final ZuulProperties zuulProperties) { - super(commandKey, client, context, zuulProperties); - } - - public OkHttpRibbonCommand(final String commandKey, - final OkHttpLoadBalancingClient client, final RibbonCommandContext context, - final ZuulProperties zuulProperties, - final FallbackProvider zuulFallbackProvider) { - super(commandKey, client, context, zuulProperties, zuulFallbackProvider); - } - - public OkHttpRibbonCommand(final String commandKey, - final OkHttpLoadBalancingClient client, final RibbonCommandContext context, - final ZuulProperties zuulProperties, - final FallbackProvider zuulFallbackProvider, final IClientConfig config) { - super(commandKey, client, context, zuulProperties, zuulFallbackProvider, config); - } - - @Override - protected OkHttpRibbonRequest createRequest() throws Exception { - return new OkHttpRibbonRequest(this.context); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactory.java deleted file mode 100644 index c2e3d5018..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactory.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.okhttp; - -import java.util.Collections; -import java.util.Set; - -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommandFactory; - -/** - * @author Spencer Gibb - * @author Ryan Baxter - */ -public class OkHttpRibbonCommandFactory extends AbstractRibbonCommandFactory { - - private SpringClientFactory clientFactory; - - private ZuulProperties zuulProperties; - - public OkHttpRibbonCommandFactory(SpringClientFactory clientFactory, - ZuulProperties zuulProperties) { - this(clientFactory, zuulProperties, Collections.emptySet()); - } - - public OkHttpRibbonCommandFactory(SpringClientFactory clientFactory, - ZuulProperties zuulProperties, Set zuulFallbackProviders) { - super(zuulFallbackProviders); - this.clientFactory = clientFactory; - this.zuulProperties = zuulProperties; - } - - @Override - public OkHttpRibbonCommand create(final RibbonCommandContext context) { - final String serviceId = context.getServiceId(); - FallbackProvider fallbackProvider = getFallbackProvider(serviceId); - final OkHttpLoadBalancingClient client = this.clientFactory.getClient(serviceId, - OkHttpLoadBalancingClient.class); - client.setLoadBalancer(this.clientFactory.getLoadBalancer(serviceId)); - - return new OkHttpRibbonCommand(serviceId, client, context, zuulProperties, - fallbackProvider, clientFactory.getClientConfig(serviceId)); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommand.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommand.java deleted file mode 100644 index 3ad23aff9..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommand.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.support; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.ClientRequest; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.client.config.IClientConfigKey; -import com.netflix.client.http.HttpResponse; -import com.netflix.config.DynamicIntProperty; -import com.netflix.config.DynamicPropertyFactory; -import com.netflix.hystrix.HystrixCommand; -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy; -import com.netflix.hystrix.HystrixThreadPoolKey; -import com.netflix.zuul.constants.ZuulConstants; -import com.netflix.zuul.context.RequestContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonHttpResponse; -import org.springframework.cloud.netflix.ribbon.support.AbstractLoadBalancingClient; -import org.springframework.cloud.netflix.ribbon.support.ContextAwareRequest; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand; -import org.springframework.http.client.ClientHttpResponse; - -/** - * @param {@link ClientRequest} subtype - * @param {@link AbstractLoadBalancingClient} subtype - * @param {@link ClientRequest} subtype - * @param {@link HttpResponse} subtype - * @author Spencer Gibb - */ -public abstract class AbstractRibbonCommand, RQ extends ClientRequest, RS extends HttpResponse> - extends HystrixCommand implements RibbonCommand { - - private static final Log LOGGER = LogFactory.getLog(AbstractRibbonCommand.class); - - protected final LBC client; - - protected RibbonCommandContext context; - - protected FallbackProvider zuulFallbackProvider; - - protected IClientConfig config; - - public AbstractRibbonCommand(LBC client, RibbonCommandContext context, - ZuulProperties zuulProperties) { - this("default", client, context, zuulProperties); - } - - public AbstractRibbonCommand(String commandKey, LBC client, - RibbonCommandContext context, ZuulProperties zuulProperties) { - this(commandKey, client, context, zuulProperties, null); - } - - public AbstractRibbonCommand(String commandKey, LBC client, - RibbonCommandContext context, ZuulProperties zuulProperties, - FallbackProvider fallbackProvider) { - this(commandKey, client, context, zuulProperties, fallbackProvider, null); - } - - public AbstractRibbonCommand(String commandKey, LBC client, - RibbonCommandContext context, ZuulProperties zuulProperties, - FallbackProvider fallbackProvider, IClientConfig config) { - this(getSetter(commandKey, zuulProperties, config), client, context, - fallbackProvider, config); - } - - protected AbstractRibbonCommand(Setter setter, LBC client, - RibbonCommandContext context, FallbackProvider fallbackProvider, - IClientConfig config) { - super(setter); - this.client = client; - this.context = context; - this.zuulFallbackProvider = fallbackProvider; - this.config = config; - } - - protected static HystrixCommandProperties.Setter createSetter(IClientConfig config, - String commandKey, ZuulProperties zuulProperties) { - int hystrixTimeout = getHystrixTimeout(config, commandKey); - return HystrixCommandProperties.Setter() - .withExecutionIsolationStrategy( - zuulProperties.getRibbonIsolationStrategy()) - .withExecutionTimeoutInMilliseconds(hystrixTimeout); - } - - protected static int getHystrixTimeout(IClientConfig config, String commandKey) { - int ribbonTimeout = getRibbonTimeout(config, commandKey); - DynamicPropertyFactory dynamicPropertyFactory = DynamicPropertyFactory - .getInstance(); - int defaultHystrixTimeout = dynamicPropertyFactory.getIntProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 0).get(); - int commandHystrixTimeout = dynamicPropertyFactory - .getIntProperty("hystrix.command." + commandKey - + ".execution.isolation.thread.timeoutInMilliseconds", 0) - .get(); - int hystrixTimeout; - if (commandHystrixTimeout > 0) { - hystrixTimeout = commandHystrixTimeout; - } - else if (defaultHystrixTimeout > 0) { - hystrixTimeout = defaultHystrixTimeout; - } - else { - hystrixTimeout = ribbonTimeout; - } - if (hystrixTimeout < ribbonTimeout) { - LOGGER.warn("The Hystrix timeout of " + hystrixTimeout + "ms for the command " - + commandKey - + " is set lower than the combination of the Ribbon read and connect timeout, " - + ribbonTimeout + "ms."); - } - return hystrixTimeout; - } - - protected static int getRibbonTimeout(IClientConfig config, String commandKey) { - int ribbonTimeout; - if (config == null) { - ribbonTimeout = RibbonClientConfiguration.DEFAULT_READ_TIMEOUT - + RibbonClientConfiguration.DEFAULT_CONNECT_TIMEOUT; - } - else { - int ribbonReadTimeout = getTimeout(config, commandKey, "ReadTimeout", - IClientConfigKey.Keys.ReadTimeout, - RibbonClientConfiguration.DEFAULT_READ_TIMEOUT); - int ribbonConnectTimeout = getTimeout(config, commandKey, "ConnectTimeout", - IClientConfigKey.Keys.ConnectTimeout, - RibbonClientConfiguration.DEFAULT_CONNECT_TIMEOUT); - int maxAutoRetries = getTimeout(config, commandKey, "MaxAutoRetries", - IClientConfigKey.Keys.MaxAutoRetries, - DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES); - int maxAutoRetriesNextServer = getTimeout(config, commandKey, - "MaxAutoRetriesNextServer", - IClientConfigKey.Keys.MaxAutoRetriesNextServer, - DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER); - ribbonTimeout = (ribbonReadTimeout + ribbonConnectTimeout) - * (maxAutoRetries + 1) * (maxAutoRetriesNextServer + 1); - } - return ribbonTimeout; - } - - private static int getTimeout(IClientConfig config, String commandKey, - String property, IClientConfigKey configKey, int defaultValue) { - DynamicPropertyFactory dynamicPropertyFactory = DynamicPropertyFactory - .getInstance(); - return dynamicPropertyFactory - .getIntProperty(commandKey + "." + config.getNameSpace() + "." + property, - config.get(configKey, defaultValue)) - .get(); - } - - @Deprecated - // TODO remove in 2.0.x - protected static Setter getSetter(final String commandKey, - ZuulProperties zuulProperties) { - return getSetter(commandKey, zuulProperties, null); - } - - protected static Setter getSetter(final String commandKey, - ZuulProperties zuulProperties, IClientConfig config) { - - // @formatter:off - Setter commandSetter = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("RibbonCommand")) - .andCommandKey(HystrixCommandKey.Factory.asKey(commandKey)); - final HystrixCommandProperties.Setter setter = createSetter(config, commandKey, zuulProperties); - if (zuulProperties.getRibbonIsolationStrategy() == ExecutionIsolationStrategy.SEMAPHORE) { - final String name = ZuulConstants.ZUUL_EUREKA + commandKey + ".semaphore.maxSemaphores"; - // we want to default to semaphore-isolation since this wraps - // 2 others commands that are already thread isolated - final DynamicIntProperty value = DynamicPropertyFactory.getInstance() - .getIntProperty(name, zuulProperties.getSemaphore().getMaxSemaphores()); - setter.withExecutionIsolationSemaphoreMaxConcurrentRequests(value.get()); - } - else if (zuulProperties.getThreadPool().isUseSeparateThreadPools()) { - final String threadPoolKey = zuulProperties.getThreadPool().getThreadPoolKeyPrefix() + commandKey; - commandSetter.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(threadPoolKey)); - } - return commandSetter.andCommandPropertiesDefaults(setter); - // @formatter:on - } - - @Override - protected ClientHttpResponse run() throws Exception { - final RequestContext context = RequestContext.getCurrentContext(); - - RQ request = createRequest(); - RS response; - - boolean retryableClient = this.client instanceof AbstractLoadBalancingClient - && ((AbstractLoadBalancingClient) this.client) - .isClientRetryable((ContextAwareRequest) request); - - if (retryableClient) { - response = this.client.execute(request, config); - } - else { - response = this.client.executeWithLoadBalancer(request, config); - } - context.set("ribbonResponse", response); - - // Explicitly close the HttpResponse if the Hystrix command timed out to - // release the underlying HTTP connection held by the response. - // - if (this.isResponseTimedOut()) { - if (response != null) { - response.close(); - } - } - - return new RibbonHttpResponse(response); - } - - @Override - protected ClientHttpResponse getFallback() { - if (zuulFallbackProvider != null) { - return getFallbackResponse(); - } - return super.getFallback(); - } - - protected ClientHttpResponse getFallbackResponse() { - Throwable cause = getFailedExecutionException(); - cause = cause == null ? getExecutionException() : cause; - return zuulFallbackProvider.fallbackResponse(context.getServiceId(), cause); - } - - public LBC getClient() { - return client; - } - - public RibbonCommandContext getContext() { - return context; - } - - protected abstract RQ createRequest() throws Exception; - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommandFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommandFactory.java deleted file mode 100644 index 3a9cfa56d..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommandFactory.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.support; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; - -/** - * @author Ryan Baxter - */ -public abstract class AbstractRibbonCommandFactory implements RibbonCommandFactory { - - private Map fallbackProviderCache; - - private FallbackProvider defaultFallbackProvider = null; - - public AbstractRibbonCommandFactory(Set fallbackProviders) { - this.fallbackProviderCache = new HashMap<>(); - for (FallbackProvider provider : fallbackProviders) { - String route = provider.getRoute(); - if ("*".equals(route) || route == null) { - defaultFallbackProvider = provider; - } - else { - fallbackProviderCache.put(route, provider); - } - } - } - - protected FallbackProvider getFallbackProvider(String route) { - FallbackProvider provider = fallbackProviderCache.get(route); - if (provider == null) { - provider = defaultFallbackProvider; - } - return provider; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/support/FilterConstants.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/support/FilterConstants.java deleted file mode 100644 index 9d318c359..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/support/FilterConstants.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.support; - -import com.netflix.zuul.ZuulFilter; - -import org.springframework.cloud.netflix.zuul.filters.pre.DebugFilter; -import org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter; -import org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter; - -/** - * @author Spencer Gibb - */ -public final class FilterConstants { - - // KEY constants ----------------------------------- - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.pre.ServletDetectionFilter}. - */ - public static final String IS_DISPATCHER_SERVLET_REQUEST_KEY = "isDispatcherServletRequest"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter}. - */ - public static final String FORWARD_TO_KEY = "forward.to"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in TODO: determine - * use. - */ - public static final String PROXY_KEY = "proxy"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter}. - */ - public static final String REQUEST_ENTITY_KEY = "requestEntity"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in to override the - * path of the request. - */ - public static final String REQUEST_URI_KEY = "requestURI"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter}. - */ - public static final String RETRYABLE_KEY = "retryable"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter}. - */ - public static final String ROUTING_DEBUG_KEY = "routingDebug"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter}. - */ - public static final String SERVICE_ID_KEY = "serviceId"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter}. - */ - public static final String LOAD_BALANCER_KEY = "loadBalancerKey"; - - // ORDER constants ----------------------------------- - - /** - * Filter Order for {@link DebugFilter#filterOrder()}. - */ - public static final int DEBUG_FILTER_ORDER = 1; - - /** - * Filter Order for - * {@link org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilter#filterOrder()}. - */ - public static final int FORM_BODY_WRAPPER_FILTER_ORDER = -1; - - /** - * Filter Order for - * {@link org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter}. - */ - public static final int PRE_DECORATION_FILTER_ORDER = 5; - - /** - * Filter Order for - * {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter#filterOrder()}. - */ - public static final int RIBBON_ROUTING_FILTER_ORDER = 10; - - /** - * Filter Order for - * {@link org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter#filterOrder()}. - */ - public static final int SEND_ERROR_FILTER_ORDER = 0; - - /** - * Filter Order for {@link SendForwardFilter#filterOrder()}. - */ - public static final int SEND_FORWARD_FILTER_ORDER = 500; - - /** - * Filter Order for - * {@link org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter#filterOrder()}. - */ - public static final int SEND_RESPONSE_FILTER_ORDER = 1000; - - /** - * Filter Order for - * {@link org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter#filterOrder()}. - */ - public static final int SIMPLE_HOST_ROUTING_FILTER_ORDER = 100; - - /** - * filter order for {@link Servlet30WrapperFilter#filterOrder()}. - */ - public static final int SERVLET_30_WRAPPER_FILTER_ORDER = -2; - - /** - * filter order for - * {@link org.springframework.cloud.netflix.zuul.filters.pre.ServletDetectionFilter#filterOrder()}. - */ - public static final int SERVLET_DETECTION_FILTER_ORDER = -3; - - // Zuul Filter TYPE constants ----------------------------------- - - /** - * {@link ZuulFilter#filterType()} error type. - */ - public static final String ERROR_TYPE = "error"; - - /** - * {@link ZuulFilter#filterType()} post type. - */ - public static final String POST_TYPE = "post"; - - /** - * {@link ZuulFilter#filterType()} pre type. - */ - public static final String PRE_TYPE = "pre"; - - /** - * {@link ZuulFilter#filterType()} route type. - */ - public static final String ROUTE_TYPE = "route"; - - // OTHER constants ----------------------------------- - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter}. - */ - public static final String FORWARD_LOCATION_PREFIX = "forward:"; - - /** - * Dfault http port. - */ - public static final int HTTP_PORT = 80; - - /** - * Default https port. - */ - public static final int HTTPS_PORT = 443; - - /** - * Http url scheme. - */ - public static final String HTTP_SCHEME = "http"; - - /** - * Https url scheme. - */ - public static final String HTTPS_SCHEME = "https"; - - // HEADER constants ----------------------------------- - - /** - * X-* Header for the matching url. Used when routes use a url rather than serviceId. - */ - public static final String SERVICE_HEADER = "X-Zuul-Service"; - - /** - * X-* Header for the matching serviceId. - */ - public static final String SERVICE_ID_HEADER = "X-Zuul-ServiceId"; - - /** - * X-Forwarded-For Header. - */ - public static final String X_FORWARDED_FOR_HEADER = "X-Forwarded-For"; - - /** - * X-Forwarded-Host Header. - */ - public static final String X_FORWARDED_HOST_HEADER = "X-Forwarded-Host"; - - /** - * X-Forwarded-Prefix Header. - */ - public static final String X_FORWARDED_PREFIX_HEADER = "X-Forwarded-Prefix"; - - /** - * X-Forwarded-Port Header. - */ - public static final String X_FORWARDED_PORT_HEADER = "X-Forwarded-Port"; - - /** - * X-Forwarded-Proto Header. - */ - public static final String X_FORWARDED_PROTO_HEADER = "X-Forwarded-Proto"; - - /** - * X-Zuul-Debug Header. - */ - public static final String X_ZUUL_DEBUG_HEADER = "X-Zuul-Debug-Header"; - - private FilterConstants() { - throw new AssertionError("Must not instantiate constant utility class"); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/DefaultCounterFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/DefaultCounterFactory.java deleted file mode 100644 index 5e263084d..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/DefaultCounterFactory.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.metrics; - -import com.netflix.zuul.monitoring.CounterFactory; -import io.micrometer.core.instrument.MeterRegistry; - -/** - * A counter based monitoring factory that uses {@link MeterRegistry} to increment - * counters. - * - * @author Anastasiia Smirnova - */ -public class DefaultCounterFactory extends CounterFactory { - - private final MeterRegistry meterRegistry; - - public DefaultCounterFactory(MeterRegistry meterRegistry) { - this.meterRegistry = meterRegistry; - } - - @Override - public void increment(String name) { - this.meterRegistry.counter(name).increment(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/EmptyCounterFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/EmptyCounterFactory.java deleted file mode 100644 index 6d9aa7854..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/EmptyCounterFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2013-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.metrics; - -import com.netflix.zuul.monitoring.CounterFactory; - -/** - * A counter based monitoring factory that does nothing. - * - * @author Anastasiia Smirnova - */ -public class EmptyCounterFactory extends CounterFactory { - - @Override - public void increment(String name) { - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/EmptyTracerFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/EmptyTracerFactory.java deleted file mode 100644 index b9138818c..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/EmptyTracerFactory.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.metrics; - -import com.netflix.zuul.monitoring.Tracer; -import com.netflix.zuul.monitoring.TracerFactory; - -/** - * A time based monitoring factory that does nothing. - * - * @author Anastasiia Smirnova - */ -public class EmptyTracerFactory extends TracerFactory { - - private final EmptyTracer emptyTracer = new EmptyTracer(); - - @Override - public Tracer startMicroTracer(String name) { - return emptyTracer; - } - - private static final class EmptyTracer implements Tracer { - - @Override - public void setName(String name) { - } - - @Override - public void stopAndLog() { - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractor.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractor.java deleted file mode 100644 index 510aad4a6..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractor.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.util; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; - -import javax.servlet.http.HttpServletRequest; - -import org.springframework.core.io.InputStreamResource; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.multipart.MultipartHttpServletRequest; -import org.springframework.web.util.UriComponentsBuilder; - -import static java.util.Arrays.stream; -import static java.util.Collections.emptyMap; -import static org.springframework.util.StringUtils.isEmpty; -import static org.springframework.util.StringUtils.tokenizeToStringArray; -import static org.springframework.util.StringUtils.uriDecode; - -/** - * Utility class providing methods for extracting {@link HttpServletRequest} content as a - * {@link MultiValueMap}. - * - * @author Eloi Poch - * @author Spencer Gibb - * @author Dmitrii Priporov - * @author Ryan Baxter - */ -public final class RequestContentDataExtractor { - - private RequestContentDataExtractor() { - throw new AssertionError("Must not instantiate utility class."); - } - - public static MultiValueMap extract(HttpServletRequest request) - throws IOException { - return (request instanceof MultipartHttpServletRequest) - ? extractFromMultipartRequest((MultipartHttpServletRequest) request) - : extractFromRequest(request); - } - - private static MultiValueMap extractFromRequest( - HttpServletRequest request) throws IOException { - MultiValueMap builder = new LinkedMultiValueMap<>(); - Set queryParams = findQueryParams(request); - - for (Entry entry : request.getParameterMap().entrySet()) { - String key = entry.getKey(); - - if (!queryParams.contains(key) && entry.getValue() != null) { - for (String value : entry.getValue()) { - builder.add(key, value); - } - } - } - - return builder; - } - - private static MultiValueMap extractFromMultipartRequest( - MultipartHttpServletRequest request) throws IOException { - MultiValueMap builder = new LinkedMultiValueMap<>(); - Map> queryParamsGroupedByName = findQueryParamsGroupedByName( - request); - Set queryParams = findQueryParams(request); - - for (Entry entry : request.getParameterMap().entrySet()) { - String key = entry.getKey(); - List listOfAllParams = stream(request.getParameterMap().get(key)) - .collect(Collectors.toList()); - List listOfOnlyQueryParams = queryParamsGroupedByName.get(key); - - if (listOfOnlyQueryParams != null) { - listOfOnlyQueryParams = listOfOnlyQueryParams.stream() - .filter(Objects::nonNull) - .map(param -> uriDecode(param, Charset.defaultCharset())) - .collect(Collectors.toList()); - if (!listOfOnlyQueryParams.containsAll(listOfAllParams)) { - listOfAllParams.removeAll(listOfOnlyQueryParams); - for (String value : listOfAllParams) { - builder.add(key, - new HttpEntity<>(value, newHttpHeaders(request, key))); - } - } - } - - if (!queryParams.contains(key)) { - for (String value : entry.getValue()) { - builder.add(key, - new HttpEntity<>(value, newHttpHeaders(request, key))); - } - } - } - - for (Entry> parts : request.getMultiFileMap() - .entrySet()) { - for (MultipartFile file : parts.getValue()) { - HttpHeaders headers = new HttpHeaders(); - headers.setContentDispositionFormData(file.getName(), - file.getOriginalFilename()); - if (file.getContentType() != null) { - headers.setContentType(MediaType.valueOf(file.getContentType())); - } - - HttpEntity entity = new HttpEntity<>( - new InputStreamResource(file.getInputStream()), headers); - builder.add(parts.getKey(), entity); - } - } - - return builder; - } - - private static HttpHeaders newHttpHeaders(MultipartHttpServletRequest request, - String key) { - HttpHeaders headers = new HttpHeaders(); - String type = request.getMultipartContentType(key); - - if (type != null) { - headers.setContentType(MediaType.valueOf(type)); - } - return headers; - } - - private static Set findQueryParams(HttpServletRequest request) { - Set result = new HashSet<>(); - String query = request.getQueryString(); - - if (query != null) { - for (String value : tokenizeToStringArray(query, "&")) { - if (value.contains("=")) { - value = value.substring(0, value.indexOf("=")); - } - result.add(value); - } - } - - return result; - } - - static Map> findQueryParamsGroupedByName( - HttpServletRequest request) { - String query = request.getQueryString(); - if (isEmpty(query)) { - return emptyMap(); - } - return UriComponentsBuilder.fromUriString("?" + query).build().getQueryParams(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestUtils.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestUtils.java deleted file mode 100644 index bdcbb881d..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestUtils.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.util; - -import com.netflix.zuul.context.RequestContext; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.IS_DISPATCHER_SERVLET_REQUEST_KEY; - -/** - * Utility class providing methods to verify if the current request is a dispatcher - * servlet or a Zuul servlet request. - * - * @author Adrian Ivan - * @author Spencer Gibb - */ -public final class RequestUtils { - - private RequestUtils() { - throw new AssertionError("Must not instantiate utility class."); - } - - /** - * @deprecated use - * {@link org.springframework.cloud.netflix.zuul.filters.support.FilterConstants#IS_DISPATCHER_SERVLET_REQUEST_KEY} - */ - @Deprecated - public static final String IS_DISPATCHERSERVLETREQUEST = IS_DISPATCHER_SERVLET_REQUEST_KEY; - - public static boolean isDispatcherServletRequest() { - return RequestContext.getCurrentContext() - .getBoolean(IS_DISPATCHER_SERVLET_REQUEST_KEY); - } - - public static boolean isZuulServletRequest() { - // extra check for dispatcher since ZuulServlet can run from ZuulController - return !isDispatcherServletRequest() - && RequestContext.getCurrentContext().getZuulEngineRan(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/ZuulRuntimeException.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/ZuulRuntimeException.java deleted file mode 100644 index c4d5593c9..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/ZuulRuntimeException.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.util; - -import com.netflix.zuul.exception.ZuulException; - -/** - * @author Spencer Gibb - */ -public class ZuulRuntimeException extends RuntimeException { - - public ZuulRuntimeException(ZuulException cause) { - super(cause); - } - - @Deprecated - public ZuulRuntimeException(Exception ex) { - super(ex); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/web/ZuulController.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/web/ZuulController.java deleted file mode 100644 index 84ed5919b..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/web/ZuulController.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.web; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.http.ZuulServlet; - -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.ServletWrappingController; - -/** - * @author Spencer Gibb - */ -public class ZuulController extends ServletWrappingController { - - public ZuulController() { - setServletClass(ZuulServlet.class); - setServletName("zuul"); - setSupportedMethods((String[]) null); // Allow all - } - - @Override - public ModelAndView handleRequest(HttpServletRequest request, - HttpServletResponse response) throws Exception { - try { - // We don't care about the other features of the base class, just want to - // handle the request - return super.handleRequestInternal(request, response); - } - finally { - // @see com.netflix.zuul.context.ContextLifecycleFilter.doFilter - RequestContext.getCurrentContext().unset(); - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/web/ZuulHandlerMapping.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/web/ZuulHandlerMapping.java deleted file mode 100644 index 2ff1d0c19..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/web/ZuulHandlerMapping.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.web; - -import java.util.Collection; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.context.RequestContext; - -import org.springframework.boot.web.servlet.error.ErrorController; -import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.util.AntPathMatcher; -import org.springframework.util.PathMatcher; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.servlet.HandlerExecutionChain; -import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping; - -/** - * MVC HandlerMapping that maps incoming request paths to remote services. - * - * @author Spencer Gibb - * @author Dave Syer - * @author João Salavessa - * @author Biju Kunjummen - */ -public class ZuulHandlerMapping extends AbstractUrlHandlerMapping { - - private final RouteLocator routeLocator; - - private final ZuulController zuul; - - private ErrorController errorController; - - private PathMatcher pathMatcher = new AntPathMatcher(); - - private volatile boolean dirty = true; - - public ZuulHandlerMapping(RouteLocator routeLocator, ZuulController zuul) { - this.routeLocator = routeLocator; - this.zuul = zuul; - setOrder(-200); - } - - @Override - protected HandlerExecutionChain getCorsHandlerExecutionChain( - HttpServletRequest request, HandlerExecutionChain chain, - CorsConfiguration config) { - if (config == null) { - // Allow CORS requests to go to the backend - return chain; - } - return super.getCorsHandlerExecutionChain(request, chain, config); - } - - public void setErrorController(ErrorController errorController) { - this.errorController = errorController; - } - - public void setDirty(boolean dirty) { - this.dirty = dirty; - if (this.routeLocator instanceof RefreshableRouteLocator) { - ((RefreshableRouteLocator) this.routeLocator).refresh(); - } - } - - @Override - protected Object lookupHandler(String urlPath, HttpServletRequest request) - throws Exception { - if (this.errorController != null - && urlPath.equals(this.errorController.getErrorPath())) { - return null; - } - if (isIgnoredPath(urlPath, this.routeLocator.getIgnoredPaths())) { - return null; - } - RequestContext ctx = RequestContext.getCurrentContext(); - if (ctx.containsKey("forward.to")) { - return null; - } - if (this.dirty) { - synchronized (this) { - if (this.dirty) { - registerHandlers(); - this.dirty = false; - } - } - } - return super.lookupHandler(urlPath, request); - } - - private boolean isIgnoredPath(String urlPath, Collection ignored) { - if (ignored != null) { - for (String ignoredPath : ignored) { - if (this.pathMatcher.match(ignoredPath, urlPath)) { - return true; - } - } - } - return false; - } - - private void registerHandlers() { - Collection routes = this.routeLocator.getRoutes(); - if (routes.isEmpty()) { - this.logger.warn("No routes found from RouteLocator"); - } - else { - for (Route route : routes) { - registerHandler(route.getFullPath(), this.zuul); - } - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-netflix-zuul/src/main/resources/META-INF/additional-spring-configuration-metadata.json deleted file mode 100644 index 61ec66969..000000000 --- a/spring-cloud-netflix-zuul/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "properties": [ - { - "defaultValue": false, - "name": "ribbon.restclient.enabled", - "description": "Enables the use of the deprecated Ribbon RestClient.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": false, - "name": "ribbon.okhttp.enabled", - "description": "Enables the use of the OK HTTP Client with Ribbon.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": false, - "name": "zuul.ribbon.eager-load.enabled", - "description": "Enables eager loading of Ribbon clients on startup.", - "type": "java.lang.Boolean" - } - ] -} \ No newline at end of file diff --git a/spring-cloud-netflix-zuul/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-zuul/src/main/resources/META-INF/spring.factories deleted file mode 100644 index ac5fe6070..000000000 --- a/spring-cloud-netflix-zuul/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,3 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.zuul.ZuulServerAutoConfiguration,\ -org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfiguration diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ContextPathZuulProxyApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ContextPathZuulProxyApplicationTests.java deleted file mode 100644 index 2412260c6..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ContextPathZuulProxyApplicationTests.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest( - classes = ContextPathZuulProxyApplicationTests.ContextPathZuulProxyApplication.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "server.servlet.contextPath: /app", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class ContextPathZuulProxyApplicationTests { - - @LocalServerPort - private int port; - - @Autowired - private TestRestTemplate testRestTemplate; - - @Autowired - private DiscoveryClientRouteLocator routes; - - @Autowired - private RoutesEndpoint endpoint; - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void getOnSelfViaSimpleHostRoutingFilter() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app/local"); - this.endpoint.reset(); - ResponseEntity result = testRestTemplate.exchange( - "http://localhost:" + this.port + "/app/self/1", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Gotten 1!"); - } - - @Test - public void stripPrefixFalseAppendsPath() { - this.routes.addRoute(new ZuulRoute("strip", "/strip/**", "strip", - "http://localhost:" + this.port + "/app/local", false, false, null)); - this.endpoint.reset(); - ResponseEntity result = testRestTemplate.exchange( - "http://localhost:" + this.port + "/app/strip", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - // Prefix not stripped to it goes to /local/strip - assertThat(result.getBody()).isEqualTo("Gotten strip!"); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @Import(NoSecurityConfiguration.class) - static class ContextPathZuulProxyApplication { - - @RequestMapping(value = "/local/{id}", method = RequestMethod.GET) - public String get(@PathVariable String id) { - return "Gotten " + id + "!"; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FiltersEndpointTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FiltersEndpointTests.java deleted file mode 100644 index dcdfd4e6d..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FiltersEndpointTests.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.util.List; -import java.util.Map; - -import com.netflix.zuul.ZuulFilter; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Bean; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hibernate.validator.internal.util.Contracts.assertTrue; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * Tests for Filters endpoint - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - properties = "management.endpoints.web.exposure.include=*") -@DirtiesContext -public class FiltersEndpointTests { - - @Autowired - private FiltersEndpoint endpoint; - - @Test - public void getFilters() { - final Map>> filters = endpoint.invoke(); - - boolean foundFilter = false; - - if (filters.containsKey("sample")) { - for (Map filterInfo : filters.get("sample")) { - if (TestFilter.class.getName().equals(filterInfo.get("class"))) { - foundFilter = true; - - // Verify filter's attributes - assertThat(filterInfo.get("order")).isEqualTo(0); - - break; // the search is over - } - } - } - - assertTrue(foundFilter, - "Could not find expected sample filter from filters endpoint"); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableZuulProxy - static class FiltersEndpointApplication { - - @Bean - public ZuulFilter sampleFilter() { - return new TestFilter(); - } - - } - - static class TestFilter extends ZuulFilter { - - @Override - public String filterType() { - return "sample"; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - return null; - } - - @Override - public int filterOrder() { - return 0; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulProxyApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulProxyApplicationTests.java deleted file mode 100644 index a438143a6..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulProxyApplicationTests.java +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.io.IOException; - -import javax.inject.Inject; -import javax.servlet.http.Part; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.actuate.trace.http.HttpTraceRepository; -import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import static java.nio.charset.Charset.defaultCharset; -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; -import static org.springframework.util.StreamUtils.copyToString; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = FormZuulProxyApplication.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "zuul.routes.simplefzpat:/simplefzpat/**" }) -@DirtiesContext -public class FormZuulProxyApplicationTests { - - @Inject - private TestRestTemplate restTemplate; - - @Before - public void setTestRequestContext() { - RequestContext.testSetCurrentContext(new RequestContext()); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void postWithForm() { - MultiValueMap form = new LinkedMultiValueMap<>(); - form.set("foo", "bar"); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); - - ResponseEntity result = sendPost("/simplefzpat/form", form, headers); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]}"); - } - - @Test - public void postWithMultipartForm() { - MultiValueMap form = new LinkedMultiValueMap<>(); - form.set("foo", "bar"); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); - - ResponseEntity result = sendPost("/simplefzpat/form", form, headers); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]}"); - } - - @Test - public void postWithMultipartFile() { - MultiValueMap form = new LinkedMultiValueMap<>(); - - HttpHeaders part = new HttpHeaders(); - part.setContentType(MediaType.TEXT_PLAIN); - part.setContentDispositionFormData("file", "foo.txt"); - - form.set("foo", new HttpEntity<>("bar".getBytes(), part)); - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); - - ResponseEntity result = sendPost("/simplefzpat/file", form, headers); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! bar"); - } - - @Test - public void postWithMultipartFileAndForm() { - MultiValueMap form = new LinkedMultiValueMap<>(); - - HttpHeaders part = new HttpHeaders(); - part.setContentType(MediaType.TEXT_PLAIN); - part.setContentDispositionFormData("file", "foo.txt"); - form.set("foo", new HttpEntity<>("bar".getBytes(), part)); - - form.set("field", "data"); - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); - - ResponseEntity result = sendPost("/simplefzpat/fileandform", form, headers); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! bar!field!data"); - } - - @Test - public void postWithMultipartApplicationJson() { - MultiValueMap form = new LinkedMultiValueMap<>(); - - HttpHeaders partHeaders = new HttpHeaders(); - partHeaders.setContentType(MediaType.APPLICATION_JSON); - form.set("field", new HttpEntity<>("{foo=[bar]}", partHeaders)); - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); - - ResponseEntity result = sendPost("/simplefzpat/json", form, headers); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]} as application/json"); - } - - @Test - public void postWithUTF8Form() { - MultiValueMap form = new LinkedMultiValueMap<>(); - - form.set("foo", "bar"); - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.valueOf( - MediaType.APPLICATION_FORM_URLENCODED_VALUE + "; charset=UTF-8")); - - ResponseEntity result = sendPost("/simplefzpat/form", form, headers); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]}"); - } - - @Test - public void postWithUrlParams() throws Exception { - MultiValueMap form = new LinkedMultiValueMap<>(); - - form.set("foo", "bar"); - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.valueOf( - MediaType.APPLICATION_FORM_URLENCODED_VALUE + "; charset=UTF-8")); - - ResponseEntity result = sendPost("/simplefzpat/form?uriParam=uriValue", form, - headers); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()) - .isEqualTo("Posted! {uriParam=[uriValue], foo=[bar]}"); - } - - @Test - public void getWithUrlParams() throws Exception { - ResponseEntity result = sendGet("/simplefzpat/form?uriParam=uriValue"); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {uriParam=[uriValue]}"); - } - - private ResponseEntity sendPost(String url, MultiValueMap form, - HttpHeaders headers) { - return restTemplate.postForEntity(url, new HttpEntity<>(form, headers), - String.class); - } - - private ResponseEntity sendGet(String url) { - return restTemplate.getForEntity(url, String.class); - } - -} - -// Don't use @SpringBootApplication because we don't want to component scan -@Configuration(proxyBeanMethods = false) -@EnableAutoConfiguration -@RestController -@EnableZuulProxy -@RibbonClients({ @RibbonClient(name = "simplefzpat", - configuration = FormRibbonClientConfiguration.class) }) -@Import(NoSecurityConfiguration.class) -class FormZuulProxyApplication { - - @RequestMapping(value = "/form", method = RequestMethod.POST) - public String accept(@RequestParam MultiValueMap form) - throws IOException { - return "Posted! " + form; - } - - @RequestMapping(value = "/form", method = RequestMethod.GET) - public String get(@RequestParam MultiValueMap form) - throws IOException { - return "Posted! " + form; - } - - // TODO: Why does this not work if you add @RequestParam as above? - @RequestMapping(value = "/file", method = RequestMethod.POST) - public String file(@RequestParam(required = false) MultipartFile file) - throws IOException { - - return "Posted! " + copyToString(file.getInputStream(), defaultCharset()); - } - - @RequestMapping(value = "/fileandform", method = RequestMethod.POST) - public String fileAndForm(@RequestParam MultipartFile file, - @RequestParam String field) throws IOException { - - return "Posted! " + copyToString(file.getInputStream(), defaultCharset()) - + "!field!" + field; - } - - @RequestMapping(value = "/json", method = RequestMethod.POST) - public String fileAndJson(@RequestPart Part field) throws IOException { - - return "Posted! " + copyToString(field.getInputStream(), defaultCharset()) - + " as " + field.getContentType(); - } - - @Bean - public ZuulFilter sampleFilter() { - return new ZuulFilter() { - - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - return null; - } - - @Override - public int filterOrder() { - return 0; - } - - }; - } - - @Bean - public HttpTraceRepository traceRepository() { - return new InMemoryHttpTraceRepository(); - } - - public static void main(String[] args) { - } - -} - -// Load balancer with fixed server list for "simplefzpat" pointing to localhost -@Configuration(proxyBeanMethods = false) -class FormRibbonClientConfiguration { - - @LocalServerPort - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulServletProxyApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulServletProxyApplicationTests.java deleted file mode 100644 index c91dc8bab..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulServletProxyApplicationTests.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.io.IOException; -import java.io.InputStream; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.trace.http.HttpTraceRepository; -import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = FormZuulServletProxyApplication.class, - webEnvironment = RANDOM_PORT, - properties = { "zuul.routes[simplefzspat].path:/simplefzspat/**", - "zuul.routes[simplefzspat].serviceId:simplefzspat" }) -@DirtiesContext -public class FormZuulServletProxyApplicationTests { - - @Autowired - private TestRestTemplate testRestTemplate; - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void unsetTestRequestContext() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void postWithForm() { - MultiValueMap form = new LinkedMultiValueMap<>(); - form.set("foo", "bar"); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); - ResponseEntity result = testRestTemplate.exchange( - "/zuul/simplefzspat/form", HttpMethod.POST, - new HttpEntity<>(form, headers), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]}"); - } - - @Test - public void postWithMultipartForm() { - MultiValueMap form = new LinkedMultiValueMap<>(); - form.set("foo", "bar"); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); - ResponseEntity result = testRestTemplate.exchange( - "/zuul/simplefzspat/form", HttpMethod.POST, - new HttpEntity<>(form, headers), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]}"); - } - - @Test - public void postWithMultipartFile() { - MultiValueMap form = new LinkedMultiValueMap<>(); - HttpHeaders part = new HttpHeaders(); - part.setContentType(MediaType.TEXT_PLAIN); - part.setContentDispositionFormData("file", "foo.txt"); - form.set("foo", new HttpEntity<>("bar".getBytes(), part)); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); - headers.set("Transfer-Encoding", "chunked"); - headers.setContentLength(-1); - ResponseEntity result = testRestTemplate.exchange( - "/zuul/simplefzspat/file", HttpMethod.POST, - new HttpEntity<>(form, headers), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! bar"); - } - - @Test - public void postWithUTF8Form() { - MultiValueMap form = new LinkedMultiValueMap<>(); - form.set("foo", "bar"); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.valueOf( - MediaType.APPLICATION_FORM_URLENCODED_VALUE + "; charset=UTF-8")); - ResponseEntity result = testRestTemplate.exchange( - "/zuul/simplefzspat/form", HttpMethod.POST, - new HttpEntity<>(form, headers), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]}"); - } - -} - -// Don't use @SpringBootApplication because we don't want to component scan -@Configuration(proxyBeanMethods = false) -@EnableAutoConfiguration -@RestController -@EnableZuulProxy -@RibbonClients(@RibbonClient(name = "simplefzspat", - configuration = ServletFormRibbonClientConfiguration.class)) -@Import(NoSecurityConfiguration.class) -class FormZuulServletProxyApplication { - - private static final Log log = LogFactory - .getLog(FormZuulServletProxyApplication.class); - - @RequestMapping(value = "/form", method = RequestMethod.POST) - public String accept(@RequestParam MultiValueMap form) - throws IOException { - return "Posted! " + form; - } - - // TODO: Why does this not work if you add @RequestParam as above? - @RequestMapping(value = "/file", method = RequestMethod.POST) - public String file(@RequestParam(required = false) MultipartFile file) - throws IOException { - byte[] bytes = new byte[0]; - if (file != null) { - if (file.getSize() > 1024) { - bytes = new byte[1024]; - InputStream inputStream = file.getInputStream(); - inputStream.read(bytes); - byte[] buffer = new byte[1024 * 1024 * 10]; - while (inputStream.read(buffer) >= 0) { - log.info("Read more bytes"); - } - } - else { - bytes = file.getBytes(); - } - } - return "Posted! " + new String(bytes); - } - - @Bean - public ZuulFilter sampleFilter() { - return new ZuulFilter() { - - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - return null; - } - - @Override - public int filterOrder() { - return 0; - } - - }; - } - - @Bean - public HttpTraceRepository traceRepository() { - return new InMemoryHttpTraceRepository(); - } - -} - -// Load balancer with fixed server list for "simplefzspat" pointing to localhost -@Configuration(proxyBeanMethods = false) -class ServletFormRibbonClientConfiguration { - - @LocalServerPort - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java deleted file mode 100644 index 6018b46b2..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RetryableZuulProxyApplication.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "zuul.routes[simplerzpat].path: /simplerzpat/**", - "zuul.routes[simplerzpat].retryable: true", - "zuul.routes[simplerzpat].serviceId: simplerzpat", - "ribbon.OkToRetryOnAllOperations: true", - "simplerzpat.ribbon.retryableStatusCodes: 404", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class RetryableZuulProxyApplicationTests { - - @Autowired - private TestRestTemplate testRestTemplate; - - @Autowired - @SuppressWarnings("unused") - private DiscoveryClientRouteLocator routes; - - @Autowired - @SuppressWarnings("unused") - private RoutesEndpoint endpoint; - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void postWithForm() { - MultiValueMap form = new LinkedMultiValueMap(); - form.set("foo", "bar"); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); - ResponseEntity result = testRestTemplate.exchange("/simplerzpat/poster", - HttpMethod.POST, new HttpEntity<>(form, headers), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]}"); - } - -} - -// Don't use @SpringBootApplication because we don't want to component scan -@Configuration(proxyBeanMethods = false) -@EnableAutoConfiguration -@RestController -@EnableZuulProxy -@RibbonClient(name = "simplerzpat", - configuration = RetryableRibbonClientConfiguration.class) -@Import(NoSecurityConfiguration.class) -class RetryableZuulProxyApplication { - - @RequestMapping(value = "/poster", method = RequestMethod.POST) - public String delete(@RequestBody MultiValueMap form) { - return "Posted! " + form; - } - - @Bean - public ZuulFilter sampleFilter() { - return new ZuulFilter() { - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - return null; - } - - @Override - public int filterOrder() { - return 0; - } - }; - } - -} - -// Load balancer with fixed server list for "simplerzpat" pointing to localhost -@Configuration(proxyBeanMethods = false) -class RetryableRibbonClientConfiguration { - - @LocalServerPort - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port), - new Server("failed-localhost", this.port)); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointDetailsTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointDetailsTests.java deleted file mode 100644 index acfcdab16..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointDetailsTests.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.context.ApplicationEventPublisher; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -/** - * @author Ryan Baxter - * @author Gregor Zurowski - */ -@SpringBootTest -@RunWith(MockitoJUnitRunner.class) -public class RoutesEndpointDetailsTests { - - private RouteLocator locator; - - private RoutesEndpoint endpoint; - - @Mock - private ApplicationEventPublisher publisher; - - @Before - public void setUp() { - this.locator = new RouteLocator() { - @Override - public Collection getIgnoredPaths() { - return null; - } - - @Override - public List getRoutes() { - List routes = new ArrayList<>(); - routes.add(new Route("foo", "foopath", "foolocation", null, true, - Collections.EMPTY_SET)); - routes.add(new Route("bar", "barpath", "barlocation", "bar-prefix", true, - Collections.EMPTY_SET)); - return routes; - } - - @Override - public Route getMatchingRoute(String path) { - return null; - } - }; - endpoint = spy(new RoutesEndpoint(locator)); - } - - @Test - public void reset() throws Exception { - this.endpoint.setApplicationEventPublisher(publisher); - Map result = new HashMap<>(); - for (Route r : locator.getRoutes()) { - result.put(r.getFullPath(), r.getLocation()); - } - assertThat(endpoint.reset()).isEqualTo(result); - verify(endpoint, times(1)).invoke(); - verify(publisher, times(1)).publishEvent(isA(RoutesRefreshedEvent.class)); - } - - @Test - public void routeDetails() throws Exception { - Map results = new HashMap<>(); - for (Route route : locator.getRoutes()) { - results.put(route.getFullPath(), new RoutesEndpoint.RouteDetails(route)); - } - assertThat(this.endpoint.invokeRouteDetails(RoutesEndpoint.FORMAT_DETAILS)) - .isEqualTo(results); - verify(endpoint, times(1)).invokeRouteDetails(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointIntegrationTests.java deleted file mode 100644 index 4a397cc1d..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointIntegrationTests.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.util.Map; - -import org.assertj.core.api.Assertions; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - * @author Gregor Zurowski - */ -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - value = { "zuul.routes.sslservice.url=https://localhost:8443", - "management.security.enabled=false", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class RoutesEndpointIntegrationTests { - - private static final String BASE_PATH = new WebEndpointProperties().getBasePath(); - - @Autowired - private TestRestTemplate restTemplate; - - @Autowired - private SimpleZuulProxyApplication.RoutesRefreshListener refreshListener; - - @Test - @SuppressWarnings("unchecked") - public void getRoutesTest() { - ResponseEntity entity = restTemplate.getForEntity(BASE_PATH + "/routes", - Map.class); - Assertions.assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - Map routes = entity.getBody(); - assertThat(routes.get("/sslservice/**")).isEqualTo("https://localhost:8443"); - } - - @Test - @SuppressWarnings("unchecked") - public void postRoutesTest() { - ResponseEntity entity = restTemplate.postForEntity(BASE_PATH + "/routes", - null, Map.class); - Assertions.assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - Map routes = entity.getBody(); - assertThat(routes.get("/sslservice/**")).isEqualTo("https://localhost:8443"); - assertThat(refreshListener.wasCalled()).isTrue(); - } - - @Test - public void getRouteDetailsTest() { - ResponseEntity> responseEntity = restTemplate - .exchange(BASE_PATH + "/routes/details", HttpMethod.GET, null, - new ParameterizedTypeReference>() { - }); - - assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); - - RoutesEndpoint.RouteDetails details = responseEntity.getBody() - .get("/sslservice/**"); - assertThat(details.getPath()).isEqualTo("/**"); - assertThat(details.getFullPath()).isEqualTo("/sslservice/**"); - assertThat(details.getLocation()).isEqualTo("https://localhost:8443"); - assertThat(details.getPrefix()).isEqualTo("/sslservice"); - assertThat(details.isPrefixStripped()).isTrue(); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @Import(NoSecurityConfiguration.class) - static class SimpleZuulProxyApplication { - - @Component - static class RoutesRefreshListener - implements ApplicationListener { - - private boolean called = false; - - @Override - public void onApplicationEvent(RoutesRefreshedEvent routesRefreshedEvent) { - called = true; - } - - public boolean wasCalled() { - return called; - } - - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointTests.java deleted file mode 100644 index 4b89fb839..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointTests.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - * @author Gregor Zurowski - */ -public class RoutesEndpointTests { - - private RouteLocator locator; - - @Before - public void setUp() { - this.locator = new RouteLocator() { - @Override - public Collection getIgnoredPaths() { - return null; - } - - @Override - public List getRoutes() { - List routes = new ArrayList<>(); - routes.add(new Route("foo", "foopath", "foolocation", null, true, - Collections.EMPTY_SET)); - routes.add(new Route("bar", "barpath", "barlocation", "/bar-prefix", true, - Collections.EMPTY_SET)); - return routes; - } - - @Override - public Route getMatchingRoute(String path) { - return null; - } - }; - } - - @Test - public void testInvoke() { - RoutesEndpoint endpoint = new RoutesEndpoint(locator); - Map result = new HashMap(); - for (Route r : locator.getRoutes()) { - result.put(r.getFullPath(), r.getLocation()); - } - assertThat(endpoint.invoke()).isEqualTo(result); - } - - @Test - public void testInvokeRouteDetails() { - RoutesEndpoint endpoint = new RoutesEndpoint(locator); - Map results = new HashMap<>(); - for (Route route : locator.getRoutes()) { - results.put(route.getFullPath(), new RoutesEndpoint.RouteDetails(route)); - } - assertThat(endpoint.invokeRouteDetails()).isEqualTo(results); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ServletPathZuulProxyApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ServletPathZuulProxyApplicationTests.java deleted file mode 100644 index 77ad24e33..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ServletPathZuulProxyApplicationTests.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.net.URI; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.RequestEntity; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest( - classes = ServletPathZuulProxyApplicationTests.ServletPathZuulProxyApplication.class, - webEnvironment = RANDOM_PORT, - properties = { "server.servlet.context-path: /app" }) -@DirtiesContext -public class ServletPathZuulProxyApplicationTests { - - @LocalServerPort - private int port; - - @Autowired - private TestRestTemplate testRestTemplate; - - @Autowired - private DiscoveryClientRouteLocator routes; - - @Autowired - private RoutesEndpoint endpoint; - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - @Ignore // FIXME: 2.1.0 - public void getOnSelfViaSimpleHostRoutingFilter() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app/local"); - this.endpoint.reset(); - ResponseEntity result = testRestTemplate.exchange("/app/self/1", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Gotten 1!"); - } - - @Test - @Ignore // FIXME: 2.1.0 - public void optionsOnRawEndpoint() throws Exception { - ResponseEntity result = testRestTemplate.exchange( - RequestEntity.options(new URI("/app/local/1")) - .header("Origin", "http://localhost:9000") - .header("Access-Control-Request-Method", "GET").build(), - String.class); - HttpHeaders httpHeaders = result.getHeaders(); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(httpHeaders.getFirst("Access-Control-Allow-Origin")).isEqualTo("*"); - } - - @Test - @Ignore // FIXME: 2.1.0 - public void optionsOnSelf() throws Exception { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app/local"); - this.endpoint.reset(); - ResponseEntity result = testRestTemplate.exchange( - RequestEntity.options(new URI("/app/self/1")) - .header("Origin", "http://localhost:9000") - .header("Access-Control-Request-Method", "GET").build(), - String.class); - HttpHeaders httpHeaders = result.getHeaders(); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(httpHeaders.getFirst("Access-Control-Allow-Origin")).isEqualTo("*"); - } - - @Test - @Ignore // FIXME: 2.1.0 - public void contentOnRawEndpoint() throws Exception { - ResponseEntity result = testRestTemplate.exchange( - RequestEntity.get(new URI("/app/local/1")).build(), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Gotten 1!"); - } - - @Test - @Ignore // FIXME: 2.1.0 - public void stripPrefixFalseAppendsPath() { - this.routes.addRoute(new ZuulRoute("strip", "/strip/**", "strip", - "http://localhost:" + this.port + "/app/local", false, false, null)); - this.endpoint.reset(); - ResponseEntity result = testRestTemplate.exchange("/app/strip", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - // Prefix not stripped to it goes to /local/strip - assertThat(result.getBody()).isEqualTo("Gotten strip!"); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @Import(NoSecurityConfiguration.class) - static class ServletPathZuulProxyApplication { - - @RequestMapping(value = "/local/{id}", method = RequestMethod.GET) - @CrossOrigin(origins = "*") - public String get(@PathVariable String id) { - return "Gotten " + id + "!"; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulProxyApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulProxyApplicationTests.java deleted file mode 100644 index 8acbeec6b..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulProxyApplicationTests.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.net.URI; -import java.net.URISyntaxException; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest( - classes = SimpleZuulProxyApplicationTests.SimpleZuulProxyApplication.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "zuul.forceOriginalQueryStringEncoding: true", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class SimpleZuulProxyApplicationTests { - - @LocalServerPort - private int port; - - @Autowired - private TestRestTemplate testRestTemplate; - - @Autowired - private DiscoveryClientRouteLocator routes; - - @Autowired - private RoutesEndpoint endpoint; - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - - this.routes.addRoute("/foo/**", "http://localhost:" + this.port + "/bar"); - this.endpoint.reset(); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void getOnSelfViaSimpleHostRoutingFilter() { - ResponseEntity result = executeSimpleRequest(HttpMethod.GET); - - assertResponseCodeAndBody(result, "get bar"); - } - - @Test - public void postOnSelfViaSimpleHostRoutingFilter() { - ResponseEntity result = executeSimpleRequest(HttpMethod.POST); - - assertResponseCodeAndBody(result, "post bar"); - } - - @Test - public void putOnSelfViaSimpleHostRoutingFilter() { - ResponseEntity result = executeSimpleRequest(HttpMethod.PUT); - - assertResponseCodeAndBody(result, "put bar"); - } - - @Test - public void patchOnSelfViaSimpleHostRoutingFilter() { - ResponseEntity result = executeSimpleRequest(HttpMethod.PATCH); - - assertResponseCodeAndBody(result, "patch bar"); - } - - @Test - public void deleteOnSelfViaSimpleHostRoutingFilter() { - ResponseEntity result = executeSimpleRequest(HttpMethod.DELETE); - - assertResponseCodeAndBody(result, "delete bar"); - } - - @Test - public void getOnSelfWithComplexQueryParam() throws URISyntaxException { - String encodedQueryString = "foo=%7B%22project%22%3A%22stream%22%2C%22logger" - + "%22%3A%22javascript%22%2C%22platform%22%3A%22javascript%22%2C%22" - + "request%22%3A%7B%22url%22%3A%22https%3A%2F%2Ffoo%2Fadmin"; - ResponseEntity result = testRestTemplate.exchange( - new URI("/foo?" + encodedQueryString), HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo(encodedQueryString); - } - - private void assertResponseCodeAndBody(ResponseEntity result, - String expectedBody) { - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo(expectedBody); - } - - private ResponseEntity executeSimpleRequest(HttpMethod httpMethod) { - ResponseEntity result = testRestTemplate.exchange("/foo?id=bar", - httpMethod, new HttpEntity<>((Void) null), String.class); - return result; - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @Import(NoSecurityConfiguration.class) - static class SimpleZuulProxyApplication { - - @RequestMapping(value = "/bar", method = RequestMethod.GET) - public String get(@RequestParam String id) { - return "get " + id; - } - - @RequestMapping(value = "/bar", method = RequestMethod.GET, params = { "foo" }) - public String complexGet(@RequestParam String foo, HttpServletRequest request) { - return request.getQueryString(); - } - - @RequestMapping(value = "/bar", method = RequestMethod.POST) - public String post(@RequestParam String id) { - return "post " + id; - } - - @RequestMapping(value = "/bar", method = RequestMethod.PUT) - public String put(@RequestParam String id) { - return "put " + id; - } - - @RequestMapping(value = "/bar", method = RequestMethod.DELETE) - public String delete(@RequestParam String id) { - return "delete " + id; - } - - @RequestMapping(value = "/bar", method = RequestMethod.PATCH) - public String patch(@RequestParam String id) { - return "patch " + id; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulServerApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulServerApplicationTests.java deleted file mode 100644 index 6e67f25b1..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulServerApplicationTests.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - properties = "zuul.routes[testclient]:/testing123/**") -@DirtiesContext -public class SimpleZuulServerApplicationTests { - - @LocalServerPort - private int port; - - @Autowired - private TestRestTemplate testRestTemplate; - - @Autowired - private RouteLocator routes; - - private String getRoute(String path) { - return this.routes.getMatchingRoute(path).getLocation(); - } - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void bindRoute() { - assertThat(getRoute("/testing123/**")).isNotNull(); - } - - @Test - public void getOnSelf() { - ResponseEntity result = testRestTemplate.exchange("/", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Hello world"); - } - - @Test - public void getOnSelfViaFilter() { - ResponseEntity result = testRestTemplate.exchange("/testing123/1", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @SpringBootConfiguration - @EnableAutoConfiguration - @RestController - @EnableZuulServer - @Import(NoSecurityConfiguration.class) - static class SimpleZuulServerApplication { - - @RequestMapping("/local") - public String local() { - return "Hello local"; - } - - @RequestMapping("/") - public String home() { - return "Hello world"; - } - - @Bean - public ZuulFilter sampleFilter() { - return new ZuulFilter() { - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - return null; - } - - @Override - public int filterOrder() { - return 0; - } - }; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializerTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializerTests.java deleted file mode 100644 index b8d945212..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializerTests.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.Map; - -import com.netflix.zuul.FilterLoader; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.filters.FilterRegistry; -import com.netflix.zuul.monitoring.CounterFactory; -import com.netflix.zuul.monitoring.TracerFactory; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.util.ReflectionUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -public class ZuulFilterInitializerTests { - - private Map filters; - - private CounterFactory counterFactory; - - private TracerFactory tracerFactory; - - private FilterLoader filterLoader; - - private FilterRegistry filterRegistry; - - private ZuulFilterInitializer initializer; - - @Before - public void init() { - filters = getFilters(); - counterFactory = mock(CounterFactory.class); - tracerFactory = mock(TracerFactory.class); - filterLoader = new FilterLoader(); - filterRegistry = getFilterRegistry(); - initializer = new ZuulFilterInitializer(filters, counterFactory, tracerFactory, - filterLoader, filterRegistry); - - initializer.contextInitialized(); - } - - @Test - public void shouldSetupOnContextInitializedEvent() { - - assertThat(TracerFactory.instance()).isEqualTo(tracerFactory); - assertThat(CounterFactory.instance()).isEqualTo(counterFactory); - assertThat(filterRegistry.getAllFilters()).containsAll(filters.values()); - - initializer.contextDestroyed(); - } - - @Test - public void shouldCleanupOnContextDestroyed() { - - initializer.contextDestroyed(); - - assertThat(ReflectionTestUtils.getField(TracerFactory.class, "INSTANCE")) - .isNull(); - assertThat(ReflectionTestUtils.getField(CounterFactory.class, "INSTANCE")) - .isNull(); - assertThat(filterRegistry.getAllFilters()).isEmpty(); - assertThat(getHashFiltersByType().isEmpty()).isTrue(); - } - - private Map getHashFiltersByType() { - Field field = ReflectionUtils.findField(FilterLoader.class, "hashFiltersByType"); - ReflectionUtils.makeAccessible(field); - return (Map) ReflectionUtils.getField(field, FilterLoader.getInstance()); - } - - private Map getFilters() { - Map filters = new HashMap<>(); - filters.put("key1", mock(ZuulFilter.class)); - filters.put("key2", mock(ZuulFilter.class)); - return filters; - } - - private FilterRegistry getFilterRegistry() { - try { - Constructor constructor = FilterRegistry.class - .getDeclaredConstructor(new Class[0]); - constructor.setAccessible(true); - return constructor.newInstance(new Object[0]); - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyApplicationTests.java deleted file mode 100644 index 33ecf2deb..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyApplicationTests.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.config.annotation.CorsRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = ZuulProxyApplicationTests.ZuulProxyApplication.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - properties = { "zuul.routes.simplezpat:/simplezpat/**", - "logging.level.org.apache.http: DEBUG" }) -@DirtiesContext -public class ZuulProxyApplicationTests { - - @LocalServerPort - private int port; - - @Autowired - private TestRestTemplate testRestTemplate; - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void getHasCorrectTransferEncoding() { - ResponseEntity result = testRestTemplate.getForEntity(url(), - String.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("missing"); - } - - @Test - public void postHasCorrectTransferEncoding() { - ResponseEntity result = testRestTemplate.postForEntity(url(), - new HttpEntity<>("hello"), String.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("missing"); - } - - @Test - public void preflightRequestSucceedsForGetRequest() { - MultiValueMap headers = new LinkedMultiValueMap<>(); - headers.put("Origin", singletonList("https://hello.com")); - headers.put("Access-Control-Request-Method", singletonList("GET")); - ResponseEntity result = testRestTemplate.exchange(url(), HttpMethod.OPTIONS, - new HttpEntity<>(headers), Void.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void preflightRequestIsForbiddenForUnsupportedMethod() { - MultiValueMap headers = new LinkedMultiValueMap<>(); - headers.put("Origin", singletonList("https://hello.com")); - headers.put("Access-Control-Request-Method", singletonList("PUT")); - ResponseEntity result = testRestTemplate.exchange(url(), HttpMethod.OPTIONS, - new HttpEntity<>(headers), Void.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); - } - - @Test - public void preflightRequestIsForbiddenForUnsupportedorigin() { - MultiValueMap headers = new LinkedMultiValueMap<>(); - headers.put("Origin", singletonList("http://unknown-origin.com")); - headers.put("Access-Control-Request-Method", singletonList("GET")); - ResponseEntity result = testRestTemplate.exchange(url(), HttpMethod.OPTIONS, - new HttpEntity<>(headers), Void.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); - } - - private String url() { - return "http://localhost:" + this.port + "/simplezpat/transferencoding"; - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @RibbonClient(name = "simplezpat", - configuration = TestRibbonClientConfiguration.class) - @Import(NoSecurityConfiguration.class) - static class ZuulProxyApplication { - - @RequestMapping(value = "/transferencoding", method = RequestMethod.GET) - public String get(@RequestHeader(name = "Transfer-Encoding", - required = false) String transferEncoding) { - if (transferEncoding == null) { - return "missing"; - } - return transferEncoding; - } - - @RequestMapping(value = "/transferencoding", method = RequestMethod.POST) - public String post( - @RequestHeader(name = "Transfer-Encoding", - required = false) String transferEncoding, - @RequestBody String hello) { - if (transferEncoding == null) { - return "missing"; - } - return transferEncoding; - } - - @Bean - public WebMvcConfigurer corsConfigurer() { - return new WebMvcConfigurer() { - public void addCorsMappings(CorsRegistry registry) { - registry.addMapping("/simplezpat/**") - .allowedOrigins("https://hello.com") - .allowedMethods("GET", "POST") - .allowedHeaders("Authorization"); - } - }; - } - - } - - // Load balancer with fixed server list for "simplezpat" pointing to localhost - @Configuration(proxyBeanMethods = false) - static class TestRibbonClientConfiguration { - - @LocalServerPort - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfigurationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfigurationTests.java deleted file mode 100644 index d3a9b4c3f..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfigurationTests.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.CompositeRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * To test the auto-configuration of Zuul Proxy - * - * @author Biju Kunjummen - * - */ - -@RunWith(SpringRunner.class) -@SpringBootTest -@DirtiesContext -public class ZuulProxyAutoConfigurationTests { - - @Autowired - private RouteLocator routeLocator; - - @Autowired(required = false) - private RibbonRoutingFilter ribbonRoutingFilter; - - @Test - public void testAutoConfiguredBeans() { - assertThat(routeLocator).isInstanceOf(CompositeRouteLocator.class); - assertThat(this.ribbonRoutingFilter).isNotNull(); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @EnableZuulProxy - static class TestConfig { - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfigurationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfigurationTests.java deleted file mode 100644 index 43a97e23d..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfigurationTests.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import org.junit.Test; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFactory; -import org.springframework.context.annotation.Bean; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * @author Spencer Gibb - * @author Biju Kunjummen - */ -public class ZuulProxyConfigurationTests { - - @Test - public void testDefaultsToApacheHttpClient() { - testClient(HttpClientRibbonCommandFactory.class, null); - testClient(HttpClientRibbonCommandFactory.class, - "ribbon.httpclient.enabled=true"); - } - - @Test - public void testEnableRestClient() { - testClient(RestClientRibbonCommandFactory.class, - "ribbon.restclient.enabled=true"); - } - - @Test - public void testEnableOkHttpClient() { - testClient(OkHttpRibbonCommandFactory.class, "ribbon.okhttp.enabled=true"); - } - - void testClient(Class clientType, String property) { - if (property == null) { - property = "aaa=bbb"; - } - new WebApplicationContextRunner().withUserConfiguration(TestConfig.class) - .withPropertyValues(property) - .run(c -> assertThat(c).hasSingleBean(clientType)); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableZuulProxy - static class TestConfig { - - @Bean - SpringClientFactory springClientFactory() { - return mock(SpringClientFactory.class); - } - - @Bean - DiscoveryClient discoveryClient() { - return mock(DiscoveryClient.class); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulServerAutoConfigurationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulServerAutoConfigurationTests.java deleted file mode 100644 index a61bbf53c..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulServerAutoConfigurationTests.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.CompositeRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * To test the auto-configuration of Zuul Proxy - * - * @author Biju Kunjummen - * - */ - -@RunWith(SpringRunner.class) -@SpringBootTest -public class ZuulServerAutoConfigurationTests { - - @Autowired - private RouteLocator routeLocator; - - @Autowired(required = false) - private RibbonRoutingFilter ribbonRoutingFilter; - - @Test - public void testAutoConfiguredBeans() { - assertThat(routeLocator).isInstanceOf(CompositeRouteLocator.class); - assertThat(ribbonRoutingFilter).isNull(); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @EnableZuulServer - static class TestConfig { - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CompositeRouteLocatorTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CompositeRouteLocatorTests.java deleted file mode 100644 index dcbf6db4c..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CompositeRouteLocatorTests.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.junit.Test; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -/** - * @author Johannes Edmeier - */ -public class CompositeRouteLocatorTests { - - private CompositeRouteLocator locator; - - public CompositeRouteLocatorTests() { - List locators = new ArrayList<>(); - locators.add( - new TestRouteLocator(asList("ign1"), asList(createRoute("1", "/pathA")))); - locators.add(new TestRouteLocator(asList("ign1", "ign2"), - asList(createRoute("2", "/pathA"), createRoute("2", "/pathB")))); - this.locator = new CompositeRouteLocator(locators); - } - - @Test - public void test_getIgnoredPaths() { - assertThat(locator.getIgnoredPaths()).contains("ign1", "ign2"); - - } - - @Test - public void test_getRoutes() { - assertThat(locator.getRoutes()).contains(createRoute("1", "/pathA"), - createRoute("2", "/pathB")); - } - - @Test - public void test_getMatchingRoute() { - assertThat(locator.getMatchingRoute("/pathA")).isNotNull(); - assertThat(locator.getMatchingRoute("/pathA").getId()).isEqualTo("1"); - assertThat(locator.getMatchingRoute("/pathB").getId()) - .as("Locator 1 should take precedence").isEqualTo("2"); - assertThat(locator.getMatchingRoute("/pathNot")).isNull(); - } - - @Test - public void test_refresh() { - RefreshableRouteLocator mock = mock(RefreshableRouteLocator.class); - new CompositeRouteLocator(asList(mock)).refresh(); - verify(mock).refresh(); - } - - private Route createRoute(String id, String path) { - return new Route(id, path, null, null, false, Collections.emptySet()); - } - - private static class TestRouteLocator implements RouteLocator { - - private Collection ignoredPaths; - - private List routes; - - TestRouteLocator(Collection ignoredPaths, List routes) { - this.ignoredPaths = ignoredPaths; - this.routes = routes; - } - - @Override - public Collection getIgnoredPaths() { - return this.ignoredPaths; - } - - @Override - public List getRoutes() { - return this.routes; - } - - @Override - public Route getMatchingRoute(String path) { - for (Route route : routes) { - if (path.startsWith(route.getPath())) { - return route; - } - } - return null; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CustomHostRoutingFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CustomHostRoutingFilterTests.java deleted file mode 100644 index 87597f920..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CustomHostRoutingFilterTests.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters; - -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import com.netflix.zuul.context.RequestContext; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.HttpClients; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; -import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientFactory; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.RoutesEndpoint; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.RestTemplate; - -import static junit.framework.TestCase.assertFalse; -import static junit.framework.TestCase.assertTrue; -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest( - classes = CustomHostRoutingFilterTests.SampleCustomZuulProxyApplication.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - properties = { "server.servlet.context-path: /app", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class CustomHostRoutingFilterTests { - - @LocalServerPort - private int port; - - @Autowired - private DiscoveryClientRouteLocator routes; - - @Autowired - private RoutesEndpoint endpoint; - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void getOnSelfViaCustomHostRoutingFilter() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/app/self/get/1", String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Get 1"); - } - - @Test - public void postOnSelfViaCustomHostRoutingFilter() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); - this.endpoint.reset(); - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add("id", "2"); - ResponseEntity result = new TestRestTemplate().postForEntity( - "http://localhost:" + this.port + "/app/self/post", params, String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Post 2"); - } - - @Test - public void putOnSelfViaCustomHostRoutingFilter() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/app/self/put/3", HttpMethod.PUT, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Put 3"); - } - - @Test - public void patchOnSelfViaCustomHostRoutingFilter() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); - this.endpoint.reset(); - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add("patch", "5"); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/app/self/patch/4", HttpMethod.PATCH, - new HttpEntity<>(params), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Patch 45"); - } - - @Test - public void getOnSelfIgnoredHeaders() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/app/self/get/1", String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertTrue(result.getHeaders().containsKey("X-NotIgnored")); - assertFalse(result.getHeaders().containsKey("X-Ignored")); - } - - @Test - public void getOnSelfWithSessionCookie() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); - this.endpoint.reset(); - - RestTemplate restTemplate = new RestTemplate(); - - ResponseEntity result1 = restTemplate.getForEntity( - "http://localhost:" + this.port + "/app/self/cookie/1", String.class); - - ResponseEntity result2 = restTemplate.getForEntity( - "http://localhost:" + this.port + "/app/self/cookie/2", String.class); - - assertThat(result1.getBody()).isEqualTo("SetCookie 1"); - assertThat(result2.getBody()).isEqualTo("GetCookie 1"); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @Import(NoSecurityConfiguration.class) - static class SampleCustomZuulProxyApplication { - - @RequestMapping(value = "/get/{id}", method = RequestMethod.GET) - public String get(@PathVariable String id, HttpServletResponse response) { - response.setHeader("X-Ignored", "foo"); - response.setHeader("X-NotIgnored", "bar"); - return "Get " + id; - } - - @RequestMapping(value = "/cookie/{id}", method = RequestMethod.GET) - public String getWithCookie(@PathVariable String id, HttpSession session) { - Object testCookie = session.getAttribute("testCookie"); - if (testCookie != null) { - return "GetCookie " + testCookie; - } - session.setAttribute("testCookie", id); - return "SetCookie " + id; - } - - @RequestMapping(value = "/post", method = RequestMethod.POST) - public String post(@RequestParam("id") String id) { - return "Post " + id; - } - - @RequestMapping(value = "/put/{id}", method = RequestMethod.PUT) - public String put(@PathVariable String id) { - return "Put " + id; - } - - @RequestMapping(value = "/patch/{id}", method = RequestMethod.PATCH) - public String patch(@PathVariable String id, - @RequestParam("patch") String patch) { - return "Patch " + id + patch; - } - - public static void main(String[] args) { - SpringApplication.run(SampleCustomZuulProxyApplication.class, args); - } - - @Configuration(proxyBeanMethods = false) - @EnableZuulProxy - protected static class CustomZuulProxyConfig { - - @Bean - public ApacheHttpClientFactory customHttpClientFactory( - HttpClientBuilder builder) { - return new CustomApacheHttpClientFactory(builder); - } - - @Bean - public CloseableHttpClient closeableClient() { - return HttpClients.custom().setDefaultCookieStore(new BasicCookieStore()) - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.DEFAULT).build()) - .build(); - } - - @Bean - public SimpleHostRoutingFilter simpleHostRoutingFilter( - ProxyRequestHelper helper, ZuulProperties zuulProperties, - CloseableHttpClient httpClient) { - return new CustomHostRoutingFilter(helper, zuulProperties, httpClient); - } - - private class CustomHostRoutingFilter extends SimpleHostRoutingFilter { - - CustomHostRoutingFilter(ProxyRequestHelper helper, - ZuulProperties zuulProperties, CloseableHttpClient httpClient) { - super(helper, zuulProperties, httpClient); - } - - @Override - public Object run() { - super.addIgnoredHeaders("X-Ignored"); - return super.run(); - } - - } - - private class CustomApacheHttpClientFactory - extends DefaultApacheHttpClientFactory { - - CustomApacheHttpClientFactory(HttpClientBuilder builder) { - super(builder); - } - - } - - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelperTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelperTests.java deleted file mode 100644 index 9615a95ff..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelperTests.java +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters; - -import java.io.IOException; -import java.util.List; - -import com.netflix.util.Pair; -import com.netflix.zuul.context.RequestContext; -import org.assertj.core.api.Assertions; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; - -import org.springframework.boot.actuate.trace.http.HttpTrace; -import org.springframework.boot.actuate.trace.http.HttpTraceRepository; -import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY; - -/** - * @author Spencer Gibb - */ -public class ProxyRequestHelperTests { - - @Mock - private HttpTraceRepository traceRepository; - - @Before - public void init() { - initMocks(this); - } - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void debug() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - request.setContent("{}".getBytes()); - request.addHeader("singleName", "singleValue"); - request.addHeader("multiName", "multiValue1"); - request.addHeader("multiName", "multiValue2"); - RequestContext.getCurrentContext().setRequest(request); - - TraceProxyRequestHelper helper = new TraceProxyRequestHelper( - new ZuulProperties()); - this.traceRepository = new InMemoryHttpTraceRepository(); - helper.setTraces(this.traceRepository); - - MultiValueMap headers = helper.buildZuulRequestHeaders(request); - - helper.debug("POST", "https://example.com", headers, new LinkedMultiValueMap<>(), - request.getInputStream()); - HttpTrace actual = this.traceRepository.findAll().get(0); - Assertions.assertThat(actual.getRequest().getHeaders()).containsKeys("singleName", - "multiName"); - } - - @Test - public void shouldDebugBodyDisabled() throws Exception { - RequestContext context = RequestContext.getCurrentContext(); - - ZuulProperties zuulProperties = new ZuulProperties(); - zuulProperties.setTraceRequestBody(false); - ProxyRequestHelper helper = new ProxyRequestHelper(zuulProperties); - - assertThat(helper.shouldDebugBody(context)).as("shouldDebugBody wrong").isFalse(); - } - - @Test - public void shouldDebugBodyChunked() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - RequestContext context = RequestContext.getCurrentContext(); - context.setChunkedRequestBody(); - context.setRequest(request); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - assertThat(helper.shouldDebugBody(context)).as("shouldDebugBody wrong").isFalse(); - } - - @Test - public void shouldDebugBodyServlet() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - RequestContext context = RequestContext.getCurrentContext(); - context.setZuulEngineRan(); - context.setRequest(request); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - assertThat(helper.shouldDebugBody(context)).as("shouldDebugBody wrong").isFalse(); - } - - @Test - public void shouldDebugBodyNullContentType() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - request.setContentType(null); - RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - - ZuulProperties zuulProperties = new ZuulProperties(); - zuulProperties.setTraceRequestBody(true); - ProxyRequestHelper helper = new ProxyRequestHelper(zuulProperties); - - assertThat(helper.shouldDebugBody(context)).as("shouldDebugBody wrong").isTrue(); - } - - @Test - public void shouldDebugBodyNullRequest() throws Exception { - RequestContext context = RequestContext.getCurrentContext(); - - ZuulProperties zuulProperties = new ZuulProperties(); - zuulProperties.setTraceRequestBody(true); - ProxyRequestHelper helper = new ProxyRequestHelper(zuulProperties); - - assertThat(helper.shouldDebugBody(context)).as("shouldDebugBody wrong").isTrue(); - } - - @Test - public void shouldDebugBodyNotMultitypeContentType() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - request.setContentType(MediaType.APPLICATION_JSON_VALUE); - RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - - ZuulProperties zuulProperties = new ZuulProperties(); - zuulProperties.setTraceRequestBody(true); - ProxyRequestHelper helper = new ProxyRequestHelper(zuulProperties); - - assertThat(helper.shouldDebugBody(context)).as("shouldDebugBody wrong").isTrue(); - } - - @Test - public void shouldDebugBodyMultitypeContentType() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - request.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE); - RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - assertThat(helper.shouldDebugBody(context)).as("shouldDebugBody wrong").isFalse(); - } - - @Test - public void buildZuulRequestHeadersWork() { - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/"); - request.addHeader("singleName", "singleValue"); - request.addHeader("multiName", "multiValue1"); - request.addHeader("multiName", "multiValue2"); - - TraceProxyRequestHelper helper = new TraceProxyRequestHelper( - new ZuulProperties()); - helper.setTraces(this.traceRepository); - - MultiValueMap headers = helper.buildZuulRequestHeaders(request); - List singleName = headers.get("singleName"); - assertThat(singleName).isNotNull(); - assertThat(singleName.size()).isEqualTo(1); - - List multiName = headers.get("multiName"); - assertThat(multiName).isNotNull(); - assertThat(multiName.size()).isEqualTo(2); - - List missingName = headers.get("missingName"); - assertThat(missingName).isNull(); - - } - - @Test - public void buildZuulRequestHeadersRequestsGzipAndOnlyGzip() { - MockHttpServletRequest request = new MockHttpServletRequest("", "/"); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - MultiValueMap headers = helper.buildZuulRequestHeaders(request); - - List acceptEncodings = headers.get("accept-encoding"); - assertThat(acceptEncodings).hasSize(1); - assertThat(acceptEncodings).containsExactly("gzip"); - } - - @Test - public void buildZuulRequestHeadersRequestsContentEncoding() { - MockHttpServletRequest request = new MockHttpServletRequest("", "/"); - request.addHeader("content-encoding", "identity"); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - MultiValueMap headers = helper.buildZuulRequestHeaders(request); - - List contentEncodings = headers.get("content-encoding"); - assertThat(contentEncodings).hasSize(1); - assertThat(contentEncodings).containsExactly("identity"); - } - - @Test - public void buildZuulRequestHeadersRequestsAcceptEncoding() { - MockHttpServletRequest request = new MockHttpServletRequest("", "/"); - request.addHeader("accept-encoding", "identity"); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - MultiValueMap headers = helper.buildZuulRequestHeaders(request); - - List acceptEncodings = headers.get("accept-encoding"); - assertThat(acceptEncodings).hasSize(1); - assertThat(acceptEncodings).containsExactly("identity"); - } - - @Test - public void addHostHeader() { - MockHttpServletRequest request = new MockHttpServletRequest("", "/"); - request.addHeader("host", "foo.com"); - - ZuulProperties zuulProperties = new ZuulProperties(); - zuulProperties.setAddHostHeader(true); - ProxyRequestHelper helper = new ProxyRequestHelper(zuulProperties); - - MultiValueMap headers = helper.buildZuulRequestHeaders(request); - - List acceptEncodings = headers.get("host"); - assertThat(acceptEncodings).hasSize(1); - assertThat(acceptEncodings).containsExactly("foo.com"); - - zuulProperties.setAddHostHeader(false); - helper = new ProxyRequestHelper(zuulProperties); - headers = helper.buildZuulRequestHeaders(request); - - acceptEncodings = headers.get("host"); - assertThat(acceptEncodings).isNull(); - } - - @Test - public void setResponseLowercase() throws IOException { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - context.setResponse(response); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - MultiValueMap headers = new HttpHeaders(); - headers.add(HttpHeaders.CONTENT_ENCODING.toLowerCase(), "gzip"); - - helper.setResponse(200, request.getInputStream(), headers); - assertThat(context.getResponseGZipped()).isTrue(); - } - - @Test - public void setResponseShouldSetOriginResponseHeaders() throws IOException { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - context.setResponse(response); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - MultiValueMap headers = new HttpHeaders(); - headers.add(HttpHeaders.CONTENT_TYPE, "text/plain"); - headers.add("some-header", "some-value"); - - helper.setResponse(200, request.getInputStream(), headers); - assertThat(context.getOriginResponseHeaders()).contains( - new Pair<>(HttpHeaders.CONTENT_TYPE, "text/plain"), - new Pair<>("some-header", "some-value")); - } - - @Test - public void setResponseUppercase() throws IOException { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - context.setResponse(response); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - MultiValueMap headers = new HttpHeaders(); - headers.add(HttpHeaders.CONTENT_ENCODING, "gzip"); - - helper.setResponse(200, request.getInputStream(), headers); - assertThat(context.getResponseGZipped()).isTrue(); - } - - @Test - public void getQueryString() { - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add("a", "1234"); - params.add("b", "5678"); - - String queryString = new ProxyRequestHelper(new ZuulProperties()) - .getQueryString(params); - - assertThat(queryString).isEqualTo("?a=1234&b=5678"); - } - - @Test - public void getQueryStringWithEmptyParam() { - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add("wsdl", ""); - - String queryString = new ProxyRequestHelper(new ZuulProperties()) - .getQueryString(params); - - assertThat(queryString).isEqualTo("?wsdl"); - } - - @Test - public void getQueryStringEncoded() { - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add("foo", "weird#chars"); - - String queryString = new ProxyRequestHelper(new ZuulProperties()) - .getQueryString(params); - - assertThat(queryString).isEqualTo("?foo=weird%23chars"); - } - - @Test - public void getQueryParamNameWithColon() { - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add("foo:bar", "baz"); - params.add("foobar", "bam"); - params.add("foo\fbar", "bat"); // form feed is the colon replacement char - - String queryString = new ProxyRequestHelper(new ZuulProperties()) - .getQueryString(params); - - assertThat(queryString).isEqualTo("?foo:bar=baz&foobar=bam&foo%0Cbar=bat"); - } - - @Test - public void buildZuulRequestURIWithUTF8() throws Exception { - String encodedURI = "/resource/esp%C3%A9cial-char"; - String decodedURI = "/resource/espécial-char"; - - MockHttpServletRequest request = new MockHttpServletRequest("GET", encodedURI); - request.setCharacterEncoding("UTF-8"); - final RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - context.set(REQUEST_URI_KEY, decodedURI); - - final String requestURI = new ProxyRequestHelper(new ZuulProperties()) - .buildZuulRequestURI(request); - assertThat(requestURI).isEqualTo(encodedURI); - } - - @Test - public void buildZuulRequestURIWithDefaultEncoding() { - String encodedURI = "/resource/esp%E9cial-char"; - String decodedURI = "/resource/espécial-char"; - - MockHttpServletRequest request = new MockHttpServletRequest("GET", encodedURI); - final RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - context.set(REQUEST_URI_KEY, decodedURI); - - final String requestURI = new ProxyRequestHelper(new ZuulProperties()) - .buildZuulRequestURI(request); - assertThat(requestURI).isEqualTo(encodedURI); - } - - @Test - public void getUTF8Url() { - String requestURI = "/oléדרעק"; - String encodedRequestURI = "/ol%C3%A9%D7%93%D7%A8%D7%A2%D7%A7"; - MockHttpServletRequest request = new MockHttpServletRequest("GET", requestURI); - request.setCharacterEncoding("UTF-8"); - - RequestContext context = RequestContext.getCurrentContext(); - context.set(REQUEST_URI_KEY, requestURI); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - String uri = helper.buildZuulRequestURI(request); - - assertThat(uri).isEqualTo(encodedRequestURI); - } - - @Test - public void getDefaultEncodingUrl() { - String requestURI = "/oléדרעק"; - String encodedRequestURI = "/ol%E9%3F%3F%3F%3F"; - MockHttpServletRequest request = new MockHttpServletRequest("GET", requestURI); - - RequestContext context = RequestContext.getCurrentContext(); - context.set(REQUEST_URI_KEY, requestURI); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - String uri = helper.buildZuulRequestURI(request); - - assertThat(uri).isEqualTo(encodedRequestURI); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocatorTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocatorTests.java deleted file mode 100644 index 496d040d7..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocatorTests.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters; - -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -import org.springframework.boot.test.system.OutputCaptureRule; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.containsString; - -/** - * @author Tom Cawley - */ -public class SimpleRouteLocatorTests { - - @Rule - public OutputCaptureRule output = new OutputCaptureRule(); - - private ZuulProperties properties; - - public SimpleRouteLocatorTests() { - } - - @Before - public void init() { - properties = new ZuulProperties(); - } - - @Test - public void test_getRoutesDefaultRouteAcceptor() { - RouteLocator locator = new SimpleRouteLocator("/", this.properties); - this.properties.getRoutes().clear(); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo")); - - assertThat(locator.getRoutes()).contains(createRoute("foo", "/**", "/foo")); - } - - @Test - public void test_getRoutesFilterRouteAcceptor() { - RouteLocator locator = new FilteringRouteLocator("/", this.properties); - this.properties.getRoutes().clear(); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo")); - this.properties.getRoutes().put("bar", new ZuulRoute("/bar/**", "bar")); - - final List routes = locator.getRoutes(); - assertThat(routes).contains(createRoute("bar", "/**", "/bar")); - assertThat(routes).hasSize(1); - } - - @Test - public void testStripPrefix() { - properties.setPrefix("/test"); - properties.setStripPrefix(true); - RouteLocator locator = new FilteringRouteLocator("/", properties); - properties.getRoutes().put("testservicea", - new ZuulRoute("/testservicea/**", "testservicea")); - assertThat(locator.getRoutes().get(0).getFullPath()) - .isEqualTo("/test/testservicea/**"); - } - - @Test - public void testPrefix() { - properties.setPrefix("/test/"); - RouteLocator locator = new FilteringRouteLocator("/", properties); - properties.getRoutes().put("testservicea", - new ZuulRoute("/testservicea/**", "testservicea")); - assertThat(locator.getRoutes().get(0).getFullPath()) - .isEqualTo("/test/testservicea/**"); - } - - @Test - public void test_getMatchingRouteFilterRouteAcceptor() { - RouteLocator locator = new FilteringRouteLocator("/", this.properties); - this.properties.getRoutes().clear(); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo")); - this.properties.getRoutes().put("bar", new ZuulRoute("/bar/**", "bar")); - - assertThat(locator.getMatchingRoute("/foo/1")).isNull(); - assertThat(locator.getMatchingRoute("/bar/1")) - .isEqualTo(createRoute("bar", "/1", "/bar")); - } - - @Test - public void testBadRegex() { - this.properties.getRoutes().clear(); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo{}/**", "foo")); - RouteLocator locator = new FilteringRouteLocator("/", this.properties); - locator.getRoutes(); - - this.output.expect(containsString("Invalid route, ")); - - } - - private Route createRoute(String id, String path, String prefix) { - return new Route(id, path, id, prefix, false, null); - } - - private static class FilteringRouteLocator extends SimpleRouteLocator { - - FilteringRouteLocator(String servletPath, ZuulProperties properties) { - super(servletPath, properties); - } - - @Override - public List getRoutes() { - return super.getRoutes().stream().filter(this::acceptRoute) - .collect(Collectors.toList()); - } - - private boolean acceptRoute(Route route) { - return route != null && !(route.getId().equals("foo")); - } - - private boolean acceptRoute(ZuulRoute route) { - return route != null && !(route.getId().equals("foo")); - } - - protected Route getRoute(ZuulRoute route, String path) { - if (acceptRoute(route)) { - return super.getRoute(route, path); - } - return null; - } - - // For testing, expose as public so we can call getRoutesMap() directly. - @Override - public Map getRoutesMap() { - return super.getRoutesMap(); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/ZuulPropertiesTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/ZuulPropertiesTests.java deleted file mode 100644 index 4143130c7..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/ZuulPropertiesTests.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters; - -import java.util.Arrays; -import java.util.Collections; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * @author Mathias Düsterhöft - */ -public class ZuulPropertiesTests { - - private ZuulProperties zuul; - - @Before - public void setup() { - this.zuul = new ZuulProperties(); - } - - @After - public void teardown() { - this.zuul = null; - } - - @Test - public void defaultIgnoredHeaders() { - assertThat(this.zuul.isIgnoreSecurityHeaders()).isTrue(); - assertThat(this.zuul.getIgnoredHeaders()) - .containsAll(ZuulProperties.SECURITY_HEADERS); - } - - @Test - public void securityHeadersNotIgnored() { - zuul.setIgnoreSecurityHeaders(false); - - assertThat(this.zuul.getIgnoredHeaders().isEmpty()).isTrue(); - } - - @Test - public void addIgnoredHeaders() { - this.zuul.setIgnoredHeaders(Collections.singleton("x-foo")); - assertThat(this.zuul.getIgnoredHeaders().contains("x-foo")).isTrue(); - } - - @Test - public void defaultSensitiveHeaders() { - ZuulRoute route = new ZuulRoute("foo"); - this.zuul.getRoutes().put("foo", route); - assertThat(this.zuul.getRoutes().get("foo").getSensitiveHeaders().isEmpty()) - .isTrue(); - assertThat(this.zuul.getSensitiveHeaders() - .containsAll(Arrays.asList("Cookie", "Set-Cookie", "Authorization"))) - .isTrue(); - assertThat(route.isCustomSensitiveHeaders()).isFalse(); - } - - @Test - public void addSensitiveHeaders() { - this.zuul.setSensitiveHeaders(Collections.singleton("x-bar")); - ZuulRoute route = new ZuulRoute("foo"); - route.setSensitiveHeaders(Collections.singleton("x-foo")); - this.zuul.getRoutes().put("foo", route); - ZuulRoute foo = this.zuul.getRoutes().get("foo"); - assertThat(foo.getSensitiveHeaders().contains("x-foo")).isTrue(); - assertThat(foo.getSensitiveHeaders().contains("Cookie")).isFalse(); - assertThat(foo.isCustomSensitiveHeaders()).isTrue(); - assertThat(this.zuul.getSensitiveHeaders().contains("x-bar")).isTrue(); - assertThat(this.zuul.getSensitiveHeaders().contains("Cookie")).isFalse(); - } - - @Test - public void createWithSensitiveHeaders() { - this.zuul.setSensitiveHeaders(Collections.singleton("x-bar")); - ZuulRoute route = new ZuulRoute("foo", "/path", "foo", "/path", false, false, - Collections.singleton("x-foo")); - this.zuul.getRoutes().put("foo", route); - ZuulRoute foo = this.zuul.getRoutes().get("foo"); - assertThat(foo.getSensitiveHeaders().contains("x-foo")).isTrue(); - assertThat(foo.getSensitiveHeaders().contains("Cookie")).isFalse(); - assertThat(foo.isCustomSensitiveHeaders()).isTrue(); - assertThat(this.zuul.getSensitiveHeaders().contains("x-bar")).isTrue(); - assertThat(this.zuul.getSensitiveHeaders().contains("Cookie")).isFalse(); - } - - @Test - public void defaultHystrixThreadPool() { - assertThat(this.zuul.getThreadPool().isUseSeparateThreadPools()).isFalse(); - assertThat(this.zuul.getThreadPool().getThreadPoolKeyPrefix()).isEqualTo(""); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/DiscoveryClientRouteLocatorTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/DiscoveryClientRouteLocatorTests.java deleted file mode 100644 index b91065f20..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/DiscoveryClientRouteLocatorTests.java +++ /dev/null @@ -1,751 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.discovery; - -import java.net.URI; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; - -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; -import org.springframework.cloud.netflix.zuul.util.RequestUtils; -import org.springframework.core.env.ConfigurableEnvironment; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.MockitoAnnotations.initMocks; - -/** - * @author Spencer Gibb - * @author Dave Syer - */ -public class DiscoveryClientRouteLocatorTests { - - public static final String IGNOREDSERVICE = "ignoredservice"; - - public static final String IGNOREDPATTERN = "/foo/**"; - - public static final String ASERVICE = "aservice"; - - public static final String MYSERVICE = "myservice"; - - @Mock - private ConfigurableEnvironment env; - - @Mock - private DiscoveryClient discovery; - - private ZuulProperties properties = new ZuulProperties(); - - private RegexMapper regexMapper = new RegexMapper(); - - @Before - public void init() { - initMocks(this); - setTestRequestcontext(); // re-initialize Zuul context for each test - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void testGetMatchingPath() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getId()).isEqualTo("foo"); - } - - @Test - public void testGetMatchingPathWithPrefix() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - this.properties.setPrefix("/proxy"); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/1"); - } - - @Test - public void testGetMatchingPathWithServletPath() throws Exception { - setTestRequestcontext(); - RequestContext.getCurrentContext().set(RequestUtils.IS_DISPATCHERSERVLETREQUEST, - true); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/app", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/app/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/1"); - } - - @Test - public void testGetMatchingPathWithZuulServletPath() throws Exception { - RequestContext.getCurrentContext().setZuulEngineRan(); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/app", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/zuul/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/1"); - - } - - @Test - public void testGetMatchingPathWithNoPrefixStripping() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setStripPrefix(false); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/proxy/foo/1"); - } - - @Test - public void testGetMatchingPathWithLocalPrefixStripping() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo")); - this.properties.setStripPrefix(false); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/proxy/1"); - } - - @Test - public void testGetMatchingPathWithGlobalPrefixStripping() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/foo/1"); - } - - @Test - public void testGetMatchingPathWithGlobalPrefixStrippingAndServletPath() - throws Exception { - RequestContext.getCurrentContext().set(RequestUtils.IS_DISPATCHERSERVLETREQUEST, - true); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/app", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/app/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/foo/1"); - } - - @Test - public void testGetMatchingPathWithGlobalPrefixStrippingAndZuulServletPath() - throws Exception { - RequestContext.getCurrentContext().setZuulEngineRan(); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/zuul/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/foo/1"); - } - - @Test - public void testGetMatchingPathWithRoutePrefixStripping() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - ZuulRoute zuulRoute = new ZuulRoute("/foo/**"); - zuulRoute.setStripPrefix(true); - this.properties.getRoutes().put("foo", zuulRoute); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/1"); - } - - @Test - public void testGetMatchingPathWithoutMatchingIgnoredPattern() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("bar", new ZuulRoute("/bar/**")); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/bar/1"); - assertThat(route.getLocation()).isEqualTo("bar"); - assertThat(route.getId()).isEqualTo("bar"); - } - - @Test - public void testGetMatchingPathWithMatchingIgnoredPattern() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/foo/1"); - assertThat(route).as("routes did not ignore " + IGNOREDPATTERN).isNull(); - } - - @Test - public void testGetMatchingPathWithMatchingIgnoredPatternWithPrefix() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - this.properties.setPrefix("/proxy"); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/1"); - } - - @Test - public void testGetMatchingPathWithMatchingIgnoredPatternWithServletPath() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/app", - this.discovery, this.properties); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/app/foo/1"); - assertThat(route).as("routes did not ignore " + IGNOREDPATTERN).isNull(); - } - - @Test - public void testGetMatchingPathWithoutMatchingIgnoredPatternWithNoPrefixStripping() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setStripPrefix(false); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/proxy/foo/1"); - } - - @Test - public void testGetMatchingPathWithMatchingIgnoredPatternWithNoPrefixStripping() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties - .setIgnoredPatterns(Collections.singleton("/proxy" + IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setStripPrefix(false); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route).as("routes did not ignore " + "/proxy" + IGNOREDPATTERN) - .isNull(); - } - - @Test - public void testGetMatchingPathWithoutMatchingIgnoredPatternWithLocalPrefixStripping() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo")); - this.properties.setStripPrefix(false); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/proxy/1"); - } - - @Test - public void testGetMatchingPathWithMatchingIgnoredPatternWithLocalPrefixStripping() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties - .setIgnoredPatterns(Collections.singleton("/proxy" + IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo")); - this.properties.setStripPrefix(false); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route).as("routes did not ignore " + "/proxy" + IGNOREDPATTERN) - .isNull(); - } - - @Test - public void testGetMatchingPathWithoutMatchingIgnoredPatternWithGlobalPrefixStripping() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/foo/1"); - } - - @Test - public void testGetMatchingPathWithMatchingIgnoredPatternWithGlobalPrefixStripping() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties - .setIgnoredPatterns(Collections.singleton("/proxy" + IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route).as("routes did not ignore " + "/proxy" + IGNOREDPATTERN) - .isNull(); - } - - @Test - public void testGetMatchingPathWithMatchingIgnoredPatternWithRoutePrefixStripping() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - ZuulRoute zuulRoute = new ZuulRoute("/foo/**"); - zuulRoute.setStripPrefix(true); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", zuulRoute); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/foo/1"); - assertThat(route).as("routes did not ignore " + IGNOREDPATTERN).isNull(); - } - - @Test - public void testGetRoutes() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/" + ASERVICE + "/**")); - this.properties.init(); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertMapping(routesMap, ASERVICE); - } - - @Test - public void testGetRoutesWithMapping() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put(ASERVICE, - new ZuulRoute("/" + ASERVICE + "/**", ASERVICE)); - this.properties.setPrefix("/foo"); - - List routesMap = routeLocator.getRoutes(); - assertMapping(routesMap, ASERVICE, "foo/" + ASERVICE); - } - - @Test - public void testGetPhysicalRoutes() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put(ASERVICE, - new ZuulRoute("/" + ASERVICE + "/**", "http://" + ASERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertMapping(routesMap, "http://" + ASERVICE, ASERVICE); - } - - @Test - public void testGetDefaultRoute() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/**", ASERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertDefaultMapping(routesMap, ASERVICE); - } - - @Test - public void testGetDefaultPhysicalRoute() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put(ASERVICE, - new ZuulRoute("/**", "http://" + ASERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertDefaultMapping(routesMap, "http://" + ASERVICE); - } - - @Test - public void testIgnoreRoutes() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredServices(Collections.singleton(IGNOREDSERVICE)); - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(IGNOREDSERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(getRoute(routesMap, getMapping(IGNOREDSERVICE))) - .as("routes did not ignore " + IGNOREDSERVICE).isNull(); - } - - @Test - public void testIgnoreRoutesWithPattern() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredServices(Collections.singleton("ignore*")); - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(IGNOREDSERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(getRoute(routesMap, getMapping(IGNOREDSERVICE))) - .as("routes did not ignore " + IGNOREDSERVICE).isNull(); - } - - @Test - public void testIgnoreAllRoutes() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredServices(Collections.singleton("*")); - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(IGNOREDSERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(getRoute(routesMap, getMapping(IGNOREDSERVICE))) - .as("routes did not ignore " + IGNOREDSERVICE).isNull(); - } - - @Test - public void testIgnoredRouteIncludedIfConfiguredAndDiscovered() { - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredServices(Collections.singleton("*")); - given(this.discovery.getServices()).willReturn(Collections.singletonList("foo")); - List routesMap = routeLocator.getRoutes(); - assertThat(getRoute(routesMap, "/foo/**")).as("routes ignored foo").isNotNull(); - } - - @Test - public void testIgnoredRoutePropertiesRemain() { - ZuulRoute route = new ZuulRoute("/foo/**"); - route.setStripPrefix(true); - route.setRetryable(Boolean.TRUE); - this.properties.getRoutes().put("foo", route); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredServices(Collections.singleton("*")); - given(this.discovery.getServices()).willReturn(Collections.singletonList("foo")); - LinkedHashMap routes = routeLocator.locateRoutes(); - ZuulRoute actual = routes.get("/foo/**"); - assertThat(actual).as("routes ignored foo").isNotNull(); - assertThat(actual.isStripPrefix()).as("stripPrefix is wrong").isTrue(); - assertThat(actual.getRetryable()).as("retryable is wrong") - .isEqualTo(Boolean.TRUE); - } - - @Test - public void testIgnoredRouteNonServiceIdPathRemains() { - // This is how you setup a route defined like zuul.proxy.route.foo=/** - ZuulRoute route = new ZuulRoute("/**", "foo"); - route.setId("foo"); - - this.properties.getRoutes().put("foo", route); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredServices(Collections.singleton("*")); - given(this.discovery.getServices()).willReturn(Collections.singletonList("foo")); - LinkedHashMap routes = routeLocator.locateRoutes(); - ZuulRoute actual = routes.get("/**"); - assertThat(actual).as("routes ignored foo").isNotNull(); - assertThat(actual.getId()).as("id is wrong").isEqualTo("foo"); - assertThat(actual.getServiceId()).as("location is wrong").isEqualTo("foo"); - assertThat(actual.getPath()).as("path is wrong").isEqualTo("/**"); - } - - @Test - public void testIgnoredRouteIncludedIfConfiguredAndNotDiscovered() { - this.properties.getRoutes().put("foo", - new ZuulRoute("/foo/**", "http://www.foo.com/")); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredServices(Collections.singleton("*")); - given(this.discovery.getServices()).willReturn(Collections.singletonList("bar")); - List routesMap = routeLocator.getRoutes(); - assertThat(getRoute(routesMap, getMapping("foo"))).as("routes ignored foo") - .isNotNull(); - } - - @Test - public void testAutoRoutes() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(MYSERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertMapping(routesMap, MYSERVICE); - } - - @Test - public void testAutoRoutesCanBeOverridden() { - ZuulRoute route = new ZuulRoute("/" + MYSERVICE + "/**", - "https://example.com/" + MYSERVICE); - this.properties.getRoutes().put(MYSERVICE, route); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(MYSERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertMapping(routesMap, "https://example.com/" + MYSERVICE, MYSERVICE); - } - - @Test - public void testIgnoredLocalServiceByDefault() { - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(MYSERVICE)); - Registration registration = new Registration() { - @Override - public String getServiceId() { - return MYSERVICE; - } - - @Override - public String getHost() { - return "localhost"; - } - - @Override - public int getPort() { - return 80; - } - - @Override - public boolean isSecure() { - return false; - } - - @Override - public URI getUri() { - return null; - } - - @Override - public Map getMetadata() { - return null; - } - }; - - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties, registration); - - LinkedHashMap routes = routeLocator.locateRoutes(); - ZuulRoute actual = routes.get("/**"); - assertThat(actual).as("routes didn't ignore " + MYSERVICE).isNull(); - - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isTrue(); - } - - @Test - public void testIgnoredLocalServiceFalse() { - this.properties.setIgnoreLocalService(false); - - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(MYSERVICE)); - - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertMapping(routesMap, MYSERVICE); - } - - @Test - public void testLocalServiceExceptionIgnored() { - given(this.discovery.getServices()).willReturn(Collections.emptyList()); - - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties, (Registration) null); - - // if no exception is thrown in constructor, this is a success - routeLocator.locateRoutes(); - } - - @Test - public void testRegExServiceRouteMapperNoServiceIdMatches() { - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(MYSERVICE)); - - PatternServiceRouteMapper regExServiceRouteMapper = new PatternServiceRouteMapper( - this.regexMapper.getServicePattern(), this.regexMapper.getRoutePattern()); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties, regExServiceRouteMapper); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertMapping(routesMap, MYSERVICE); - } - - @Test - public void testRegExServiceRouteMapperServiceIdMatches() { - given(this.discovery.getServices()) - .willReturn(Collections.singletonList("rest-service-v1")); - - PatternServiceRouteMapper regExServiceRouteMapper = new PatternServiceRouteMapper( - this.regexMapper.getServicePattern(), this.regexMapper.getRoutePattern()); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties, regExServiceRouteMapper); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertMapping(routesMap, "rest-service-v1", "v1/rest-service"); - } - - protected void assertMapping(List routesMap, String serviceId) { - assertMapping(routesMap, serviceId, serviceId); - } - - protected void assertMapping(List routesMap, String expectedRoute, - String key) { - String mapping = getMapping(key); - Route route = getRoute(routesMap, mapping); - assertThat(route).as("Could not find route for " + key).isNotNull(); - String location = route.getLocation(); - assertThat(location).as("routesMap had wrong value for " + mapping) - .isEqualTo(expectedRoute); - } - - private String getMapping(String serviceId) { - return "/" + serviceId + "/**"; - } - - protected void assertDefaultMapping(List routesMap, String expectedRoute) { - String mapping = "/**"; - String route = getRoute(routesMap, mapping).getLocation(); - assertThat(route).as("routesMap had wrong value for " + mapping) - .isEqualTo(expectedRoute); - } - - private Route getRoute(List routes, String path) { - for (Route route : routes) { - String pattern = route.getFullPath(); - if (path.equals(pattern)) { - return route; - } - } - return null; - } - - private void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - public static class RegexMapper { - - private boolean enabled = false; - - private String servicePattern = "(?.*)-(?v.*$)"; - - private String routePattern = "${version}/${name}"; - - public RegexMapper() { - } - - public RegexMapper(boolean enabled, String servicePattern, String routePattern) { - this.enabled = enabled; - this.servicePattern = servicePattern; - this.routePattern = routePattern; - } - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public String getServicePattern() { - return servicePattern; - } - - public void setServicePattern(String servicePattern) { - this.servicePattern = servicePattern; - } - - public String getRoutePattern() { - return routePattern; - } - - public void setRoutePattern(String routePattern) { - this.routePattern = routePattern; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapperIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapperIntegrationTests.java deleted file mode 100644 index 455953246..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapperIntegrationTests.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.discovery; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.RoutesEndpoint; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Stéphane Leroy - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=regex-test-application", - "spring.jmx.enabled=false", "eureka.client.enabled=false", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class PatternServiceRouteMapperIntegrationTests { - - protected static final String SERVICE_ID = "domain-service-v1"; - - @LocalServerPort - private int port; - - @Autowired - private DiscoveryClientRouteLocator routes; - - @Autowired - private RoutesEndpoint endpoint; - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void getRegexMappedService() { - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/v1/domain/service/get/1", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Get 1"); - } - - @Test - public void getStaticRoute() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/get/1", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Get 1"); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @RibbonClient(value = SERVICE_ID, - configuration = SimpleRibbonClientConfiguration.class) - @Import(NoSecurityConfiguration.class) - protected static class SampleCustomZuulProxyApplication { - - @Bean - public DiscoveryClient discoveryClient() { - DiscoveryClient discoveryClient = mock(DiscoveryClient.class); - List services = new ArrayList<>(); - services.add(SERVICE_ID); - when(discoveryClient.getServices()).thenReturn(services); - return discoveryClient; - } - - @RequestMapping(value = "/get/{id}", method = RequestMethod.GET) - public String get(@PathVariable String id) { - return "Get " + id; - } - - @Bean - public PatternServiceRouteMapper serviceRouteMapper() { - return new PatternServiceRouteMapper( - "(?^.+)-(?.+)-(?v.+$)", - "${version}/${domain}/${name}"); - } - - } - - protected static class SimpleRibbonClientConfiguration { - - @LocalServerPort - private int port = 0; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapperTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapperTests.java deleted file mode 100644 index 6c6100d2f..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapperTests.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2015-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.discovery; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Stéphane Leroy - */ -public class PatternServiceRouteMapperTests { - - /** - * Service pattern that follow convention {domain}-{name}-{version}. The name is - * optional - */ - public static final String SERVICE_PATTERN = "(?^\\w+)(-(?\\w+)-|-)(?v\\d+$)"; - - public static final String ROUTE_PATTERN = "${version}/${domain}/${name}"; - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void test_return_mapped_route_if_serviceid_matches() { - PatternServiceRouteMapper toTest = new PatternServiceRouteMapper(SERVICE_PATTERN, - ROUTE_PATTERN); - - assertThat(toTest.apply("rest-service-v1")).as("service version convention") - .isEqualTo("v1/rest/service"); - } - - @Test - public void test_return_serviceid_if_no_matches() { - PatternServiceRouteMapper toTest = new PatternServiceRouteMapper(SERVICE_PATTERN, - ROUTE_PATTERN); - - // No version here - assertThat(toTest.apply("rest-service")).as("No matches for this service id") - .isEqualTo("rest-service"); - } - - @Test - public void test_route_should_be_cleaned_before_returned() { - // Messy patterns - PatternServiceRouteMapper toTest = new PatternServiceRouteMapper( - SERVICE_PATTERN + "(?.)?", - "/${version}/${nevermatch}/${domain}/${name}/"); - assertThat(toTest.apply("domain-service-v1")).as("No matches for this service id") - .isEqualTo("v1/domain/service"); - assertThat(toTest.apply("domain-v1")).as("No matches for this service id") - .isEqualTo("v1/domain"); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilterIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilterIntegrationTests.java deleted file mode 100644 index 755343e34..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilterIntegrationTests.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.post; - -import java.util.List; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.context.RequestContext; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestMapping; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Biju Kunjummen - */ - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { "zuul.routes.aservice.path:/service/**", - "zuul.routes.aservice.strip-prefix:true", "eureka.client.enabled:false" }) -@DirtiesContext -public class LocationRewriteFilterIntegrationTests { - - @LocalServerPort - private int port; - - @Before - public void before() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @Test - public void testWithRedirectPrefixStripped() { - String url = "http://localhost:" + port + "/service/redirectingUri"; - ResponseEntity response = new TestRestTemplate().getForEntity(url, - String.class); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.FOUND); - List locationHeaders = response.getHeaders().get("Location"); - - assertThat(locationHeaders).hasSize(1); - String locationHeader = locationHeaders.get(0); - assertThat(locationHeader).withFailMessage("Location should have prefix") - .isEqualTo( - String.format("http://localhost:%d/service/redirectedUri", port)); - - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableZuulProxy - @Controller - @RibbonClient(name = "aservice", configuration = RibbonConfig.class) - @Import(NoSecurityConfiguration.class) - protected static class Config { - - @RequestMapping("/redirectingUri") - public String redirect1() { - return "redirect:/redirectedUri"; - } - - @Bean - public LocationRewriteFilter locationRewriteFilter() { - return new LocationRewriteFilter(); - } - - } - - public static class RibbonConfig { - - @LocalServerPort - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilterTests.java deleted file mode 100644 index f80eb1334..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilterTests.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.post; - -import java.util.Collections; - -import com.netflix.util.Pair; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * @author Biju Kunjummen - */ - -public class LocationRewriteFilterTests { - - private final String ZUUL_HOST = "myzuul.com"; - - private final String ZUUL_SCHEME = "https"; - - private final int ZUUL_PORT = 8443; - - private final String ZUUL_BASE_URL = String.format("%s://%s:%d", ZUUL_SCHEME, - ZUUL_HOST, ZUUL_PORT); - - private final String SERVER_HOST = "someserver.com"; - - private final String SERVER_SCHEME = "http"; - - private final int SERVER_PORT = 8564; - - private final String SERVER_BASE_URL = String.format("%s://%s:%d", SERVER_SCHEME, - SERVER_HOST, SERVER_PORT); - - @Before - public void before() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void reset() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void shouldRewriteLocationHeadersWithRoutePrefix() { - RequestContext context = RequestContext.getCurrentContext(); - ZuulProperties zuulProperties = new ZuulProperties(); - LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties, - new Route("service1", "/redirectingUri", "service1", "prefix", false, - Collections.EMPTY_SET, true), - "/prefix/redirectingUri", "/redirectedUri;someparam?param1=abc"); - filter.run(); - assertThat(getLocationHeader(context).second()).isEqualTo(String - .format("%s/prefix/redirectedUri;someparam?param1=abc", ZUUL_BASE_URL)); - } - - @Test - public void shouldBeUntouchedIfNoRoutesFound() { - RequestContext context = RequestContext.getCurrentContext(); - ZuulProperties zuulProperties = new ZuulProperties(); - LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties, null, - "/prefix/redirectingUri", "/redirectedUri;someparam?param1=abc"); - filter.run(); - assertThat(getLocationHeader(context).second()).isEqualTo( - String.format("%s/redirectedUri;someparam?param1=abc", SERVER_BASE_URL)); - } - - @Test - public void shouldRewriteLocationHeadersIfPrefixIsNotStripped() { - RequestContext context = RequestContext.getCurrentContext(); - ZuulProperties zuulProperties = new ZuulProperties(); - LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties, - new Route("service1", "/something/redirectingUri", "service1", "prefix", - false, Collections.EMPTY_SET, false), - "/prefix/redirectingUri", - "/something/redirectedUri;someparam?param1=abc"); - filter.run(); - assertThat(getLocationHeader(context).second()).isEqualTo(String.format( - "%s/something/redirectedUri;someparam?param1=abc", ZUUL_BASE_URL)); - } - - @Test - public void shouldRewriteLocationHeadersIfPrefixIsEmpty() { - RequestContext context = RequestContext.getCurrentContext(); - ZuulProperties zuulProperties = new ZuulProperties(); - LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties, - new Route("service1", "/something/redirectingUri", "service1", "", false, - Collections.EMPTY_SET, true), - "/redirectingUri", "/something/redirectedUri;someparam?param1=abc"); - filter.run(); - assertThat(getLocationHeader(context).second()).isEqualTo(String.format( - "%s/something/redirectedUri;someparam?param1=abc", ZUUL_BASE_URL)); - } - - @Test - public void shouldAddBackGlobalPrefixIfPresent() { - RequestContext context = RequestContext.getCurrentContext(); - ZuulProperties zuulProperties = new ZuulProperties(); - zuulProperties.setPrefix("global"); - zuulProperties.setStripPrefix(true); - LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties, - new Route("service1", "/something/redirectingUri", "service1", "prefix", - false, Collections.EMPTY_SET, true), - "/global/prefix/redirectingUri", - "/something/redirectedUri;someparam?param1=abc"); - filter.run(); - assertThat(getLocationHeader(context).second()).isEqualTo(String.format( - "%s/global/prefix/something/redirectedUri;someparam?param1=abc", - ZUUL_BASE_URL)); - } - - @Test - public void shouldNotAddBackGlobalPrefixIfNotStripped() { - RequestContext context = RequestContext.getCurrentContext(); - ZuulProperties zuulProperties = new ZuulProperties(); - zuulProperties.setPrefix("global"); - zuulProperties.setStripPrefix(false); - LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties, - new Route("service1", "/something/redirectingUri", "service1", "prefix", - false, Collections.EMPTY_SET, true), - "/global/prefix/redirectingUri", - "/global/something/redirectedUri;someparam?param1=abc"); - filter.run(); - assertThat(getLocationHeader(context).second()).isEqualTo(String.format( - "%s/global/prefix/something/redirectedUri;someparam?param1=abc", - ZUUL_BASE_URL)); - } - - private LocationRewriteFilter setFilterUpWith(RequestContext context, - ZuulProperties zuulProperties, Route route, String toZuulRequestUri, - String redirectedUri) { - MockHttpServletRequest httpServletRequest = new MockHttpServletRequest(); - httpServletRequest.setRequestURI(toZuulRequestUri); - httpServletRequest.setServerName(ZUUL_HOST); - httpServletRequest.setScheme(ZUUL_SCHEME); - httpServletRequest.setServerPort(ZUUL_PORT); - context.setRequest(httpServletRequest); - - MockHttpServletResponse httpServletResponse = new MockHttpServletResponse(); - context.getZuulResponseHeaders().add(new Pair<>("Location", - String.format("%s%s", SERVER_BASE_URL, redirectedUri))); - context.setResponse(httpServletResponse); - - RouteLocator routeLocator = mock(RouteLocator.class); - when(routeLocator.getMatchingRoute(toZuulRequestUri)).thenReturn(route); - LocationRewriteFilter filter = new LocationRewriteFilter(zuulProperties, - routeLocator); - - return filter; - } - - private Pair getLocationHeader(RequestContext ctx) { - if (ctx.getZuulResponseHeaders() != null) { - for (Pair pair : ctx.getZuulResponseHeaders()) { - if (pair.first().equals("Location")) { - return pair; - } - } - } - return null; - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterIntegrationTests.java deleted file mode 100644 index 20a1b64eb..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterIntegrationTests.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.post; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.MockClock; -import io.micrometer.core.instrument.simple.SimpleConfig; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest(properties = "zuul.routes.filtertest:/filtertest/**", - webEnvironment = RANDOM_PORT) -@DirtiesContext -public class SendErrorFilterIntegrationTests { - - @Autowired - private MeterRegistry meterRegistry; - - @LocalServerPort - private int port; - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void testPreFails() { - String url = "http://localhost:" + port + "/filtertest/get?failpre=true"; - ResponseEntity response = new TestRestTemplate().getForEntity(url, - String.class); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - - assertMetrics("pre"); - } - - private void assertMetrics(String filterType) { - Double count = meterRegistry.counter("ZUUL::EXCEPTION:" + filterType + "::500") - .count(); - assertThat(count.longValue()).isEqualTo(1L); - count = meterRegistry.counter("ZUUL::EXCEPTION:null:500").count(); - assertThat(count.longValue()).isEqualTo(0L); - } - - @Test - public void testRouteFails() { - String url = "http://localhost:" + port + "/filtertest/get?failroute=true"; - ResponseEntity response = new TestRestTemplate().getForEntity(url, - String.class); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - - assertMetrics("route"); - } - - @Test - public void testPostFails() { - String url = "http://localhost:" + port + "/filtertest/get?failpost=true"; - ResponseEntity response = new TestRestTemplate().getForEntity(url, - String.class); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - - // FIXME: 2.1.0 assertMetrics("post"); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableZuulProxy - @RestController - @RibbonClient(name = "filtertest", configuration = RibbonConfig.class) - @Import(NoSecurityConfiguration.class) - protected static class Config { - - @RequestMapping("/get") - public String get() { - return "Hello"; - } - - @Bean - public ZuulFilter testPreFilter() { - return new FailureFilter() { - @Override - public String filterType() { - return PRE_TYPE; - } - }; - } - - @Bean - public ZuulFilter testRouteFilter() { - return new FailureFilter() { - @Override - public String filterType() { - return ROUTE_TYPE; - } - }; - } - - @Bean - public ZuulFilter testPostFilter() { - return new FailureFilter() { - @Override - public String filterType() { - return POST_TYPE; - } - }; - } - - @Bean - public MeterRegistry meterRegistry() { - return new SimpleMeterRegistry(SimpleConfig.DEFAULT, new MockClock()); - } - - } - - @Configuration(proxyBeanMethods = false) - private static class RibbonConfig { - - @LocalServerPort - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - - private abstract static class FailureFilter extends ZuulFilter { - - @Override - public int filterOrder() { - return Integer.MIN_VALUE; - } - - @Override - public boolean shouldFilter() { - HttpServletRequest request = RequestContext.getCurrentContext().getRequest(); - return request.getParameter("fail" + filterType()) != null; - } - - @Override - public Object run() { - HttpServletRequest request = RequestContext.getCurrentContext().getRequest(); - if (request.getParameter("fail" + filterType()) != null) { - throw new RuntimeException("failing on purpose in " + filterType()); - } - return null; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterTests.java deleted file mode 100644 index c3f18a477..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterTests.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.post; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.exception.ZuulException; -import com.netflix.zuul.monitoring.MonitoringHelper; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.http.HttpStatus; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * @author Spencer Gibb - */ -public class SendErrorFilterTests { - - @Before - public void setTestRequestcontext() { - MonitoringHelper.initMocks(); - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void reset() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void runsNormally() { - SendErrorFilter filter = createSendErrorFilter(new MockHttpServletRequest()); - assertThat(filter.shouldFilter()).as("shouldFilter returned false").isTrue(); - filter.run(); - } - - private SendErrorFilter createSendErrorFilter(HttpServletRequest request) { - RequestContext context = new RequestContext(); - context.setRequest(request); - context.setResponse(new MockHttpServletResponse()); - context.setThrowable(new ZuulException(new RuntimeException(), - HttpStatus.NOT_FOUND.value(), null)); - RequestContext.testSetCurrentContext(context); - SendErrorFilter filter = new SendErrorFilter(); - filter.setErrorPath("/error"); - return filter; - } - - @Test - public void noRequestDispatcher() { - SendErrorFilter filter = createSendErrorFilter(mock(HttpServletRequest.class)); - assertThat(filter.shouldFilter()).as("shouldFilter returned false").isTrue(); - filter.run(); - } - - @Test - public void doesNotRunTwice() { - SendErrorFilter filter = createSendErrorFilter(new MockHttpServletRequest()); - assertThat(filter.shouldFilter()).as("shouldFilter returned false").isTrue(); - filter.run(); - assertThat(filter.shouldFilter()).as("shouldFilter returned true").isFalse(); - } - - @Test - public void setResponseCode() { - SendErrorFilter filter = createSendErrorFilter(new MockHttpServletRequest()); - filter.run(); - - RequestContext ctx = RequestContext.getCurrentContext(); - int resCode = ctx.getResponse().getStatus(); - int ctxCode = ctx.getResponseStatusCode(); - - assertThat(resCode).as("invalid response code: " + resCode) - .isEqualTo(HttpStatus.NOT_FOUND.value()); - assertThat(ctxCode).as("invalid response code in RequestContext: " + ctxCode) - .isEqualTo(resCode); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilterTests.java deleted file mode 100644 index 1c29ae8ba..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilterTests.java +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.post; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.lang.reflect.UndeclaredThrowableException; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; - -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.netflix.zuul.constants.ZuulHeaders; -import com.netflix.zuul.context.Debug; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.http.HttpStatus; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.web.util.WebUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_ZUUL_DEBUG_HEADER; - -/** - * @author Spencer Gibb - */ -public class SendResponseFilterTests { - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - context.setRequest(new MockHttpServletRequest()); - context.setResponse(new MockHttpServletResponse()); - context.setResponseGZipped(false); - - RequestContext.testSetCurrentContext(context); - } - - @After - public void reset() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void runsNormally() throws Exception { - String characterEncoding = null; - String content = "hello"; - runFilter(characterEncoding, content, false); - } - - @Test - public void useServlet31Works() { - assertThat(new SendResponseFilter().isUseServlet31()).isTrue(); - } - - @Test - public void characterEncodingNotOverridden() throws Exception { - String characterEncoding = "UTF-16"; - String content = "\u00a5"; - runFilter(characterEncoding, content, true); - } - - @Test - public void runWithDebugHeader() throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setIncludeDebugHeader(true); - - SendResponseFilter filter = createFilter(properties, "hello", null, - new MockHttpServletResponse(), false); - Debug.addRoutingDebug("test"); - filter.run(); - - String debugHeader = RequestContext.getCurrentContext().getResponse() - .getHeader(X_ZUUL_DEBUG_HEADER); - assertThat(debugHeader).as("wrong debug header").isEqualTo("[[[test]]]"); - } - - /* - * GZip NOT requested and NOT a GZip response -> Content-Length forwarded asis - */ - @Test - public void runWithOriginContentLength() throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setSetContentLength(true); - - SendResponseFilter filter = createFilter(properties, "hello", null, - new MockHttpServletResponse(), false); - RequestContext.getCurrentContext().setOriginContentLength(6L); // for test - RequestContext.getCurrentContext().setResponseGZipped(false); - filter.run(); - - String contentLength = RequestContext.getCurrentContext().getResponse() - .getHeader("Content-Length"); - assertThat(contentLength).as("wrong origin content length").isEqualTo("6"); - } - - /* - * Unknown encoding requested and NOT a GZip response -> Content-Length forwarded asis - */ - @Test - public void runWithOriginContentLength_content_encoding_header() throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setSetContentLength(true); - - SendResponseFilter filter = createFilter(properties, "hello", null, - new MockHttpServletResponse(), false); - RequestContext.getCurrentContext().addZuulResponseHeader("Content-Encoding", - "unknown"); - RequestContext.getCurrentContext().setOriginContentLength(6L); // for test - RequestContext.getCurrentContext().setResponseGZipped(false); - filter.run(); - - MockHttpServletResponse response = (MockHttpServletResponse) RequestContext - .getCurrentContext().getResponse(); - assertThat(response.getHeader("Content-Length")).as("wrong origin content length") - .isEqualTo("6"); - assertThat(response.getHeader("Content-Encoding")).isEqualTo("unknown"); - } - - /* - * GZip requested and GZip response -> Content-Length forwarded asis, response - * compressed - */ - @Test - public void runWithOriginContentLength_gzipRequested_gzipResponse() throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setSetContentLength(true); - - SendResponseFilter filter = new SendResponseFilter(properties); - - byte[] gzipData = gzipData("hello"); - - RequestContext.getCurrentContext().setOriginContentLength((long) gzipData.length); // for - // test - RequestContext.getCurrentContext().setResponseGZipped(true); - RequestContext.getCurrentContext() - .setResponseDataStream(new ByteArrayInputStream(gzipData)); - ((MockHttpServletRequest) RequestContext.getCurrentContext().getRequest()) - .addHeader(ZuulHeaders.ACCEPT_ENCODING, "gzip"); - - filter.run(); - - MockHttpServletResponse response = (MockHttpServletResponse) RequestContext - .getCurrentContext().getResponse(); - assertThat(response.getHeader("Content-Length")) - .isEqualTo(Integer.toString(gzipData.length)); - assertThat(response.getHeader("Content-Encoding")).isEqualTo("gzip"); - assertThat(response.getContentAsByteArray()).isEqualTo(gzipData); - - BufferedReader reader = new BufferedReader( - new InputStreamReader(new GZIPInputStream( - new ByteArrayInputStream(response.getContentAsByteArray())))); - assertThat(reader.readLine()).isEqualTo("hello"); - } - - /* - * GZip NOT requested and GZip response -> Content-Length discarded and response - * uncompressed - */ - @Test - public void runWithOriginContentLength_gzipNotRequested_gzipResponse() - throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setSetContentLength(true); - - SendResponseFilter filter = new SendResponseFilter(properties); - - byte[] gzipData = gzipData("hello"); - - RequestContext.getCurrentContext().setOriginContentLength((long) gzipData.length); // for - // test - RequestContext.getCurrentContext().setResponseGZipped(true); - RequestContext.getCurrentContext() - .setResponseDataStream(new ByteArrayInputStream(gzipData)); - - filter.run(); - - MockHttpServletResponse response = (MockHttpServletResponse) RequestContext - .getCurrentContext().getResponse(); - assertThat(response.getHeader("Content-Length")).isNull(); - assertThat(response.getHeader("Content-Encoding")).isNull(); - assertThat(response.getContentAsString()).as("wrong content").isEqualTo("hello"); - } - - /* - * GZip NOT requested and GZip response -> Content-Length discarded and response - * uncompressed - */ - @Test - public void runWithOriginContentLength_gzipNotRequested_gzipResponse_content_encoding_header() - throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setSetContentLength(true); - - SendResponseFilter filter = new SendResponseFilter(properties); - - byte[] gzipData = gzipData("hello"); - - RequestContext.getCurrentContext().addZuulResponseHeader("Content-Encoding", - "gzip"); - RequestContext.getCurrentContext().setOriginContentLength((long) gzipData.length); // for - // test - RequestContext.getCurrentContext().setResponseGZipped(true); - RequestContext.getCurrentContext() - .setResponseDataStream(new ByteArrayInputStream(gzipData)); - - filter.run(); - - MockHttpServletResponse response = (MockHttpServletResponse) RequestContext - .getCurrentContext().getResponse(); - assertThat(response.getHeader("Content-Length")).isNull(); - assertThat(response.getHeader("Content-Encoding")).isNull(); - assertThat(response.getContentAsString()).as("wrong content").isEqualTo("hello"); - } - - /* - * Origin sends a non gzip response with Content-Encoding: gzip Request does not - * support GZIP -> filter fails to uncompress and send stream "asis". Content-Length - * is NOT preserved. - */ - @Test - public void invalidGzipResponseFromOrigin() throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setSetContentLength(true); - - SendResponseFilter filter = new SendResponseFilter(properties); - - byte[] gzipData = "hello".getBytes(); - - RequestContext.getCurrentContext().setOriginContentLength((long) gzipData.length); // for - // test - RequestContext.getCurrentContext().setResponseGZipped(true); // say it is GZipped - // although not - // the case - RequestContext.getCurrentContext() - .setResponseDataStream(new ByteArrayInputStream(gzipData)); - - filter.run(); - - MockHttpServletResponse response = (MockHttpServletResponse) RequestContext - .getCurrentContext().getResponse(); - assertThat(response.getHeader("Content-Length")).isNull(); - assertThat(response.getHeader("Content-Encoding")).isNull(); - assertThat(response.getContentAsString()).as("wrong content").isEqualTo("hello"); // response - // sent - // "asis" - } - - /* - * Empty response from origin with Content-Encoding: gzip Request does not support - * GZIP -> filter should not fail in decoding the *empty* response stream - */ - @Test - public void emptyGzipResponseFromOrigin() throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setSetContentLength(true); - - SendResponseFilter filter = new SendResponseFilter(properties); - - byte[] gzipData = new byte[] {}; - - RequestContext.getCurrentContext().setResponseGZipped(true); - RequestContext.getCurrentContext() - .setResponseDataStream(new ByteArrayInputStream(gzipData)); - - filter.run(); - - MockHttpServletResponse response = (MockHttpServletResponse) RequestContext - .getCurrentContext().getResponse(); - assertThat(response.getHeader("Content-Length")).isNull(); - assertThat(response.getHeader("Content-Encoding")).isNull(); - assertThat(response.getContentAsByteArray()).isEqualTo(gzipData); - } - - @Test - public void closeResponseOutputStreamError() throws Exception { - HttpServletResponse response = mock(HttpServletResponse.class); - InputStream mockStream = spy( - new ByteArrayInputStream("Hello\n".getBytes("UTF-8"))); - - RequestContext context = new RequestContext(); - context.setRequest(new MockHttpServletRequest()); - context.setResponse(response); - context.setResponseDataStream(mockStream); - context.setResponseGZipped(false); - Closeable zuulResponse = mock(Closeable.class); - context.set("zuulResponse", zuulResponse); - RequestContext.testSetCurrentContext(context); - - SendResponseFilter filter = new SendResponseFilter(); - - ServletOutputStream zuuloutputstream = mock(ServletOutputStream.class); - doThrow(new IOException("Response to client closed")).when(zuuloutputstream) - .write(isA(byte[].class), anyInt(), anyInt()); - - when(response.getOutputStream()).thenReturn(zuuloutputstream); - - try { - filter.run(); - } - catch (UndeclaredThrowableException ex) { - assertThat(ex.getUndeclaredThrowable().getMessage()) - .isEqualTo("Response to client closed"); - } - - verify(zuulResponse).close(); - verify(mockStream).close(); - } - - @Test - public void testCloseResponseDataStream() throws Exception { - HttpServletResponse response = mock(HttpServletResponse.class); - InputStream mockStream = spy( - new ByteArrayInputStream("Hello\n".getBytes("UTF-8"))); - - RequestContext context = new RequestContext(); - context.setRequest(new MockHttpServletRequest()); - context.setResponse(response); - context.setResponseDataStream(mockStream); - context.setResponseGZipped(false); - Closeable zuulResponse = mock(Closeable.class); - context.set("zuulResponse", zuulResponse); - RequestContext.testSetCurrentContext(context); - - when(response.getOutputStream()).thenReturn(mock(ServletOutputStream.class)); - - SendResponseFilter filter = new SendResponseFilter(); - - filter.run(); - - verify(mockStream).close(); - } - - private void runFilter(String characterEncoding, String content, - boolean streamContent) throws Exception { - MockHttpServletResponse response = new MockHttpServletResponse(); - SendResponseFilter filter = createFilter(content, characterEncoding, response, - streamContent); - assertThat(filter.shouldFilter()).as("shouldFilter returned false").isTrue(); - filter.run(); - String encoding = RequestContext.getCurrentContext().getResponse() - .getCharacterEncoding(); - String expectedEncoding = characterEncoding != null ? characterEncoding - : WebUtils.DEFAULT_CHARACTER_ENCODING; - assertThat(encoding).as("wrong character encoding").isEqualTo(expectedEncoding); - assertThat(response.getContentAsString()).as("wrong content").isEqualTo(content); - } - - private SendResponseFilter createFilter(String content, String characterEncoding, - MockHttpServletResponse response, boolean streamContent) throws Exception { - return createFilter(new ZuulProperties(), content, characterEncoding, response, - streamContent); - } - - private SendResponseFilter createFilter(ZuulProperties properties, String content, - String characterEncoding, MockHttpServletResponse response, - boolean streamContent) throws Exception { - HttpServletRequest request = new MockHttpServletRequest(); - RequestContext context = new RequestContext(); - context.setRequest(request); - context.setResponse(response); - - if (characterEncoding != null) { - response.setCharacterEncoding(characterEncoding); - } - - if (streamContent) { - context.setResponseDataStream( - new ByteArrayInputStream(content.getBytes(characterEncoding))); - } - else { - context.setResponseBody(content); - } - - context.setResponseGZipped(false); - context.set("error.status_code", HttpStatus.NOT_FOUND.value()); - RequestContext.testSetCurrentContext(context); - SendResponseFilter filter = new SendResponseFilter(properties); - return filter; - } - - private byte[] gzipData(String content) throws IOException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - PrintWriter gzip = new PrintWriter(new GZIPOutputStream(bos)); - gzip.print(content); - gzip.flush(); - gzip.close(); - - return bos.toByteArray(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilterTests.java deleted file mode 100644 index 054fe8eb0..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilterTests.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 2016-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.pre; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.http.Part; - -import com.netflix.zuul.context.RequestContext; -import org.apache.commons.io.IOUtils; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.mock.web.MockMultipartHttpServletRequest; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Michael Hartle - */ -public class FormBodyWrapperFilterTests { - - private FormBodyWrapperFilter filter; - - private MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest(); - - @Before - public void init() { - this.filter = new FormBodyWrapperFilter(); - RequestContext ctx = RequestContext.getCurrentContext(); - ctx.clear(); - ctx.setRequest(this.request); - } - - @Test - public void multiplePartNamesWithMultipleParts() - throws IOException, ServletException { - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - - final Map> firstPartHeaders = new HashMap<>(); - final byte[] firstPartBody = "{ \"u\" : 1 }".getBytes(); - final Part firstPart = new MockPart("a", "application/json", null, - firstPartHeaders, firstPartBody); - this.request.addPart(firstPart); - - final Map> secondPartHeaders = new HashMap<>(); - final byte[] secondPartBody = "%PDF...1".getBytes(); - final Part secondPart = new MockPart("b", "application/pdf", "document.pdf", - secondPartHeaders, secondPartBody); - this.request.addPart(secondPart); - - final Map> thirdPartHeaders = new HashMap<>(); - final byte[] thirdPartBody = "%PDF...2".getBytes(); - final Part thirdPart = new MockPart("c", "application/pdf", "attachment1.pdf", - thirdPartHeaders, thirdPartBody); - this.request.addPart(thirdPart); - - final Map> fourthPartHeaders = new HashMap<>(); - final byte[] fourthPartBody = "%PDF...3".getBytes(); - final Part fourthPart = new MockPart("c", "application/pdf", "attachment2.pdf", - fourthPartHeaders, fourthPartBody); - this.request.addPart(fourthPart); - - final Map> fifthPartHeaders = new HashMap<>(); - final byte[] fifthPartBody = "%PDF...4".getBytes(); - final Part fifthPart = new MockPart("c", "application/pdf", "attachment3.pdf", - fifthPartHeaders, fifthPartBody); - this.request.addPart(fifthPart); - - this.filter.run(); - - final RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getRequest().getRequestURI()).isEqualTo("/api/foo/1"); - assertThat(ctx.getRequest().getRemoteAddr()).isEqualTo("5.6.7.8"); - assertThat(ctx.getRequest().getParts().size()).isEqualTo(5); - - final Part[] parts = ctx.getRequest().getParts().toArray(new Part[0]); - assertThat(parts[0].getName()).isEqualTo("a"); - assertThat(parts[0].getSubmittedFileName()).isEqualTo(null); - assertThat(parts[0].getContentType()).isEqualTo("application/json"); - assertThat(IOUtils.toByteArray(parts[0].getInputStream())) - .isEqualTo(firstPartBody); - - assertThat(parts[1].getName()).isEqualTo("b"); - assertThat(parts[1].getSubmittedFileName()).isEqualTo("document.pdf"); - assertThat(parts[1].getContentType()).isEqualTo("application/pdf"); - assertThat(IOUtils.toByteArray(parts[1].getInputStream())) - .isEqualTo(secondPartBody); - - assertThat(parts[2].getName()).isEqualTo("c"); - assertThat(parts[2].getSubmittedFileName()).isEqualTo("attachment1.pdf"); - assertThat(parts[2].getContentType()).isEqualTo("application/pdf"); - assertThat(IOUtils.toByteArray(parts[2].getInputStream())) - .isEqualTo(thirdPartBody); - - assertThat(parts[3].getName()).isEqualTo("c"); - assertThat(parts[3].getSubmittedFileName()).isEqualTo("attachment2.pdf"); - assertThat(parts[3].getContentType()).isEqualTo("application/pdf"); - assertThat(IOUtils.toByteArray(parts[3].getInputStream())) - .isEqualTo(fourthPartBody); - - assertThat(parts[4].getName()).isEqualTo("c"); - assertThat(parts[4].getSubmittedFileName()).isEqualTo("attachment3.pdf"); - assertThat(parts[4].getContentType()).isEqualTo("application/pdf"); - assertThat(IOUtils.toByteArray(parts[4].getInputStream())) - .isEqualTo(fifthPartBody); - } - - private class MockPart implements Part { - - private final String name; - - private final String contentType; - - private final String submittedFileName; - - private final Map> headers; - - private final byte[] body; - - MockPart(final String name, final String contentType, - final String submittedFileName, final Map> headers, - final byte[] body) { - this.name = name; - this.contentType = contentType; - this.submittedFileName = submittedFileName; - this.headers = headers; - this.body = body; - } - - @Override - public InputStream getInputStream() throws IOException { - return new ByteArrayInputStream(this.body); - } - - @Override - public String getContentType() { - return this.contentType; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public String getSubmittedFileName() { - return this.submittedFileName; - } - - @Override - public long getSize() { - return this.body != null ? this.body.length : 0; - } - - @Override - public void write(String fileName) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public void delete() throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public String getHeader(String name) { - if (this.headers == null) { - return null; - } - - final List values = this.headers.get(name); - - if (values == null || values.size() == 0) { - return null; - } - - return values.get(0); - } - - @Override - public Collection getHeaders(String name) { - if (this.headers == null) { - return null; - } - - return this.headers.get(name); - } - - @Override - public Collection getHeaderNames() { - if (this.headers == null) { - return null; - } - - return this.headers.keySet(); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java deleted file mode 100755 index 5e325b6ca..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java +++ /dev/null @@ -1,711 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.pre; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import com.netflix.util.Pair; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; - -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.util.MultiValueMap; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_TO_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY; - -/** - * @author Dave Syer - */ -@RunWith(ModifiedClassPathRunner.class) -// This is needed for sensitiveHeadersOverrideEmpty, if Spring Security is on the -// classpath -// then sensitive headers will always be present. -@ClassPathExclusions({ "spring-security-*.jar" }) -public class PreDecorationFilterTests { - - private PreDecorationFilter filter; - - @Mock - private DiscoveryClient discovery; - - private ZuulProperties properties = new ZuulProperties(); - - private DiscoveryClientRouteLocator routeLocator; - - private MockHttpServletRequest request = new MockHttpServletRequest(); - - private ProxyRequestHelper proxyRequestHelper = new ProxyRequestHelper(); - - @Before - public void init() { - initMocks(this); - this.properties = new ZuulProperties(); - this.proxyRequestHelper = new ProxyRequestHelper(properties); - this.routeLocator = new DiscoveryClientRouteLocator("/", this.discovery, - this.properties); - this.filter = new PreDecorationFilter(this.routeLocator, "/", this.properties, - this.proxyRequestHelper); - RequestContext ctx = RequestContext.getCurrentContext(); - ctx.clear(); - ctx.setRequest(this.request); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void basicProperties() throws Exception { - assertThat(this.filter.filterOrder()).isEqualTo(5); - assertThat(this.filter.shouldFilter()).isEqualTo(true); - assertThat(this.filter.filterType()).isEqualTo(PRE_TYPE); - } - - @Test - public void skippedIfServiceIdSet() throws Exception { - RequestContext.getCurrentContext().set(SERVICE_ID_KEY, "myservice"); - assertThat(this.filter.shouldFilter()).isEqualTo(false); - } - - @Test - public void skippedIfForwardToSet() throws Exception { - RequestContext.getCurrentContext().set(FORWARD_TO_KEY, "myconteext"); - assertThat(this.filter.shouldFilter()).isEqualTo(false); - } - - @Test - public void xForwardedHostHasPort() throws Exception { - this.properties.setPrefix("/api"); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost:8080"); - } - - @Test - public void xForwardedHostAndProtoAppend() throws Exception { - this.properties.setPrefix("/api"); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.request.addHeader("X-Forwarded-Host", "example.com"); - this.request.addHeader("X-Forwarded-Proto", "https"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("example.com,localhost:8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")) - .isEqualTo("443,8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("https,http"); - } - - @Test - public void xForwardedHostOnlyAppends() throws Exception { - this.properties.setPrefix("/api"); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.request.addHeader("X-Forwarded-Host", "example.com"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("example.com,localhost:8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")).isEqualTo("8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - } - - @Test - public void xForwardedProtoOnlyAppends() throws Exception { - this.properties.setPrefix("/api"); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.request.addHeader("X-Forwarded-Proto", "https"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost:8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")) - .isEqualTo("443,8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("https,http"); - } - - @Test - public void xForwardedProtoHttpOnlyAppends() throws Exception { - this.properties.setPrefix("/api"); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.request.addHeader("X-Forwarded-Proto", "http"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost:8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")) - .isEqualTo("80,8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http,http"); - } - - @Test - public void xForwardedPortOnlyAppends() throws Exception { - this.properties.setPrefix("/api"); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.request.addHeader("X-Forwarded-Port", "456"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost:8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")) - .isEqualTo("456,8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - } - - @Test - public void xForwardedPortAndProtoAppends() throws Exception { - this.properties.setPrefix("/api"); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.request.addHeader("X-Forwarded-Proto", "https"); - this.request.addHeader("X-Forwarded-Port", "456"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost:8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")) - .isEqualTo("456,8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("https,http"); - } - - @Test - public void hostHeaderSet() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setAddHostHeader(true); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost:8080"); - assertThat(ctx.getZuulRequestHeaders().get("host")).isEqualTo("localhost:8080"); - } - - @Test - public void prefixRouteAddsHeader() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.addHeader("X-Forwarded-For", "1.2.3.4"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/foo/1"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")).isEqualTo("80"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-prefix")) - .isEqualTo("/api"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-for")) - .isEqualTo("1.2.3.4, 5.6.7.8"); - assertThat(getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")) - .isEqualTo("foo"); - } - - @Test - public void prefixRouteWithPrefixHeaderConcatsHeader() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.addHeader("X-Forwarded-For", "1.2.3.4"); - this.request.addHeader("X-Forwarded-Prefix", "/prefix"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/foo/1"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")).isEqualTo("80"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-prefix")) - .isEqualTo("/prefix/api"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-for")) - .isEqualTo("1.2.3.4, 5.6.7.8"); - assertThat(getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")) - .isEqualTo("foo"); - } - - @Test - public void routeWithContextPath() { - this.properties.setStripPrefix(false); - this.request.setRequestURI("/api/foo/1"); - this.request.setContextPath("/context-path"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/api/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/api/foo/1"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")).isEqualTo("80"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-prefix")) - .isEqualTo("/context-path"); - assertThat(getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")) - .isEqualTo("foo"); - } - - @Test - public void prefixRouteWithContextPath() { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.request.setRequestURI("/api/foo/1"); - this.request.setContextPath("/context-path"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/foo/1"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")).isEqualTo("80"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-prefix")) - .isEqualTo("/context-path/api"); - assertThat(getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")) - .isEqualTo("foo"); - } - - @Test - public void dontDecodeUrl() { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setDecodeUrl(false); - this.request.setRequestURI("/api/foo/encoded%2Fpath"); - this.request.setContextPath("/context-path"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter = new PreDecorationFilter(this.routeLocator, "/", this.properties, - this.proxyRequestHelper); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/foo/encoded%2Fpath"); - } - - @Test - public void routeIgnoreContextPathIfPrefixHeader() { - this.properties.setStripPrefix(false); - this.request.setRequestURI("/api/foo/1"); - this.request.setContextPath("/context-path"); - this.request.addHeader("X-Forwarded-Prefix", "/prefix"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/api/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/api/foo/1"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")).isEqualTo("80"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-prefix")) - .isEqualTo("/prefix"); - assertThat(getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")) - .isEqualTo("foo"); - } - - @Test - public void prefixRouteIgnoreContextPathIfPrefixHeader() { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.request.setRequestURI("/api/foo/1"); - this.request.setContextPath("/context-path"); - this.request.addHeader("X-Forwarded-Prefix", "/prefix"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/foo/1"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")).isEqualTo("80"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-prefix")) - .isEqualTo("/prefix/api"); - assertThat(getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")) - .isEqualTo("foo"); - } - - @Test - public void forwardRouteAddsLocation() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.request.setRequestURI("/api/foo/1"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(FORWARD_TO_KEY)).isEqualTo("/foo/1"); - } - - @Test - public void forwardWithoutStripPrefixAppendsPath() throws Exception { - this.request.setRequestURI("/foo/1"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", null, "forward:/bar", false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(FORWARD_TO_KEY)).isEqualTo("/bar/foo/1"); - } - - @Test - public void prefixRouteWithRouteStrippingAddsHeader() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.request.setRequestURI("/api/foo/1"); - this.routeLocator.addRoute("/foo/**", "foo"); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/1"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-prefix")) - .isEqualTo("/api/foo"); - assertThat(getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")) - .isEqualTo("foo"); - } - - @Test - public void routeNotFound() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null)); - - this.request.setRequestURI("/api/bar/1"); - - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(FORWARD_TO_KEY)).isEqualTo("/api/bar/1"); - } - - @Test - public void routeNotFoundDispatcherServletSpecialPath() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setAddProxyHeaders(true); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null)); - - this.filter = new PreDecorationFilter(this.routeLocator, "/special", - this.properties, this.proxyRequestHelper); - - this.request.setRequestURI("/api/bar/1"); - - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(FORWARD_TO_KEY)).isEqualTo("/special/api/bar/1"); - } - - @Test - public void routeNotFoundZuulRequest() throws Exception { - setTestRequestContext(); - RequestContext ctx = RequestContext.getCurrentContext(); - RequestContext.getCurrentContext().setZuulEngineRan(); - this.request.setRequestURI("/zuul/api/bar/1"); - ctx.setRequest(this.request); - - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setServletPath("/zuul"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null)); - - this.filter.run(); - - assertThat(ctx.get(FORWARD_TO_KEY)).isEqualTo("/api/bar/1"); - } - - @Test - public void routeNotFoundZuulRequestDispatcherServletSpecialPath() throws Exception { - setTestRequestContext(); - RequestContext ctx = RequestContext.getCurrentContext(); - RequestContext.getCurrentContext().setZuulEngineRan(); - this.request.setRequestURI("/zuul/api/bar/1"); - ctx.setRequest(this.request); - - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setServletPath("/zuul"); - this.properties.setAddProxyHeaders(true); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null)); - this.filter = new PreDecorationFilter(this.routeLocator, "/special", - this.properties, this.proxyRequestHelper); - - this.filter.run(); - - assertThat(ctx.get(FORWARD_TO_KEY)).isEqualTo("/special/api/bar/1"); - } - - @Test - public void routeNotFoundZuulRequestZuulHomeMapping() throws Exception { - setTestRequestContext(); - RequestContext ctx = RequestContext.getCurrentContext(); - RequestContext.getCurrentContext().setZuulEngineRan(); - this.request.setRequestURI("/api/bar/1"); - ctx.setRequest(this.request); - - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setServletPath("/"); - this.properties.setAddProxyHeaders(true); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null)); - - this.filter = new PreDecorationFilter(this.routeLocator, "/special", - this.properties, this.proxyRequestHelper); - - this.filter.run(); - - assertThat(ctx.get(FORWARD_TO_KEY)).isEqualTo("/special/api/bar/1"); - } - - @Test - public void sensitiveHeadersOverride() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setSensitiveHeaders(Collections.singleton("x-bar")); - this.request.setRequestURI("/api/foo/1"); - ZuulRoute route = new ZuulRoute("/foo/**", "foo"); - route.setSensitiveHeaders(Collections.singleton("x-foo")); - this.routeLocator.addRoute(route); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - @SuppressWarnings("unchecked") - Set sensitiveHeaders = (Set) ctx - .get(ProxyRequestHelper.IGNORED_HEADERS); - assertThat(sensitiveHeaders.containsAll(Collections.singletonList("x-foo"))) - .as("sensitiveHeaders is wrong: " + sensitiveHeaders).isTrue(); - assertThat(sensitiveHeaders.contains("Cookie")) - .as("sensitiveHeaders is wrong: " + sensitiveHeaders).isFalse(); - } - - @Test - public void sensitiveHeadersOverrideEmpty() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setSensitiveHeaders(Collections.singleton("x-bar")); - this.request.setRequestURI("/api/foo/1"); - ZuulRoute route = new ZuulRoute("/foo/**", "foo"); - route.setSensitiveHeaders(Collections.emptySet()); - this.routeLocator.addRoute(route); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - @SuppressWarnings("unchecked") - Set sensitiveHeaders = (Set) ctx - .get(ProxyRequestHelper.IGNORED_HEADERS); - assertThat(sensitiveHeaders.isEmpty()) - .as("sensitiveHeaders is wrong: " + sensitiveHeaders).isTrue(); - } - - @Test - public void sensitiveHeadersDefaults() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setSensitiveHeaders(Collections.singleton("x-bar")); - this.request.setRequestURI("/api/foo/1"); - this.routeLocator.addRoute("/foo/**", "foo"); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - @SuppressWarnings("unchecked") - Set sensitiveHeaders = (Set) ctx - .get(ProxyRequestHelper.IGNORED_HEADERS); - assertThat(sensitiveHeaders.containsAll(Collections.singletonList("x-bar"))) - .as("sensitiveHeaders is wrong: " + sensitiveHeaders).isTrue(); - assertThat(sensitiveHeaders.contains("Cookie")).as("sensitiveHeaders is wrong") - .isFalse(); - } - - @Test - public void sensitiveHeadersCaseInsensitive() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setSensitiveHeaders(Collections.singleton("X-bAr")); - this.request.setRequestURI("/api/foo/1"); - this.routeLocator.addRoute("/foo/**", "foo"); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - @SuppressWarnings("unchecked") - Set sensitiveHeaders = (Set) ctx - .get(ProxyRequestHelper.IGNORED_HEADERS); - assertThat(sensitiveHeaders.containsAll(Collections.singletonList("x-bar"))) - .as("sensitiveHeaders is wrong: " + sensitiveHeaders).isTrue(); - } - - @Test - public void sensitiveHeadersOverrideCaseInsensitive() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setSensitiveHeaders(Collections.singleton("X-bAr")); - this.request.setRequestURI("/api/foo/1"); - ZuulRoute route = new ZuulRoute("/foo/**", "foo"); - route.setSensitiveHeaders(Collections.singleton("X-Foo")); - this.routeLocator.addRoute(route); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - @SuppressWarnings("unchecked") - Set sensitiveHeaders = (Set) ctx - .get(ProxyRequestHelper.IGNORED_HEADERS); - assertThat(sensitiveHeaders.containsAll(Collections.singletonList("x-foo"))) - .as("sensitiveHeaders is wrong: " + sensitiveHeaders).isTrue(); - } - - @Test - public void ignoredHeadersAlreadySetInRequestContextDontGetOverridden() - throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setSensitiveHeaders(Collections.singleton("x-bar")); - this.request.setRequestURI("/api/foo/1"); - this.routeLocator.addRoute("/foo/**", "foo"); - RequestContext ctx = RequestContext.getCurrentContext(); - ctx.set(ProxyRequestHelper.IGNORED_HEADERS, - new HashSet<>(Arrays.asList("x-foo"))); - this.filter.run(); - @SuppressWarnings("unchecked") - Set sensitiveHeaders = (Set) ctx - .get(ProxyRequestHelper.IGNORED_HEADERS); - assertThat(sensitiveHeaders.containsAll(Arrays.asList("x-bar", "x-foo"))) - .as("sensitiveHeaders is wrong: " + sensitiveHeaders).isTrue(); - } - - @Test - public void urlProperlyDecodedWhenCharacterEncodingIsSet() throws Exception { - this.request.setCharacterEncoding("UTF-8"); - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.request.setRequestURI("/api/foo/ol%C3%A9%D7%93%D7%A8%D7%A2%D7%A7"); - this.routeLocator.addRoute("/foo/**", "foo"); - RequestContext ctx = RequestContext.getCurrentContext(); - this.filter.run(); - String decodedRequestURI = (String) ctx.get(REQUEST_URI_KEY); - assertThat(decodedRequestURI.equals("/oléדרעק")).isTrue(); - } - - @Test - public void headersAreProperlyIgnored() throws Exception { - proxyRequestHelper.addIgnoredHeaders("x-forwarded-host", "x-forwarded-port"); - request.addHeader("x-forwarded-host", "B,127.0.0.1:8080"); - request.addHeader("x-forwarded-port", "A,8080"); - request.addHeader("x-forwarded-proto", "C,http"); - - MultiValueMap result = proxyRequestHelper - .buildZuulRequestHeaders(request); - - assertThat(result.containsKey("x-forwarded-proto")).isTrue(); - assertThat(result.containsKey("x-forwarded-host")).isFalse(); - assertThat(result.containsKey("x-forwarded-port")).isFalse(); - } - - @Test - public void nullDispatcherServletPath() { - this.filter = new PreDecorationFilter(this.routeLocator, null, this.properties, - this.proxyRequestHelper); - - String forwardUri = this.filter.getForwardUri("/mypath"); - assertThat(forwardUri).isEqualTo("/mypath"); - } - - private Object getHeader(List> headers, String key) { - String value = null; - for (Pair pair : headers) { - if (pair.first().toLowerCase().equals(key.toLowerCase())) { - value = pair.second(); - break; - } - } - return value; - } - - private void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/EagerLoadOfZuulConfigurationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/EagerLoadOfZuulConfigurationTests.java deleted file mode 100644 index eb9f69c69..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/EagerLoadOfZuulConfigurationTests.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import java.util.concurrent.atomic.AtomicInteger; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringRunner.class) -@SpringBootTest(properties = { "zuul.routes.eagerroute.service-id=eager", - "zuul.ribbon.eager-load.enabled=true" }) -@DirtiesContext -public class EagerLoadOfZuulConfigurationTests { - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void testEagerLoading() { - // Child context FooConfig should have been eagerly instantiated.. - assertThat(Foo.getInstanceCount()).isEqualTo(1); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - @EnableZuulProxy - @RibbonClients(@RibbonClient(name = "eager", configuration = FooConfig.class)) - static class TestConfig { - - } - - static class Foo { - - private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger(); - - Foo() { - INSTANCE_COUNT.incrementAndGet(); - } - - public static int getInstanceCount() { - return INSTANCE_COUNT.get(); - } - - } - - static class FooConfig { - - @Bean - public Foo foo() { - return new Foo(); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/LazyLoadOfZuulConfigurationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/LazyLoadOfZuulConfigurationTests.java deleted file mode 100644 index b8c89b800..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/LazyLoadOfZuulConfigurationTests.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import java.util.concurrent.atomic.AtomicInteger; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - properties = { "zuul.routes.lazyroute.service-id=lazy", - "zuul.routes.lazyroute.path=/lazy/**", - "zuul.ribbon.eager-load.enabled=false" }) -@DirtiesContext -public class LazyLoadOfZuulConfigurationTests { - - @LocalServerPort - protected int port; - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void testLazyLoading() { - // Child context FooConfig should be lazily created.. - assertThat(Foo.getInstanceCount()).isEqualTo(0); - - String uri = String.format("http://localhost:%d/lazy/sample", this.port); - - ResponseEntity result = new TestRestTemplate().getForEntity(uri, - String.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - - // the instance should be available now.. - assertThat(Foo.getInstanceCount()).isEqualTo(1); - - assertThat(result.getBody()).isEqualTo("sample"); - } - - @EnableAutoConfiguration - @SpringBootConfiguration - @EnableZuulProxy - @RestController - @RibbonClient(name = "lazy", configuration = FooConfig.class) - @Import(NoSecurityConfiguration.class) - static class TestConfig { - - @RequestMapping("/sample") - public String sampleEndpoint() { - return "sample"; - } - - } - - static class Foo { - - private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger(); - - Foo() { - INSTANCE_COUNT.incrementAndGet(); - } - - public static int getInstanceCount() { - return INSTANCE_COUNT.get(); - } - - } - - static class FooConfig { - - @Bean - public Foo foo() { - return new Foo(); - } - - @LocalServerPort - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommandTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommandTests.java deleted file mode 100644 index 14f203441..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommandTests.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.net.URI; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Collections; - -import com.netflix.client.http.HttpRequest; -import com.netflix.client.http.HttpRequest.Verb; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.StreamUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -public class RestClientRibbonCommandTests { - - private ZuulProperties zuulProperties; - - @Before - public void setUp() { - zuulProperties = new ZuulProperties(); - } - - /** - * Tests old constructors kept for backwards compatibility with Spring Cloud Sleuth - * 1.x versions - */ - @Test - @Deprecated - public void testNullEntityWithOldConstruct() throws Exception { - String uri = "https://example.com"; - LinkedMultiValueMap headers = new LinkedMultiValueMap<>(); - headers.add("my-header", "my-value"); - LinkedMultiValueMap params = new LinkedMultiValueMap<>(); - params.add("myparam", "myparamval"); - RestClientRibbonCommand command = new RestClientRibbonCommand("cmd", null, - Verb.GET, uri, false, headers, params, null); - - HttpRequest request = command.createRequest(); - - assertThat(request.getUri().toString()).as("uri is wrong").startsWith(uri); - assertThat(request.getHttpHeaders().getFirstValue("my-header")) - .as("my-header is wrong").isEqualTo("my-value"); - assertThat(request.getQueryParams().get("myparam").iterator().next()) - .as("myparam is missing").isEqualTo("myparamval"); - - command = new RestClientRibbonCommand("cmd", null, new RibbonCommandContext( - "example", "GET", uri, false, headers, params, null), zuulProperties); - - request = command.createRequest(); - - assertThat(request.getUri().toString()).as("uri is wrong").startsWith(uri); - assertThat(request.getHttpHeaders().getFirstValue("my-header")) - .as("my-header is wrong").isEqualTo("my-value"); - assertThat(request.getQueryParams().get("myparam").iterator().next()) - .as("myparam is missing").isEqualTo("myparamval"); - } - - @Test - public void testNullEntity() throws Exception { - String uri = "https://example.com"; - LinkedMultiValueMap headers = new LinkedMultiValueMap<>(); - headers.add("my-header", "my-value"); - LinkedMultiValueMap params = new LinkedMultiValueMap<>(); - params.add("myparam", "myparamval"); - RestClientRibbonCommand command = new RestClientRibbonCommand( - "cmd", null, new RibbonCommandContext("example", "GET", uri, false, - headers, params, null, new ArrayList()), - zuulProperties); - - HttpRequest request = command.createRequest(); - - assertThat(request.getUri().toString()).as("uri is wrong").startsWith(uri); - assertThat(request.getHttpHeaders().getFirstValue("my-header")) - .as("my-header is wrong").isEqualTo("my-value"); - assertThat(request.getQueryParams().get("myparam").iterator().next()) - .as("myparam is missing").isEqualTo("myparamval"); - } - - @Test - // this situation happens, see - // https://github.com/spring-cloud/spring-cloud-netflix/issues/1042#issuecomment-227723877 - public void testEmptyEntityGet() throws Exception { - String entityValue = ""; - testEntity(entityValue, new ByteArrayInputStream(entityValue.getBytes()), false, - "GET"); - } - - @Test - public void testNonEmptyEntityPost() throws Exception { - String entityValue = "abcd"; - testEntity(entityValue, new ByteArrayInputStream(entityValue.getBytes()), true, - "POST"); - } - - @Test - public void testNonEmptyEntityDelete() throws Exception { - String entityValue = "abcd"; - testEntity(entityValue, new ByteArrayInputStream(entityValue.getBytes()), true, - "DELETE"); - } - - void testEntity(String entityValue, ByteArrayInputStream requestEntity, - boolean addContentLengthHeader, String method) throws Exception { - String lengthString = String.valueOf(entityValue.length()); - Long length = null; - URI uri = URI.create("https://example.com"); - LinkedMultiValueMap headers = new LinkedMultiValueMap<>(); - if (addContentLengthHeader) { - headers.add("Content-Length", lengthString); - length = (long) entityValue.length(); - } - - RibbonRequestCustomizer requestCustomizer = new RibbonRequestCustomizer() { - @Override - public boolean accepts(Class builderClass) { - return builderClass == HttpRequest.Builder.class; - } - - @Override - public void customize(HttpRequest.Builder builder) { - builder.header("from-customizer", "foo"); - } - }; - RibbonCommandContext context = new RibbonCommandContext("example", method, - uri.toString(), false, headers, new LinkedMultiValueMap(), - requestEntity, Collections.singletonList(requestCustomizer)); - context.setContentLength(length); - RestClientRibbonCommand command = new RestClientRibbonCommand("cmd", null, - context, zuulProperties); - - HttpRequest request = command.createRequest(); - - assertThat(request.getUri().toString()).as("uri is wrong") - .startsWith(uri.toString()); - if (addContentLengthHeader) { - assertThat(request.getHttpHeaders().getFirstValue("Content-Length")) - .as("Content-Length is wrong").isEqualTo(lengthString); - } - assertThat(request.getHttpHeaders().getFirstValue("from-customizer")) - .as("from-customizer is wrong").isEqualTo("foo"); - - if (method.equalsIgnoreCase("DELETE")) { - assertThat(request.getEntity()).as("entity is was non-null").isNull(); - } - else { - assertThat(request.getEntity()).as("entity is missing").isNotNull(); - assertThat(InputStream.class.isAssignableFrom(request.getEntity().getClass())) - .as("entity is wrong type").isTrue(); - InputStream entity = (InputStream) request.getEntity(); - String string = StreamUtils.copyToString(entity, Charset.forName("UTF-8")); - assertThat(string).as("content is wrong").isEqualTo(entityValue); - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilterLoadBalancerKeyIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilterLoadBalancerKeyIntegrationTests.java deleted file mode 100644 index d75c123ec..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilterLoadBalancerKeyIntegrationTests.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.loadbalancer.AvailabilityFilteringRule; -import com.netflix.loadbalancer.IRule; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.LOAD_BALANCER_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; - -/** - * @author Yongsung Yoon - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = CanaryTestZuulProxyApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - value = { "zuul.routes.simple.path: /simple/**" }) -@DirtiesContext -public class RibbonRoutingFilterLoadBalancerKeyIntegrationTests { - - @Autowired - private TestRestTemplate testRestTemplate; - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void invokeWithUserDefinedCanaryHeader() { - HttpHeaders headers = new HttpHeaders(); - headers.set("X-Canary-Test", "true"); - - ResponseEntity result = testRestTemplate.exchange("/simple/hello", - HttpMethod.GET, new HttpEntity<>(headers), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("canary"); - } - - @Test - public void invokeWithoutUserDefinedCanaryHeader() { - HttpHeaders headers = new HttpHeaders(); - ResponseEntity result = testRestTemplate.exchange("/simple/hello", - HttpMethod.GET, new HttpEntity<>(headers), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - } - -} - -@Configuration(proxyBeanMethods = false) -@EnableAutoConfiguration -@RestController -@EnableZuulProxy -@RibbonClient(name = "simple", configuration = CanaryTestRibbonClientConfiguration.class) -@Import(NoSecurityConfiguration.class) -class CanaryTestZuulProxyApplication { - - @RequestMapping(value = "/hello", method = RequestMethod.GET) - public String hello() { - return "canary"; - } - - @Bean - public ZuulFilter testCanarySupportPreFilter() { - return new ZuulFilter() { - @Override - public Object run() { - RequestContext context = RequestContext.getCurrentContext(); - if (checkIfCanaryRequest(context)) { - context.set(LOAD_BALANCER_KEY, "canary"); // set loadBalancerKey for - // IRule - } - return null; - } - - private boolean checkIfCanaryRequest(RequestContext context) { - HttpServletRequest request = context.getRequest(); - String canaryHeader = request.getHeader("X-Canary-Test"); // user defined - // header - - if ((canaryHeader != null) && (canaryHeader.equalsIgnoreCase("true"))) { - return true; - } - return false; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public int filterOrder() { - return 0; - } - }; - } - -} - -@Configuration(proxyBeanMethods = false) -class CanaryTestRibbonClientConfiguration { - - @LocalServerPort - private int port; - - private static Server testCanaryInstance; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>( - new Server("normal-routing-notexist-localhost", this.port)); - } - - @Bean - public IRule canaryTestRule() { - if (testCanaryInstance == null) { - testCanaryInstance = new Server("localhost", port); // use test server as a - // canary instance - } - return new TestCanaryRule(); - } - - public static class TestCanaryRule extends AvailabilityFilteringRule { - - @Override - public Server choose(Object key) { - if ((key != null) && (key.equals("canary"))) { - return testCanaryInstance; // choose test canary server instead of normal - // servers. - } - return super.choose(key); // normal routing - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilterTests.java deleted file mode 100644 index 364ca050a..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilterTests.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collections; - -import javax.servlet.http.HttpServletResponse; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer; -import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.LOAD_BALANCER_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY; - -/** - * @author Spencer Gibb - * @author Yongsung Yoon - * @author Gang Li - */ -public class RibbonRoutingFilterTests { - - private RequestContext requestContext; - - private RibbonRoutingFilter filter; - - @Before - public void setUp() throws Exception { - setUpRequestContext(); - setupRibbonRoutingFilter(); - } - - @After - public void tearDown() throws Exception { - requestContext.unset(); - } - - @Test - public void useServlet31Works() { - assertThat(filter.isUseServlet31()).isTrue(); - } - - @Test - public void testLoadBalancerKeyToRibbonCommandContext() throws Exception { - final String testKey = "testLoadBalancerKey"; - requestContext.set(LOAD_BALANCER_KEY, testKey); - RibbonCommandContext commandContext = filter.buildCommandContext(requestContext); - - assertThat(commandContext.getLoadBalancerKey()).isEqualTo(testKey); - } - - @Test - public void testNullLoadBalancerKeyToRibbonCommandContext() throws Exception { - requestContext.set(LOAD_BALANCER_KEY, null); - RibbonCommandContext commandContext = filter.buildCommandContext(requestContext); - - assertThat(commandContext.getLoadBalancerKey()).isNull(); - } - - @Test - public void testSetResponseWithNonHttpStatusCode() throws Exception { - ClientHttpResponse response = this.createClientHttpResponseWithNonStatus(); - this.filter.setResponse(response); - assertThat(517).isEqualTo(this.requestContext.get("responseStatusCode")); - } - - @Test - public void testSetResponseWithHttpStatusCode() throws Exception { - ClientHttpResponse response = this.createClientHttpResponse(); - this.filter.setResponse(response); - assertThat(200).isEqualTo(this.requestContext.get("responseStatusCode")); - } - - private void setUpRequestContext() { - requestContext = RequestContext.getCurrentContext(); - MockHttpServletRequest mockRequest = new MockHttpServletRequest(); - HttpServletResponse httpServletResponse = new MockHttpServletResponse(); - mockRequest.setMethod("GET"); - mockRequest.setRequestURI("/foo/bar"); - requestContext.setRequest(mockRequest); - requestContext.setRequestQueryParams(Collections.EMPTY_MAP); - requestContext.set(SERVICE_ID_KEY, "testServiceId"); - requestContext.set("response", httpServletResponse); - } - - private void setupRibbonRoutingFilter() { - RibbonCommandFactory factory = mock(RibbonCommandFactory.class); - filter = new RibbonRoutingFilter(new ProxyRequestHelper(new ZuulProperties()), - factory, Collections.emptyList()); - } - - private ClientHttpResponse createClientHttpResponseWithNonStatus() { - return new ClientHttpResponse() { - @Override - public HttpStatus getStatusCode() throws IOException { - return null; - } - - @Override - public int getRawStatusCode() throws IOException { - return 517; - } - - @Override - public String getStatusText() throws IOException { - return "Fail"; - } - - @Override - public void close() { - - } - - @Override - public InputStream getBody() throws IOException { - return new ByteArrayInputStream("Fail".getBytes()); - } - - @Override - public HttpHeaders getHeaders() { - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.setContentType(MediaType.APPLICATION_JSON); - return httpHeaders; - } - }; - } - - private ClientHttpResponse createClientHttpResponse() { - return new ClientHttpResponse() { - @Override - public HttpStatus getStatusCode() throws IOException { - return HttpStatus.OK; - } - - @Override - public int getRawStatusCode() throws IOException { - return 200; - } - - @Override - public String getStatusText() throws IOException { - return "OK"; - } - - @Override - public void close() { - - } - - @Override - public InputStream getBody() throws IOException { - return new ByteArrayInputStream("OK".getBytes()); - } - - @Override - public HttpHeaders getHeaders() { - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.setContentType(MediaType.APPLICATION_JSON); - return httpHeaders; - } - }; - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SendForwardFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SendForwardFilterTests.java deleted file mode 100644 index 2479164c3..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SendForwardFilterTests.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_TO_KEY; - -/** - * @author Dave Syer - */ -public class SendForwardFilterTests { - - @After - public void reset() { - RequestContext.getCurrentContext().clear(); - } - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @Test - public void runsNormally() { - SendForwardFilter filter = createSendForwardFilter(new MockHttpServletRequest()); - assertThat(filter.shouldFilter()).as("shouldFilter returned false").isTrue(); - filter.run(); - } - - private SendForwardFilter createSendForwardFilter(HttpServletRequest request) { - RequestContext context = new RequestContext(); - context.setRequest(request); - context.setResponse(new MockHttpServletResponse()); - context.set(FORWARD_TO_KEY, "/foo"); - RequestContext.testSetCurrentContext(context); - SendForwardFilter filter = new SendForwardFilter(); - return filter; - } - - @Test - public void doesNotRunTwice() { - SendForwardFilter filter = createSendForwardFilter(new MockHttpServletRequest()); - assertThat(filter.shouldFilter()).as("shouldFilter returned false").isTrue(); - filter.run(); - assertThat(filter.shouldFilter()).as("shouldFilter returned true").isFalse(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterIntegrationTests.java deleted file mode 100644 index e25c4f6b5..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterIntegrationTests.java +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.zip.GZIPOutputStream; - -import javax.servlet.MultipartConfigElement; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpHeaders; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Andreas Kluth - * @author Spencer Gibb - * @author Gang Li - */ -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - properties = { "server.servlet.context-path: /app" }) -@DirtiesContext -public class SimpleHostRoutingFilterIntegrationTests { - - @LocalServerPort - private int port; - - /* - * @Autowired private SimpleHostRoutingFilter filter; - * - * @Before public void setup() { CounterFactory.initialize(new EmptyCounterFactory()); - * RequestContext.testSetCurrentContext(new RequestContext()); } - * - * @After public void clear() { CounterFactory.initialize(null); - * - * RequestContext.testSetCurrentContext(null); - * RequestContext.getCurrentContext().clear(); } - * - * @Test public void contentLengthNegativeTest() throws IOException { - * contentLengthTest(-1000L); } - * - * @Test public void contentLengthNegativeOneTest() throws IOException { - * contentLengthTest(-1L); } - * - * @Test public void contentLengthZeroTest() throws IOException { - * contentLengthTest(0L); } - * - * @Test public void contentLengthOneTest() throws IOException { - * contentLengthTest(1L); } - * - * @Test public void contentLength1KbTest() throws IOException { - * contentLengthTest(1000L); } - * - * @Test public void contentLength1MbTest() throws IOException { - * contentLengthTest(1000000L); } - * - * @Test public void contentLength1GbTest() throws IOException { - * contentLengthTest(1000000000L); } - * - * @Test public void contentLength2GbTest() throws IOException { - * contentLengthTest(2000000000L); } - * - * @Test public void contentLength3GbTest() throws IOException { - * contentLengthTest(3000000000L); } - * - * @Test public void contentLength4GbTest() throws IOException { - * contentLengthTest(4000000000L); } - * - * @Test public void contentLength5GbTest() throws IOException { - * contentLengthTest(5000000000L); } - * - * @Test public void contentLength6GbTest() throws IOException { - * contentLengthTest(6000000000L); } - * - * @Test public void contentLengthServlet30WithHeaderNegativeTest() throws IOException - * { contentLengthServlet30WithHeaderTest(-1000L); } - * - * @Test public void contentLengthServlet30WithHeaderNegativeOneTest() throws - * IOException { contentLengthServlet30WithHeaderTest(-1L); } - * - * @Test public void contentLengthServlet30WithHeaderZeroTest() throws IOException { - * contentLengthServlet30WithHeaderTest(0L); } - * - * @Test public void contentLengthServlet30WithHeaderOneTest() throws IOException { - * contentLengthServlet30WithHeaderTest(1L); } - * - * @Test public void contentLengthServlet30WithHeader1KbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(1000L); } - * - * @Test public void contentLengthServlet30WithHeader1MbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(1000000L); } - * - * @Test public void contentLengthServlet30WithHeader1GbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(1000000000L); } - * - * @Test public void contentLengthServlet30WithHeader2GbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(2000000000L); } - * - * @Test public void contentLengthServlet30WithHeader3GbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(3000000000L); } - * - * @Test public void contentLengthServlet30WithHeader4GbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(4000000000L); } - * - * @Test public void contentLengthServlet30WithHeader5GbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(5000000000L); } - * - * @Test public void contentLengthServlet30WithHeader6GbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(6000000000L); } - * - * @Test public void contentLengthServlet30WithInvalidLongHeaderTest() throws - * IOException { setupContext(); MockMultipartHttpServletRequest request = - * getMockedReqest(-1L); request.addHeader(HttpHeaders.CONTENT_LENGTH, "InvalidLong"); - * contentLengthTest(-1L, getServlet30Filter(), request); } - * - * @Test public void contentLengthServlet30WithoutHeaderNegativeTest() throws - * IOException { contentLengthServlet30WithoutHeaderTest(-1000L); } - * - * @Test public void contentLengthServlet30WithoutHeaderNegativeOneTest() throws - * IOException { contentLengthServlet30WithoutHeaderTest(-1L); } - * - * @Test public void contentLengthServlet30WithoutHeaderZeroTest() throws IOException - * { contentLengthServlet30WithoutHeaderTest(0L); } - * - * @Test public void contentLengthServlet30WithoutHeaderOneTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(1L); } - * - * @Test public void contentLengthServlet30WithoutHeader1KbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(1000L); } - * - * @Test public void contentLengthServlet30WithoutHeader1MbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(1000000L); } - * - * @Test public void contentLengthServlet30WithoutHeader1GbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(1000000000L); } - * - * @Test public void contentLengthServlet30WithoutHeader2GbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(2000000000L); } - * - * @Test public void contentLengthServlet30WithoutHeader3GbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(3000000000L); } - * - * @Test public void contentLengthServlet30WithoutHeader4GbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(4000000000L); } - * - * @Test public void contentLengthServlet30WithoutHeader5GbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(5000000000L); } - * - * @Test public void contentLengthServlet30WithoutHeader6GbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(6000000000L); } - * - * public void contentLengthTest(Long contentLength) throws IOException { - * setupContext(); - * - * contentLengthTest(contentLength, getFilter(), getMockedReqest(contentLength)); } - * - * public void contentLengthServlet30WithHeaderTest(Long contentLength) throws - * IOException { setupContext(); MockMultipartHttpServletRequest request = - * getMockedReqest(contentLength); request.addHeader(HttpHeaders.CONTENT_LENGTH, - * contentLength); contentLengthTest(contentLength, getServlet30Filter(), request); } - * - * public void contentLengthServlet30WithoutHeaderTest(Long contentLength) throws - * IOException { setupContext(); - * - * //Although contentLength.intValue is not always equals to contentLength, that's the - * expected result when calling // request.getContentLength() from servlet 3.0 - * implementation. contentLengthTest(Long.parseLong("" + contentLength.intValue()), - * getServlet30Filter(), getMockedReqest(contentLength)); } - * - * public MockMultipartHttpServletRequest getMockedReqest(final Long contentLength) - * throws IOException { - * - * MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest() { - * - * @Override public int getContentLength() { return contentLength.intValue(); } - * - * @Override public long getContentLengthLong() { return contentLength; } }; - * - * return request; } - * - * public void contentLengthTest(Long expectedContentLength, SimpleHostRoutingFilter - * filter, MockMultipartHttpServletRequest request) throws IOException { byte[] data = - * "poprqwueproqiwuerpoqweiurpo".getBytes(); MockMultipartFile file = new - * MockMultipartFile("test.zip", "test.zip", "application/zip", data); String boundary - * = "q1w2e3r4t5y6u7i8o9"; request.setContentType("multipart/form-data; boundary=" + - * boundary); request.setContent( createFileContent(data, boundary, "application/zip", - * "test.zip")); request.addFile(file); request.setMethod("POST"); - * request.setParameter("variant", "php"); request.setParameter("os", "mac"); - * request.setParameter("version", "3.4"); request.setRequestURI("/app/echo"); - * - * MockHttpServletResponse response = new MockHttpServletResponse(); - * RequestContext.getCurrentContext().setRequest(request); - * RequestContext.getCurrentContext().setResponse(response); URL url = new - * URL("http://localhost:" + this.port); - * RequestContext.getCurrentContext().set("routeHost", url); filter.run(); - * - * CloseableHttpResponse httpResponse = (CloseableHttpResponse) - * RequestContext.getCurrentContext() .get("zuulResponse"); - * assertThat(httpResponse.getStatusLine().getStatusCode(), equalTo(200)); InputStream - * zuulResponse = httpResponse.getEntity().getContent(); assertThat(zuulResponse, - * not(instanceOf(EmptyInputStream.class))); String responseString = - * IOUtils.toString(new GZIPInputStream( zuulResponse)); - * assertTrue(!responseString.isEmpty()); if (expectedContentLength < 0) { - * assertThat(responseString, containsString("\"" + - * HttpHeaders.TRANSFER_ENCODING.toLowerCase() + "\":\"chunked\"")); - * assertThat(responseString, - * not(containsString(HttpHeaders.CONTENT_LENGTH.toLowerCase()))); } else { - * assertThat(responseString, containsString("\"" + - * HttpHeaders.CONTENT_LENGTH.toLowerCase() + "\":\"" + expectedContentLength + - * "\"")); } } - * - * public byte[] createFileContent(byte[] data, String boundary, String contentType, - * String fileName) { String start = "--" + boundary + - * "\r\n Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + - * "\"\r\n" + "Content-type: " + contentType + "\r\n\r\n"; ; - * - * String end = "\r\n--" + boundary + "--"; // correction suggested @butfly return - * ArrayUtils.addAll(start.getBytes(), ArrayUtils.addAll(data, end.getBytes())); } - * - * @Test public void httpClientDoesNotDecompressEncodedData() throws Exception { - * setupContext(); InputStreamEntity inputStreamEntity = new InputStreamEntity(new - * ByteArrayInputStream(new byte[]{1})); HttpRequest httpRequest = - * getFilter().buildHttpRequest("GET", "/app/compressed/get/1", inputStreamEntity, new - * LinkedMultiValueMap<>(), new LinkedMultiValueMap<>(), new - * MockHttpServletRequest()); - * - * CloseableHttpResponse response = getFilter().newClient().execute(new - * HttpHost("localhost", this.port), httpRequest); assertEquals(200, - * response.getStatusLine().getStatusCode()); byte[] responseBytes = - * copyToByteArray(response.getEntity().getContent()); - * assertTrue(Arrays.equals(GZIPCompression.compress("Get 1"), responseBytes)); } - * - * @Test public void httpClientPreservesUnencodedData() throws Exception { - * setupContext(); InputStreamEntity inputStreamEntity = new InputStreamEntity(new - * ByteArrayInputStream(new byte[]{1})); HttpRequest httpRequest = - * getFilter().buildHttpRequest("GET", "/app/get/1", inputStreamEntity, new - * LinkedMultiValueMap<>(), new LinkedMultiValueMap<>(), new - * MockHttpServletRequest()); - * - * CloseableHttpResponse response = getFilter().newClient().execute(new - * HttpHost("localhost", this.port), httpRequest); assertEquals(200, - * response.getStatusLine().getStatusCode()); String responseString = - * copyToString(response.getEntity().getContent(), Charset.forName("UTF-8")); - * assertTrue("Get 1".equals(responseString)); } - * - * @Test public void redirectTest() throws IOException { setupContext(); - * InputStreamEntity inputStreamEntity = new InputStreamEntity(new - * ByteArrayInputStream(new byte[]{})); HttpRequest httpRequest = - * getFilter().buildHttpRequest("GET", "/app/redirect", inputStreamEntity, new - * LinkedMultiValueMap<>(), new LinkedMultiValueMap<>(), new - * MockHttpServletRequest()); - * - * CloseableHttpResponse response = getFilter().newClient().execute(new - * HttpHost("localhost", this.port), httpRequest); assertEquals(302, - * response.getStatusLine().getStatusCode()); String responseString = - * copyToString(response.getEntity().getContent(), Charset.forName("UTF-8")); - * assertTrue(response.getLastHeader("Location").getValue().contains("/app/get/5")); } - * - * @Test(expected = ZuulRuntimeException.class) public void run() throws Exception { - * setupContext(); MockHttpServletRequest request = new MockHttpServletRequest("POST", - * "/"); request.setContent("{1}".getBytes()); request.addHeader("singleName", - * "singleValue"); request.addHeader("multiName", "multiValue1"); - * request.addHeader("multiName", "multiValue2"); - * RequestContext.getCurrentContext().setRequest(request); URL url = new - * URL("http://localhost:8080"); RequestContext.getCurrentContext().set("routeHost", - * url); getFilter().run(); } - * - * private void setupContext() { } - * - * private SimpleHostRoutingFilter getFilter() { return this.filter; } - * - * private SimpleHostRoutingFilter getServlet30Filter() { SimpleHostRoutingFilter - * filter = getFilter(); filter.setUseServlet31(false); return filter; } - */ - /* - * @Configuration - * - * @EnableConfigurationProperties protected static class TestConfiguration { - * - * @Bean ZuulProperties zuulProperties() { return new ZuulProperties(); } - * - * @Bean ApacheHttpClientFactory clientFactory() {return new - * DefaultApacheHttpClientFactory(HttpClientBuilder.create()); } - * - * @Bean ApacheHttpClientConnectionManagerFactory connectionManagerFactory() { return - * new DefaultApacheHttpClientConnectionManagerFactory(); } - * - * @Bean SimpleHostRoutingFilter simpleHostRoutingFilter(ZuulProperties - * zuulProperties, ApacheHttpClientConnectionManagerFactory connectionManagerFactory, - * ApacheHttpClientFactory clientFactory) { return new SimpleHostRoutingFilter(new - * ProxyRequestHelper(), zuulProperties, connectionManagerFactory, clientFactory); } } - */ - - @Test - public void test() { - - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @RestController - @Import(NoSecurityConfiguration.class) - static class SampleApplication { - - @RequestMapping(value = "/compressed/get/{id}", method = RequestMethod.GET) - public byte[] getCompressed(@PathVariable String id, HttpServletResponse response) - throws IOException { - response.setHeader("content-encoding", "gzip"); - return GZIPCompression.compress("Get " + id); - } - - @RequestMapping(value = "/get/{id}", method = RequestMethod.GET) - public String getString(@PathVariable String id, HttpServletResponse response) - throws IOException { - return "Get " + id; - } - - @RequestMapping(value = "/redirect", method = RequestMethod.GET) - public String redirect(HttpServletResponse response) throws IOException { - response.sendRedirect("/app/get/5"); - return null; - } - - @RequestMapping("/echo") - public Map echoRequestAttributes( - @RequestHeader HttpHeaders httpHeaders, HttpServletRequest request) - throws IOException { - Map result = new HashMap<>(); - result.put("headers", httpHeaders.toSingleValueMap()); - - return result; - } - - @Bean - MultipartConfigElement multipartConfigElement() { - long maxSize = 10L * 1024 * 1024 * 1024; - return new MultipartConfigElement("", maxSize, maxSize, 0); - } - - } - - static class GZIPCompression { - - public static byte[] compress(final String str) throws IOException { - if ((str == null) || (str.length() == 0)) { - return null; - } - ByteArrayOutputStream obj = new ByteArrayOutputStream(); - GZIPOutputStream gzip = new GZIPOutputStream(obj); - gzip.write(str.getBytes("UTF-8")); - gzip.close(); - return obj.toByteArray(); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterTests.java deleted file mode 100644 index 9493c2e9d..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterTests.java +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.net.URL; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.monitoring.CounterFactory; -import org.apache.http.HttpEntityEnclosingRequest; -import org.apache.http.HttpRequest; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.Configurable; -import org.apache.http.client.methods.HttpPatch; -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.entity.InputStreamEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.assertj.core.api.Assertions; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; -import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientConnectionManagerFactory; -import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientFactory; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.metrics.EmptyCounterFactory; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.ReflectionUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.util.StreamUtils.copyToByteArray; - -/** - * @author Andreas Kluth - * @author Spencer Gibb - * @author Gang Li - * @author Denys Ivano - */ -public class SimpleHostRoutingFilterTests { - - private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - - @Before - public void setup() { - CounterFactory.initialize(new EmptyCounterFactory()); - RequestContext.testSetCurrentContext(new RequestContext()); - } - - @After - public void clear() { - if (this.context != null) { - this.context.close(); - } - CounterFactory.initialize(null); - - RequestContext.testSetCurrentContext(null); - RequestContext.getCurrentContext().clear(); - } - - @Test - public void timeoutPropertiesAreApplied() { - TestPropertyValues - .of("zuul.host.socket-timeout-millis=11000", - "zuul.host.connect-timeout-millis=2100", - "zuul.host.connection-request-timeout-millis=2500") - .applyTo(this.context); - setupContext(); - CloseableHttpClient httpClient = getFilter().newClient(); - Assertions.assertThat(httpClient).isInstanceOf(Configurable.class); - RequestConfig config = ((Configurable) httpClient).getConfig(); - assertThat(config.getSocketTimeout()).isEqualTo(11000); - assertThat(config.getConnectTimeout()).isEqualTo(2100); - assertThat(config.getConnectionRequestTimeout()).isEqualTo(2500); - } - - @Test - public void connectionPropertiesAreApplied() { - TestPropertyValues.of("zuul.host.maxTotalConnections=100", - "zuul.host.maxPerRouteConnections=10", "zuul.host.timeToLive=5", - "zuul.host.timeUnit=SECONDS").applyTo(this.context); - setupContext(); - PoolingHttpClientConnectionManager connMgr = (PoolingHttpClientConnectionManager) getFilter() - .getConnectionManager(); - assertThat(connMgr.getMaxTotal()).isEqualTo(100); - assertThat(connMgr.getDefaultMaxPerRoute()).isEqualTo(10); - Object pool = getField(connMgr, "pool"); - assertThat(pool).hasFieldOrPropertyWithValue("timeToLive", 5L); - assertThat(pool).hasFieldOrPropertyWithValue("timeUnit", TimeUnit.SECONDS); - } - - @SuppressWarnings("unchecked") - private T getField(Object target, String name) { - Field field = ReflectionUtils.findField(target.getClass(), name); - if (field == null) { - throw new IllegalArgumentException( - target.getClass() + " does not have field " + name); - } - ReflectionUtils.makeAccessible(field); - Object value = ReflectionUtils.getField(field, target); - return (T) value; - } - - @Test - public void validateSslHostnamesByDefault() { - setupContext(); - assertThat(getFilter().isSslHostnameValidationEnabled()) - .as("Hostname verification should be enabled by default").isTrue(); - } - - @Test - public void validationOfSslHostnamesCanBeDisabledViaProperty() { - TestPropertyValues.of("zuul.sslHostnameValidationEnabled=false") - .applyTo(this.context); - setupContext(); - assertThat(getFilter().isSslHostnameValidationEnabled()) - .as("Hostname verification should be disabled via property").isFalse(); - } - - @Test - public void defaultPropertiesAreApplied() { - setupContext(); - PoolingHttpClientConnectionManager connMgr = (PoolingHttpClientConnectionManager) getFilter() - .getConnectionManager(); - - assertThat(connMgr.getMaxTotal()).isEqualTo(200); - assertThat(connMgr.getDefaultMaxPerRoute()).isEqualTo(20); - } - - @Test - public void deleteRequestBuiltWithBody() { - setupContext(); - InputStreamEntity inputStreamEntity = new InputStreamEntity( - new ByteArrayInputStream(new byte[] { 1 })); - HttpRequest httpRequest = getFilter().buildHttpRequest("DELETE", "uri", - inputStreamEntity, new LinkedMultiValueMap<>(), - new LinkedMultiValueMap<>(), new MockHttpServletRequest()); - - assertThat(httpRequest instanceof HttpEntityEnclosingRequest).isTrue(); - HttpEntityEnclosingRequest httpEntityEnclosingRequest = (HttpEntityEnclosingRequest) httpRequest; - assertThat(httpEntityEnclosingRequest.getEntity() != null).isTrue(); - } - - @Test - public void zuulHostKeysUpdateHttpClient() { - setupContext(); - SimpleHostRoutingFilter filter = getFilter(); - CloseableHttpClient httpClient = extractHttpClient(filter); - EnvironmentChangeEvent event = new EnvironmentChangeEvent( - Collections.singleton("zuul.host.mykey")); - filter.onApplicationEvent(event); - CloseableHttpClient newhttpClient = extractHttpClient(filter); - Assertions.assertThat(httpClient).isNotEqualTo(newhttpClient); - } - - private CloseableHttpClient extractHttpClient(SimpleHostRoutingFilter filter) { - return (CloseableHttpClient) ReflectionTestUtils.getField(filter, "httpClient"); - } - - @Test - public void zuulHostKeysUpdateHttpClientConnectionManagerIsNotShutDown() { - setupContext(); - SimpleHostRoutingFilter filter = getFilter(); - EnvironmentChangeEvent event = new EnvironmentChangeEvent( - Collections.singleton("zuul.host.mykey")); - filter.onApplicationEvent(event); - - CloseableHttpClient httpClient = extractHttpClient(filter); - PoolingHttpClientConnectionManager connMgr = (PoolingHttpClientConnectionManager) extractConnectionManager( - httpClient); - AtomicBoolean isShutDown = getField(connMgr, "isShutDown"); - assertThat(isShutDown.get()).as("Connection manager shut down").isFalse(); - Object pool = getField(connMgr, "pool"); - assertThat(pool).hasFieldOrPropertyWithValue("isShutDown", false); - } - - private HttpClientConnectionManager extractConnectionManager( - CloseableHttpClient httpClient) { - // Default implementation is org.apache.http.impl.client.InternalHttpClient - return getField(httpClient, "connManager"); - } - - @Test - public void zuulHostKeysUpdateHttpClientUsesNewConnectionManager() { - setupContext(); - SimpleHostRoutingFilter filter = getFilter(); - PoolingHttpClientConnectionManager connMgr = (PoolingHttpClientConnectionManager) filter - .getConnectionManager(); - EnvironmentChangeEvent event = new EnvironmentChangeEvent( - Collections.singleton("zuul.host.mykey")); - filter.onApplicationEvent(event); - - PoolingHttpClientConnectionManager newConnMgr = (PoolingHttpClientConnectionManager) filter - .getConnectionManager(); - CloseableHttpClient httpClient = extractHttpClient(filter); - HttpClientConnectionManager usedConnMgr = extractConnectionManager(httpClient); - assertThat(usedConnMgr).isNotEqualTo(connMgr); - assertThat(usedConnMgr).isEqualTo(newConnMgr); - } - - @Test - public void zuulHostKeysUpdateConnectionManagerPropertiesAreChanged() { - setupContext(); - SimpleHostRoutingFilter filter = getFilter(); - ZuulProperties.Host host = context.getBean(ZuulProperties.class).getHost(); - host.setMaxTotalConnections(50); - host.setMaxPerRouteConnections(10); - host.setTimeToLive(10); - host.setTimeUnit(TimeUnit.SECONDS); - EnvironmentChangeEvent event = new EnvironmentChangeEvent( - new HashSet<>(Arrays.asList("zuul.host.maxTotalConnections", - "zuul.host.maxPerRouteConnections", "zuul.host.timeToLive", - "zuul.host.timeUnit"))); - filter.onApplicationEvent(event); - - PoolingHttpClientConnectionManager connMgr = (PoolingHttpClientConnectionManager) filter - .getConnectionManager(); - assertThat(connMgr.getMaxTotal()).isEqualTo(50); - assertThat(connMgr.getDefaultMaxPerRoute()).isEqualTo(10); - Object pool = getField(connMgr, "pool"); - assertThat(pool).hasFieldOrPropertyWithValue("timeToLive", 10L); - assertThat(pool).hasFieldOrPropertyWithValue("timeUnit", TimeUnit.SECONDS); - } - - @Test - public void getRequestBody() throws Exception { - setupContext(); - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - request.setContent("{1}".getBytes()); - request.addHeader("singleName", "singleValue"); - request.addHeader("multiName", "multiValue1"); - request.addHeader("multiName", "multiValue2"); - RequestContext.getCurrentContext().setRequest(request); - InputStream inputStream = getFilter().getRequestBody(request); - assertThat(Arrays.equals("{1}".getBytes(), copyToByteArray(inputStream))) - .isTrue(); - } - - @Test - public void putRequestBuiltWithBody() { - setupContext(); - InputStreamEntity inputStreamEntity = new InputStreamEntity( - new ByteArrayInputStream(new byte[] { 1 })); - HttpRequest httpRequest = getFilter().buildHttpRequest("PUT", "uri", - inputStreamEntity, new LinkedMultiValueMap<>(), - new LinkedMultiValueMap<>(), new MockHttpServletRequest()); - - assertThat(httpRequest instanceof HttpEntityEnclosingRequest).isTrue(); - HttpEntityEnclosingRequest httpEntityEnclosingRequest = (HttpEntityEnclosingRequest) httpRequest; - assertThat(httpEntityEnclosingRequest.getEntity() != null).isTrue(); - } - - @Test - public void postRequestBuiltWithBody() { - setupContext(); - InputStreamEntity inputStreamEntity = new InputStreamEntity( - new ByteArrayInputStream(new byte[] { 1 })); - HttpRequest httpRequest = getFilter().buildHttpRequest("POST", "uri", - inputStreamEntity, new LinkedMultiValueMap<>(), - new LinkedMultiValueMap<>(), new MockHttpServletRequest()); - - assertThat(httpRequest instanceof HttpEntityEnclosingRequest).isTrue(); - HttpEntityEnclosingRequest httpEntityEnclosingRequest = (HttpEntityEnclosingRequest) httpRequest; - assertThat(httpEntityEnclosingRequest.getEntity() != null).isTrue(); - } - - @Test - public void pathRequestBuiltWithBody() { - setupContext(); - InputStreamEntity inputStreamEntity = new InputStreamEntity( - new ByteArrayInputStream(new byte[] { 1 })); - HttpRequest httpRequest = getFilter().buildHttpRequest("PATCH", "uri", - inputStreamEntity, new LinkedMultiValueMap<>(), - new LinkedMultiValueMap<>(), new MockHttpServletRequest()); - - HttpPatch basicHttpRequest = (HttpPatch) httpRequest; - assertThat(basicHttpRequest.getEntity() != null).isTrue(); - } - - @Test - public void shouldFilterFalse() { - setupContext(); - assertThat(getFilter().shouldFilter()).isEqualTo(false); - } - - @Test - public void shouldFilterTrue() throws Exception { - setupContext(); - RequestContext.getCurrentContext().set("routeHost", - new URL("http://localhost:8080")); - RequestContext.getCurrentContext().set("sendZuulResponse", true); - assertThat(getFilter().shouldFilter()).isEqualTo(true); - } - - @Test - public void filterOrder() { - setupContext(); - assertThat(getFilter().filterOrder()).isEqualTo(100); - } - - private void setupContext() { - this.context.register(PropertyPlaceholderAutoConfiguration.class, - TestConfiguration.class); - this.context.refresh(); - } - - private SimpleHostRoutingFilter getFilter() { - return this.context.getBean(SimpleHostRoutingFilter.class); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties - protected static class TestConfiguration { - - @Bean - ZuulProperties zuulProperties() { - return new ZuulProperties(); - } - - @Bean - ApacheHttpClientFactory clientFactory() { - return new DefaultApacheHttpClientFactory(HttpClientBuilder.create()); - } - - @Bean - ApacheHttpClientConnectionManagerFactory connectionManagerFactory() { - return new DefaultApacheHttpClientConnectionManagerFactory(); - } - - @Bean - SimpleHostRoutingFilter simpleHostRoutingFilter(ZuulProperties zuulProperties, - ApacheHttpClientConnectionManagerFactory connectionManagerFactory, - ApacheHttpClientFactory clientFactory) { - return new SimpleHostRoutingFilter(new ProxyRequestHelper(zuulProperties), - zuulProperties, connectionManagerFactory, clientFactory); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactoryTest.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactoryTest.java deleted file mode 100644 index f834472a4..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactoryTest.java +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.apache; - -import java.util.HashSet; - -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.client.config.IClientConfigKey; -import com.netflix.config.ConfigurationManager; -import com.netflix.hystrix.strategy.properties.HystrixPropertiesFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * @author Ryan Baxter - * @author Gang Li - */ -public class HttpClientRibbonCommandFactoryTest { - - SpringClientFactory springClientFactory; - - ZuulProperties zuulProperties; - - HttpClientRibbonCommandFactory ribbonCommandFactory; - - @Before - public void setup() { - this.springClientFactory = mock(SpringClientFactory.class); - this.zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - doReturn(loadBalancingHttpClient).when(this.springClientFactory) - .getClient(anyString(), eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(this.springClientFactory) - .getClientConfig(anyString()); - this.ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - } - - @After - public void after() { - ConfigurationManager.getConfigInstance().clear(); - HystrixPropertiesFactory.reset(); - } - - @Test - public void testHystrixTimeoutValue() throws Exception { - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = this.ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testHystrixTimeoutValueSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 50); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = this.ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testHystrixTimeoutValueCommandSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.service.execution.isolation.thread.timeoutInMilliseconds", - 50); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = this.ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testHystrixTimeoutValueCommandAndDefaultSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 30); - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.service.execution.isolation.thread.timeoutInMilliseconds", - 50); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = this.ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testHystrixTimeoutValueRibbonTimeouts() throws Exception { - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(1200); - } - - @Test - public void testHystrixDefaultAndRibbonSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 30); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(30); - } - - @Test - public void testHystrixCommandAndRibbonSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 30); - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.service.execution.isolation.thread.timeoutInMilliseconds", - 50); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testDefaultRibbonSetting() throws Exception { - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory commandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testRibbonTimeoutAndRibbonRetriesDefaultAndNameSpaceSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.test.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.test.ReadTimeout", - 1000); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(1200); - } - - @Test - public void testRibbonTimeoutAndRibbonRetriesDefaultAndDefaultSpaceSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testRibbonTimeoutAndRibbonNameSpaceRetriesDefaultAndDefaultSpaceSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.test.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testRibbonRetriesAndRibbonTimeoutSetting() throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(3600); - } - - @Test - public void testRibbonCommandRetriesAndRibbonCommandTimeoutSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(12000); - } - - @Test - public void testRibbonCommandRetriesAndRibbonCommandTimeoutPartOfSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(6000); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFallbackTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFallbackTests.java deleted file mode 100644 index f7ff2cef7..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFallbackTests.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2016-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.apache; - -import com.netflix.zuul.context.RequestContext; -import org.junit.Before; -import org.junit.runner.RunWith; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.route.support.RibbonCommandFallbackTests; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = RibbonCommandFallbackTests.TestConfig.class, - webEnvironment = RANDOM_PORT, properties = { "zuul.routes.simple: /simple/**", - "zuul.routes.another: /another/twolevel/**", "ribbon.ReadTimeout: 1" }) -@DirtiesContext -public class HttpClientRibbonCommandFallbackTests extends RibbonCommandFallbackTests { - - @Before - public void init() { - RequestContext.getCurrentContext().clear(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandIntegrationTests.java deleted file mode 100644 index de6c7c2f0..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandIntegrationTests.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.apache; - -import java.util.Collections; -import java.util.Set; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.support.ZuulProxyTestBase; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.util.WebUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.http.HttpHeaders.SET_COOKIE; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = HttpClientRibbonCommandIntegrationTests.TestConfig.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "zuul.routes.other: /test/**=http://localhost:7777/local", - "zuul.routes.another: /another/twolevel/**", - "zuul.routes.simple: /simple/**", "zuul.routes.singleton.id: singleton", - "zuul.routes.singleton.path: /singleton/**", - "zuul.routes.singleton.sensitiveHeaders: ", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase { - - @Before - public void init() { - super.setTestRequestcontext(); - } - - @Test - public void patchOnSelfViaRibbonRoutingFilter() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/1", HttpMethod.PATCH, - new HttpEntity<>("TestPatch"), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Patched 1!"); - } - - @Test - public void postOnSelfViaRibbonRoutingFilter() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/1", HttpMethod.POST, - new HttpEntity<>("TestPost"), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted 1!"); - } - - @Test - public void deleteOnSelfViaRibbonRoutingFilter() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/1", HttpMethod.DELETE, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Deleted 1!"); - } - - @Test - public void ribbonLoadBalancingHttpClientCookiePolicy() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/downstream_cookie", - HttpMethod.POST, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Cookie 434354454!"); - assertThat(result.getHeaders().getFirst(SET_COOKIE)).isNull(); - - // if new instance of RibbonLoadBalancingHttpClient is getting created every time - // and HttpClient is not reused then there are no concerns for the shared cookie - // storage - // but since https://github.com/spring-cloud/spring-cloud-netflix/issues/1150 is - // on the way a - result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/singleton/downstream_cookie", - HttpMethod.POST, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Cookie 434354454!"); - assertThat(result.getHeaders().getFirst(SET_COOKIE)) - .isEqualTo("jsessionid=434354454"); - - result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/singleton/downstream_cookie", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Cookie null!"); - } - - @Test - public void ribbonCommandFactoryOverridden() { - assertThat(this.ribbonCommandFactory instanceof HttpClientRibbonCommandFactory) - .as("ribbonCommandFactory not a HttpClientRibbonCommandFactory").isTrue(); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @RibbonClients({ @RibbonClient(name = "simple", - configuration = ZuulProxyTestBase.SimpleRibbonClientConfiguration.class), - @RibbonClient(name = "another", - configuration = ZuulProxyTestBase.AnotherRibbonClientConfiguration.class), - @RibbonClient(name = "singleton", - configuration = SingletonRibbonClientConfiguration.class) }) - @Import(NoSecurityConfiguration.class) - static class TestConfig extends ZuulProxyTestBase.AbstractZuulProxyApplication { - - @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); - - @RequestMapping(value = "/local/{id}", method = RequestMethod.PATCH) - public String patch(@PathVariable final String id, - @RequestBody final String body) { - return "Patched " + id + "!"; - } - - @RequestMapping(value = "/downstream_cookie", method = RequestMethod.POST) - public String setDownstreamCookie(HttpServletResponse response) { - response.addCookie(new Cookie("jsessionid", "434354454")); - return "Cookie 434354454!"; - } - - @RequestMapping(value = "/downstream_cookie", method = RequestMethod.GET) - public String readDownstreamCookie(HttpServletRequest request) { - final Cookie cookie = WebUtils.getCookie(request, "jsessionid"); - return "Cookie " + cookie + "!"; - } - - @Bean - public RibbonCommandFactory ribbonCommandFactory( - final SpringClientFactory clientFactory) { - return new HttpClientRibbonCommandFactory(clientFactory, new ZuulProperties(), - zuulFallbackProviders); - } - - @Bean - public ZuulProxyTestBase.MyErrorController myErrorController( - ErrorAttributes errorAttributes) { - return new ZuulProxyTestBase.MyErrorController(errorAttributes); - } - - } - - // Load balancer with fixed server list and defined ribbon rest client - @Configuration(proxyBeanMethods = false) - public static class SingletonRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - @Bean - public RibbonLoadBalancingHttpClient ribbonClient(IClientConfig config, - ILoadBalancer loadBalancer, RetryHandler retryHandler) { - final RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient( - config, new DefaultServerIntrospector()); - client.setLoadBalancer(loadBalancer); - client.setRetryHandler(retryHandler); - return client; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonRetryIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonRetryIntegrationTests.java deleted file mode 100644 index cb188798b..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonRetryIntegrationTests.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.apache; - -import org.junit.runner.RunWith; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.route.support.RibbonRetryIntegrationTestBase; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RibbonRetryIntegrationTestBase.RetryableTestConfig.class, - // - webEnvironment = RANDOM_PORT, properties = { "zuul.retryable: false", /* - * Disable - * retry - * by - * default, - * have - * each - * route - * enable - * it - */ - "hystrix.command.default.execution.timeout.enabled: false", /* - * Disable - * hystrix so - * its timeout - * doesnt get - * in the way - */ - "ribbon.ReadTimeout: 1000", /* - * Make sure ribbon will timeout before the - * thread is done sleeping - */ - "zuul.routes.retryable.id: retryable", - "zuul.routes.retryable.path: /retryable/**", - "zuul.routes.retryable.retryable: true", - "retryable.ribbon.OkToRetryOnAllOperations: true", - "retryable.ribbon.MaxAutoRetries: 1", - "retryable.ribbon.MaxAutoRetriesNextServer: 1", - "zuul.routes.getretryable.id: getretryable", - "zuul.routes.getretryable.path: /getretryable/**", - "zuul.routes.getretryable.retryable: true", - "getretryable.ribbon.MaxAutoRetries: 1", - "getretryable.ribbon.MaxAutoRetriesNextServer: 1", - "zuul.routes.disableretry.id: disableretry", - "zuul.routes.disableretry.path: /disableretry/**", - "zuul.routes.disableretry.retryable: false", /* - * This will override the - * global - */ - "disableretry.ribbon.MaxAutoRetries: 1", - "disableretry.ribbon.MaxAutoRetriesNextServer: 1", - "zuul.routes.globalretrydisabled: /globalretrydisabled/**", - "globalretrydisabled.ribbon.MaxAutoRetries: 1", - "globalretrydisabled.ribbon.MaxAutoRetriesNextServer: 1", - "retryable.ribbon.retryableStatusCodes: 404,403" }) -@DirtiesContext -public class HttpClientRibbonRetryIntegrationTests - extends RibbonRetryIntegrationTestBase { - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactoryTest.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactoryTest.java deleted file mode 100644 index 2ed90fc7c..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactoryTest.java +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.okhttp; - -import java.util.HashSet; - -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.client.config.IClientConfigKey; -import com.netflix.config.ConfigurationManager; -import com.netflix.hystrix.strategy.properties.HystrixPropertiesFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * @author Ryan Baxter - * @author Gang Li - */ -public class OkHttpRibbonCommandFactoryTest { - - SpringClientFactory springClientFactory; - - ZuulProperties zuulProperties; - - OkHttpRibbonCommandFactory commandFactory; - - @Before - public void setup() { - this.springClientFactory = mock(SpringClientFactory.class); - this.zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - doReturn(loadBalancingHttpClient).when(this.springClientFactory) - .getClient(anyString(), eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(this.springClientFactory) - .getClientConfig(anyString()); - commandFactory = new OkHttpRibbonCommandFactory(springClientFactory, - zuulProperties, new HashSet()); - } - - @After - public void after() { - ConfigurationManager.getConfigInstance().clear(); - HystrixPropertiesFactory.reset(); - } - - @Test - public void testHystrixTimeoutValue() throws Exception { - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = this.commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testHystrixTimeoutValueSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 50); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = this.commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testHystrixTimeoutValueCommandSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.service.execution.isolation.thread.timeoutInMilliseconds", - 50); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = this.commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testHystrixTimeoutValueCommandAndDefaultSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 30); - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.service.execution.isolation.thread.timeoutInMilliseconds", - 50); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = this.commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testHystrixDefaultAndRibbonSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 30); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(30); - } - - @Test - public void testHystrixCommandAndRibbonSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 30); - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.service.execution.isolation.thread.timeoutInMilliseconds", - 50); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testDefaultRibbonSetting() throws Exception { - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testRibbonAndRibbonRetriesDefaultSetting() throws Exception { - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(1200); - } - - @Test - public void testRibbonTimeoutAndRibbonRetriesDefaultAndNameSpaceSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.test.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.test.ReadTimeout", - 1000); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl("test"); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testRibbonTimeoutAndRibbonRetriesDefaultAndDefaultSpaceSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testRibbonTimeoutAndRibbonNameSpaceRetriesDefaultAndDefaultSpaceSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.test.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl("test"); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(1800); - } - - @Test - public void testRibbonRetriesAndRibbonTimeoutSetting() throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(3600); - } - - @Test - public void testRibbonCommandRetriesAndRibbonCommandTimeoutSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(12000); - } - - @Test - public void testRibbonCommandRetriesAndRibbonCommandTimeoutPartOfSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(6000); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFallbackTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFallbackTests.java deleted file mode 100644 index 677b702dc..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFallbackTests.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.okhttp; - -import com.netflix.zuul.context.RequestContext; -import org.junit.Before; -import org.junit.runner.RunWith; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.route.support.RibbonCommandFallbackTests; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RibbonCommandFallbackTests.TestConfig.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - value = { "zuul.routes.simple: /simple/**", - "zuul.routes.another: /another/twolevel/**", "ribbon.ReadTimeout: 1" }) -@DirtiesContext -@Import(NoSecurityConfiguration.class) -public class OkHttpRibbonCommandFallbackTests extends RibbonCommandFallbackTests { - - @Before - public void init() { - RequestContext.getCurrentContext().clear(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java deleted file mode 100644 index b20c19858..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.okhttp; - -import java.util.Collections; -import java.util.Set; - -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.support.ZuulProxyTestBase; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = OkHttpRibbonCommandIntegrationTests.TestConfig.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "zuul.routes.other: /test/**=http://localhost:7777/local", - "zuul.routes.another: /another/twolevel/**", - "zuul.routes.simple: /simple/**", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class OkHttpRibbonCommandIntegrationTests extends ZuulProxyTestBase { - - @Before - public void init() { - super.setTestRequestcontext(); - } - - @Test - public void patchOnSelfViaRibbonRoutingFilter() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/1", HttpMethod.PATCH, - new HttpEntity<>("TestPatch"), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Patched 1!"); - } - - @Test - public void postOnSelfViaRibbonRoutingFilter() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/1", HttpMethod.POST, - new HttpEntity<>("TestPost"), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted 1!"); - } - - @Test - public void deleteOnSelfViaRibbonRoutingFilter() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/1", HttpMethod.DELETE, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Deleted 1!"); - } - - @Test - public void ribbonCommandFactoryOverridden() { - assertThat(this.ribbonCommandFactory instanceof OkHttpRibbonCommandFactory) - .as("ribbonCommandFactory not a OkHttpRibbonCommandFactory").isTrue(); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @RibbonClients({ - @RibbonClient(name = "simple", - configuration = SimpleRibbonClientConfiguration.class), - @RibbonClient(name = "another", - configuration = AnotherRibbonClientConfiguration.class) }) - @Import(NoSecurityConfiguration.class) - static class TestConfig extends ZuulProxyTestBase.AbstractZuulProxyApplication { - - @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); - - @Bean - public RibbonCommandFactory ribbonCommandFactory( - final SpringClientFactory clientFactory) { - return new OkHttpRibbonCommandFactory(clientFactory, new ZuulProperties(), - zuulFallbackProviders); - } - - @Bean - public MyErrorController myErrorController(ErrorAttributes errorAttributes) { - return new MyErrorController(errorAttributes); - } - - @Bean - public IClientConfig config() { - return new DefaultClientConfigImpl(); - } - - @Bean - public OkHttpLoadBalancingClient okClient(IClientConfig config) { - final OkHttpLoadBalancingClient client = new OkHttpLoadBalancingClient(config, - new DefaultServerIntrospector()); - client.setLoadBalancer(new TestLoadBalancer<>()); - client.setRetryHandler(new DefaultLoadBalancerRetryHandler()); - return client; - } - - } - - static class TestLoadBalancer extends ZoneAwareLoadBalancer { - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonRetryIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonRetryIntegrationTests.java deleted file mode 100644 index aaf7c9705..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonRetryIntegrationTests.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.okhttp; - -import org.junit.runner.RunWith; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.route.support.RibbonRetryIntegrationTestBase; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RibbonRetryIntegrationTestBase.RetryableTestConfig.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - value = { "zuul.retryable: false", /* - * Disable retry by default, have each route - * enable it - */ - "ribbon.okhttp.enabled: true", - "hystrix.command.default.execution.timeout.enabled: false", /* - * Disable - * hystrix so - * its timeout - * doesnt get - * in the way - */ - "ribbon.ReadTimeout: 1000", /* - * Make sure ribbon will timeout before the - * thread is done sleeping - */ - "zuul.routes.retryable.id: retryable", - "zuul.routes.retryable.path: /retryable/**", - "zuul.routes.retryable.retryable: true", - "retryable.ribbon.OkToRetryOnAllOperations: true", - "retryable.ribbon.retryableStatusCodes: 404", - "retryable.ribbon.MaxAutoRetries: 1", - "retryable.ribbon.MaxAutoRetriesNextServer: 1", - "zuul.routes.getretryable.id: getretryable", - "zuul.routes.getretryable.path: /getretryable/**", - "zuul.routes.getretryable.retryable: true", - "getretryable.ribbon.MaxAutoRetries: 1", - "getretryable.ribbon.MaxAutoRetriesNextServer: 1", - "zuul.routes.disableretry.path: /disableretry/**", - "zuul.routes.disableretry.path: /disableretry/**", - "zuul.routes.disableretry.retryable: false", /* - * This will override the - * global - */ - "disableretry.ribbon.MaxAutoRetries: 1", - "disableretry.ribbon.MaxAutoRetriesNextServer: 1", - "zuul.routes.globalretrydisabled: /globalretrydisabled/**", - "globalretrydisabled.ribbon.MaxAutoRetries: 1", - "globalretrydisabled.ribbon.MaxAutoRetriesNextServer: 1" }) -@DirtiesContext -public class OkHttpRibbonRetryIntegrationTests extends RibbonRetryIntegrationTestBase { - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandFallbackTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandFallbackTests.java deleted file mode 100644 index 9e1b8b1cf..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandFallbackTests.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.restclient; - -import com.netflix.zuul.context.RequestContext; -import org.junit.Before; -import org.junit.runner.RunWith; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.route.support.RibbonCommandFallbackTests; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RibbonCommandFallbackTests.TestConfig.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - value = { "zuul.routes.simple: /simple/**", - "zuul.routes.another: /another/twolevel/**", "ribbon.ReadTimeout: 1" }) -@DirtiesContext -public class RestClientRibbonCommandFallbackTests extends RibbonCommandFallbackTests { - - @Before - public void init() { - RequestContext.getCurrentContext().clear(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandIntegrationTests.java deleted file mode 100644 index 7ecbe874d..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandIntegrationTests.java +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.restclient; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.UUID; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.client.ClientException; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.niws.client.http.RestClient; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.boot.web.servlet.filter.ApplicationContextHeaderFilter; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommand; -import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.support.NoEncodingFormHttpMessageConverter; -import org.springframework.cloud.netflix.zuul.filters.route.support.ZuulProxyTestBase; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.StringHttpMessageConverter; -import org.springframework.mock.http.client.MockClientHttpResponse; -import org.springframework.security.config.annotation.web.WebSecurityConfigurer; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.web.firewall.StrictHttpFirewall; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.bind.annotation.MatrixVariable; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RestClientRibbonCommandIntegrationTests.TestConfig.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "zuul.routes.other: /test/**=http://localhost:7777/local", - "zuul.routes.another: /another/twolevel/**", - "zuul.routes.simple: /simple/**", "zuul.routes.badhost: /badhost/**", - "zuul.ignored-headers: X-Header", "zuul.routes.rnd: /rnd/**", - "rnd.ribbon.listOfServers: ${random.value}", - "zuul.remove-semicolon-content: false", "ribbon.restclient.enabled=true", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class RestClientRibbonCommandIntegrationTests extends ZuulProxyTestBase { - - @Autowired - DiscoveryClientRouteLocator routeLocator; - - @Override - protected boolean supportsPatch() { - return false; - } - - @Override - protected boolean supportsDeleteWithBody() { - return false; - } - - @Test - public void simpleHostRouteWithTrailingSlash() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/trailing-slash", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("/trailing-slash"); - assertThat(this.myErrorController.wasControllerUsed()).isFalse(); - } - - @Test - public void simpleHostRouteWithNonExistentUrl() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - String uri = "/self/nonExistentUrl"; - this.myErrorController.setUriToMatch(uri); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); - assertThat(this.myErrorController.wasControllerUsed()).isFalse(); - } - - @Test - public void simpleHostRouteIgnoredHeader() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/add-header", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getHeaders().get("X-Header")).isNull(); - } - - @Test - public void simpleHostRouteDefaultIgnoredHeader() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/add-header", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - List headers = result.getHeaders().get("X-Application-Context"); - assertThat(headers).as("header was null").isNotNull(); - assertThat(headers.toString()).isEqualTo("[application-1]"); - } - - @Test - public void simpleHostRouteWithQuery() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/query?foo=bar", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("/query?foo=bar"); - } - - @Test - public void simpleHostRouteWithMatrix() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/matrix/my;q=2;p=1/more;x=2", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("my=1-2;more=2"); - } - - @Test - public void simpleHostRouteWithEncodedQuery() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/query?foo={foo}", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class, "weird#chars"); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("/query?foo=weird#chars"); - } - - @Test - public void simpleHostRouteWithColonParamNames() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port - + "/self/colonquery?foo:bar={foobar0}&foobar={foobar1}", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class, "baz", - "bam"); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("/colonquery?foo:bar=baz&foobar=bam"); - } - - @Test - public void simpleHostRouteWithContentType() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/content-type", HttpMethod.POST, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo(""); - } - - @Test - public void ribbonCommandForbidden() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/throwexception/403", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); - } - - @Test - public void ribbonCommandServiceUnavailable() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/throwexception/503", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.SERVICE_UNAVAILABLE); - } - - @Test - public void ribbonCommandBadHost() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/badhost/1", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - // JSON response - assertThat(result.getBody()).contains("\"status\":500"); - } - - @Test - public void ribbonCommandRandomHostFromConfig() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/rnd/1", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - // JSON response - assertThat(result.getBody()).contains("\"status\":500"); - } - - @Test - public void ribbonCommandFactoryOverridden() { - assertThat(this.ribbonCommandFactory instanceof TestConfig.MyRibbonCommandFactory) - .as("ribbonCommandFactory not a MyRibbonCommandFactory").isTrue(); - } - - @Override - @SuppressWarnings("deprecation") - @Test - public void javascriptEncodedFormParams() { - TestRestTemplate testRestTemplate = new TestRestTemplate(); - ArrayList> converters = new ArrayList<>(); - converters.addAll(Arrays.asList(new StringHttpMessageConverter(), - new NoEncodingFormHttpMessageConverter())); - testRestTemplate.getRestTemplate().setMessageConverters(converters); - - MultiValueMap map = new LinkedMultiValueMap<>(); - map.add("foo", "(bar)"); - ResponseEntity result = testRestTemplate.postForEntity( - "http://localhost:" + this.port + "/simple/local", map, String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()) - .isEqualTo("Posted [(bar)] and Content-Length was: -1!"); - } - - @Test - public void routeLocatorOverridden() { - assertThat(this.routeLocator instanceof TestConfig.MyRouteLocator) - .as("routeLocator not a MyRouteLocator").isTrue(); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @RibbonClients({ - @RibbonClient(name = "badhost", - configuration = TestConfig.BadHostRibbonClientConfiguration.class), - @RibbonClient(name = "simple", - configuration = ZuulProxyTestBase.SimpleRibbonClientConfiguration.class), - @RibbonClient(name = "another", - configuration = ZuulProxyTestBase.AnotherRibbonClientConfiguration.class) }) - @Import(NoSecurityConfiguration.class) - static class TestConfig extends ZuulProxyTestBase.AbstractZuulProxyApplication { - - @Autowired(required = false) - private Set fallbackProviders = Collections.emptySet(); - - @RequestMapping("/trailing-slash") - public String trailingSlash(HttpServletRequest request) { - return request.getRequestURI(); - } - - @RequestMapping("/content-type") - public String contentType(HttpServletRequest request) { - String header = request.getHeader("Content-Type"); - return header == null ? "" : header; - } - - @RequestMapping("/add-header") - public ResponseEntity addHeader(HttpServletRequest request) { - HttpHeaders headers = new HttpHeaders(); - headers.set("X-Header", "FOO"); - ResponseEntity result = new ResponseEntity<>(request.getRequestURI(), - headers, HttpStatus.OK); - return result; - } - - @RequestMapping("/query") - public String query(HttpServletRequest request, @RequestParam String foo) { - return request.getRequestURI() + "?foo=" + foo; - } - - @RequestMapping("/colonquery") - public String colonQuery(HttpServletRequest request, - @RequestParam(name = "foo:bar") String foobar0, - @RequestParam(name = "foobar") String foobar1) { - return request.getRequestURI() + "?foo:bar=" + foobar0 + "&foobar=" + foobar1; - } - - @RequestMapping("/matrix/{name}/{another}") - public String matrix(@PathVariable("name") String name, - @MatrixVariable(value = "p", pathVar = "name") int p, - @MatrixVariable(value = "q", pathVar = "name") int q, - @PathVariable("another") String another, - @MatrixVariable(value = "x", pathVar = "another") int x) { - return name + "=" + p + "-" + q + ";" + another + "=" + x; - } - - @Bean - public RibbonCommandFactory ribbonCommandFactory( - SpringClientFactory clientFactory) { - return new MyRibbonCommandFactory(clientFactory, fallbackProviders); - } - - @Bean - public DiscoveryClientRouteLocator discoveryRouteLocator( - DiscoveryClient discoveryClient, ZuulProperties zuulProperties) { - return new MyRouteLocator("/", discoveryClient, zuulProperties); - } - - @Bean - public MyErrorController myErrorController(ErrorAttributes errorAttributes) { - return new MyErrorController(errorAttributes); - } - - @Bean - public ApplicationContextHeaderFilter applicationContextIdFilter( - ApplicationContext context) { - return new ApplicationContextHeaderFilter(context); - } - - public static void main(String[] args) { - SpringApplication.run(TestConfig.class, args); - } - - public static class MyRibbonCommandFactory - extends RestClientRibbonCommandFactory { - - private SpringClientFactory clientFactory; - - MyRibbonCommandFactory(SpringClientFactory clientFactory, - Set fallbackProviders) { - super(clientFactory, new ZuulProperties(), fallbackProviders); - this.clientFactory = clientFactory; - } - - @Override - @SuppressWarnings("deprecation") - public RestClientRibbonCommand create(RibbonCommandContext context) { - String uri = context.getUri(); - if (uri.startsWith("/throwexception/")) { - String code = uri.replace("/throwexception/", ""); - RestClient restClient = clientFactory - .getClient(context.getServiceId(), RestClient.class); - return new MyCommand(Integer.parseInt(code), context.getServiceId(), - restClient, context); - } - return super.create(context); - } - - } - - static class MyCommand extends RestClientRibbonCommand { - - private int errorCode; - - MyCommand(int errorCode, String commandKey, RestClient restClient, - RibbonCommandContext context) { - super(commandKey, restClient, context, new ZuulProperties()); - this.errorCode = errorCode; - } - - @Override - protected ClientHttpResponse run() throws Exception { - if (this.errorCode == 503) { - throw new ClientException(ClientException.ErrorType.SERVER_THROTTLED); - } - return new MockClientHttpResponse(new byte[0], - HttpStatus.valueOf(this.errorCode)); - } - - } - - // Load balancer with fixed server list for "simple" pointing to bad host - @Configuration(proxyBeanMethods = false) - static class BadHostRibbonClientConfiguration { - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>( - new Server(UUID.randomUUID().toString(), 4322)); - } - - } - - // This is needed to allow semicolon separators used in matrix variables - @Configuration(proxyBeanMethods = false) - static class CustomHttpFirewallConfig - implements WebSecurityConfigurer { - - @Override - public void init(WebSecurity webSecurity) throws Exception { - } - - @Override - public void configure(WebSecurity builder) throws Exception { - StrictHttpFirewall firewall = new StrictHttpFirewall(); - firewall.setAllowSemicolon(true); - builder.httpFirewall(firewall); - } - - } - - static class MyRouteLocator extends DiscoveryClientRouteLocator { - - MyRouteLocator(String servletPath, DiscoveryClient discovery, - ZuulProperties properties) { - super(servletPath, discovery, properties); - } - - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/NoEncodingFormHttpMessageConverter.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/NoEncodingFormHttpMessageConverter.java deleted file mode 100644 index 51f77de5b..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/NoEncodingFormHttpMessageConverter.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.support; - -import java.io.IOException; -import java.util.Iterator; - -import org.springframework.http.HttpOutputMessage; -import org.springframework.http.MediaType; -import org.springframework.http.converter.FormHttpMessageConverter; -import org.springframework.http.converter.HttpMessageNotWritableException; -import org.springframework.util.MultiValueMap; -import org.springframework.util.StreamUtils; - -/** - * @author Jacques-Etienne Beaudet - */ -public class NoEncodingFormHttpMessageConverter extends FormHttpMessageConverter { - - @SuppressWarnings("unchecked") - @Override - public void write(MultiValueMap map, MediaType contentType, - HttpOutputMessage outputMessage) - throws IOException, HttpMessageNotWritableException { - - MultiValueMap form = (MultiValueMap) map; - StringBuilder builder = new StringBuilder(); - for (Iterator nameIterator = form.keySet().iterator(); nameIterator - .hasNext();) { - String name = nameIterator.next(); - for (Iterator valueIterator = form.get(name).iterator(); valueIterator - .hasNext();) { - String value = valueIterator.next(); - builder.append(name); - if (value != null) { - builder.append('='); - builder.append(value); - if (valueIterator.hasNext()) { - builder.append('&'); - } - } - } - if (nameIterator.hasNext()) { - builder.append('&'); - } - } - final byte[] bytes = builder.toString() - .getBytes(FormHttpMessageConverter.DEFAULT_CHARSET); - outputMessage.getHeaders().setContentLength(bytes.length); - outputMessage.getHeaders().setContentType(MediaType.APPLICATION_FORM_URLENCODED); - - StreamUtils.copy(bytes, outputMessage.getBody()); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandCauseFallbackPropagationTest.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandCauseFallbackPropagationTest.java deleted file mode 100644 index c66f03aff..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandCauseFallbackPropagationTest.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.support; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.UUID; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.ClientException; -import com.netflix.client.ClientRequest; -import com.netflix.client.IResponse; -import com.netflix.client.RequestSpecificRetryHandler; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.client.http.HttpResponse; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.exception.HystrixTimeoutException; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.client.ClientHttpResponse; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * @author Dominik Mostek - */ -public class RibbonCommandCauseFallbackPropagationTest { - - private RibbonCommandContext context; - - @Before - public void setup() { - context = mock(RibbonCommandContext.class); - doReturn("fooRoute").when(context).getServiceId(); - } - - @Test - public void providerIsCalledInCaseOfException() throws Exception { - FallbackProvider provider = new TestFallbackProvider( - getClientHttpResponse(HttpStatus.INTERNAL_SERVER_ERROR)); - RuntimeException exception = new RuntimeException("Failed!"); - TestRibbonCommand testCommand = new TestRibbonCommand(new TestClient(exception), - provider, context); - - ClientHttpResponse response = testCommand.execute(); - - assertThat(response).isNotNull(); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - } - - @Test - public void causeIsProvidedForNewInterface() throws Exception { - TestFallbackProvider provider = TestFallbackProvider - .withResponse(HttpStatus.NOT_FOUND); - RuntimeException exception = new RuntimeException("Failed!"); - TestRibbonCommand testCommand = new TestRibbonCommand(new TestClient(exception), - provider, context); - - ClientHttpResponse response = testCommand.execute(); - - assertThat(response).isNotNull(); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); - Throwable cause = provider.getCause(); - assertThat(cause.getClass()).isEqualTo(exception.getClass()); - assertThat(cause.getMessage()).isEqualTo(exception.getMessage()); - } - - @Test - public void executionExceptionIsUsedInsteadWhenFailedExceptionIsNull() - throws Exception { - TestFallbackProvider provider = TestFallbackProvider - .withResponse(HttpStatus.BAD_GATEWAY); - final RuntimeException exception = new RuntimeException("Failed!"); - TestRibbonCommand testCommand = new TestRibbonCommand(new TestClient(exception), - provider, context) { - @Override - public Throwable getFailedExecutionException() { - return null; - } - - @Override - public Throwable getExecutionException() { - return exception; - } - }; - - ClientHttpResponse response = testCommand.execute(); - - assertThat(response).isNotNull(); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_GATEWAY); - } - - @Test - public void timeoutExceptionIsPropagated() throws Exception { - TestFallbackProvider provider = TestFallbackProvider - .withResponse(HttpStatus.CONFLICT); - RuntimeException exception = new RuntimeException("Failed!"); - TestRibbonCommand testCommand = new TestRibbonCommand(new TestClient(exception), - provider, 1, context) { - @Override - protected ClientRequest createRequest() throws Exception { - Thread.sleep(5); - return super.createRequest(); - } - }; - - ClientHttpResponse response = testCommand.execute(); - - assertThat(response).isNotNull(); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CONFLICT); - assertThat(provider.getCause()).isNotNull(); - assertThat(provider.getCause().getClass()) - .isEqualTo(HystrixTimeoutException.class); - } - - private static ClientHttpResponse getClientHttpResponse(final HttpStatus status) { - return new ClientHttpResponse() { - @Override - public HttpStatus getStatusCode() throws IOException { - return status; - } - - @Override - public int getRawStatusCode() throws IOException { - return getStatusCode().value(); - } - - @Override - public String getStatusText() throws IOException { - return getStatusCode().getReasonPhrase(); - } - - @Override - public void close() { - } - - @Override - public InputStream getBody() throws IOException { - return new ByteArrayInputStream("test".getBytes()); - } - - @Override - public HttpHeaders getHeaders() { - return new HttpHeaders(); - } - }; - } - - public static class TestFallbackProvider implements FallbackProvider { - - private final ClientHttpResponse response; - - private Throwable cause; - - public TestFallbackProvider(final ClientHttpResponse response) { - this.response = response; - } - - @Override - public ClientHttpResponse fallbackResponse(String route, final Throwable cause) { - this.cause = cause; - return response; - } - - @Override - public String getRoute() { - return "test-route"; - } - - public Throwable getCause() { - return cause; - } - - public static TestFallbackProvider withResponse(final HttpStatus status) { - return new TestFallbackProvider(getClientHttpResponse(status)); - } - - } - - @SuppressWarnings("rawtypes") - public static class TestClient extends AbstractLoadBalancerAwareClient { - - private final RuntimeException exception; - - public TestClient(RuntimeException exception) { - super(null); - this.exception = exception; - } - - @Override - public IResponse executeWithLoadBalancer(final ClientRequest request, - final IClientConfig requestConfig) throws ClientException { - throw exception; - } - - @Override - public RequestSpecificRetryHandler getRequestSpecificRetryHandler( - final ClientRequest clientRequest, final IClientConfig iClientConfig) { - return null; - } - - @Override - public IResponse execute(final ClientRequest clientRequest, - final IClientConfig iClientConfig) throws Exception { - return null; - } - - } - - public static class TestRibbonCommand extends - AbstractRibbonCommand, ClientRequest, HttpResponse> { - - public TestRibbonCommand( - AbstractLoadBalancerAwareClient client, - FallbackProvider fallbackProvider, RibbonCommandContext context) { - this(client, new ZuulProperties(), fallbackProvider, context); - } - - public TestRibbonCommand( - AbstractLoadBalancerAwareClient client, - ZuulProperties zuulProperties, FallbackProvider fallbackProvider, - RibbonCommandContext context) { - super("testCommand" + UUID.randomUUID(), client, context, zuulProperties, - fallbackProvider); - } - - public TestRibbonCommand( - AbstractLoadBalancerAwareClient client, - FallbackProvider fallbackProvider, int timeout, - RibbonCommandContext context) { - // different name is used because of properties caching - super(getSetter("testCommand" + UUID.randomUUID(), new ZuulProperties(), - new DefaultClientConfigImpl()).andCommandPropertiesDefaults( - defauts(timeout)), - client, context, fallbackProvider, null); - } - - private static HystrixCommandProperties.Setter defauts(final int timeout) { - return HystrixCommandProperties.Setter().withExecutionTimeoutEnabled(true) - .withExecutionIsolationStrategy( - HystrixCommandProperties.ExecutionIsolationStrategy.THREAD) - .withExecutionTimeoutInMilliseconds(timeout); - } - - @Override - protected ClientRequest createRequest() throws Exception { - return null; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandFallbackTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandFallbackTests.java deleted file mode 100644 index 5fc26c6ac..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandFallbackTests.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.support; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collections; -import java.util.Set; - -import org.junit.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - */ -public abstract class RibbonCommandFallbackTests { - - @LocalServerPort - protected int port; - - @Test - public void fallback() { - String uri = "/simple/slow"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("fallback"); - } - - @Test - public void defaultFallback() { - String uri = "/another/twolevel/slow"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("default fallback"); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @RibbonClients({ @RibbonClient(name = "simple", - configuration = ZuulProxyTestBase.SimpleRibbonClientConfiguration.class), - @RibbonClient(name = "another", - configuration = ZuulProxyTestBase.AnotherRibbonClientConfiguration.class) }) - @Import(NoSecurityConfiguration.class) - public static class TestConfig - extends ZuulProxyTestBase.AbstractZuulProxyApplication { - - @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); - - @Bean - public RibbonCommandFactory ribbonCommandFactory( - final SpringClientFactory clientFactory) { - return new HttpClientRibbonCommandFactory(clientFactory, new ZuulProperties(), - zuulFallbackProviders); - } - - @Bean - public ZuulProxyTestBase.MyErrorController myErrorController( - ErrorAttributes errorAttributes) { - return new ZuulProxyTestBase.MyErrorController(errorAttributes); - } - - @Bean - public FallbackProvider defaultFallbackProvider() { - return new DefaultFallbackProvider(); - } - - } - - public static class DefaultFallbackProvider implements FallbackProvider { - - @Override - public String getRoute() { - return "*"; - } - - @Override - public ClientHttpResponse fallbackResponse(final String route, Throwable cause) { - return new ClientHttpResponse() { - @Override - public HttpStatus getStatusCode() throws IOException { - return HttpStatus.OK; - } - - @Override - public int getRawStatusCode() throws IOException { - if (route.equals("another")) { - return 200; - } - return 500; - } - - @Override - public String getStatusText() throws IOException { - return null; - } - - @Override - public void close() { - - } - - @Override - public InputStream getBody() throws IOException { - return new ByteArrayInputStream("default fallback".getBytes()); - } - - @Override - public HttpHeaders getHeaders() { - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.TEXT_HTML); - return headers; - } - }; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandHystrixThreadPoolKeyTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandHystrixThreadPoolKeyTests.java deleted file mode 100644 index d17bb77c5..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandHystrixThreadPoolKeyTests.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.support; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.ClientRequest; -import com.netflix.client.http.HttpResponse; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.strategy.HystrixPlugins; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Yongsung Yoon - */ -public class RibbonCommandHystrixThreadPoolKeyTests { - - private ZuulProperties zuulProperties; - - @Before - public void setUp() throws Exception { - zuulProperties = new ZuulProperties(); - } - - @After - public void tearDown() throws Exception { - HystrixPlugins.reset(); - } - - @Test - public void testDefaultHystrixThreadPoolKey() throws Exception { - zuulProperties.setRibbonIsolationStrategy( - HystrixCommandProperties.ExecutionIsolationStrategy.THREAD); - - TestRibbonCommand ribbonCommand1 = new TestRibbonCommand("testCommand1", - zuulProperties); - TestRibbonCommand ribbonCommand2 = new TestRibbonCommand("testCommand2", - zuulProperties); - - // CommandGroupKey should be used as ThreadPoolKey as default. - assertThat(ribbonCommand1.getThreadPoolKey().name()) - .isEqualTo(ribbonCommand1.getCommandGroup().name()); - assertThat(ribbonCommand2.getThreadPoolKey().name()) - .isEqualTo(ribbonCommand2.getCommandGroup().name()); - } - - @Test - public void testUseSeparateThreadPools() throws Exception { - zuulProperties.setRibbonIsolationStrategy( - HystrixCommandProperties.ExecutionIsolationStrategy.THREAD); - zuulProperties.getThreadPool().setUseSeparateThreadPools(true); - - TestRibbonCommand ribbonCommand1 = new TestRibbonCommand("testCommand1", - zuulProperties); - TestRibbonCommand ribbonCommand2 = new TestRibbonCommand("testCommand2", - zuulProperties); - - assertThat(ribbonCommand1.getThreadPoolKey().name()).isEqualTo("testCommand1"); - assertThat(ribbonCommand2.getThreadPoolKey().name()).isEqualTo("testCommand2"); - } - - @Test - public void testThreadPoolKeyPrefix() throws Exception { - final String prefix = "zuulgw-"; - - zuulProperties.setRibbonIsolationStrategy( - HystrixCommandProperties.ExecutionIsolationStrategy.THREAD); - zuulProperties.getThreadPool().setUseSeparateThreadPools(true); - zuulProperties.getThreadPool().setThreadPoolKeyPrefix(prefix); - - TestRibbonCommand ribbonCommand1 = new TestRibbonCommand("testCommand1", - zuulProperties); - TestRibbonCommand ribbonCommand2 = new TestRibbonCommand("testCommand2", - zuulProperties); - - assertThat(ribbonCommand1.getThreadPoolKey().name()) - .isEqualTo(prefix + "testCommand1"); - assertThat(ribbonCommand2.getThreadPoolKey().name()) - .isEqualTo(prefix + "testCommand2"); - } - - @Test - public void testNoSideEffectOnSemaphoreIsolation() throws Exception { - final String prefix = "zuulgw-"; - - zuulProperties.setRibbonIsolationStrategy( - HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE); - zuulProperties.getThreadPool().setUseSeparateThreadPools(true); - zuulProperties.getThreadPool().setThreadPoolKeyPrefix(prefix); - - TestRibbonCommand ribbonCommand1 = new TestRibbonCommand("testCommand1", - zuulProperties); - TestRibbonCommand ribbonCommand2 = new TestRibbonCommand("testCommand2", - zuulProperties); - - // There should be no side effect on semaphore isolation - assertThat(ribbonCommand1.getThreadPoolKey().name()) - .isEqualTo(ribbonCommand1.getCommandGroup().name()); - assertThat(ribbonCommand2.getThreadPoolKey().name()) - .isEqualTo(ribbonCommand2.getCommandGroup().name()); - } - - public static class TestRibbonCommand extends - AbstractRibbonCommand, ClientRequest, HttpResponse> { - - public TestRibbonCommand(String commandKey, ZuulProperties zuulProperties) { - super(commandKey, null, null, zuulProperties); - } - - @Override - protected ClientRequest createRequest() throws Exception { - return null; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonRetryIntegrationTestBase.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonRetryIntegrationTestBase.java deleted file mode 100644 index 0189d5e00..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonRetryIntegrationTestBase.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.support; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.context.RequestContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryFactory; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicy; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - */ -public abstract class RibbonRetryIntegrationTestBase { - - private final Log LOG = LogFactory.getLog(RibbonRetryIntegrationTestBase.class); - - @Value("${local.server.port}") - protected int port; - - @Before - public void setup() { - RequestContext.getCurrentContext().clear(); - String uri = "/resetError"; - new TestRestTemplate().exchange("http://localhost:" + this.port + uri, - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - } - - @Test - public void retryable() { - String uri = "/retryable/everyothererror"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void retryableFourOFour() { - String uri = "/retryable/404everyothererror"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void postRetryOK() { - String uri = "/retryable/posteveryothererror"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.POST, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void getRetryable() { - String uri = "/getretryable/everyothererror"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void postNotRetryable() { - String uri = "/getretryable/posteveryothererror"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.POST, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - } - - @Test - public void disableRetry() { - String uri = "/disableretry/everyothererror"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - LOG.info("Response Body: " + result.getBody()); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.GATEWAY_TIMEOUT); - } - - @Test - public void globalRetryDisabled() { - String uri = "/globalretrydisabled/everyothererror"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - LOG.info("Response Body: " + result.getBody()); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.GATEWAY_TIMEOUT); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @RibbonClients({ - @RibbonClient(name = "retryable", - configuration = RibbonClientConfiguration.class), - @RibbonClient(name = "disableretry", - configuration = RibbonClientConfiguration.class), - @RibbonClient(name = "globalretrydisabled", - configuration = RibbonClientConfiguration.class), - @RibbonClient(name = "getretryable", - configuration = RibbonClientConfiguration.class) }) - @Import(NoSecurityConfiguration.class) - public static class RetryableTestConfig { - - private final Log LOG = LogFactory.getLog(RetryableTestConfig.class); - - private boolean error = true; - - @RequestMapping("/resetError") - public void resetError() { - error = true; - } - - @RequestMapping("/everyothererror") - public ResponseEntity timeout() { - boolean shouldError = error; - error = !error; - try { - if (shouldError) { - Thread.sleep(80000); - } - } - catch (InterruptedException e) { - LOG.info(e); - Thread.currentThread().interrupt(); - } - - return new ResponseEntity("no error", HttpStatus.OK); - } - - @RequestMapping(path = "/posteveryothererror", method = RequestMethod.POST) - public ResponseEntity postTimeout() { - return timeout(); - } - - @RequestMapping("/404everyothererror") - @ResponseStatus(HttpStatus.NOT_FOUND) - public ResponseEntity fourOFourError() { - boolean shouldError = error; - error = !error; - if (shouldError) { - return new ResponseEntity("not found", HttpStatus.NOT_FOUND); - } - return new ResponseEntity("no error", HttpStatus.OK); - } - - } - - @Configuration(proxyBeanMethods = false) - public static class RibbonClientConfiguration { - - @Value("${local.server.port}") - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - - @Configuration(proxyBeanMethods = false) - public static class FourOFourRetryableRibbonConfiguration - extends RibbonClientConfiguration { - - @Bean - public LoadBalancedRetryFactory loadBalancedRetryPolicyFactory( - SpringClientFactory factory) { - return new MyRibbonRetryFactory(factory); - } - - public static class MyRibbonRetryFactory extends RibbonLoadBalancedRetryFactory { - - private SpringClientFactory factory; - - public MyRibbonRetryFactory(SpringClientFactory clientFactory) { - super(clientFactory); - this.factory = clientFactory; - } - - @Override - public LoadBalancedRetryPolicy createRetryPolicy(String serviceId, - ServiceInstanceChooser loadBalanceChooser) { - RibbonLoadBalancerContext lbContext = this.factory - .getLoadBalancerContext(serviceId); - return new MyLoadBalancedRetryPolicy(serviceId, lbContext, - loadBalanceChooser); - } - - class MyLoadBalancedRetryPolicy extends RibbonLoadBalancedRetryPolicy { - - MyLoadBalancedRetryPolicy(String serviceId, - RibbonLoadBalancerContext context, - ServiceInstanceChooser loadBalanceChooser) { - super(serviceId, context, loadBalanceChooser); - } - - @Override - public boolean retryableStatusCode(int statusCode) { - if (statusCode == HttpStatus.NOT_FOUND.value()) { - return true; - } - return super.retryableStatusCode(statusCode); - } - - } - - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java deleted file mode 100644 index b9ef63268..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.filters.route.support; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.web.ErrorProperties; -import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.RoutesEndpoint; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.support.RibbonRetryIntegrationTestBase.RetryableTestConfig; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.format.support.FormattingConversionService; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.converter.FormHttpMessageConverter; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.StringHttpMessageConverter; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.accept.ContentNegotiationManager; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import org.springframework.web.servlet.resource.ResourceUrlProvider; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.is; -import static org.junit.Assume.assumeThat; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; - -/** - * @author Spencer Gibb - * @author Ryan Baxter - */ -public abstract class ZuulProxyTestBase { - - @Value("${local.server.port}") - protected int port; - - @Autowired - protected DiscoveryClientRouteLocator routes; - - @Autowired - protected RoutesEndpoint endpoint; - - @Autowired - protected RibbonCommandFactory ribbonCommandFactory; - - @Autowired - protected MyErrorController myErrorController; - - @Before - public void cleanup() { - this.myErrorController.clear(); - } - - @Before - public void setTestRequestcontext() { - RequestContext.testSetCurrentContext(null); - RequestContext.getCurrentContext().unset(); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - /** - * used to disable patch tests if client doesn't support it - */ - protected boolean supportsPatch() { - return true; - } - - /** - * used to switch delete tests with a boyd if client doesn't support it - */ - protected boolean supportsDeleteWithBody() { - return true; - } - - protected String getRoute(String path) { - for (Route route : this.routes.getRoutes()) { - if (path.equals(route.getFullPath())) { - return route.getLocation(); - } - } - return null; - } - - @Test - public void bindRouteUsingPhysicalRoute() { - assertThat(getRoute("/test/**")).isEqualTo("http://localhost:7777/local"); - } - - @Test - public void bindRouteUsingOnlyPath() { - assertThat(getRoute("/simple/**")).isEqualTo("simple"); - } - - @Test - public void getOnSelfViaRibbonRoutingFilter() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/1", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Gotten 1!"); - } - - @Test - public void deleteOnSelfViaSimpleHostRoutingFilter() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/local"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/1", HttpMethod.DELETE, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Deleted 1!"); - } - - @Test - public void stripPrefixFalseAppendsPath() { - this.routes.addRoute(new ZuulProperties.ZuulRoute("strip", "/strip/**", "strip", - "http://localhost:" + this.port + "/local", false, false, null)); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/strip", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - // Prefix not stripped to it goes to /local/strip - assertThat(result.getBody()).isEqualTo("Gotten strip!"); - } - - @Test - public void testNotFoundFromApp() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/notfound", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); - } - - @Test - public void testNotFoundOnProxy() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/myinvalidpath", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); - } - - @Test - public void getSecondLevel() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/another/twolevel/local/1", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Gotten 1!"); - } - - @Test - public void ribbonRouteWithSpace() { - String uri = "/simple/spa ce"; - this.myErrorController.setUriToMatch(uri); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Hello space"); - assertThat(myErrorController.wasControllerUsed()).isFalse(); - } - - @Test - public void ribbonDeleteWithBody() { - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/deletewithbody", - HttpMethod.DELETE, new HttpEntity<>("deleterequestbody"), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - if (supportsDeleteWithBody()) { - assertThat(result.getBody()).isEqualTo("Deleted deleterequestbody"); - } - else { - assertThat(result.getBody()).isEqualTo("Deleted null"); - } - } - - @Test - public void ribbonRouteWithNonExistentUri() { - String uri = "/simple/nonExistent"; - this.myErrorController.setUriToMatch(uri); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); - assertThat(myErrorController.wasControllerUsed()).isFalse(); - } - - @Test - public void simpleHostRouteWithSpace() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port); - this.endpoint.reset(); - - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/spa ce", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Hello space"); - } - - @Test - public void simpleHostRouteWithOriginalQueryString() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port); - this.endpoint.reset(); - - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port - + "/self/qstring?original=value1&original=value2", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Received {original=[value1, value2]}"); - } - - @Test - public void simpleHostRouteWithOverriddenQString() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port); - this.endpoint.reset(); - - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port - + "/self/qstring?override=true&different=key", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Received {key=[overridden]}"); - } - - @Test - public void patchOnSelfViaSimpleHostRoutingFilter() { - assumeThat(supportsPatch(), is(true)); - - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/local"); - this.endpoint.reset(); - - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/1", HttpMethod.PATCH, - new HttpEntity<>("TestPatch"), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Patched 1!"); - } - - @SuppressWarnings("deprecation") - @Test - public void javascriptEncodedFormParams() { - TestRestTemplate testRestTemplate = new TestRestTemplate(); - ArrayList> converters = new ArrayList<>(); - converters.addAll(Arrays.asList(new StringHttpMessageConverter(), - new NoEncodingFormHttpMessageConverter())); - testRestTemplate.getRestTemplate().setMessageConverters(converters); - - MultiValueMap map = new LinkedMultiValueMap<>(); - map.add("foo", "(bar)"); - ResponseEntity result = testRestTemplate.postForEntity( - "http://localhost:" + this.port + "/simple/local", map, String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()) - .isEqualTo("Posted [(bar)] and Content-Length was: 13!"); - } - - public static abstract class AbstractZuulProxyApplication - extends DelegatingWebMvcConfiguration { - - private final Log LOG = LogFactory.getLog(RetryableTestConfig.class); - - @RequestMapping(value = "/local/{id}", method = RequestMethod.PATCH) - public String patch(@PathVariable final String id, - @RequestBody final String body) { - return "Patched " + id + "!"; - } - - @RequestMapping("/testing123") - public String testing123() { - throw new RuntimeException("myerror"); - } - - @RequestMapping("/local") - public String local() { - return "Hello local"; - } - - @RequestMapping(value = "/local", method = RequestMethod.POST) - public String postWithFormParam(HttpServletRequest request, - @RequestBody MultiValueMap body) { - return "Posted " + body.get("foo") + " and Content-Length was: " - + request.getContentLength() + "!"; - } - - @RequestMapping(value = "/deletewithbody", method = RequestMethod.DELETE) - public String deleteWithBody(@RequestBody(required = false) String body) { - return "Deleted " + body; - } - - @RequestMapping(value = "/local/{id}", method = RequestMethod.DELETE) - public String delete(@PathVariable String id) { - return "Deleted " + id + "!"; - } - - @RequestMapping(value = "/local/{id}", method = RequestMethod.GET) - public ResponseEntity get(@PathVariable String id) { - if ("notfound".equalsIgnoreCase(id)) { - return ResponseEntity.notFound().build(); - } - return ResponseEntity.ok("Gotten " + id + "!"); - } - - @RequestMapping(value = "/local/{id}", method = RequestMethod.POST) - public String post(@PathVariable String id, @RequestBody String body) { - return "Posted " + id + "!"; - } - - @RequestMapping("/qstring") - public String qstring(@RequestParam MultiValueMap params) { - return "Received " + params.toString(); - } - - @RequestMapping("/") - public String home() { - return "Hello world"; - } - - @RequestMapping("/spa ce") - public String space() { - return "Hello space"; - } - - @RequestMapping("/slow") - public String slow() { - try { - Thread.sleep(80000); - } - catch (InterruptedException e) { - LOG.info(e); - Thread.currentThread().interrupt(); - } - return "slow"; - } - - @Bean - public FallbackProvider fallbackProvider() { - return new ZuulFallbackProvider(); - } - - @Bean - public ZuulFilter sampleFilter() { - return new ZuulFilter() { - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - if (RequestContext.getCurrentContext().getRequest().getParameterMap() - .containsKey("override")) { - Map> overridden = new HashMap<>(); - overridden.put("key", Arrays.asList("overridden")); - RequestContext.getCurrentContext() - .setRequestQueryParams(overridden); - } - return null; - } - - @Override - public int filterOrder() { - return 0; - } - }; - - } - - @Override - public RequestMappingHandlerMapping requestMappingHandlerMapping( - ContentNegotiationManager mvcContentNegotiationManager, - FormattingConversionService mvcConversionService, - ResourceUrlProvider mvcResourceUrlProvider) { - RequestMappingHandlerMapping mapping = super.requestMappingHandlerMapping( - mvcContentNegotiationManager, mvcConversionService, - mvcResourceUrlProvider); - mapping.setRemoveSemicolonContent(false); - return mapping; - } - - } - - public static class ZuulFallbackProvider implements FallbackProvider { - - @Override - public String getRoute() { - return "simple"; - } - - @Override - public ClientHttpResponse fallbackResponse(String route, Throwable cause) { - return new ClientHttpResponse() { - @Override - public HttpStatus getStatusCode() throws IOException { - return HttpStatus.OK; - } - - @Override - public int getRawStatusCode() throws IOException { - return 200; - } - - @Override - public String getStatusText() throws IOException { - return null; - } - - @Override - public void close() { - - } - - @Override - public InputStream getBody() throws IOException { - return new ByteArrayInputStream("fallback".getBytes()); - } - - @Override - public HttpHeaders getHeaders() { - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.TEXT_HTML); - return headers; - } - }; - } - - } - - @Configuration(proxyBeanMethods = false) - public class FormEncodedMessageConverterConfiguration - extends WebMvcConfigurerAdapter { - - @Override - public void configureMessageConverters(List> converters) { - FormHttpMessageConverter converter = new FormHttpMessageConverter(); - MediaType mediaType = new MediaType("application", "x-www-form-urlencoded", - Charset.forName("UTF-8")); - converter.setSupportedMediaTypes(Arrays.asList(mediaType)); - converters.add(converter); - super.configureMessageConverters(converters); - } - - } - - // Load balancer with fixed server list for "simple" pointing to localhost - @Configuration(proxyBeanMethods = false) - public static class SimpleRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - - @Configuration(proxyBeanMethods = false) - public static class AnotherRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - - public static class MyErrorController extends BasicErrorController { - - ThreadLocal uriToMatch = new ThreadLocal<>(); - - AtomicBoolean controllerUsed = new AtomicBoolean(); - - public MyErrorController(ErrorAttributes errorAttributes) { - super(errorAttributes, new ErrorProperties()); - } - - @Override - public ResponseEntity> error(HttpServletRequest request) { - String errorUri = (String) request - .getAttribute("javax.servlet.error.request_uri"); - - if (errorUri != null && errorUri.equals(this.uriToMatch.get())) { - controllerUsed.set(true); - } - this.uriToMatch.remove(); - return super.error(request); - } - - public void setUriToMatch(String uri) { - this.uriToMatch.set(uri); - } - - public boolean wasControllerUsed() { - return this.controllerUsed.get(); - } - - public void clear() { - this.controllerUsed.set(false); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/DefaultCounterFactoryTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/DefaultCounterFactoryTests.java deleted file mode 100644 index 5d2c4362f..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/DefaultCounterFactoryTests.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.metrics; - -import com.netflix.zuul.monitoring.CounterFactory; -import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.MeterRegistry; -import org.junit.Test; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class DefaultCounterFactoryTests { - - private static final String NAME = "my-super-metric-name"; - - @Test - public void shouldIncrement() throws Exception { - MeterRegistry meterRegistry = mock(MeterRegistry.class); - CounterFactory factory = new DefaultCounterFactory(meterRegistry); - - Counter counter = mock(Counter.class); - when(meterRegistry.counter(NAME)).thenReturn(counter); - - factory.increment(NAME); - - verify(counter).increment(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/ZuulEmptyMetricsApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/ZuulEmptyMetricsApplicationTests.java deleted file mode 100644 index a6ea4c1c4..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/ZuulEmptyMetricsApplicationTests.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.metrics; - -import com.netflix.zuul.monitoring.CounterFactory; -import com.netflix.zuul.monitoring.TracerFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.netflix.zuul.EnableZuulServer; -import org.springframework.cloud.netflix.zuul.test.TestAutoConfiguration; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({ "spring-boot-starter-actuator-*.jar", "spring-boot-actuator-*.jar", - "micrometer-core-*.jar" }) -public class ZuulEmptyMetricsApplicationTests { - - private ConfigurableApplicationContext context; - - @Before - public void setUp() throws Exception { - ConfigurableApplicationContext context = new SpringApplicationBuilder( - ZuulEmptyMetricsApplicationTestsConfiguration.class) - .web(WebApplicationType.NONE).run("--debug"); - this.context = context; - } - - @After - public void tearDown() throws Exception { - if (this.context != null) { - this.context.close(); - } - } - - @Test - public void shouldSetupDefaultCounterFactoryIfCounterServiceIsPresent() - throws Exception { - CounterFactory factory = this.context.getBean(CounterFactory.class); - - assertThat(factory.getClass()).isEqualTo(EmptyCounterFactory.class); - } - - @Test - public void shouldSetupEmptyTracerFactory() throws Exception { - TracerFactory factory = this.context.getBean(TracerFactory.class); - - assertThat(factory.getClass()).isEqualTo(EmptyTracerFactory.class); - } - - @EnableAutoConfiguration(exclude = TestAutoConfiguration.class) - @Configuration(proxyBeanMethods = false) - // @Import(NoSecurityConfiguration.class) - @EnableZuulServer - @EnableConfigurationProperties(ServerProperties.class) - static class ZuulEmptyMetricsApplicationTestsConfiguration { - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/ZuulMetricsApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/ZuulMetricsApplicationTests.java deleted file mode 100644 index 47a8aa88d..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/ZuulMetricsApplicationTests.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.metrics; - -import com.netflix.zuul.exception.ZuulException; -import com.netflix.zuul.monitoring.CounterFactory; -import com.netflix.zuul.monitoring.TracerFactory; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.MockClock; -import io.micrometer.core.instrument.simple.SimpleConfig; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.EnableZuulServer; -import org.springframework.cloud.netflix.zuul.util.ZuulRuntimeException; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = { - ZuulMetricsApplicationTests.ZuulMetricsApplicationTestsConfiguration.class, - ZuulMetricsApplicationTests.ZuulConfig.class }, webEnvironment = RANDOM_PORT) -@DirtiesContext -public class ZuulMetricsApplicationTests { - - @Autowired - private CounterFactory counterFactory; - - @Autowired - private TracerFactory tracerFactory; - - @Autowired - private MeterRegistry meterRegistry; - - @Test - public void shouldSetupDefaultCounterFactoryIfCounterServiceIsPresent() - throws Exception { - assertThat(counterFactory.getClass()).isEqualTo(DefaultCounterFactory.class); - } - - @Test - public void shouldSetupEmptyTracerFactory() throws Exception { - assertThat(tracerFactory.getClass()).isEqualTo(EmptyTracerFactory.class); - } - - @Test - @SuppressWarnings("all") - public void shouldIncrementCounters() throws Exception { - new ZuulRuntimeException(new Exception()); - - Double count = meterRegistry.counter("ZUUL::EXCEPTION:null:500").count(); - assertThat(0L).isEqualTo(count.longValue()); - - new ZuulException("any", 500, "cause"); - new ZuulException("any", 500, "cause"); - - count = meterRegistry.counter("ZUUL::EXCEPTION:cause:500").count(); - assertThat(2L).isEqualTo(count.longValue()); - - new ZuulException("any", 404, "cause2"); - new ZuulException("any", 404, "cause2"); - new ZuulException("any", 404, "cause2"); - - count = meterRegistry.counter("ZUUL::EXCEPTION:cause2:404").count(); - assertThat(3L).isEqualTo(count.longValue()); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @EnableZuulServer - static class ZuulConfig { - - } - - @Configuration(proxyBeanMethods = false) - static class ZuulMetricsApplicationTestsConfiguration { - - @Bean - public MeterRegistry meterRegistry() { - return new SimpleMeterRegistry(SimpleConfig.DEFAULT, new MockClock()); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/AdhocTestSuite.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/AdhocTestSuite.java deleted file mode 100644 index 14a60e88c..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/AdhocTestSuite.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.test; - -import org.junit.Ignore; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilterIntegrationTests; - -/** - * A test suite for probing weird ordering problems in the zuul tests. - * - * @author Spencer Gibb - */ -@RunWith(Suite.class) -@SuiteClasses({ - org.springframework.cloud.netflix.zuul.ZuulServerAutoConfigurationTests.class, - org.springframework.cloud.netflix.zuul.RoutesEndpointTests.class, - org.springframework.cloud.netflix.zuul.FormZuulServletProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.metrics.DefaultCounterFactoryTests.class, - org.springframework.cloud.netflix.zuul.metrics.ZuulEmptyMetricsApplicationTests.class, - org.springframework.cloud.netflix.zuul.metrics.ZuulMetricsApplicationTests.class, - org.springframework.cloud.netflix.zuul.web.ZuulHandlerMappingTests.class, - org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfigurationTests.class, - org.springframework.cloud.netflix.zuul.RetryableZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.ServletPathZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.FormZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.filters.CompositeRouteLocatorTests.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFallbackTests.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactoryTest.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonRetryIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.LazyLoadOfZuulConfigurationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.EagerLoadOfZuulConfigurationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommandTests.class, - org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilterLoadBalancerKeyIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFallbackTests.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonRetryIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFactoryTest.class, - org.springframework.cloud.netflix.zuul.filters.route.restclient.RestClientRibbonCommandIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.restclient.RestClientRibbonCommandFallbackTests.class, - org.springframework.cloud.netflix.zuul.filters.route.support.RibbonCommandCauseFallbackPropagationTest.class, - org.springframework.cloud.netflix.zuul.filters.route.support.RibbonCommandHystrixThreadPoolKeyTests.class, - SimpleHostRoutingFilterIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelperTests.class, - org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocatorTests.class, - org.springframework.cloud.netflix.zuul.filters.ZuulPropertiesTests.class, - org.springframework.cloud.netflix.zuul.filters.CustomHostRoutingFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapperIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapperTests.class, - org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocatorTests.class, - org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.post.LocationRewriteFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilterIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.post.LocationRewriteFilterIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilterTests.class, - org.springframework.cloud.netflix.zuul.RoutesEndpointDetailsTests.class, - org.springframework.cloud.netflix.zuul.ZuulProxyConfigurationTests.class, - org.springframework.cloud.netflix.zuul.ZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.SimpleZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.ZuulFilterInitializerTests.class, - org.springframework.cloud.netflix.zuul.RoutesEndpointIntegrationTests.class, - org.springframework.cloud.netflix.zuul.test.ZuulApacheHttpClientConfigurationTests.class, - org.springframework.cloud.netflix.zuul.test.ZuulOkHttpClientConfigurationTests.class, - org.springframework.cloud.netflix.zuul.ContextPathZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.SimpleZuulServerApplicationTests.class, - org.springframework.cloud.netflix.zuul.FiltersEndpointTests.class }) -@Ignore -public class AdhocTestSuite { - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/AdhocZuulTestSuite.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/AdhocZuulTestSuite.java deleted file mode 100644 index 2336fc4ee..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/AdhocZuulTestSuite.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.test; - -import org.junit.Ignore; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilterIntegrationTests; - -/** - * A test suite for probing weird ordering problems in the tests. - * - * @author Dave Syer - */ -@RunWith(Suite.class) -@SuiteClasses({ - org.springframework.cloud.netflix.zuul.ContextPathZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.filters.CompositeRouteLocatorTests.class, - org.springframework.cloud.netflix.zuul.filters.CustomHostRoutingFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocatorTests.class, - org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapperIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapperTests.class, - org.springframework.cloud.netflix.zuul.filters.post.LocationRewriteFilterIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.post.LocationRewriteFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilterIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelperTests.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactoryTest.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFallbackTests.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonRetryIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.EagerLoadOfZuulConfigurationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.LazyLoadOfZuulConfigurationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFactoryTest.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFallbackTests.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonRetryIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.restclient.RestClientRibbonCommandFallbackTests.class, - org.springframework.cloud.netflix.zuul.filters.route.restclient.RestClientRibbonCommandIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommandTests.class, - org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilterTests.class, - SimpleHostRoutingFilterIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.support.RibbonCommandCauseFallbackPropagationTest.class, - org.springframework.cloud.netflix.zuul.filters.route.support.RibbonCommandHystrixThreadPoolKeyTests.class, - org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocatorTests.class, - org.springframework.cloud.netflix.zuul.filters.ZuulPropertiesTests.class, - org.springframework.cloud.netflix.zuul.FiltersEndpointTests.class, - org.springframework.cloud.netflix.zuul.FormZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.FormZuulServletProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.metrics.DefaultCounterFactoryTests.class, - org.springframework.cloud.netflix.zuul.metrics.ZuulEmptyMetricsApplicationTests.class, - org.springframework.cloud.netflix.zuul.metrics.ZuulMetricsApplicationTests.class, - org.springframework.cloud.netflix.zuul.RetryableZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.RoutesEndpointDetailsTests.class, - org.springframework.cloud.netflix.zuul.RoutesEndpointIntegrationTests.class, - org.springframework.cloud.netflix.zuul.RoutesEndpointTests.class, - org.springframework.cloud.netflix.zuul.ServletPathZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.SimpleZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.SimpleZuulServerApplicationTests.class, - org.springframework.cloud.netflix.zuul.test.ZuulApacheHttpClientConfigurationTests.class, - org.springframework.cloud.netflix.zuul.test.ZuulOkHttpClientConfigurationTests.class, - org.springframework.cloud.netflix.zuul.web.ZuulHandlerMappingTests.class, - org.springframework.cloud.netflix.zuul.ZuulFilterInitializerTests.class, - org.springframework.cloud.netflix.zuul.ZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfigurationTests.class, - org.springframework.cloud.netflix.zuul.ZuulProxyConfigurationTests.class, - org.springframework.cloud.netflix.zuul.ZuulServerAutoConfigurationTests.class }) -@Ignore -public class AdhocZuulTestSuite { - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/NoSecurityConfiguration.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/NoSecurityConfiguration.java deleted file mode 100644 index f73bcdb9a..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/NoSecurityConfiguration.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.test; - -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration(proxyBeanMethods = false) -public class NoSecurityConfiguration extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.authorizeRequests().anyRequest().permitAll().and().csrf().disable(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/TestAutoConfiguration.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/TestAutoConfiguration.java deleted file mode 100644 index 516fcf2dd..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/TestAutoConfiguration.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.test; - -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.web.firewall.StrictHttpFirewall; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@Import({ NoopDiscoveryClientAutoConfiguration.class }) -@AutoConfigureBefore(SecurityAutoConfiguration.class) -public class TestAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - @Order(Ordered.HIGHEST_PRECEDENCE) - protected static class TestSecurityConfiguration - extends WebSecurityConfigurerAdapter { - - TestSecurityConfiguration() { - super(true); - } - - @Override - public void configure(WebSecurity web) { - StrictHttpFirewall httpFirewall = new StrictHttpFirewall(); - httpFirewall.setAllowSemicolon(true); - web.httpFirewall(httpFirewall); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - // super.configure(http); - http.antMatcher("/proxy-username").httpBasic().and().authorizeRequests() - .antMatchers("/**").permitAll(); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/ZuulApacheHttpClientConfigurationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/ZuulApacheHttpClientConfigurationTests.java deleted file mode 100644 index 0e6aa11f5..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/ZuulApacheHttpClientConfigurationTests.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.test; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.ArrayList; - -import org.apache.http.Header; -import org.apache.http.StatusLine; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.message.BasicHeader; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockingDetails; -import org.mockito.Mockito; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; -import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientFactory; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter; -import org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommand; -import org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.ReflectionUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.mockingDetails; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(properties = { "ribbon.eureka.enabled = false" }) -@DirtiesContext -public class ZuulApacheHttpClientConfigurationTests { - - @Autowired - SimpleHostRoutingFilter simpleHostRoutingFilter; - - @Autowired - HttpClientRibbonCommandFactory httpClientRibbonCommandFactory; - - @Test - public void testHttpClientSimpleHostRoutingFilter() { - CloseableHttpClient httpClient = getField(simpleHostRoutingFilter, "httpClient"); - MockingDetails httpClientDetails = mockingDetails(httpClient); - assertThat(httpClientDetails.isMock()); - } - - @Test - public void testRibbonLoadBalancingHttpClient() { - RibbonCommandContext context = new RibbonCommandContext("foo", " GET", - "http://localhost", false, new LinkedMultiValueMap<>(), - new LinkedMultiValueMap<>(), null, new ArrayList<>(), 0L); - HttpClientRibbonCommand command = httpClientRibbonCommandFactory.create(context); - RibbonLoadBalancingHttpClient ribbonClient = command.getClient(); - CloseableHttpClient httpClient = getField(ribbonClient, "delegate"); - MockingDetails httpClientDetails = mockingDetails(httpClient); - assertThat(httpClientDetails.isMock()); - } - - @SuppressWarnings("unchecked") - protected T getField(Object target, String name) { - Field field = ReflectionUtils.findField(target.getClass(), name); - ReflectionUtils.makeAccessible(field); - Object value = ReflectionUtils.getField(field, target); - return (T) value; - } - - @Bean - public ApacheHttpClientFactory apacheHttpClientFactory(HttpClientBuilder builder) { - return new TestConfig.MyApacheHttpClientFactory(builder); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableZuulProxy - static class TestConfig { - - static class MyApacheHttpClientFactory extends DefaultApacheHttpClientFactory { - - MyApacheHttpClientFactory(HttpClientBuilder builder) { - super(builder); - } - - @Override - public HttpClientBuilder createBuilder() { - CloseableHttpClient client = mock(CloseableHttpClient.class); - CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - Mockito.doReturn(statusLine).when(response).getStatusLine(); - Header[] headers = new BasicHeader[0]; - doReturn(headers).when(response).getAllHeaders(); - try { - Mockito.doReturn(response).when(client) - .execute(any(HttpUriRequest.class)); - } - catch (IOException e) { - e.printStackTrace(); - } - HttpClientBuilder builder = mock(HttpClientBuilder.class); - Mockito.doReturn(client).when(builder).build(); - return builder; - } - - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/ZuulOkHttpClientConfigurationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/ZuulOkHttpClientConfigurationTests.java deleted file mode 100644 index 3f2f21cd7..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/ZuulOkHttpClientConfigurationTests.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.test; - -import java.lang.reflect.Field; -import java.util.ArrayList; - -import okhttp3.OkHttpClient; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockingDetails; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory; -import org.springframework.cloud.commons.httpclient.OkHttpClientFactory; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommand; -import org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.ReflectionUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.mockingDetails; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(properties = { "spring.cloud.httpclientfactories.ok.enabled: true", - "ribbon.eureka.enabled = false", "ribbon.okhttp.enabled: true", - "ribbon.httpclient.enabled: false" }) -@DirtiesContext -public class ZuulOkHttpClientConfigurationTests { - - @Autowired - OkHttpClientFactory okHttpClientFactory; - - @Autowired - OkHttpClientConnectionPoolFactory connectionPoolFactory; - - @Autowired - OkHttpRibbonCommandFactory okHttpRibbonCommandFactory; - - @Test - public void testOkHttpLoadBalancingHttpClient() { - RibbonCommandContext context = new RibbonCommandContext("foo", " GET", - "http://localhost", false, new LinkedMultiValueMap<>(), - new LinkedMultiValueMap<>(), null, new ArrayList<>(), 0L); - OkHttpRibbonCommand command = okHttpRibbonCommandFactory.create(context); - OkHttpLoadBalancingClient ribbonClient = command.getClient(); - OkHttpClient httpClient = getField(ribbonClient, "delegate"); - MockingDetails httpClientDetails = mockingDetails(httpClient); - assertThat(httpClientDetails.isMock()).isTrue(); - } - - protected T getField(Object target, String name) { - Field field = ReflectionUtils.findField(target.getClass(), name); - ReflectionUtils.makeAccessible(field); - Object value = ReflectionUtils.getField(field, target); - return (T) value; - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableZuulProxy - static class TestConfig { - - @Bean - public OkHttpClient client() { - return mock(OkHttpClient.class); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractorTest.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractorTest.java deleted file mode 100644 index 8145907dd..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractorTest.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.util; - -import java.io.IOException; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import org.springframework.http.HttpEntity; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.multipart.MultipartHttpServletRequest; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.beans.HasPropertyWithValue.hasProperty; -import static org.mockito.Mockito.when; - -/** - * Created by Dmitrii_Priporov on 01.07.18. - */ -@RunWith(MockitoJUnitRunner.class) -public class RequestContentDataExtractorTest { - - @Mock - private MultipartHttpServletRequest request; - - @Test - public void methodExtractShouldReturnNotDuplicatedValuesFromRequest() - throws Exception { - // when - when(request.getMultiFileMap()).thenReturn(new LinkedMultiValueMap<>()); - when(request.getQueryString()).thenReturn("uid=12&uid=34"); - - Map expectedParameterMap = new HashMap() { - { - put("uid", new String[] { "65" }); - } - }; - when(request.getParameterMap()).thenReturn(expectedParameterMap); - - // action - MultiValueMap result = RequestContentDataExtractor - .extract(request); - - // then - assertThat(result).isNotNull(); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get("uid")).isNotNull(); - assertThat(result.get("uid")).hasSize(1); - Assert.assertThat(result.get("uid"), hasItem(hasProperty("body", equalTo("65")))); - Assert.assertThat(result.get("uid"), - hasItem(hasProperty("headers", notNullValue()))); - } - - @Test - public void methodExtractShouldReturnNotDuplicatedValuesFromRequestWhenEncoded() - throws Exception { - // when - when(request.getMultiFileMap()).thenReturn(new LinkedMultiValueMap<>()); - when(request.getQueryString()).thenReturn("uid=hello%20world"); - - Map expectedParameterMap = new HashMap() { - { - put("uid", new String[] { "hello world" }); - } - }; - when(request.getParameterMap()).thenReturn(expectedParameterMap); - - // action - MultiValueMap result = RequestContentDataExtractor - .extract(request); - - // then - assertThat(result).isNotNull(); - assertThat(result.size()).isEqualTo(0); - } - - @Test - public void findQueryParamsGroupedByNameShouldReturnCorrectResult() { - // when - when(request.getQueryString()).thenReturn("uid=12&uid=34"); - - // action - Map> result = RequestContentDataExtractor - .findQueryParamsGroupedByName(request); - - // then - assertThat(result).containsEntry("uid", asList("12", "34")); - assertThat(result.size()).isEqualTo(1); - } - - @Test - public void findQueryParamsGroupedByNameShouldReturnEmptyMapWhenQueryIsEmpty() { - // when - when(request.getQueryString()).thenReturn(""); - - // action - Map> result = RequestContentDataExtractor - .findQueryParamsGroupedByName(request); - - // then - assertThat(result).isNotNull(); - assertThat(result.size()).isEqualTo(0); - } - - @Test - public void findQueryParamsGroupedByNameShouldReturnEmptyMapWhenQueryIsNull() { - // when - when(request.getQueryString()).thenReturn(null); - - // action - Map> result = RequestContentDataExtractor - .findQueryParamsGroupedByName(request); - - // then - assertThat(result).isNotNull(); - assertThat(result.size()).isEqualTo(0); - } - - @Test - public void findQueryParamsGroupedByNameShouldReturnEmptyMapWhenQueryValueIsNull() - throws IOException { - // when - Map paramMap = new HashMap<>(); - paramMap.put("uid", new String[] { "foo", "bar" }); - when(request.getQueryString()).thenReturn("uid"); - when(request.getParameterMap()).thenReturn(paramMap); - when(request.getMultiFileMap()).thenReturn(new LinkedMultiValueMap<>()); - - // action - Map> result = RequestContentDataExtractor.extract(request); - - // then - List uidResult = new LinkedList(); - uidResult.add(new HttpEntity<>("foo")); - uidResult.add(new HttpEntity<>("bar")); - assertThat(result).isNotNull(); - assertThat(result).containsEntry("uid", uidResult); - assertThat(result.size()).isEqualTo(1); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/web/ZuulHandlerMappingTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/web/ZuulHandlerMappingTests.java deleted file mode 100644 index 571120ea2..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/web/ZuulHandlerMappingTests.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.netflix.zuul.web; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import com.netflix.zuul.context.RequestContext; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; - -import org.springframework.boot.web.servlet.error.ErrorController; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.mock.web.MockHttpServletRequest; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * @author Biju Kunjummen - */ -public class ZuulHandlerMappingTests { - - private ZuulHandlerMapping mapping; - - private RouteLocator locator = Mockito.mock(RouteLocator.class); - - private ErrorController errors = Mockito.mock(ErrorController.class); - - private MockHttpServletRequest request = new MockHttpServletRequest(); - - @Before - public void init() { - RequestContext.getCurrentContext().clear(); - this.mapping = new ZuulHandlerMapping(this.locator, new ZuulController()); - this.mapping.setErrorController(this.errors); - Mockito.when(this.errors.getErrorPath()).thenReturn("/error"); - } - - @Test - public void mappedPath() throws Exception { - Mockito.when(this.locator.getRoutes()).thenReturn(Collections - .singletonList(new Route("foo", "/foo/**", "foo", "", null, null))); - this.request.setServletPath("/foo/"); - this.mapping.setDirty(true); - assertThat(this.mapping.getHandler(this.request)).isNotNull(); - } - - @Test - public void defaultPath() throws Exception { - Mockito.when(this.locator.getRoutes()).thenReturn(Collections - .singletonList(new Route("default", "/**", "foo", "", null, null))); - this.request.setServletPath("/"); - this.mapping.setDirty(true); - assertThat(this.mapping.getHandler(this.request)).isNotNull(); - } - - @Test - public void errorPath() throws Exception { - Mockito.when(this.locator.getRoutes()).thenReturn(Collections - .singletonList(new Route("default", "/**", "foo", "", null, null))); - this.request.setServletPath("/error"); - this.mapping.setDirty(true); - assertThat(this.mapping.getHandler(this.request)).isNull(); - } - - @Test - public void ignoredPathsShouldNotReturnAHandler() throws Exception { - assertThat(mappingWithIgnoredPathsAndRoutes(Arrays.asList("/p1/**"), - new Route("p1", "/p1/**", "p1", "", null, null)) - .getHandler(requestForAPath("/p1"))).isNull(); - - assertThat(mappingWithIgnoredPathsAndRoutes(Arrays.asList("/p1/**/p3/"), - new Route("p1", "/p1/**/p3", "p1", "", null, null)) - .getHandler(requestForAPath("/p1/p2/p3"))).isNull(); - - assertThat(mappingWithIgnoredPathsAndRoutes(Arrays.asList("/p1/**/p3/**"), - new Route("p1", "/p1/**/p3", "p1", "", null, null)) - .getHandler(requestForAPath("/p1/p2/p3"))).isNull(); - - assertThat(mappingWithIgnoredPathsAndRoutes(Arrays.asList("/p1/**/p4/"), - new Route("p1", "/p1/**/p4/", "p1", "", null, null)) - .getHandler(requestForAPath("/p1/p2/p3/p4"))).isNull(); - } - - private ZuulHandlerMapping mappingWithIgnoredPathsAndRoutes(List ignoredPaths, - Route route) { - RouteLocator routeLocator = Mockito.mock(RouteLocator.class); - Mockito.when(routeLocator.getIgnoredPaths()).thenReturn(ignoredPaths); - Mockito.when(routeLocator.getRoutes()) - .thenReturn(Collections.singletonList(route)); - ZuulHandlerMapping zuulHandlerMapping = new ZuulHandlerMapping(routeLocator, - new ZuulController()); - return zuulHandlerMapping; - } - - private MockHttpServletRequest requestForAPath(String path) { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setServletPath(path); - return request; - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/resources/META-INF/spring.factories b/spring-cloud-netflix-zuul/src/test/resources/META-INF/spring.factories deleted file mode 100644 index 9819adfef..000000000 --- a/spring-cloud-netflix-zuul/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.zuul.test.TestAutoConfiguration diff --git a/spring-cloud-netflix-zuul/src/test/resources/application.yml b/spring-cloud-netflix-zuul/src/test/resources/application.yml deleted file mode 100644 index de191f824..000000000 --- a/spring-cloud-netflix-zuul/src/test/resources/application.yml +++ /dev/null @@ -1,26 +0,0 @@ -server: - port: 9999 - compression: - enabled: true - min-response-size: 1024 - mime-types: application/xml,application/json -spring: - application: - name: testclient -#zuul: - #prefix: /api - #strip-prefix: true -# routes: -# test: -# serviceId: testclient -# path: /testing123/** -# stores: -# url: http://localhost:8081 -# path: /stores/** -hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000 -management: - context-path: /admin -endpoints.default.web.enabled: true -logging: - level: - org.springframework.cloud.netflix.zuul: DEBUG \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-eureka-client/pom.xml b/spring-cloud-starter-netflix-eureka-client/pom.xml similarity index 69% rename from spring-cloud-starter-netflix/spring-cloud-starter-netflix-eureka-client/pom.xml rename to spring-cloud-starter-netflix-eureka-client/pom.xml index 1433d2286..0b6c8b17a 100644 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-eureka-client/pom.xml +++ b/spring-cloud-starter-netflix-eureka-client/pom.xml @@ -3,8 +3,8 @@ 4.0.0 org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT + spring-cloud-netflix + 3.0.0.BUILD-SNAPSHOT spring-cloud-starter-netflix-eureka-client Spring Cloud Starter Netflix Eureka Client @@ -19,10 +19,6 @@ org.springframework.cloud spring-cloud-starter - - org.springframework.cloud - spring-cloud-netflix-hystrix - org.springframework.cloud spring-cloud-netflix-eureka-client @@ -35,22 +31,10 @@ com.netflix.eureka eureka-core - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - org.springframework.cloud spring-cloud-starter-loadbalancer - - com.netflix.ribbon - ribbon-eureka - com.thoughtworks.xstream xstream diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-eureka-server/pom.xml b/spring-cloud-starter-netflix-eureka-server/pom.xml similarity index 71% rename from spring-cloud-starter-netflix/spring-cloud-starter-netflix-eureka-server/pom.xml rename to spring-cloud-starter-netflix-eureka-server/pom.xml index b57820d4d..ab4ec0e6d 100644 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-eureka-server/pom.xml +++ b/spring-cloud-starter-netflix-eureka-server/pom.xml @@ -2,8 +2,8 @@ 4.0.0 org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT + spring-cloud-netflix + 3.0.0.BUILD-SNAPSHOT spring-cloud-starter-netflix-eureka-server Spring Cloud Starter Netflix Eureka Server @@ -22,22 +22,10 @@ org.springframework.cloud spring-cloud-netflix-eureka-server - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - org.springframework.cloud spring-cloud-starter-loadbalancer - - com.netflix.ribbon - ribbon-eureka - org.glassfish.jaxb diff --git a/spring-cloud-starter-netflix/pom.xml b/spring-cloud-starter-netflix/pom.xml deleted file mode 100644 index d2c7f1644..000000000 --- a/spring-cloud-starter-netflix/pom.xml +++ /dev/null @@ -1,25 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - spring-cloud-starter-netflix - pom - Spring Cloud Netflix Starters - Spring Cloud Netflix Starters - - spring-cloud-starter-netflix-archaius - spring-cloud-starter-netflix-eureka-client - spring-cloud-starter-netflix-eureka-server - spring-cloud-starter-netflix-hystrix - spring-cloud-starter-netflix-hystrix-dashboard - spring-cloud-starter-netflix-ribbon - spring-cloud-starter-netflix-turbine - spring-cloud-starter-netflix-turbine-stream - spring-cloud-starter-netflix-zuul - - \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-archaius/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-netflix-archaius/pom.xml deleted file mode 100644 index dd6f8b519..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-archaius/pom.xml +++ /dev/null @@ -1,39 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT - - spring-cloud-starter-netflix-archaius - Spring Cloud Starter Netflix Archaius - Spring Cloud Starter Netflix Archaius - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - - org.springframework.cloud - spring-cloud-starter - - - org.springframework.cloud - spring-cloud-netflix-ribbon - - - org.springframework.cloud - spring-cloud-netflix-archaius - - - com.netflix.archaius - archaius-core - - - commons-configuration - commons-configuration - - - diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-hystrix-dashboard/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-netflix-hystrix-dashboard/pom.xml deleted file mode 100644 index 621600c1a..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-hystrix-dashboard/pom.xml +++ /dev/null @@ -1,35 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT - - spring-cloud-starter-netflix-hystrix-dashboard - Spring Cloud Starter Netflix Hystrix Dashboard - Spring Cloud Starter Netflix Hystrix Dashboard - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.cloud - spring-cloud-starter - - - org.springframework.cloud - spring-cloud-netflix-hystrix-dashboard - - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - - - \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-hystrix/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-netflix-hystrix/pom.xml deleted file mode 100644 index bd2d326b0..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-hystrix/pom.xml +++ /dev/null @@ -1,55 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT - - spring-cloud-starter-netflix-hystrix - Spring Cloud Starter Netflix Hystrix - Spring Cloud Starter Netflix Hystrix - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - - org.springframework.cloud - spring-cloud-starter - - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.springframework.cloud - spring-cloud-netflix-ribbon - - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - - - com.netflix.hystrix - hystrix-core - - - com.netflix.hystrix - hystrix-serialization - - - com.netflix.hystrix - hystrix-metrics-event-stream - - - com.netflix.hystrix - hystrix-javanica - - - io.reactivex - rxjava-reactive-streams - - - \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-ribbon/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-netflix-ribbon/pom.xml deleted file mode 100644 index cdd753854..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-ribbon/pom.xml +++ /dev/null @@ -1,61 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT - - spring-cloud-starter-netflix-ribbon - Spring Cloud Starter Netflix Ribbon - Spring Cloud Starter Netflix Ribbon - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - - org.springframework.cloud - spring-cloud-starter - - - org.springframework.cloud - spring-cloud-netflix-ribbon - - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - - - com.netflix.ribbon - ribbon - - - io.netty - netty-codec-http - - - io.netty - netty-transport-native-epoll - - - - - com.netflix.ribbon - ribbon-core - - - com.netflix.ribbon - ribbon-httpclient - - - com.netflix.ribbon - ribbon-loadbalancer - - - io.reactivex - rxjava - - - \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-turbine-stream/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-netflix-turbine-stream/pom.xml deleted file mode 100644 index 69e434f5b..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-turbine-stream/pom.xml +++ /dev/null @@ -1,75 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT - - spring-cloud-starter-netflix-turbine-stream - Spring Cloud Starter Netflix Turbine Stream - Spring Cloud Starter Netflix Turbine Stream - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - 2.0.0-DP.2 - - - - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client - - - spring-boot-starter-tomcat - org.springframework.boot - - - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - - - org.springframework.cloud - spring-cloud-netflix-turbine-stream - - - org.springframework.cloud - spring-cloud-stream - - - com.fasterxml.jackson.core - jackson-databind - - - com.netflix.turbine - turbine-core - ${turbine.version} - - - com.netflix.rxjava - rxjava-core - - - org.slf4j - slf4j-simple - - - - - io.reactivex - rxjava - - - org.apache.tomcat.embed - tomcat-embed-el - - - \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-turbine/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-netflix-turbine/pom.xml deleted file mode 100644 index a4ce24716..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-turbine/pom.xml +++ /dev/null @@ -1,61 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT - - spring-cloud-starter-netflix-turbine - Spring Cloud Starter Netflix Turbine - Spring Cloud Starter Netflix Turbine - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - 1.0.0 - - - - org.springframework.cloud - spring-cloud-starter - - - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client - - - org.springframework.cloud - spring-cloud-netflix-turbine - - - com.netflix.turbine - turbine-core - ${turbine.version} - - - javax.servlet - servlet-api - - - log4j - log4j - - - com.netflix.rxjava - rxjava-core - - - org.slf4j - slf4j-simple - - - org.mockito - mockito-all - - - - - \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-zuul/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-netflix-zuul/pom.xml deleted file mode 100644 index 56dbe043a..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-zuul/pom.xml +++ /dev/null @@ -1,51 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT - - spring-cloud-starter-netflix-zuul - Spring Cloud Starter Netflix Zuul - Spring Cloud Starter Netflix Zuul - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - - org.springframework.cloud - spring-cloud-netflix-zuul - - - org.springframework.cloud - spring-cloud-starter - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.cloud - spring-cloud-starter-netflix-hystrix - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - - - com.netflix.zuul - zuul-core - - - \ No newline at end of file